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 "IdentifierResolver.h"
16 #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 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;
37 IdDeclInfoMap() : CurIndex(VECTOR_SIZE) {}
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);
45 //===----------------------------------------------------------------------===//
46 // IdDeclInfo Implementation
47 //===----------------------------------------------------------------------===//
49 /// AddShadowed - Add a decl by putting it directly above the 'Shadow' decl.
50 /// Later lookups will find the 'Shadow' decl first. The 'Shadow' decl must
51 /// be already added to the scope chain and must be in the same context as
52 /// the decl that we want to add.
53 void IdentifierResolver::IdDeclInfo::AddShadowed(NamedDecl *D,
55 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
56 if (Shadow == *(I-1)) {
62 assert(0 && "Shadow wasn't in scope chain!");
65 /// RemoveDecl - Remove the decl from the scope chain.
66 /// The decl must already be part of the decl chain.
67 void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
68 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
75 assert(0 && "Didn't find this decl on its identifier's chain!");
79 IdentifierResolver::IdDeclInfo::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
80 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
91 //===----------------------------------------------------------------------===//
92 // IdentifierResolver Implementation
93 //===----------------------------------------------------------------------===//
95 IdentifierResolver::IdentifierResolver(const LangOptions &langOpt)
96 : LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) {
98 IdentifierResolver::~IdentifierResolver() {
102 /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
103 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
104 /// true if 'D' belongs to the given declaration context.
105 bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
106 ASTContext &Context, Scope *S) const {
107 Ctx = Ctx->getLookupContext();
109 if (Ctx->isFunctionOrMethod()) {
110 // Ignore the scopes associated within transparent declaration contexts.
111 while (S->getEntity() &&
112 ((DeclContext *)S->getEntity())->isTransparentContext())
115 if (S->isDeclScope(Action::DeclPtrTy::make(D)))
117 if (LangOpt.CPlusPlus) {
119 // The name declared in a catch exception-declaration is local to the
120 // handler and shall not be redeclared in the outermost block of the
123 // Names declared in the for-init-statement, and in the condition of if,
124 // while, for, and switch statements are local to the if, while, for, or
125 // switch statement (including the controlled statement), and shall not be
126 // redeclared in a subsequent condition of that statement nor in the
127 // outermost block (or, for the if statement, any of the outermost blocks)
128 // of the controlled statement.
130 assert(S->getParent() && "No TUScope?");
131 if (S->getParent()->getFlags() & Scope::ControlScope)
132 return S->getParent()->isDeclScope(Action::DeclPtrTy::make(D));
137 return D->getDeclContext()->getLookupContext() == Ctx->getPrimaryContext();
140 /// AddDecl - Link the decl to its shadowed decl chain.
141 void IdentifierResolver::AddDecl(NamedDecl *D) {
142 DeclarationName Name = D->getDeclName();
143 void *Ptr = Name.getFETokenInfo<void>();
146 Name.setFETokenInfo(D);
152 if (isDeclPtr(Ptr)) {
153 Name.setFETokenInfo(NULL);
154 IDI = &(*IdDeclInfos)[Name];
155 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
158 IDI = toIdDeclInfo(Ptr);
163 /// AddShadowedDecl - Link the decl to its shadowed decl chain putting it
164 /// after the decl that the iterator points to, thus the 'Shadow' decl will be
165 /// encountered before the 'D' decl.
166 void IdentifierResolver::AddShadowedDecl(NamedDecl *D, NamedDecl *Shadow) {
167 assert(D->getDeclName() == Shadow->getDeclName() && "Different ids!");
169 DeclarationName Name = D->getDeclName();
170 void *Ptr = Name.getFETokenInfo<void>();
171 assert(Ptr && "No decl from Ptr ?");
175 if (isDeclPtr(Ptr)) {
176 Name.setFETokenInfo(NULL);
177 IDI = &(*IdDeclInfos)[Name];
178 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
179 assert(PrevD == Shadow && "Invalid shadow decl ?");
185 IDI = toIdDeclInfo(Ptr);
186 IDI->AddShadowed(D, Shadow);
189 /// RemoveDecl - Unlink the decl from its shadowed decl chain.
190 /// The decl must already be part of the decl chain.
191 void IdentifierResolver::RemoveDecl(NamedDecl *D) {
192 assert(D && "null param passed");
193 DeclarationName Name = D->getDeclName();
194 void *Ptr = Name.getFETokenInfo<void>();
196 assert(Ptr && "Didn't find this decl on its identifier's chain!");
198 if (isDeclPtr(Ptr)) {
199 assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
200 Name.setFETokenInfo(NULL);
204 return toIdDeclInfo(Ptr)->RemoveDecl(D);
207 bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
208 assert(Old->getDeclName() == New->getDeclName() &&
209 "Cannot replace a decl with another decl of a different name");
211 DeclarationName Name = Old->getDeclName();
212 void *Ptr = Name.getFETokenInfo<void>();
217 if (isDeclPtr(Ptr)) {
219 Name.setFETokenInfo(New);
225 return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New);
228 /// begin - Returns an iterator for decls with name 'Name'.
229 IdentifierResolver::iterator
230 IdentifierResolver::begin(DeclarationName Name) {
231 void *Ptr = Name.getFETokenInfo<void>();
232 if (!Ptr) return end();
235 return iterator(static_cast<NamedDecl*>(Ptr));
237 IdDeclInfo *IDI = toIdDeclInfo(Ptr);
239 IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
240 if (I != IDI->decls_begin())
241 return iterator(I-1);
246 void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
248 void *Ptr = II->getFETokenInfo<void>();
251 II->setFETokenInfo(D);
257 if (isDeclPtr(Ptr)) {
258 II->setFETokenInfo(NULL);
259 IDI = &(*IdDeclInfos)[II];
260 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
263 IDI = toIdDeclInfo(Ptr);
268 //===----------------------------------------------------------------------===//
269 // IdDeclInfoMap Implementation
270 //===----------------------------------------------------------------------===//
272 /// Returns the IdDeclInfo associated to the DeclarationName.
273 /// It creates a new IdDeclInfo if one was not created before for this id.
274 IdentifierResolver::IdDeclInfo &
275 IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
276 void *Ptr = Name.getFETokenInfo<void>();
278 if (Ptr) return *toIdDeclInfo(Ptr);
280 if (CurIndex == VECTOR_SIZE) {
281 // Add a IdDeclInfo vector 'pool'
282 IDIVecs.push_back(std::vector<IdDeclInfo>());
284 IDIVecs.back().resize(VECTOR_SIZE);
287 IdDeclInfo *IDI = &IDIVecs.back()[CurIndex];
288 Name.setFETokenInfo(reinterpret_cast<void*>(
289 reinterpret_cast<uintptr_t>(IDI) | 0x1)