clang API Documentation
00001 //===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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 the IdentifierResolver class, which is used for lexical 00011 // scoped lookup, based on declaration names. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H 00016 #define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H 00017 00018 #include "clang/Basic/IdentifierTable.h" 00019 #include "llvm/ADT/SmallVector.h" 00020 00021 namespace clang { 00022 00023 class ASTContext; 00024 class Decl; 00025 class DeclContext; 00026 class DeclarationName; 00027 class ExternalPreprocessorSource; 00028 class NamedDecl; 00029 class Preprocessor; 00030 class Scope; 00031 00032 /// IdentifierResolver - Keeps track of shadowed decls on enclosing 00033 /// scopes. It manages the shadowing chains of declaration names and 00034 /// implements efficient decl lookup based on a declaration name. 00035 class IdentifierResolver { 00036 00037 /// IdDeclInfo - Keeps track of information about decls associated 00038 /// to a particular declaration name. IdDeclInfos are lazily 00039 /// constructed and assigned to a declaration name the first time a 00040 /// decl with that declaration name is shadowed in some scope. 00041 class IdDeclInfo { 00042 public: 00043 typedef SmallVector<NamedDecl*, 2> DeclsTy; 00044 00045 inline DeclsTy::iterator decls_begin() { return Decls.begin(); } 00046 inline DeclsTy::iterator decls_end() { return Decls.end(); } 00047 00048 void AddDecl(NamedDecl *D) { Decls.push_back(D); } 00049 00050 /// RemoveDecl - Remove the decl from the scope chain. 00051 /// The decl must already be part of the decl chain. 00052 void RemoveDecl(NamedDecl *D); 00053 00054 /// \brief Insert the given declaration at the given position in the list. 00055 void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) { 00056 Decls.insert(Pos, D); 00057 } 00058 00059 private: 00060 DeclsTy Decls; 00061 }; 00062 00063 public: 00064 00065 /// iterator - Iterate over the decls of a specified declaration name. 00066 /// It will walk or not the parent declaration contexts depending on how 00067 /// it was instantiated. 00068 class iterator { 00069 public: 00070 typedef NamedDecl * value_type; 00071 typedef NamedDecl * reference; 00072 typedef NamedDecl * pointer; 00073 typedef std::input_iterator_tag iterator_category; 00074 typedef std::ptrdiff_t difference_type; 00075 00076 /// Ptr - There are 3 forms that 'Ptr' represents: 00077 /// 1) A single NamedDecl. (Ptr & 0x1 == 0) 00078 /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the 00079 /// same declaration context. (Ptr & 0x3 == 0x1) 00080 /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent 00081 /// declaration contexts too. (Ptr & 0x3 == 0x3) 00082 uintptr_t Ptr; 00083 typedef IdDeclInfo::DeclsTy::iterator BaseIter; 00084 00085 /// A single NamedDecl. (Ptr & 0x1 == 0) 00086 iterator(NamedDecl *D) { 00087 Ptr = reinterpret_cast<uintptr_t>(D); 00088 assert((Ptr & 0x1) == 0 && "Invalid Ptr!"); 00089 } 00090 /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration 00091 /// contexts depending on 'LookInParentCtx'. 00092 iterator(BaseIter I) { 00093 Ptr = reinterpret_cast<uintptr_t>(I) | 0x1; 00094 } 00095 00096 bool isIterator() const { return (Ptr & 0x1); } 00097 00098 BaseIter getIterator() const { 00099 assert(isIterator() && "Ptr not an iterator!"); 00100 return reinterpret_cast<BaseIter>(Ptr & ~0x3); 00101 } 00102 00103 friend class IdentifierResolver; 00104 00105 void incrementSlowCase(); 00106 public: 00107 iterator() : Ptr(0) {} 00108 00109 NamedDecl *operator*() const { 00110 if (isIterator()) 00111 return *getIterator(); 00112 else 00113 return reinterpret_cast<NamedDecl*>(Ptr); 00114 } 00115 00116 bool operator==(const iterator &RHS) const { 00117 return Ptr == RHS.Ptr; 00118 } 00119 bool operator!=(const iterator &RHS) const { 00120 return Ptr != RHS.Ptr; 00121 } 00122 00123 // Preincrement. 00124 iterator& operator++() { 00125 if (!isIterator()) // common case. 00126 Ptr = 0; 00127 else 00128 incrementSlowCase(); 00129 return *this; 00130 } 00131 00132 uintptr_t getAsOpaqueValue() const { return Ptr; } 00133 00134 static iterator getFromOpaqueValue(uintptr_t P) { 00135 iterator Result; 00136 Result.Ptr = P; 00137 return Result; 00138 } 00139 }; 00140 00141 /// begin - Returns an iterator for decls with the name 'Name'. 00142 iterator begin(DeclarationName Name); 00143 00144 /// end - Returns an iterator that has 'finished'. 00145 iterator end() { 00146 return iterator(); 00147 } 00148 00149 /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true 00150 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns 00151 /// true if 'D' belongs to the given declaration context. 00152 /// 00153 /// \param AllowInlineNamespace If \c true, we are checking whether a prior 00154 /// declaration is in scope in a declaration that requires a prior 00155 /// declaration (because it is either explicitly qualified or is a 00156 /// template instantiation or specialization). In this case, a 00157 /// declaration is in scope if it's in the inline namespace set of the 00158 /// context. 00159 bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr, 00160 bool AllowInlineNamespace = false) const; 00161 00162 /// AddDecl - Link the decl to its shadowed decl chain. 00163 void AddDecl(NamedDecl *D); 00164 00165 /// RemoveDecl - Unlink the decl from its shadowed decl chain. 00166 /// The decl must already be part of the decl chain. 00167 void RemoveDecl(NamedDecl *D); 00168 00169 /// \brief Insert the given declaration after the given iterator 00170 /// position. 00171 void InsertDeclAfter(iterator Pos, NamedDecl *D); 00172 00173 /// \brief Try to add the given declaration to the top level scope, if it 00174 /// (or a redeclaration of it) hasn't already been added. 00175 /// 00176 /// \param D The externally-produced declaration to add. 00177 /// 00178 /// \param Name The name of the externally-produced declaration. 00179 /// 00180 /// \returns true if the declaration was added, false otherwise. 00181 bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name); 00182 00183 explicit IdentifierResolver(Preprocessor &PP); 00184 ~IdentifierResolver(); 00185 00186 private: 00187 const LangOptions &LangOpt; 00188 Preprocessor &PP; 00189 00190 class IdDeclInfoMap; 00191 IdDeclInfoMap *IdDeclInfos; 00192 00193 void updatingIdentifier(IdentifierInfo &II); 00194 void readingIdentifier(IdentifierInfo &II); 00195 00196 /// FETokenInfo contains a Decl pointer if lower bit == 0. 00197 static inline bool isDeclPtr(void *Ptr) { 00198 return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0; 00199 } 00200 00201 /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1. 00202 static inline IdDeclInfo *toIdDeclInfo(void *Ptr) { 00203 assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1 00204 && "Ptr not a IdDeclInfo* !"); 00205 return reinterpret_cast<IdDeclInfo*>( 00206 reinterpret_cast<uintptr_t>(Ptr) & ~0x1 00207 ); 00208 } 00209 }; 00210 00211 } // end namespace clang 00212 00213 #endif