clang API Documentation

DependentDiagnostic.h
Go to the documentation of this file.
00001 //===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines interfaces for diagnostics which may or may
00011 //  fire based on how a template is instantiated.
00012 //
00013 //  At the moment, the only consumer of this interface is access
00014 //  control.
00015 //
00016 //===----------------------------------------------------------------------===//
00017 
00018 #ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
00019 #define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
00020 
00021 #include "clang/AST/DeclBase.h"
00022 #include "clang/AST/DeclContextInternals.h"
00023 #include "clang/AST/Type.h"
00024 #include "clang/Basic/PartialDiagnostic.h"
00025 #include "clang/Basic/SourceLocation.h"
00026 
00027 namespace clang {
00028 
00029 class ASTContext;
00030 class CXXRecordDecl;
00031 class NamedDecl;
00032 
00033 /// A dependently-generated diagnostic.
00034 class DependentDiagnostic {
00035 public:
00036   enum AccessNonce { Access = 0 };
00037 
00038   static DependentDiagnostic *Create(ASTContext &Context,
00039                                      DeclContext *Parent,
00040                                      AccessNonce _,
00041                                      SourceLocation Loc,
00042                                      bool IsMemberAccess,
00043                                      AccessSpecifier AS,
00044                                      NamedDecl *TargetDecl,
00045                                      CXXRecordDecl *NamingClass,
00046                                      QualType BaseObjectType,
00047                                      const PartialDiagnostic &PDiag) {
00048     DependentDiagnostic *DD = Create(Context, Parent, PDiag);
00049     DD->AccessData.Loc = Loc.getRawEncoding();
00050     DD->AccessData.IsMember = IsMemberAccess;
00051     DD->AccessData.Access = AS;
00052     DD->AccessData.TargetDecl = TargetDecl;
00053     DD->AccessData.NamingClass = NamingClass;
00054     DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
00055     return DD;
00056   }
00057 
00058   unsigned getKind() const {
00059     return Access;
00060   }
00061 
00062   bool isAccessToMember() const {
00063     assert(getKind() == Access);
00064     return AccessData.IsMember;
00065   }
00066 
00067   AccessSpecifier getAccess() const {
00068     assert(getKind() == Access);
00069     return AccessSpecifier(AccessData.Access);
00070   }
00071 
00072   SourceLocation getAccessLoc() const {
00073     assert(getKind() == Access);
00074     return SourceLocation::getFromRawEncoding(AccessData.Loc);
00075   }
00076 
00077   NamedDecl *getAccessTarget() const {
00078     assert(getKind() == Access);
00079     return AccessData.TargetDecl;
00080   }
00081 
00082   NamedDecl *getAccessNamingClass() const {
00083     assert(getKind() == Access);
00084     return AccessData.NamingClass;
00085   }
00086 
00087   QualType getAccessBaseObjectType() const {
00088     assert(getKind() == Access);
00089     return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
00090   }
00091 
00092   const PartialDiagnostic &getDiagnostic() const {
00093     return Diag;
00094   }
00095 
00096 private:
00097   DependentDiagnostic(const PartialDiagnostic &PDiag,
00098                       PartialDiagnostic::Storage *Storage) 
00099     : Diag(PDiag, Storage) {}
00100   
00101   static DependentDiagnostic *Create(ASTContext &Context,
00102                                      DeclContext *Parent,
00103                                      const PartialDiagnostic &PDiag);
00104 
00105   friend class DependentStoredDeclsMap;
00106   friend class DeclContext::ddiag_iterator;
00107   DependentDiagnostic *NextDiagnostic;
00108 
00109   PartialDiagnostic Diag;
00110 
00111   struct {
00112     unsigned Loc;
00113     unsigned Access : 2;
00114     unsigned IsMember : 1;
00115     NamedDecl *TargetDecl;
00116     CXXRecordDecl *NamingClass;
00117     void *BaseObjectType;
00118   } AccessData;
00119 };
00120 
00121 /// 
00122 
00123 /// An iterator over the dependent diagnostics in a dependent context.
00124 class DeclContext::ddiag_iterator {
00125 public:
00126   ddiag_iterator() : Ptr(nullptr) {}
00127   explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
00128 
00129   typedef DependentDiagnostic *value_type;
00130   typedef DependentDiagnostic *reference;
00131   typedef DependentDiagnostic *pointer;
00132   typedef int difference_type;
00133   typedef std::forward_iterator_tag iterator_category;
00134 
00135   reference operator*() const { return Ptr; }
00136 
00137   ddiag_iterator &operator++() {
00138     assert(Ptr && "attempt to increment past end of diag list");
00139     Ptr = Ptr->NextDiagnostic;
00140     return *this;
00141   }
00142 
00143   ddiag_iterator operator++(int) {
00144     ddiag_iterator tmp = *this;
00145     ++*this;
00146     return tmp;
00147   }
00148 
00149   bool operator==(ddiag_iterator Other) const {
00150     return Ptr == Other.Ptr;
00151   }
00152 
00153   bool operator!=(ddiag_iterator Other) const {
00154     return Ptr != Other.Ptr;
00155   }
00156 
00157   ddiag_iterator &operator+=(difference_type N) {
00158     assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
00159     while (N--)
00160       ++*this;
00161     return *this;
00162   }
00163 
00164   ddiag_iterator operator+(difference_type N) const {
00165     ddiag_iterator tmp = *this;
00166     tmp += N;
00167     return tmp;
00168   }
00169 
00170 private:
00171   DependentDiagnostic *Ptr;
00172 };
00173 
00174 inline DeclContext::ddiag_range DeclContext::ddiags() const {
00175   assert(isDependentContext()
00176          && "cannot iterate dependent diagnostics of non-dependent context");
00177   const DependentStoredDeclsMap *Map
00178     = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
00179 
00180   if (!Map)
00181     return ddiag_range();
00182 
00183   return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
00184 }
00185 
00186 }
00187 
00188 #endif