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_AST_SEMA_IDENTIFIERRESOLVER_H 00016 #define LLVM_CLANG_AST_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 /// Replaces the Old declaration with the New declaration. If the 00055 /// replacement is successful, returns true. If the old 00056 /// declaration was not found, returns false. 00057 bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); 00058 00059 /// \brief Insert the given declaration at the given position in the list. 00060 void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) { 00061 Decls.insert(Pos, D); 00062 } 00063 00064 private: 00065 DeclsTy Decls; 00066 }; 00067 00068 public: 00069 00070 /// iterator - Iterate over the decls of a specified declaration name. 00071 /// It will walk or not the parent declaration contexts depending on how 00072 /// it was instantiated. 00073 class iterator { 00074 public: 00075 typedef NamedDecl * value_type; 00076 typedef NamedDecl * reference; 00077 typedef NamedDecl * pointer; 00078 typedef std::input_iterator_tag iterator_category; 00079 typedef std::ptrdiff_t difference_type; 00080 00081 /// Ptr - There are 3 forms that 'Ptr' represents: 00082 /// 1) A single NamedDecl. (Ptr & 0x1 == 0) 00083 /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the 00084 /// same declaration context. (Ptr & 0x3 == 0x1) 00085 /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent 00086 /// declaration contexts too. (Ptr & 0x3 == 0x3) 00087 uintptr_t Ptr; 00088 typedef IdDeclInfo::DeclsTy::iterator BaseIter; 00089 00090 /// A single NamedDecl. (Ptr & 0x1 == 0) 00091 iterator(NamedDecl *D) { 00092 Ptr = reinterpret_cast<uintptr_t>(D); 00093 assert((Ptr & 0x1) == 0 && "Invalid Ptr!"); 00094 } 00095 /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration 00096 /// contexts depending on 'LookInParentCtx'. 00097 iterator(BaseIter I) { 00098 Ptr = reinterpret_cast<uintptr_t>(I) | 0x1; 00099 } 00100 00101 bool isIterator() const { return (Ptr & 0x1); } 00102 00103 BaseIter getIterator() const { 00104 assert(isIterator() && "Ptr not an iterator!"); 00105 return reinterpret_cast<BaseIter>(Ptr & ~0x3); 00106 } 00107 00108 friend class IdentifierResolver; 00109 00110 void incrementSlowCase(); 00111 public: 00112 iterator() : Ptr(0) {} 00113 00114 NamedDecl *operator*() const { 00115 if (isIterator()) 00116 return *getIterator(); 00117 else 00118 return reinterpret_cast<NamedDecl*>(Ptr); 00119 } 00120 00121 bool operator==(const iterator &RHS) const { 00122 return Ptr == RHS.Ptr; 00123 } 00124 bool operator!=(const iterator &RHS) const { 00125 return Ptr != RHS.Ptr; 00126 } 00127 00128 // Preincrement. 00129 iterator& operator++() { 00130 if (!isIterator()) // common case. 00131 Ptr = 0; 00132 else 00133 incrementSlowCase(); 00134 return *this; 00135 } 00136 00137 uintptr_t getAsOpaqueValue() const { return Ptr; } 00138 00139 static iterator getFromOpaqueValue(uintptr_t P) { 00140 iterator Result; 00141 Result.Ptr = P; 00142 return Result; 00143 } 00144 }; 00145 00146 /// begin - Returns an iterator for decls with the name 'Name'. 00147 iterator begin(DeclarationName Name); 00148 00149 /// end - Returns an iterator that has 'finished'. 00150 iterator end() { 00151 return iterator(); 00152 } 00153 00154 /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true 00155 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns 00156 /// true if 'D' belongs to the given declaration context. 00157 /// 00158 /// \param ExplicitInstantiationOrSpecialization When true, we are checking 00159 /// whether the declaration is in scope for the purposes of explicit template 00160 /// instantiation or specialization. The default is false. 00161 bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context, 00162 Scope *S = 0, 00163 bool ExplicitInstantiationOrSpecialization = false) const; 00164 00165 /// AddDecl - Link the decl to its shadowed decl chain. 00166 void AddDecl(NamedDecl *D); 00167 00168 /// RemoveDecl - Unlink the decl from its shadowed decl chain. 00169 /// The decl must already be part of the decl chain. 00170 void RemoveDecl(NamedDecl *D); 00171 00172 /// Replace the decl Old with the new declaration New on its 00173 /// identifier chain. Returns true if the old declaration was found 00174 /// (and, therefore, replaced). 00175 bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); 00176 00177 /// \brief Insert the given declaration after the given iterator 00178 /// position. 00179 void InsertDeclAfter(iterator Pos, NamedDecl *D); 00180 00181 /// \brief Try to add the given declaration to the top level scope, if it 00182 /// (or a redeclaration of it) hasn't already been added. 00183 /// 00184 /// \param D The externally-produced declaration to add. 00185 /// 00186 /// \param Name The name of the externally-produced declaration. 00187 /// 00188 /// \returns true if the declaration was added, false otherwise. 00189 bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name); 00190 00191 explicit IdentifierResolver(Preprocessor &PP); 00192 ~IdentifierResolver(); 00193 00194 private: 00195 const LangOptions &LangOpt; 00196 Preprocessor &PP; 00197 00198 class IdDeclInfoMap; 00199 IdDeclInfoMap *IdDeclInfos; 00200 00201 void updatingIdentifier(IdentifierInfo &II); 00202 void readingIdentifier(IdentifierInfo &II); 00203 00204 /// FETokenInfo contains a Decl pointer if lower bit == 0. 00205 static inline bool isDeclPtr(void *Ptr) { 00206 return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0; 00207 } 00208 00209 /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1. 00210 static inline IdDeclInfo *toIdDeclInfo(void *Ptr) { 00211 assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1 00212 && "Ptr not a IdDeclInfo* !"); 00213 return reinterpret_cast<IdDeclInfo*>( 00214 reinterpret_cast<uintptr_t>(Ptr) & ~0x1 00215 ); 00216 } 00217 }; 00218 00219 } // end namespace clang 00220 00221 #endif