clang: lib/Sema/IdentifierResolver.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
23#include "llvm/Support/ErrorHandling.h"
24#include
25#include
26
27using namespace clang;
28
29
30
31
32
33
34
35
37 static const unsigned int POOL_SIZE = 512;
38
39
40
41
42 struct IdDeclInfoPool {
43 IdDeclInfoPool *Next;
44 IdDeclInfo Pool[POOL_SIZE];
45
46 IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
47 };
48
49 IdDeclInfoPool *CurPool = nullptr;
50 unsigned int CurIndex = POOL_SIZE;
51
52public:
54
56 IdDeclInfoPool *Cur = CurPool;
57 while (IdDeclInfoPool *P = Cur) {
58 Cur = Cur->Next;
59 delete P;
60 }
61 }
62
65
66
67
69};
70
71
72
73
74
75
76
77void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
78 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
79 if (D == *(I-1)) {
80 Decls.erase(I-1);
81 return;
82 }
83 }
84
85 llvm_unreachable("Didn't find this decl on its identifier's chain!");
86}
87
88
89
90
91
93 : LangOpt(PP.getLangOpts()), PP(PP), IdDeclInfos(new IdDeclInfoMap) {}
94
96 delete IdDeclInfos;
97}
98
99
100
101
103 bool AllowInlineNamespace) const {
104 Ctx = Ctx->getRedeclContext();
105
106
107
108 if (LangOpt.HLSL && isa(D))
109 return false;
110 if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) {
111
112 while (S->getEntity() &&
113 (S->getEntity()->isTransparentContext() ||
114 (!LangOpt.CPlusPlus && isa(S->getEntity()))))
115 S = S->getParent();
116
117 if (S->isDeclScope(D))
118 return true;
119 if (LangOpt.CPlusPlus) {
120
121
122
123
124
125
126
127
128
129
130
131
132 assert(S->getParent() && "No TUScope?");
133
134
135 if (S->getParent()->isControlScope() && !S->isFunctionScope()) {
136 S = S->getParent();
137 if (S->isDeclScope(D))
138 return true;
139 }
140 if (S->isFnTryCatchScope())
141 return S->getParent()->isDeclScope(D);
142 }
143 return false;
144 }
145
146
147
148
150 return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)
151 : Ctx->Equals(DCtx);
152}
153
154
158 updatingIdentifier(*II);
159
160 void *Ptr = Name.getFETokenInfo();
161
162 if (!Ptr) {
163 Name.setFETokenInfo(D);
164 return;
165 }
166
167 IdDeclInfo *IDI;
168
169 if (isDeclPtr(Ptr)) {
170 Name.setFETokenInfo(nullptr);
171 IDI = &(*IdDeclInfos)[Name];
173 IDI->AddDecl(PrevD);
174 } else
175 IDI = toIdDeclInfo(Ptr);
176
177 IDI->AddDecl(D);
178}
179
183 updatingIdentifier(*II);
184
185 void *Ptr = Name.getFETokenInfo();
186
187 if (!Ptr) {
189 return;
190 }
191
192 if (isDeclPtr(Ptr)) {
193
194
196
201 } else {
202
204 }
205
206 return;
207 }
208
209
210
211 IdDeclInfo *IDI = toIdDeclInfo(Ptr);
214 } else
215 IDI->InsertDecl(IDI->decls_begin(), D);
216}
217
218
219
221 assert(D && "null param passed");
224 updatingIdentifier(*II);
225
226 void *Ptr = Name.getFETokenInfo();
227
228 assert(Ptr && "Didn't find this decl on its identifier's chain!");
229
230 if (isDeclPtr(Ptr)) {
231 assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
232 Name.setFETokenInfo(nullptr);
233 return;
234 }
235
236 return toIdDeclInfo(Ptr)->RemoveDecl(D);
237}
238
239llvm::iterator_rangeIdentifierResolver::iterator
242}
243
246 readingIdentifier(*II);
247
248 void *Ptr = Name.getFETokenInfo();
249 if (!Ptr) return end();
250
251 if (isDeclPtr(Ptr))
253
254 IdDeclInfo *IDI = toIdDeclInfo(Ptr);
255
256 IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
257 if (I != IDI->decls_begin())
259
260 return end();
261}
262
263namespace {
264
265enum DeclMatchKind {
266 DMK_Different,
267 DMK_Replace,
268 DMK_Ignore
269};
270
271}
272
273
274
275
277
278 if (Existing == New)
279 return DMK_Ignore;
280
281
283 return DMK_Different;
284
285
287
288
290 return DMK_Different;
291
292
294 if (Existing == MostRecent)
295 return DMK_Ignore;
296
297 if (New == MostRecent)
298 return DMK_Replace;
299
300
301
302 for (auto *RD : New->redecls()) {
303 if (RD == Existing)
304 return DMK_Replace;
305
306 if (RD->isCanonicalDecl())
307 break;
308 }
309
310 return DMK_Ignore;
311 }
312
313 return DMK_Different;
314}
315
318 readingIdentifier(*II);
319
320 void *Ptr = Name.getFETokenInfo();
321
322 if (!Ptr) {
323 Name.setFETokenInfo(D);
324 return true;
325 }
326
327 IdDeclInfo *IDI;
328
329 if (isDeclPtr(Ptr)) {
331
333 case DMK_Different:
334 break;
335
336 case DMK_Ignore:
337 return false;
338
339 case DMK_Replace:
340 Name.setFETokenInfo(D);
341 return true;
342 }
343
344 Name.setFETokenInfo(nullptr);
345 IDI = &(*IdDeclInfos)[Name];
346
347
348
350 IDI->AddDecl(D);
351 IDI->AddDecl(PrevD);
352 } else {
353 IDI->AddDecl(PrevD);
354 IDI->AddDecl(D);
355 }
356 return true;
357 }
358
359 IDI = toIdDeclInfo(Ptr);
360
361
362
363 for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(),
364 IEnd = IDI->decls_end();
365 I != IEnd; ++I) {
366
368 case DMK_Different:
369 break;
370
371 case DMK_Ignore:
372 return false;
373
374 case DMK_Replace:
375 *I = D;
376 return true;
377 }
378
379 if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
380
381
382 IDI->InsertDecl(I, D);
383 return true;
384 }
385 }
386
387
388 IDI->AddDecl(D);
389 return true;
390}
391
392void IdentifierResolver::readingIdentifier(IdentifierInfo &II) {
395}
396
397void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) {
400
403}
404
405
406
407
408
409
410
411IdentifierResolver::IdDeclInfo &
413 void *Ptr = Name.getFETokenInfo();
414
415 if (Ptr) return *toIdDeclInfo(Ptr);
416
417 if (CurIndex == POOL_SIZE) {
418 CurPool = new IdDeclInfoPool(CurPool);
419 CurIndex = 0;
420 }
421 IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
422 Name.setFETokenInfo(reinterpret_cast<void*>(
423 reinterpret_cast<uintptr_t>(IDI) | 0x1)
424 );
425 ++CurIndex;
426 return *IDI;
427}
428
431 void *InfoPtr = D->getDeclName().getFETokenInfo();
432 assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
433 IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
434
436 if (I != Info->decls_begin())
438 else
440}
static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New)
Compare two declarations to see whether they are different or, if they are the same,...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::Preprocessor interface.
IdDeclInfoMap - Associates IdDeclInfos with declaration names.
IdDeclInfoMap(const IdDeclInfoMap &)=delete
IdDeclInfoMap & operator=(const IdDeclInfoMap &)=delete
IdDeclInfo & operator[](DeclarationName Name)
Returns the IdDeclInfo associated to the DeclarationName.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool isTranslationUnit() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Decl - This represents one declaration (or definition), e.g.
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
DeclContext * getDeclContext()
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
virtual void updateOutOfDateIdentifier(const IdentifierInfo &II)=0
Update an out-of-date identifier.
One of these records is kept for each identifier that is lexed.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
void setFETokenInfoChangedSinceDeserialization()
Note that the frontend token information for this identifier has changed since it was loaded from an ...
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
iterator - Iterate over the decls of a specified declaration name.
IdDeclInfo::DeclsTy::iterator BaseIter
BaseIter getIterator() const
iterator begin(DeclarationName Name)
Returns an iterator over decls with the name 'Name'.
void RemoveDecl(NamedDecl *D)
RemoveDecl - Unlink the decl from its shadowed decl chain.
IdentifierResolver(Preprocessor &PP)
void InsertDeclAfter(iterator Pos, NamedDecl *D)
Insert the given declaration after the given iterator position.
bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name)
Try to add the given declaration to the top level scope, if it (or a redeclaration of it) hasn't alre...
iterator end()
Returns the end iterator.
void AddDecl(NamedDecl *D)
AddDecl - Link the decl to its shadowed decl chain.
llvm::iterator_range< iterator > decls(DeclarationName Name)
Returns a range of decls with the name 'Name'.
bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false) const
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...
This represents a decl that may have a name.
NamedDecl * getMostRecentDecl()
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
ExternalPreprocessorSource * getExternalSource() const
Scope - A scope is a transient data structure that is used while parsing the program.
The JSON file list parser is used to communicate input to InstallAPI.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...