1 //===- IdentifierResolver.cpp - 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 implements the IdentifierResolver class, which is used for lexical 11 // scoped lookup, based on declaration names. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/Sema/IdentifierResolver.h" 16 #include "clang/Sema/Scope.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/Basic/LangOptions.h" 19 20 using namespace clang; 21 22 //===----------------------------------------------------------------------===// 23 // IdDeclInfoMap class 24 //===----------------------------------------------------------------------===// 25 26 /// IdDeclInfoMap - Associates IdDeclInfos with declaration names. 27 /// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each 28 /// individual IdDeclInfo to heap. 29 class IdentifierResolver::IdDeclInfoMap { 30 static const unsigned int POOL_SIZE = 512; 31 32 /// We use our own linked-list implementation because it is sadly 33 /// impossible to add something to a pre-C++0x STL container without 34 /// a completely unnecessary copy. 35 struct IdDeclInfoPool { 36 IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {} 37 38 IdDeclInfoPool *Next; 39 IdDeclInfo Pool[POOL_SIZE]; 40 }; 41 42 IdDeclInfoPool *CurPool; 43 unsigned int CurIndex; 44 45 public: 46 IdDeclInfoMap() : CurPool(0), CurIndex(POOL_SIZE) {} 47 48 ~IdDeclInfoMap() { 49 IdDeclInfoPool *Cur = CurPool; 50 while (IdDeclInfoPool *P = Cur) { 51 Cur = Cur->Next; 52 delete P; 53 } 54 } 55 56 /// Returns the IdDeclInfo associated to the DeclarationName. 57 /// It creates a new IdDeclInfo if one was not created before for this id. 58 IdDeclInfo &operator[](DeclarationName Name); 59 }; 60 61 62 //===----------------------------------------------------------------------===// 63 // IdDeclInfo Implementation 64 //===----------------------------------------------------------------------===// 65 66 /// RemoveDecl - Remove the decl from the scope chain. 67 /// The decl must already be part of the decl chain. 68 void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) { 69 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) { 70 if (D == *(I-1)) { 71 Decls.erase(I-1); 72 return; 73 } 74 } 75 76 assert(0 && "Didn't find this decl on its identifier's chain!"); 77 } 78 79 bool 80 IdentifierResolver::IdDeclInfo::ReplaceDecl(NamedDecl *Old, NamedDecl *New) { 81 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) { 82 if (Old == *(I-1)) { 83 *(I - 1) = New; 84 return true; 85 } 86 } 87 88 return false; 89 } 90 91 92 //===----------------------------------------------------------------------===// 93 // IdentifierResolver Implementation 94 //===----------------------------------------------------------------------===// 95 96 IdentifierResolver::IdentifierResolver(const LangOptions &langOpt) 97 : LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) { 98 } 99 IdentifierResolver::~IdentifierResolver() { 100 delete IdDeclInfos; 101 } 102 103 /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true 104 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns 105 /// true if 'D' belongs to the given declaration context. 106 bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, 107 ASTContext &Context, Scope *S, 108 bool ExplicitInstantiationOrSpecialization) const { 109 Ctx = Ctx->getRedeclContext(); 110 111 if (Ctx->isFunctionOrMethod()) { 112 // Ignore the scopes associated within transparent declaration contexts. 113 while (S->getEntity() && 114 ((DeclContext *)S->getEntity())->isTransparentContext()) 115 S = S->getParent(); 116 117 if (S->isDeclScope(D)) 118 return true; 119 if (LangOpt.CPlusPlus) { 120 // C++ 3.3.2p3: 121 // The name declared in a catch exception-declaration is local to the 122 // handler and shall not be redeclared in the outermost block of the 123 // handler. 124 // C++ 3.3.2p4: 125 // Names declared in the for-init-statement, and in the condition of if, 126 // while, for, and switch statements are local to the if, while, for, or 127 // switch statement (including the controlled statement), and shall not be 128 // redeclared in a subsequent condition of that statement nor in the 129 // outermost block (or, for the if statement, any of the outermost blocks) 130 // of the controlled statement. 131 // 132 assert(S->getParent() && "No TUScope?"); 133 if (S->getParent()->getFlags() & Scope::ControlScope) 134 return S->getParent()->isDeclScope(D); 135 } 136 return false; 137 } 138 139 DeclContext *DCtx = D->getDeclContext()->getRedeclContext(); 140 return ExplicitInstantiationOrSpecialization 141 ? Ctx->InEnclosingNamespaceSetOf(DCtx) 142 : Ctx->Equals(DCtx); 143 } 144 145 /// AddDecl - Link the decl to its shadowed decl chain. 146 void IdentifierResolver::AddDecl(NamedDecl *D) { 147 DeclarationName Name = D->getDeclName(); 148 if (IdentifierInfo *II = Name.getAsIdentifierInfo()) 149 II->setIsFromAST(false); 150 151 void *Ptr = Name.getFETokenInfo<void>(); 152 153 if (!Ptr) { 154 Name.setFETokenInfo(D); 155 return; 156 } 157 158 IdDeclInfo *IDI; 159 160 if (isDeclPtr(Ptr)) { 161 Name.setFETokenInfo(NULL); 162 IDI = &(*IdDeclInfos)[Name]; 163 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); 164 IDI->AddDecl(PrevD); 165 } else 166 IDI = toIdDeclInfo(Ptr); 167 168 IDI->AddDecl(D); 169 } 170 171 void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) { 172 DeclarationName Name = D->getDeclName(); 173 void *Ptr = Name.getFETokenInfo<void>(); 174 175 if (!Ptr) { 176 AddDecl(D); 177 return; 178 } 179 180 if (isDeclPtr(Ptr)) { 181 // We only have a single declaration: insert before or after it, 182 // as appropriate. 183 if (Pos == iterator()) { 184 // Add the new declaration before the existing declaration. 185 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); 186 RemoveDecl(PrevD); 187 AddDecl(D); 188 AddDecl(PrevD); 189 } else { 190 // Add new declaration after the existing declaration. 191 AddDecl(D); 192 } 193 194 return; 195 } 196 197 if (IdentifierInfo *II = Name.getAsIdentifierInfo()) 198 II->setIsFromAST(false); 199 200 // General case: insert the declaration at the appropriate point in the 201 // list, which already has at least two elements. 202 IdDeclInfo *IDI = toIdDeclInfo(Ptr); 203 if (Pos.isIterator()) { 204 IDI->InsertDecl(Pos.getIterator() + 1, D); 205 } else 206 IDI->InsertDecl(IDI->decls_begin(), D); 207 } 208 209 /// RemoveDecl - Unlink the decl from its shadowed decl chain. 210 /// The decl must already be part of the decl chain. 211 void IdentifierResolver::RemoveDecl(NamedDecl *D) { 212 assert(D && "null param passed"); 213 DeclarationName Name = D->getDeclName(); 214 if (IdentifierInfo *II = Name.getAsIdentifierInfo()) 215 II->setIsFromAST(false); 216 217 void *Ptr = Name.getFETokenInfo<void>(); 218 219 assert(Ptr && "Didn't find this decl on its identifier's chain!"); 220 221 if (isDeclPtr(Ptr)) { 222 assert(D == Ptr && "Didn't find this decl on its identifier's chain!"); 223 Name.setFETokenInfo(NULL); 224 return; 225 } 226 227 return toIdDeclInfo(Ptr)->RemoveDecl(D); 228 } 229 230 bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) { 231 assert(Old->getDeclName() == New->getDeclName() && 232 "Cannot replace a decl with another decl of a different name"); 233 234 DeclarationName Name = Old->getDeclName(); 235 if (IdentifierInfo *II = Name.getAsIdentifierInfo()) 236 II->setIsFromAST(false); 237 238 void *Ptr = Name.getFETokenInfo<void>(); 239 240 if (!Ptr) 241 return false; 242 243 if (isDeclPtr(Ptr)) { 244 if (Ptr == Old) { 245 Name.setFETokenInfo(New); 246 return true; 247 } 248 return false; 249 } 250 251 return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New); 252 } 253 254 /// begin - Returns an iterator for decls with name 'Name'. 255 IdentifierResolver::iterator 256 IdentifierResolver::begin(DeclarationName Name) { 257 void *Ptr = Name.getFETokenInfo<void>(); 258 if (!Ptr) return end(); 259 260 if (isDeclPtr(Ptr)) 261 return iterator(static_cast<NamedDecl*>(Ptr)); 262 263 IdDeclInfo *IDI = toIdDeclInfo(Ptr); 264 265 IdDeclInfo::DeclsTy::iterator I = IDI->decls_end(); 266 if (I != IDI->decls_begin()) 267 return iterator(I-1); 268 // No decls found. 269 return end(); 270 } 271 272 void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II, 273 NamedDecl *D) { 274 II->setIsFromAST(false); 275 void *Ptr = II->getFETokenInfo<void>(); 276 277 if (!Ptr) { 278 II->setFETokenInfo(D); 279 return; 280 } 281 282 IdDeclInfo *IDI; 283 284 if (isDeclPtr(Ptr)) { 285 II->setFETokenInfo(NULL); 286 IDI = &(*IdDeclInfos)[II]; 287 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); 288 IDI->AddDecl(PrevD); 289 } else 290 IDI = toIdDeclInfo(Ptr); 291 292 IDI->AddDecl(D); 293 } 294 295 //===----------------------------------------------------------------------===// 296 // IdDeclInfoMap Implementation 297 //===----------------------------------------------------------------------===// 298 299 /// Returns the IdDeclInfo associated to the DeclarationName. 300 /// It creates a new IdDeclInfo if one was not created before for this id. 301 IdentifierResolver::IdDeclInfo & 302 IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) { 303 void *Ptr = Name.getFETokenInfo<void>(); 304 305 if (Ptr) return *toIdDeclInfo(Ptr); 306 307 if (CurIndex == POOL_SIZE) { 308 CurPool = new IdDeclInfoPool(CurPool); 309 CurIndex = 0; 310 } 311 IdDeclInfo *IDI = &CurPool->Pool[CurIndex]; 312 Name.setFETokenInfo(reinterpret_cast<void*>( 313 reinterpret_cast<uintptr_t>(IDI) | 0x1) 314 ); 315 ++CurIndex; 316 return *IDI; 317 } 318 319 void IdentifierResolver::iterator::incrementSlowCase() { 320 NamedDecl *D = **this; 321 void *InfoPtr = D->getDeclName().getFETokenInfo<void>(); 322 assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?"); 323 IdDeclInfo *Info = toIdDeclInfo(InfoPtr); 324 325 BaseIter I = getIterator(); 326 if (I != Info->decls_begin()) 327 *this = iterator(I-1); 328 else // No more decls. 329 *this = iterator(); 330 } 331