IdentifierResolver.h revision 7cd088e519d7e6caa4c4c12db52e0e4ae35d25c2
1//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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 the IdentifierResolver class, which is used for lexical 11// scoped lookup, based on declaration names. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H 16#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H 17 18#include "clang/Basic/IdentifierTable.h" 19 20namespace clang { 21 22class ASTContext; 23class Decl; 24class DeclContext; 25class DeclarationName; 26class NamedDecl; 27class Scope; 28 29/// IdentifierResolver - Keeps track of shadowed decls on enclosing 30/// scopes. It manages the shadowing chains of declaration names and 31/// implements efficent decl lookup based on a declaration name. 32class IdentifierResolver { 33 34 /// IdDeclInfo - Keeps track of information about decls associated 35 /// to a particular declaration name. IdDeclInfos are lazily 36 /// constructed and assigned to a declaration name the first time a 37 /// decl with that declaration name is shadowed in some scope. 38 class IdDeclInfo { 39 public: 40 typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy; 41 42 inline DeclsTy::iterator decls_begin() { return Decls.begin(); } 43 inline DeclsTy::iterator decls_end() { return Decls.end(); } 44 45 void AddDecl(NamedDecl *D) { Decls.push_back(D); } 46 47 /// RemoveDecl - Remove the decl from the scope chain. 48 /// The decl must already be part of the decl chain. 49 void RemoveDecl(NamedDecl *D); 50 51 /// Replaces the Old declaration with the New declaration. If the 52 /// replacement is successful, returns true. If the old 53 /// declaration was not found, returns false. 54 bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); 55 56 private: 57 DeclsTy Decls; 58 }; 59 60public: 61 62 /// iterator - Iterate over the decls of a specified declaration name. 63 /// It will walk or not the parent declaration contexts depending on how 64 /// it was instantiated. 65 class iterator { 66 public: 67 typedef NamedDecl * value_type; 68 typedef NamedDecl * reference; 69 typedef NamedDecl * pointer; 70 typedef std::input_iterator_tag iterator_category; 71 typedef std::ptrdiff_t difference_type; 72 73 /// Ptr - There are 3 forms that 'Ptr' represents: 74 /// 1) A single NamedDecl. (Ptr & 0x1 == 0) 75 /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the 76 /// same declaration context. (Ptr & 0x3 == 0x1) 77 /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent 78 /// declaration contexts too. (Ptr & 0x3 == 0x3) 79 uintptr_t Ptr; 80 typedef IdDeclInfo::DeclsTy::iterator BaseIter; 81 82 /// A single NamedDecl. (Ptr & 0x1 == 0) 83 iterator(NamedDecl *D) { 84 Ptr = reinterpret_cast<uintptr_t>(D); 85 assert((Ptr & 0x1) == 0 && "Invalid Ptr!"); 86 } 87 /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration 88 /// contexts depending on 'LookInParentCtx'. 89 iterator(BaseIter I) { 90 Ptr = reinterpret_cast<uintptr_t>(I) | 0x1; 91 } 92 93 bool isIterator() const { return (Ptr & 0x1); } 94 95 BaseIter getIterator() const { 96 assert(isIterator() && "Ptr not an iterator!"); 97 return reinterpret_cast<BaseIter>(Ptr & ~0x3); 98 } 99 100 friend class IdentifierResolver; 101 102 void incrementSlowCase(); 103 public: 104 iterator() : Ptr(0) {} 105 106 NamedDecl *operator*() const { 107 if (isIterator()) 108 return *getIterator(); 109 else 110 return reinterpret_cast<NamedDecl*>(Ptr); 111 } 112 113 bool operator==(const iterator &RHS) const { 114 return Ptr == RHS.Ptr; 115 } 116 bool operator!=(const iterator &RHS) const { 117 return Ptr != RHS.Ptr; 118 } 119 120 // Preincrement. 121 iterator& operator++() { 122 if (!isIterator()) // common case. 123 Ptr = 0; 124 else 125 incrementSlowCase(); 126 return *this; 127 } 128 129 uintptr_t getAsOpaqueValue() const { return Ptr; } 130 131 static iterator getFromOpaqueValue(uintptr_t P) { 132 iterator Result; 133 Result.Ptr = P; 134 return Result; 135 } 136 }; 137 138 /// begin - Returns an iterator for decls with the name 'Name'. 139 static iterator begin(DeclarationName Name); 140 141 /// end - Returns an iterator that has 'finished'. 142 static iterator end() { 143 return iterator(); 144 } 145 146 /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true 147 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns 148 /// true if 'D' belongs to the given declaration context. 149 bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context, 150 Scope *S = 0) const; 151 152 /// AddDecl - Link the decl to its shadowed decl chain. 153 void AddDecl(NamedDecl *D); 154 155 /// RemoveDecl - Unlink the decl from its shadowed decl chain. 156 /// The decl must already be part of the decl chain. 157 void RemoveDecl(NamedDecl *D); 158 159 /// Replace the decl Old with the new declaration New on its 160 /// identifier chain. Returns true if the old declaration was found 161 /// (and, therefore, replaced). 162 bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); 163 164 /// \brief Link the declaration into the chain of declarations for 165 /// the given identifier. 166 /// 167 /// This is a lower-level routine used by the AST reader to link a 168 /// declaration into a specific IdentifierInfo before the 169 /// declaration actually has a name. 170 void AddDeclToIdentifierChain(IdentifierInfo *II, NamedDecl *D); 171 172 explicit IdentifierResolver(const LangOptions &LangOpt); 173 ~IdentifierResolver(); 174 175private: 176 const LangOptions &LangOpt; 177 178 class IdDeclInfoMap; 179 IdDeclInfoMap *IdDeclInfos; 180 181 /// FETokenInfo contains a Decl pointer if lower bit == 0. 182 static inline bool isDeclPtr(void *Ptr) { 183 return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0; 184 } 185 186 /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1. 187 static inline IdDeclInfo *toIdDeclInfo(void *Ptr) { 188 assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1 189 && "Ptr not a IdDeclInfo* !"); 190 return reinterpret_cast<IdDeclInfo*>( 191 reinterpret_cast<uintptr_t>(Ptr) & ~0x1 192 ); 193 } 194}; 195 196} // end namespace clang 197 198#endif 199