File indexing completed on 2026-05-10 08:36:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
0018 #define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
0019
0020 #include "clang/AST/DeclBase.h"
0021 #include "clang/AST/DeclContextInternals.h"
0022 #include "clang/AST/Type.h"
0023 #include "clang/Basic/PartialDiagnostic.h"
0024 #include "clang/Basic/SourceLocation.h"
0025 #include "clang/Basic/Specifiers.h"
0026 #include <cassert>
0027 #include <iterator>
0028
0029 namespace clang {
0030
0031 class ASTContext;
0032 class CXXRecordDecl;
0033 class NamedDecl;
0034
0035
0036 class DependentDiagnostic {
0037 public:
0038 enum AccessNonce { Access = 0 };
0039
0040 static DependentDiagnostic *Create(ASTContext &Context,
0041 DeclContext *Parent,
0042 AccessNonce _,
0043 SourceLocation Loc,
0044 bool IsMemberAccess,
0045 AccessSpecifier AS,
0046 NamedDecl *TargetDecl,
0047 CXXRecordDecl *NamingClass,
0048 QualType BaseObjectType,
0049 const PartialDiagnostic &PDiag) {
0050 DependentDiagnostic *DD = Create(Context, Parent, PDiag);
0051 DD->AccessData.Loc = Loc;
0052 DD->AccessData.IsMember = IsMemberAccess;
0053 DD->AccessData.Access = AS;
0054 DD->AccessData.TargetDecl = TargetDecl;
0055 DD->AccessData.NamingClass = NamingClass;
0056 DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
0057 return DD;
0058 }
0059
0060 unsigned getKind() const {
0061 return Access;
0062 }
0063
0064 bool isAccessToMember() const {
0065 assert(getKind() == Access);
0066 return AccessData.IsMember;
0067 }
0068
0069 AccessSpecifier getAccess() const {
0070 assert(getKind() == Access);
0071 return AccessSpecifier(AccessData.Access);
0072 }
0073
0074 SourceLocation getAccessLoc() const {
0075 assert(getKind() == Access);
0076 return AccessData.Loc;
0077 }
0078
0079 NamedDecl *getAccessTarget() const {
0080 assert(getKind() == Access);
0081 return AccessData.TargetDecl;
0082 }
0083
0084 NamedDecl *getAccessNamingClass() const {
0085 assert(getKind() == Access);
0086 return AccessData.NamingClass;
0087 }
0088
0089 QualType getAccessBaseObjectType() const {
0090 assert(getKind() == Access);
0091 return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
0092 }
0093
0094 const PartialDiagnostic &getDiagnostic() const {
0095 return Diag;
0096 }
0097
0098 private:
0099 friend class DeclContext::ddiag_iterator;
0100 friend class DependentStoredDeclsMap;
0101
0102 DependentDiagnostic(const PartialDiagnostic &PDiag,
0103 DiagnosticStorage *Storage)
0104 : Diag(PDiag, Storage) {}
0105
0106 static DependentDiagnostic *Create(ASTContext &Context,
0107 DeclContext *Parent,
0108 const PartialDiagnostic &PDiag);
0109
0110 DependentDiagnostic *NextDiagnostic;
0111
0112 PartialDiagnostic Diag;
0113
0114 struct {
0115 SourceLocation Loc;
0116 LLVM_PREFERRED_TYPE(AccessSpecifier)
0117 unsigned Access : 2;
0118 LLVM_PREFERRED_TYPE(bool)
0119 unsigned IsMember : 1;
0120 NamedDecl *TargetDecl;
0121 CXXRecordDecl *NamingClass;
0122 void *BaseObjectType;
0123 } AccessData;
0124 };
0125
0126
0127 class DeclContext::ddiag_iterator {
0128 public:
0129 ddiag_iterator() = default;
0130 explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
0131
0132 using value_type = DependentDiagnostic *;
0133 using reference = DependentDiagnostic *;
0134 using pointer = DependentDiagnostic *;
0135 using difference_type = int;
0136 using iterator_category = std::forward_iterator_tag;
0137
0138 reference operator*() const { return Ptr; }
0139
0140 ddiag_iterator &operator++() {
0141 assert(Ptr && "attempt to increment past end of diag list");
0142 Ptr = Ptr->NextDiagnostic;
0143 return *this;
0144 }
0145
0146 ddiag_iterator operator++(int) {
0147 ddiag_iterator tmp = *this;
0148 ++*this;
0149 return tmp;
0150 }
0151
0152 bool operator==(ddiag_iterator Other) const {
0153 return Ptr == Other.Ptr;
0154 }
0155
0156 bool operator!=(ddiag_iterator Other) const {
0157 return Ptr != Other.Ptr;
0158 }
0159
0160 ddiag_iterator &operator+=(difference_type N) {
0161 assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
0162 while (N--)
0163 ++*this;
0164 return *this;
0165 }
0166
0167 ddiag_iterator operator+(difference_type N) const {
0168 ddiag_iterator tmp = *this;
0169 tmp += N;
0170 return tmp;
0171 }
0172
0173 private:
0174 DependentDiagnostic *Ptr = nullptr;
0175 };
0176
0177 inline DeclContext::ddiag_range DeclContext::ddiags() const {
0178 assert(isDependentContext()
0179 && "cannot iterate dependent diagnostics of non-dependent context");
0180 const DependentStoredDeclsMap *Map
0181 = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
0182
0183 if (!Map)
0184
0185 return ddiag_range(ddiag_iterator(), ddiag_iterator());
0186
0187 return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
0188 }
0189
0190 }
0191
0192 #endif