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