blob: 037802c64042c6d35f8105cc2580dd0128538c2d [file] [log] [blame]
Chris Lattnera2f42b12008-04-11 07:06:57 +00001//===- 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//
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000010// This file implements the IdentifierResolver class, which is used for lexical
Chris Lattnera2f42b12008-04-11 07:06:57 +000011// scoped lookup, based on identifier.
12//
13//===----------------------------------------------------------------------===//
14
15#include "IdentifierResolver.h"
16#include "clang/Basic/IdentifierTable.h"
17#include "clang/AST/Decl.h"
Douglas Gregor2ce52f32008-04-13 21:07:44 +000018#include "clang/Parse/Scope.h"
Chris Lattnera2f42b12008-04-11 07:06:57 +000019#include <list>
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000020#include <vector>
Chris Lattnera2f42b12008-04-11 07:06:57 +000021
22using namespace clang;
23
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000024namespace {
25
Chris Lattnera2f42b12008-04-11 07:06:57 +000026class IdDeclInfo;
27
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000028/// Identifier's FETokenInfo contains a Decl pointer if lower bit == 0.
Chris Lattnera2f42b12008-04-11 07:06:57 +000029static inline bool isDeclPtr(void *Ptr) {
30 return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
31}
32
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000033/// Identifier's FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
Chris Lattnera2f42b12008-04-11 07:06:57 +000034static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
35 return reinterpret_cast<IdDeclInfo*>(
36 reinterpret_cast<uintptr_t>(Ptr) & ~0x1
37 );
38}
39
40
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000041/// IdDeclInfo - Keeps track of information about decls associated to a
42/// particular identifier. IdDeclInfos are lazily constructed and assigned
43/// to an identifier the first time a decl with that identifier is shadowed
44/// in some scope.
Chris Lattnera2f42b12008-04-11 07:06:57 +000045class IdDeclInfo {
46 typedef llvm::SmallVector<NamedDecl *, 2> ShadowedTy;
47 ShadowedTy ShadowedDecls;
48
49public:
50 typedef ShadowedTy::iterator ShadowedIter;
51
52 inline ShadowedIter shadowed_begin() { return ShadowedDecls.begin(); }
53 inline ShadowedIter shadowed_end() { return ShadowedDecls.end(); }
54
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000055 /// Add a decl in the scope chain.
Chris Lattnera2f42b12008-04-11 07:06:57 +000056 void PushShadowed(NamedDecl *D) {
57 assert(D && "Decl null");
58 ShadowedDecls.push_back(D);
59 }
60
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000061 /// Add the decl at the top of scope chain.
Chris Lattnera2f42b12008-04-11 07:06:57 +000062 void PushGlobalShadowed(NamedDecl *D) {
63 assert(D && "Decl null");
64 ShadowedDecls.insert(ShadowedDecls.begin(), D);
65 }
66
67 /// RemoveShadowed - Remove the decl from the scope chain.
68 /// The decl must already be part of the decl chain.
69 void RemoveShadowed(NamedDecl *D);
70};
71
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000072} // end anonymous namespace
73
Chris Lattnera2f42b12008-04-11 07:06:57 +000074
75/// IdDeclInfoMap - Associates IdDeclInfos with Identifiers.
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000076/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
Chris Lattnera2f42b12008-04-11 07:06:57 +000077/// individual IdDeclInfo to heap.
78class IdentifierResolver::IdDeclInfoMap {
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000079 static const unsigned int VECTOR_SIZE = 512;
80 // Holds vectors of IdDeclInfos that serve as 'pools'.
81 // New vectors are added when the current one is full.
82 std::list< std::vector<IdDeclInfo> > IDIVecs;
Chris Lattnera2f42b12008-04-11 07:06:57 +000083 unsigned int CurIndex;
84
85public:
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000086 IdDeclInfoMap() : CurIndex(VECTOR_SIZE) {}
Chris Lattnera2f42b12008-04-11 07:06:57 +000087
88 /// Returns the IdDeclInfo associated to the IdentifierInfo.
89 /// It creates a new IdDeclInfo if one was not created before for this id.
90 IdDeclInfo &operator[](IdentifierInfo *II);
91};
92
93
94IdentifierResolver::IdentifierResolver() : IdDeclInfos(*new IdDeclInfoMap) {}
95IdentifierResolver::~IdentifierResolver() { delete &IdDeclInfos; }
96
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000097/// AddDecl - Link the decl to its shadowed decl chain.
Chris Lattnera2f42b12008-04-11 07:06:57 +000098void IdentifierResolver::AddDecl(NamedDecl *D, Scope *S) {
99 assert(D && S && "null param passed");
100 IdentifierInfo *II = D->getIdentifier();
101 void *Ptr = II->getFETokenInfo<void>();
102
103 if (!Ptr) {
104 II->setFETokenInfo(D);
105 return;
106 }
107
108 IdDeclInfo *IDI;
109
110 if (isDeclPtr(Ptr)) {
111 II->setFETokenInfo(NULL);
112 IDI = &IdDeclInfos[II];
113 IDI->PushShadowed(static_cast<NamedDecl*>(Ptr));
114 } else
115 IDI = toIdDeclInfo(Ptr);
116
Douglas Gregor2ce52f32008-04-13 21:07:44 +0000117 // C++ [basic.scope]p4:
118 // -- exactly one declaration shall declare a class name or
119 // enumeration name that is not a typedef name and the other
120 // declarations shall all refer to the same object or
121 // enumerator, or all refer to functions and function templates;
122 // in this case the class name or enumeration name is hidden.
123 if (isa<TagDecl>(D)) {
124 // We are pushing the name of a tag (enum or class).
125 IdDeclInfo::ShadowedIter TopIter = IDI->shadowed_end() - 1;
126 if (S->isDeclScope(*TopIter)) {
127 // There is already a declaration with the same name in the same
128 // scope. It must be found before we find the new declaration,
129 // so swap the order on the shadowed declaration stack.
130 NamedDecl *Temp = *TopIter;
131 *TopIter = D;
132 D = Temp;
133 }
134 }
135
Chris Lattnera2f42b12008-04-11 07:06:57 +0000136 IDI->PushShadowed(D);
137}
138
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000139/// AddGlobalDecl - Link the decl at the top of the shadowed decl chain.
Chris Lattnera2f42b12008-04-11 07:06:57 +0000140void IdentifierResolver::AddGlobalDecl(NamedDecl *D) {
141 assert(D && "null param passed");
142 IdentifierInfo *II = D->getIdentifier();
143 void *Ptr = II->getFETokenInfo<void>();
144
145 if (!Ptr) {
146 II->setFETokenInfo(D);
147 return;
148 }
149
150 IdDeclInfo *IDI;
151
152 if (isDeclPtr(Ptr)) {
153 II->setFETokenInfo(NULL);
154 IDI = &IdDeclInfos[II];
155 IDI->PushShadowed(static_cast<NamedDecl*>(Ptr));
156 } else
157 IDI = toIdDeclInfo(Ptr);
158
159 IDI->PushGlobalShadowed(D);
160}
161
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000162/// RemoveDecl - Unlink the decl from its shadowed decl chain.
Chris Lattnera2f42b12008-04-11 07:06:57 +0000163/// The decl must already be part of the decl chain.
164void IdentifierResolver::RemoveDecl(NamedDecl *D) {
165 assert(D && "null param passed");
166 IdentifierInfo *II = D->getIdentifier();
167 void *Ptr = II->getFETokenInfo<void>();
168
169 assert(Ptr && "Didn't find this decl on its identifier's chain!");
170
171 if (isDeclPtr(Ptr)) {
172 assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
173 II->setFETokenInfo(NULL);
174 return;
175 }
176
177 return toIdDeclInfo(Ptr)->RemoveShadowed(D);
178}
179
180/// Lookup - Find the non-shadowed decl that belongs to a particular
181/// Decl::IdentifierNamespace.
Douglas Gregor2ce52f32008-04-13 21:07:44 +0000182NamedDecl *IdentifierResolver::Lookup(const IdentifierInfo *II, unsigned NS) {
Chris Lattnera2f42b12008-04-11 07:06:57 +0000183 assert(II && "null param passed");
Chris Lattnera2f42b12008-04-11 07:06:57 +0000184 void *Ptr = II->getFETokenInfo<void>();
185
186 if (!Ptr) return NULL;
187
188 if (isDeclPtr(Ptr)) {
189 NamedDecl *D = static_cast<NamedDecl*>(Ptr);
Douglas Gregor2ce52f32008-04-13 21:07:44 +0000190 return (D->getIdentifierNamespace() & NS) ? D : NULL;
Chris Lattnera2f42b12008-04-11 07:06:57 +0000191 }
192
193 IdDeclInfo *IDI = toIdDeclInfo(Ptr);
194
195 // ShadowedDecls are ordered from most shadowed to less shadowed.
196 // So we do a reverse iteration from end to begin.
197 for (IdDeclInfo::ShadowedIter SI = IDI->shadowed_end();
198 SI != IDI->shadowed_begin(); --SI) {
199 NamedDecl *D = *(SI-1);
Douglas Gregor2ce52f32008-04-13 21:07:44 +0000200 if (D->getIdentifierNamespace() & NS)
Chris Lattnera2f42b12008-04-11 07:06:57 +0000201 return D;
202 }
203
204 // we didn't find the decl.
205 return NULL;
206}
207
208/// RemoveShadowed - Remove the decl from the scope chain.
209/// The decl must already be part of the decl chain.
210void IdDeclInfo::RemoveShadowed(NamedDecl *D) {
211 assert(D && "null decl passed");
Argyrios Kyrtzidis72e62b02008-04-12 12:38:58 +0000212 assert(!ShadowedDecls.empty() &&
Chris Lattnera2f42b12008-04-11 07:06:57 +0000213 "Didn't find this decl on its identifier's chain!");
214
215 // common case
216 if (D == ShadowedDecls.back()) {
217 ShadowedDecls.pop_back();
218 return;
219 }
220
221 for (ShadowedIter SI = ShadowedDecls.end()-1;
222 SI != ShadowedDecls.begin(); --SI) {
223 if (*(SI-1) == D) {
224 ShadowedDecls.erase(SI-1);
225 return;
226 }
227 }
228
229 assert(false && "Didn't find this decl on its identifier's chain!");
230}
231
232/// Returns the IdDeclInfo associated to the IdentifierInfo.
233/// It creates a new IdDeclInfo if one was not created before for this id.
234IdDeclInfo &IdentifierResolver::IdDeclInfoMap::operator[](IdentifierInfo *II) {
235 assert (II && "null IdentifierInfo passed");
236 void *Ptr = II->getFETokenInfo<void>();
237
238 if (Ptr) {
239 assert(!isDeclPtr(Ptr) && "didn't clear decl for FEToken");
240 return *toIdDeclInfo(Ptr);
241 }
242
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000243 if (CurIndex == VECTOR_SIZE) {
244 // Add a IdDeclInfo vector 'pool'
Argyrios Kyrtzidis72e62b02008-04-12 12:38:58 +0000245 IDIVecs.push_back(std::vector<IdDeclInfo>());
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000246 // Fill the vector
247 IDIVecs.back().resize(VECTOR_SIZE);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000248 CurIndex = 0;
249 }
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000250 IdDeclInfo *IDI = &IDIVecs.back()[CurIndex];
Chris Lattnera2f42b12008-04-11 07:06:57 +0000251 II->setFETokenInfo(reinterpret_cast<void*>(
252 reinterpret_cast<uintptr_t>(IDI) | 0x1)
253 );
254 ++CurIndex;
255 return *IDI;
256}