1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "clang/Sema/IdentifierResolver.h" |
15 | #include "clang/AST/Decl.h" |
16 | #include "clang/AST/DeclBase.h" |
17 | #include "clang/AST/DeclarationName.h" |
18 | #include "clang/Basic/IdentifierTable.h" |
19 | #include "clang/Basic/LangOptions.h" |
20 | #include "clang/Lex/ExternalPreprocessorSource.h" |
21 | #include "clang/Lex/Preprocessor.h" |
22 | #include "clang/Sema/Scope.h" |
23 | #include "llvm/Support/ErrorHandling.h" |
24 | #include <cassert> |
25 | #include <cstdint> |
26 | |
27 | using namespace clang; |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | class IdentifierResolver::IdDeclInfoMap { |
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 | |
52 | public: |
53 | IdDeclInfoMap() = default; |
54 | |
55 | ~IdDeclInfoMap() { |
56 | IdDeclInfoPool *Cur = CurPool; |
57 | while (IdDeclInfoPool *P = Cur) { |
58 | Cur = Cur->Next; |
59 | delete P; |
60 | } |
61 | } |
62 | |
63 | |
64 | |
65 | IdDeclInfo &operator[](DeclarationName Name); |
66 | }; |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) { |
75 | for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) { |
76 | if (D == *(I-1)) { |
77 | Decls.erase(I-1); |
78 | return; |
79 | } |
80 | } |
81 | |
82 | llvm_unreachable("Didn't find this decl on its identifier's chain!"); |
83 | } |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | IdentifierResolver::IdentifierResolver(Preprocessor &PP) |
90 | : LangOpt(PP.getLangOpts()), PP(PP), IdDeclInfos(new IdDeclInfoMap) {} |
91 | |
92 | IdentifierResolver::~IdentifierResolver() { |
93 | delete IdDeclInfos; |
94 | } |
95 | |
96 | |
97 | |
98 | |
99 | bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S, |
100 | bool AllowInlineNamespace) const { |
101 | Ctx = Ctx->getRedeclContext(); |
102 | |
103 | if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) { |
104 | |
105 | while (S->getEntity() && S->getEntity()->isTransparentContext()) |
106 | S = S->getParent(); |
107 | |
108 | if (S->isDeclScope(D)) |
109 | return true; |
110 | if (LangOpt.CPlusPlus) { |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | (0) . __assert_fail ("S->getParent() && \"No TUScope?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/IdentifierResolver.cpp", 123, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(S->getParent() && "No TUScope?"); |
124 | if (S->getParent()->getFlags() & Scope::ControlScope) { |
125 | S = S->getParent(); |
126 | if (S->isDeclScope(D)) |
127 | return true; |
128 | } |
129 | if (S->getFlags() & Scope::FnTryCatchScope) |
130 | return S->getParent()->isDeclScope(D); |
131 | } |
132 | return false; |
133 | } |
134 | |
135 | |
136 | |
137 | |
138 | DeclContext *DCtx = D->getDeclContext()->getRedeclContext(); |
139 | return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx) |
140 | : Ctx->Equals(DCtx); |
141 | } |
142 | |
143 | |
144 | void IdentifierResolver::AddDecl(NamedDecl *D) { |
145 | DeclarationName Name = D->getDeclName(); |
146 | if (IdentifierInfo *II = Name.getAsIdentifierInfo()) |
147 | updatingIdentifier(*II); |
148 | |
149 | void *Ptr = Name.getFETokenInfo(); |
150 | |
151 | if (!Ptr) { |
152 | Name.setFETokenInfo(D); |
153 | return; |
154 | } |
155 | |
156 | IdDeclInfo *IDI; |
157 | |
158 | if (isDeclPtr(Ptr)) { |
159 | Name.setFETokenInfo(nullptr); |
160 | IDI = &(*IdDeclInfos)[Name]; |
161 | NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); |
162 | IDI->AddDecl(PrevD); |
163 | } else |
164 | IDI = toIdDeclInfo(Ptr); |
165 | |
166 | IDI->AddDecl(D); |
167 | } |
168 | |
169 | void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) { |
170 | DeclarationName Name = D->getDeclName(); |
171 | if (IdentifierInfo *II = Name.getAsIdentifierInfo()) |
172 | updatingIdentifier(*II); |
173 | |
174 | void *Ptr = Name.getFETokenInfo(); |
175 | |
176 | if (!Ptr) { |
177 | AddDecl(D); |
178 | return; |
179 | } |
180 | |
181 | if (isDeclPtr(Ptr)) { |
182 | |
183 | |
184 | if (Pos == iterator()) { |
185 | |
186 | NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); |
187 | RemoveDecl(PrevD); |
188 | AddDecl(D); |
189 | AddDecl(PrevD); |
190 | } else { |
191 | |
192 | AddDecl(D); |
193 | } |
194 | |
195 | return; |
196 | } |
197 | |
198 | |
199 | |
200 | IdDeclInfo *IDI = toIdDeclInfo(Ptr); |
201 | if (Pos.isIterator()) { |
202 | IDI->InsertDecl(Pos.getIterator() + 1, D); |
203 | } else |
204 | IDI->InsertDecl(IDI->decls_begin(), D); |
205 | } |
206 | |
207 | |
208 | |
209 | void IdentifierResolver::RemoveDecl(NamedDecl *D) { |
210 | (0) . __assert_fail ("D && \"null param passed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/IdentifierResolver.cpp", 210, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(D && "null param passed"); |
211 | DeclarationName Name = D->getDeclName(); |
212 | if (IdentifierInfo *II = Name.getAsIdentifierInfo()) |
213 | updatingIdentifier(*II); |
214 | |
215 | void *Ptr = Name.getFETokenInfo(); |
216 | |
217 | (0) . __assert_fail ("Ptr && \"Didn't find this decl on its identifier's chain!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/IdentifierResolver.cpp", 217, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Ptr && "Didn't find this decl on its identifier's chain!"); |
218 | |
219 | if (isDeclPtr(Ptr)) { |
220 | (0) . __assert_fail ("D == Ptr && \"Didn't find this decl on its identifier's chain!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/IdentifierResolver.cpp", 220, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(D == Ptr && "Didn't find this decl on its identifier's chain!"); |
221 | Name.setFETokenInfo(nullptr); |
222 | return; |
223 | } |
224 | |
225 | return toIdDeclInfo(Ptr)->RemoveDecl(D); |
226 | } |
227 | |
228 | |
229 | IdentifierResolver::iterator |
230 | IdentifierResolver::begin(DeclarationName Name) { |
231 | if (IdentifierInfo *II = Name.getAsIdentifierInfo()) |
232 | readingIdentifier(*II); |
233 | |
234 | void *Ptr = Name.getFETokenInfo(); |
235 | if (!Ptr) return end(); |
236 | |
237 | if (isDeclPtr(Ptr)) |
238 | return iterator(static_cast<NamedDecl*>(Ptr)); |
239 | |
240 | IdDeclInfo *IDI = toIdDeclInfo(Ptr); |
241 | |
242 | IdDeclInfo::DeclsTy::iterator I = IDI->decls_end(); |
243 | if (I != IDI->decls_begin()) |
244 | return iterator(I-1); |
245 | |
246 | return end(); |
247 | } |
248 | |
249 | namespace { |
250 | |
251 | enum DeclMatchKind { |
252 | DMK_Different, |
253 | DMK_Replace, |
254 | DMK_Ignore |
255 | }; |
256 | |
257 | } |
258 | |
259 | |
260 | |
261 | |
262 | static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New) { |
263 | |
264 | if (Existing == New) |
265 | return DMK_Ignore; |
266 | |
267 | |
268 | if (Existing->getKind() != New->getKind()) |
269 | return DMK_Different; |
270 | |
271 | |
272 | if (Existing->getCanonicalDecl() == New->getCanonicalDecl()) { |
273 | |
274 | |
275 | if (Existing->isFromASTFile() && New->isFromASTFile()) |
276 | return DMK_Different; |
277 | |
278 | |
279 | Decl *MostRecent = Existing->getMostRecentDecl(); |
280 | if (Existing == MostRecent) |
281 | return DMK_Ignore; |
282 | |
283 | if (New == MostRecent) |
284 | return DMK_Replace; |
285 | |
286 | |
287 | |
288 | for (auto RD : New->redecls()) { |
289 | if (RD == Existing) |
290 | return DMK_Replace; |
291 | |
292 | if (RD->isCanonicalDecl()) |
293 | break; |
294 | } |
295 | |
296 | return DMK_Ignore; |
297 | } |
298 | |
299 | return DMK_Different; |
300 | } |
301 | |
302 | bool IdentifierResolver::tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name){ |
303 | if (IdentifierInfo *II = Name.getAsIdentifierInfo()) |
304 | readingIdentifier(*II); |
305 | |
306 | void *Ptr = Name.getFETokenInfo(); |
307 | |
308 | if (!Ptr) { |
309 | Name.setFETokenInfo(D); |
310 | return true; |
311 | } |
312 | |
313 | IdDeclInfo *IDI; |
314 | |
315 | if (isDeclPtr(Ptr)) { |
316 | NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); |
317 | |
318 | switch (compareDeclarations(PrevD, D)) { |
319 | case DMK_Different: |
320 | break; |
321 | |
322 | case DMK_Ignore: |
323 | return false; |
324 | |
325 | case DMK_Replace: |
326 | Name.setFETokenInfo(D); |
327 | return true; |
328 | } |
329 | |
330 | Name.setFETokenInfo(nullptr); |
331 | IDI = &(*IdDeclInfos)[Name]; |
332 | |
333 | |
334 | |
335 | if (!PrevD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { |
336 | IDI->AddDecl(D); |
337 | IDI->AddDecl(PrevD); |
338 | } else { |
339 | IDI->AddDecl(PrevD); |
340 | IDI->AddDecl(D); |
341 | } |
342 | return true; |
343 | } |
344 | |
345 | IDI = toIdDeclInfo(Ptr); |
346 | |
347 | |
348 | |
349 | for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(), |
350 | IEnd = IDI->decls_end(); |
351 | I != IEnd; ++I) { |
352 | |
353 | switch (compareDeclarations(*I, D)) { |
354 | case DMK_Different: |
355 | break; |
356 | |
357 | case DMK_Ignore: |
358 | return false; |
359 | |
360 | case DMK_Replace: |
361 | *I = D; |
362 | return true; |
363 | } |
364 | |
365 | if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) { |
366 | |
367 | |
368 | IDI->InsertDecl(I, D); |
369 | return true; |
370 | } |
371 | } |
372 | |
373 | |
374 | IDI->AddDecl(D); |
375 | return true; |
376 | } |
377 | |
378 | void IdentifierResolver::readingIdentifier(IdentifierInfo &II) { |
379 | if (II.isOutOfDate()) |
380 | PP.getExternalSource()->updateOutOfDateIdentifier(II); |
381 | } |
382 | |
383 | void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) { |
384 | if (II.isOutOfDate()) |
385 | PP.getExternalSource()->updateOutOfDateIdentifier(II); |
386 | |
387 | if (II.isFromAST()) |
388 | II.setFETokenInfoChangedSinceDeserialization(); |
389 | } |
390 | |
391 | |
392 | |
393 | |
394 | |
395 | |
396 | |
397 | IdentifierResolver::IdDeclInfo & |
398 | IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) { |
399 | void *Ptr = Name.getFETokenInfo(); |
400 | |
401 | if (Ptr) return *toIdDeclInfo(Ptr); |
402 | |
403 | if (CurIndex == POOL_SIZE) { |
404 | CurPool = new IdDeclInfoPool(CurPool); |
405 | CurIndex = 0; |
406 | } |
407 | IdDeclInfo *IDI = &CurPool->Pool[CurIndex]; |
408 | Name.setFETokenInfo(reinterpret_cast<void*>( |
409 | reinterpret_cast<uintptr_t>(IDI) | 0x1) |
410 | ); |
411 | ++CurIndex; |
412 | return *IDI; |
413 | } |
414 | |
415 | void IdentifierResolver::iterator::incrementSlowCase() { |
416 | NamedDecl *D = **this; |
417 | void *InfoPtr = D->getDeclName().getFETokenInfo(); |
418 | (0) . __assert_fail ("!isDeclPtr(InfoPtr) && \"Decl with wrong id ?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/IdentifierResolver.cpp", 418, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?"); |
419 | IdDeclInfo *Info = toIdDeclInfo(InfoPtr); |
420 | |
421 | BaseIter I = getIterator(); |
422 | if (I != Info->decls_begin()) |
423 | *this = iterator(I-1); |
424 | else |
425 | *this = iterator(); |
426 | } |
427 | |