Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //==- DependentDiagnostic.h - Dependently-generated diagnostics --*- C++ -*-==//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file defines interfaces for diagnostics which may or may
  10. //  fire based on how a template is instantiated.
  11. //
  12. //  At the moment, the only consumer of this interface is access
  13. //  control.
  14. //
  15. //===----------------------------------------------------------------------===//
  16.  
  17. #ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
  18. #define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
  19.  
  20. #include "clang/AST/DeclBase.h"
  21. #include "clang/AST/DeclContextInternals.h"
  22. #include "clang/AST/Type.h"
  23. #include "clang/Basic/PartialDiagnostic.h"
  24. #include "clang/Basic/SourceLocation.h"
  25. #include "clang/Basic/Specifiers.h"
  26. #include <cassert>
  27. #include <iterator>
  28.  
  29. namespace clang {
  30.  
  31. class ASTContext;
  32. class CXXRecordDecl;
  33. class NamedDecl;
  34.  
  35. /// A dependently-generated diagnostic.
  36. class DependentDiagnostic {
  37. public:
  38.   enum AccessNonce { Access = 0 };
  39.  
  40.   static DependentDiagnostic *Create(ASTContext &Context,
  41.                                      DeclContext *Parent,
  42.                                      AccessNonce _,
  43.                                      SourceLocation Loc,
  44.                                      bool IsMemberAccess,
  45.                                      AccessSpecifier AS,
  46.                                      NamedDecl *TargetDecl,
  47.                                      CXXRecordDecl *NamingClass,
  48.                                      QualType BaseObjectType,
  49.                                      const PartialDiagnostic &PDiag) {
  50.     DependentDiagnostic *DD = Create(Context, Parent, PDiag);
  51.     DD->AccessData.Loc = Loc;
  52.     DD->AccessData.IsMember = IsMemberAccess;
  53.     DD->AccessData.Access = AS;
  54.     DD->AccessData.TargetDecl = TargetDecl;
  55.     DD->AccessData.NamingClass = NamingClass;
  56.     DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
  57.     return DD;
  58.   }
  59.  
  60.   unsigned getKind() const {
  61.     return Access;
  62.   }
  63.  
  64.   bool isAccessToMember() const {
  65.     assert(getKind() == Access);
  66.     return AccessData.IsMember;
  67.   }
  68.  
  69.   AccessSpecifier getAccess() const {
  70.     assert(getKind() == Access);
  71.     return AccessSpecifier(AccessData.Access);
  72.   }
  73.  
  74.   SourceLocation getAccessLoc() const {
  75.     assert(getKind() == Access);
  76.     return AccessData.Loc;
  77.   }
  78.  
  79.   NamedDecl *getAccessTarget() const {
  80.     assert(getKind() == Access);
  81.     return AccessData.TargetDecl;
  82.   }
  83.  
  84.   NamedDecl *getAccessNamingClass() const {
  85.     assert(getKind() == Access);
  86.     return AccessData.NamingClass;
  87.   }
  88.  
  89.   QualType getAccessBaseObjectType() const {
  90.     assert(getKind() == Access);
  91.     return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
  92.   }
  93.  
  94.   const PartialDiagnostic &getDiagnostic() const {
  95.     return Diag;
  96.   }
  97.  
  98. private:
  99.   friend class DeclContext::ddiag_iterator;
  100.   friend class DependentStoredDeclsMap;
  101.  
  102.   DependentDiagnostic(const PartialDiagnostic &PDiag,
  103.                       DiagnosticStorage *Storage)
  104.       : Diag(PDiag, Storage) {}
  105.  
  106.   static DependentDiagnostic *Create(ASTContext &Context,
  107.                                      DeclContext *Parent,
  108.                                      const PartialDiagnostic &PDiag);
  109.  
  110.   DependentDiagnostic *NextDiagnostic;
  111.  
  112.   PartialDiagnostic Diag;
  113.  
  114.   struct {
  115.     SourceLocation Loc;
  116.     unsigned Access : 2;
  117.     unsigned IsMember : 1;
  118.     NamedDecl *TargetDecl;
  119.     CXXRecordDecl *NamingClass;
  120.     void *BaseObjectType;
  121.   } AccessData;
  122. };
  123.  
  124. /// An iterator over the dependent diagnostics in a dependent context.
  125. class DeclContext::ddiag_iterator {
  126. public:
  127.   ddiag_iterator() = default;
  128.   explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
  129.  
  130.   using value_type = DependentDiagnostic *;
  131.   using reference = DependentDiagnostic *;
  132.   using pointer = DependentDiagnostic *;
  133.   using difference_type = int;
  134.   using iterator_category = std::forward_iterator_tag;
  135.  
  136.   reference operator*() const { return Ptr; }
  137.  
  138.   ddiag_iterator &operator++() {
  139.     assert(Ptr && "attempt to increment past end of diag list");
  140.     Ptr = Ptr->NextDiagnostic;
  141.     return *this;
  142.   }
  143.  
  144.   ddiag_iterator operator++(int) {
  145.     ddiag_iterator tmp = *this;
  146.     ++*this;
  147.     return tmp;
  148.   }
  149.  
  150.   bool operator==(ddiag_iterator Other) const {
  151.     return Ptr == Other.Ptr;
  152.   }
  153.  
  154.   bool operator!=(ddiag_iterator Other) const {
  155.     return Ptr != Other.Ptr;
  156.   }
  157.  
  158.   ddiag_iterator &operator+=(difference_type N) {
  159.     assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
  160.     while (N--)
  161.       ++*this;
  162.     return *this;
  163.   }
  164.  
  165.   ddiag_iterator operator+(difference_type N) const {
  166.     ddiag_iterator tmp = *this;
  167.     tmp += N;
  168.     return tmp;
  169.   }
  170.  
  171. private:
  172.   DependentDiagnostic *Ptr = nullptr;
  173. };
  174.  
  175. inline DeclContext::ddiag_range DeclContext::ddiags() const {
  176.   assert(isDependentContext()
  177.          && "cannot iterate dependent diagnostics of non-dependent context");
  178.   const DependentStoredDeclsMap *Map
  179.     = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
  180.  
  181.   if (!Map)
  182.     // Return an empty range using the always-end default constructor.
  183.     return ddiag_range(ddiag_iterator(), ddiag_iterator());
  184.  
  185.   return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
  186. }
  187.  
  188. } // namespace clang
  189.  
  190. #endif // LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
  191.