1 //===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the IdentifierResolver class, which is used for lexical
11 // scoped lookup, based on declaration names.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Sema/IdentifierResolver.h"
16 #include "clang/Sema/Scope.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/Basic/LangOptions.h"
20 using namespace clang;
22 //===----------------------------------------------------------------------===//
23 // IdDeclInfoMap class
24 //===----------------------------------------------------------------------===//
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;
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) {}
39 IdDeclInfo Pool[POOL_SIZE];
42 IdDeclInfoPool *CurPool;
43 unsigned int CurIndex;
46 IdDeclInfoMap() : CurPool(0), CurIndex(POOL_SIZE) {}
49 IdDeclInfoPool *Cur = CurPool;
50 while (IdDeclInfoPool *P = Cur) {
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);
62 //===----------------------------------------------------------------------===//
63 // IdDeclInfo Implementation
64 //===----------------------------------------------------------------------===//
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) {
76 llvm_unreachable("Didn't find this decl on its identifier's chain!");
80 IdentifierResolver::IdDeclInfo::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
81 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
92 //===----------------------------------------------------------------------===//
93 // IdentifierResolver Implementation
94 //===----------------------------------------------------------------------===//
96 IdentifierResolver::IdentifierResolver(const LangOptions &langOpt)
97 : LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) {
99 IdentifierResolver::~IdentifierResolver() {
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();
111 if (Ctx->isFunctionOrMethod()) {
112 // Ignore the scopes associated within transparent declaration contexts.
113 while (S->getEntity() &&
114 ((DeclContext *)S->getEntity())->isTransparentContext())
117 if (S->isDeclScope(D))
119 if (LangOpt.CPlusPlus) {
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
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.
132 assert(S->getParent() && "No TUScope?");
133 if (S->getParent()->getFlags() & Scope::ControlScope)
134 return S->getParent()->isDeclScope(D);
139 DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
140 return ExplicitInstantiationOrSpecialization
141 ? Ctx->InEnclosingNamespaceSetOf(DCtx)
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);
151 void *Ptr = Name.getFETokenInfo<void>();
154 Name.setFETokenInfo(D);
160 if (isDeclPtr(Ptr)) {
161 Name.setFETokenInfo(NULL);
162 IDI = &(*IdDeclInfos)[Name];
163 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
166 IDI = toIdDeclInfo(Ptr);
171 void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) {
172 DeclarationName Name = D->getDeclName();
173 void *Ptr = Name.getFETokenInfo<void>();
180 if (isDeclPtr(Ptr)) {
181 // We only have a single declaration: insert before or after it,
183 if (Pos == iterator()) {
184 // Add the new declaration before the existing declaration.
185 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
190 // Add new declaration after the existing declaration.
197 if (IdentifierInfo *II = Name.getAsIdentifierInfo())
198 II->setIsFromAST(false);
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);
206 IDI->InsertDecl(IDI->decls_begin(), D);
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);
217 void *Ptr = Name.getFETokenInfo<void>();
219 assert(Ptr && "Didn't find this decl on its identifier's chain!");
221 if (isDeclPtr(Ptr)) {
222 assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
223 Name.setFETokenInfo(NULL);
227 return toIdDeclInfo(Ptr)->RemoveDecl(D);
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");
234 DeclarationName Name = Old->getDeclName();
235 if (IdentifierInfo *II = Name.getAsIdentifierInfo())
236 II->setIsFromAST(false);
238 void *Ptr = Name.getFETokenInfo<void>();
243 if (isDeclPtr(Ptr)) {
245 Name.setFETokenInfo(New);
251 return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New);
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();
261 return iterator(static_cast<NamedDecl*>(Ptr));
263 IdDeclInfo *IDI = toIdDeclInfo(Ptr);
265 IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
266 if (I != IDI->decls_begin())
267 return iterator(I-1);
272 void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
274 II->setIsFromAST(false);
275 void *Ptr = II->getFETokenInfo<void>();
278 II->setFETokenInfo(D);
284 if (isDeclPtr(Ptr)) {
285 II->setFETokenInfo(NULL);
286 IDI = &(*IdDeclInfos)[II];
287 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
290 IDI = toIdDeclInfo(Ptr);
295 //===----------------------------------------------------------------------===//
296 // IdDeclInfoMap Implementation
297 //===----------------------------------------------------------------------===//
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>();
305 if (Ptr) return *toIdDeclInfo(Ptr);
307 if (CurIndex == POOL_SIZE) {
308 CurPool = new IdDeclInfoPool(CurPool);
311 IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
312 Name.setFETokenInfo(reinterpret_cast<void*>(
313 reinterpret_cast<uintptr_t>(IDI) | 0x1)
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);
325 BaseIter I = getIterator();
326 if (I != Info->decls_begin())
327 *this = iterator(I-1);
328 else // No more decls.