IdentifierResolver.cpp revision f8fd82ba49827db0f6a6ba00c55a7b56b12a19fa
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 "IdentifierResolver.h" 16#include "clang/Basic/LangOptions.h" 17#include <list> 18#include <vector> 19 20using 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. 29class IdentifierResolver::IdDeclInfoMap { 30 static const unsigned int VECTOR_SIZE = 512; 31 // Holds vectors of IdDeclInfos that serve as 'pools'. 32 // New vectors are added when the current one is full. 33 std::list< std::vector<IdDeclInfo> > IDIVecs; 34 unsigned int CurIndex; 35 36public: 37 IdDeclInfoMap() : CurIndex(VECTOR_SIZE) {} 38 39 /// Returns the IdDeclInfo associated to the DeclarationName. 40 /// It creates a new IdDeclInfo if one was not created before for this id. 41 IdDeclInfo &operator[](DeclarationName Name); 42}; 43 44 45//===----------------------------------------------------------------------===// 46// IdDeclInfo Implementation 47//===----------------------------------------------------------------------===// 48 49/// RemoveDecl - Remove the decl from the scope chain. 50/// The decl must already be part of the decl chain. 51void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) { 52 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) { 53 if (D == *(I-1)) { 54 Decls.erase(I-1); 55 return; 56 } 57 } 58 59 assert(0 && "Didn't find this decl on its identifier's chain!"); 60} 61 62bool 63IdentifierResolver::IdDeclInfo::ReplaceDecl(NamedDecl *Old, NamedDecl *New) { 64 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) { 65 if (Old == *(I-1)) { 66 *(I - 1) = New; 67 return true; 68 } 69 } 70 71 return false; 72} 73 74 75//===----------------------------------------------------------------------===// 76// IdentifierResolver Implementation 77//===----------------------------------------------------------------------===// 78 79IdentifierResolver::IdentifierResolver(const LangOptions &langOpt) 80 : LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) { 81} 82IdentifierResolver::~IdentifierResolver() { 83 delete IdDeclInfos; 84} 85 86/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true 87/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns 88/// true if 'D' belongs to the given declaration context. 89bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, 90 ASTContext &Context, Scope *S) const { 91 Ctx = Ctx->getLookupContext(); 92 93 if (Ctx->isFunctionOrMethod()) { 94 // Ignore the scopes associated within transparent declaration contexts. 95 while (S->getEntity() && 96 ((DeclContext *)S->getEntity())->isTransparentContext()) 97 S = S->getParent(); 98 99 if (S->isDeclScope(Action::DeclPtrTy::make(D))) 100 return true; 101 if (LangOpt.CPlusPlus) { 102 // C++ 3.3.2p3: 103 // The name declared in a catch exception-declaration is local to the 104 // handler and shall not be redeclared in the outermost block of the 105 // handler. 106 // C++ 3.3.2p4: 107 // Names declared in the for-init-statement, and in the condition of if, 108 // while, for, and switch statements are local to the if, while, for, or 109 // switch statement (including the controlled statement), and shall not be 110 // redeclared in a subsequent condition of that statement nor in the 111 // outermost block (or, for the if statement, any of the outermost blocks) 112 // of the controlled statement. 113 // 114 assert(S->getParent() && "No TUScope?"); 115 if (S->getParent()->getFlags() & Scope::ControlScope) 116 return S->getParent()->isDeclScope(Action::DeclPtrTy::make(D)); 117 } 118 return false; 119 } 120 121 return D->getDeclContext()->getLookupContext()->Equals(Ctx); 122} 123 124/// AddDecl - Link the decl to its shadowed decl chain. 125void IdentifierResolver::AddDecl(NamedDecl *D) { 126 DeclarationName Name = D->getDeclName(); 127 void *Ptr = Name.getFETokenInfo<void>(); 128 129 if (!Ptr) { 130 Name.setFETokenInfo(D); 131 return; 132 } 133 134 IdDeclInfo *IDI; 135 136 if (isDeclPtr(Ptr)) { 137 Name.setFETokenInfo(NULL); 138 IDI = &(*IdDeclInfos)[Name]; 139 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); 140 IDI->AddDecl(PrevD); 141 } else 142 IDI = toIdDeclInfo(Ptr); 143 144 IDI->AddDecl(D); 145} 146 147/// RemoveDecl - Unlink the decl from its shadowed decl chain. 148/// The decl must already be part of the decl chain. 149void IdentifierResolver::RemoveDecl(NamedDecl *D) { 150 assert(D && "null param passed"); 151 DeclarationName Name = D->getDeclName(); 152 void *Ptr = Name.getFETokenInfo<void>(); 153 154 assert(Ptr && "Didn't find this decl on its identifier's chain!"); 155 156 if (isDeclPtr(Ptr)) { 157 assert(D == Ptr && "Didn't find this decl on its identifier's chain!"); 158 Name.setFETokenInfo(NULL); 159 return; 160 } 161 162 return toIdDeclInfo(Ptr)->RemoveDecl(D); 163} 164 165bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) { 166 assert(Old->getDeclName() == New->getDeclName() && 167 "Cannot replace a decl with another decl of a different name"); 168 169 DeclarationName Name = Old->getDeclName(); 170 void *Ptr = Name.getFETokenInfo<void>(); 171 172 if (!Ptr) 173 return false; 174 175 if (isDeclPtr(Ptr)) { 176 if (Ptr == Old) { 177 Name.setFETokenInfo(New); 178 return true; 179 } 180 return false; 181 } 182 183 return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New); 184} 185 186/// begin - Returns an iterator for decls with name 'Name'. 187IdentifierResolver::iterator 188IdentifierResolver::begin(DeclarationName Name) { 189 void *Ptr = Name.getFETokenInfo<void>(); 190 if (!Ptr) return end(); 191 192 if (isDeclPtr(Ptr)) 193 return iterator(static_cast<NamedDecl*>(Ptr)); 194 195 IdDeclInfo *IDI = toIdDeclInfo(Ptr); 196 197 IdDeclInfo::DeclsTy::iterator I = IDI->decls_end(); 198 if (I != IDI->decls_begin()) 199 return iterator(I-1); 200 // No decls found. 201 return end(); 202} 203 204void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II, 205 NamedDecl *D) { 206 void *Ptr = II->getFETokenInfo<void>(); 207 208 if (!Ptr) { 209 II->setFETokenInfo(D); 210 return; 211 } 212 213 IdDeclInfo *IDI; 214 215 if (isDeclPtr(Ptr)) { 216 II->setFETokenInfo(NULL); 217 IDI = &(*IdDeclInfos)[II]; 218 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); 219 IDI->AddDecl(PrevD); 220 } else 221 IDI = toIdDeclInfo(Ptr); 222 223 IDI->AddDecl(D); 224} 225 226//===----------------------------------------------------------------------===// 227// IdDeclInfoMap Implementation 228//===----------------------------------------------------------------------===// 229 230/// Returns the IdDeclInfo associated to the DeclarationName. 231/// It creates a new IdDeclInfo if one was not created before for this id. 232IdentifierResolver::IdDeclInfo & 233IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) { 234 void *Ptr = Name.getFETokenInfo<void>(); 235 236 if (Ptr) return *toIdDeclInfo(Ptr); 237 238 if (CurIndex == VECTOR_SIZE) { 239 // Add a IdDeclInfo vector 'pool' 240 IDIVecs.push_back(std::vector<IdDeclInfo>()); 241 // Fill the vector 242 IDIVecs.back().resize(VECTOR_SIZE); 243 CurIndex = 0; 244 } 245 IdDeclInfo *IDI = &IDIVecs.back()[CurIndex]; 246 Name.setFETokenInfo(reinterpret_cast<void*>( 247 reinterpret_cast<uintptr_t>(IDI) | 0x1) 248 ); 249 ++CurIndex; 250 return *IDI; 251} 252