File indexing completed on 2026-05-10 08:37:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
0015 #define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
0016
0017 #include "clang/Basic/LLVM.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include <cassert>
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <iterator>
0023
0024 namespace clang {
0025
0026 class Decl;
0027 class DeclarationName;
0028 class DeclContext;
0029 class IdentifierInfo;
0030 class LangOptions;
0031 class NamedDecl;
0032 class Preprocessor;
0033 class Scope;
0034
0035
0036
0037
0038 class IdentifierResolver {
0039
0040
0041
0042
0043 class IdDeclInfo {
0044 public:
0045 using DeclsTy = SmallVector<NamedDecl *, 2>;
0046
0047 DeclsTy::iterator decls_begin() { return Decls.begin(); }
0048 DeclsTy::iterator decls_end() { return Decls.end(); }
0049
0050 void AddDecl(NamedDecl *D) { Decls.push_back(D); }
0051
0052
0053
0054 void RemoveDecl(NamedDecl *D);
0055
0056
0057 void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
0058 Decls.insert(Pos, D);
0059 }
0060
0061 private:
0062 DeclsTy Decls;
0063 };
0064
0065 public:
0066
0067
0068
0069 class iterator {
0070 public:
0071 friend class IdentifierResolver;
0072
0073 using value_type = NamedDecl *;
0074 using reference = NamedDecl *;
0075 using pointer = NamedDecl *;
0076 using iterator_category = std::input_iterator_tag;
0077 using difference_type = std::ptrdiff_t;
0078
0079
0080
0081
0082
0083 uintptr_t Ptr = 0;
0084 using BaseIter = IdDeclInfo::DeclsTy::iterator;
0085
0086
0087 iterator(NamedDecl *D) {
0088 Ptr = reinterpret_cast<uintptr_t>(D);
0089 assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
0090 }
0091
0092
0093
0094 iterator(BaseIter I) {
0095 Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
0096 }
0097
0098 bool isIterator() const { return (Ptr & 0x1); }
0099
0100 BaseIter getIterator() const {
0101 assert(isIterator() && "Ptr not an iterator!");
0102 return reinterpret_cast<BaseIter>(Ptr & ~0x1);
0103 }
0104
0105 void incrementSlowCase();
0106
0107 public:
0108 iterator() = default;
0109
0110 NamedDecl *operator*() const {
0111 if (isIterator())
0112 return *getIterator();
0113 else
0114 return reinterpret_cast<NamedDecl*>(Ptr);
0115 }
0116
0117 bool operator==(const iterator &RHS) const {
0118 return Ptr == RHS.Ptr;
0119 }
0120 bool operator!=(const iterator &RHS) const {
0121 return Ptr != RHS.Ptr;
0122 }
0123
0124
0125 iterator& operator++() {
0126 if (!isIterator())
0127 Ptr = 0;
0128 else
0129 incrementSlowCase();
0130 return *this;
0131 }
0132 };
0133
0134 explicit IdentifierResolver(Preprocessor &PP);
0135 ~IdentifierResolver();
0136
0137 IdentifierResolver(const IdentifierResolver &) = delete;
0138 IdentifierResolver &operator=(const IdentifierResolver &) = delete;
0139
0140
0141 llvm::iterator_range<iterator> decls(DeclarationName Name);
0142
0143
0144 iterator begin(DeclarationName Name);
0145
0146
0147 iterator end() { return iterator(); }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
0160 bool AllowInlineNamespace = false) const;
0161
0162
0163 void AddDecl(NamedDecl *D);
0164
0165
0166
0167 void RemoveDecl(NamedDecl *D);
0168
0169
0170
0171 void InsertDeclAfter(iterator Pos, NamedDecl *D);
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name);
0182
0183 private:
0184 const LangOptions &LangOpt;
0185 Preprocessor &PP;
0186
0187 class IdDeclInfoMap;
0188 IdDeclInfoMap *IdDeclInfos;
0189
0190 void updatingIdentifier(IdentifierInfo &II);
0191 void readingIdentifier(IdentifierInfo &II);
0192
0193
0194 static inline bool isDeclPtr(void *Ptr) {
0195 return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
0196 }
0197
0198
0199 static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
0200 assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
0201 && "Ptr not a IdDeclInfo* !");
0202 return reinterpret_cast<IdDeclInfo*>(
0203 reinterpret_cast<uintptr_t>(Ptr) & ~0x1);
0204 }
0205 };
0206
0207 }
0208
0209 #endif