1f4a2713aSLionel Sambuc //===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the IdentifierResolver class, which is used for lexical
11f4a2713aSLionel Sambuc // scoped lookup, based on declaration names.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc
15f4a2713aSLionel Sambuc #include "clang/Sema/IdentifierResolver.h"
16f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
17f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.h"
18f4a2713aSLionel Sambuc #include "clang/Lex/ExternalPreprocessorSource.h"
19f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
20f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
21f4a2713aSLionel Sambuc
22f4a2713aSLionel Sambuc using namespace clang;
23f4a2713aSLionel Sambuc
24f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
25f4a2713aSLionel Sambuc // IdDeclInfoMap class
26f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
27f4a2713aSLionel Sambuc
28f4a2713aSLionel Sambuc /// IdDeclInfoMap - Associates IdDeclInfos with declaration names.
29f4a2713aSLionel Sambuc /// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
30f4a2713aSLionel Sambuc /// individual IdDeclInfo to heap.
31f4a2713aSLionel Sambuc class IdentifierResolver::IdDeclInfoMap {
32f4a2713aSLionel Sambuc static const unsigned int POOL_SIZE = 512;
33f4a2713aSLionel Sambuc
34f4a2713aSLionel Sambuc /// We use our own linked-list implementation because it is sadly
35f4a2713aSLionel Sambuc /// impossible to add something to a pre-C++0x STL container without
36f4a2713aSLionel Sambuc /// a completely unnecessary copy.
37f4a2713aSLionel Sambuc struct IdDeclInfoPool {
IdDeclInfoPoolIdentifierResolver::IdDeclInfoMap::IdDeclInfoPool38f4a2713aSLionel Sambuc IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
39f4a2713aSLionel Sambuc
40f4a2713aSLionel Sambuc IdDeclInfoPool *Next;
41f4a2713aSLionel Sambuc IdDeclInfo Pool[POOL_SIZE];
42f4a2713aSLionel Sambuc };
43f4a2713aSLionel Sambuc
44f4a2713aSLionel Sambuc IdDeclInfoPool *CurPool;
45f4a2713aSLionel Sambuc unsigned int CurIndex;
46f4a2713aSLionel Sambuc
47f4a2713aSLionel Sambuc public:
IdDeclInfoMap()48*0a6a1f1dSLionel Sambuc IdDeclInfoMap() : CurPool(nullptr), CurIndex(POOL_SIZE) {}
49f4a2713aSLionel Sambuc
~IdDeclInfoMap()50f4a2713aSLionel Sambuc ~IdDeclInfoMap() {
51f4a2713aSLionel Sambuc IdDeclInfoPool *Cur = CurPool;
52f4a2713aSLionel Sambuc while (IdDeclInfoPool *P = Cur) {
53f4a2713aSLionel Sambuc Cur = Cur->Next;
54f4a2713aSLionel Sambuc delete P;
55f4a2713aSLionel Sambuc }
56f4a2713aSLionel Sambuc }
57f4a2713aSLionel Sambuc
58f4a2713aSLionel Sambuc /// Returns the IdDeclInfo associated to the DeclarationName.
59f4a2713aSLionel Sambuc /// It creates a new IdDeclInfo if one was not created before for this id.
60f4a2713aSLionel Sambuc IdDeclInfo &operator[](DeclarationName Name);
61f4a2713aSLionel Sambuc };
62f4a2713aSLionel Sambuc
63f4a2713aSLionel Sambuc
64f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
65f4a2713aSLionel Sambuc // IdDeclInfo Implementation
66f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
67f4a2713aSLionel Sambuc
68f4a2713aSLionel Sambuc /// RemoveDecl - Remove the decl from the scope chain.
69f4a2713aSLionel Sambuc /// The decl must already be part of the decl chain.
RemoveDecl(NamedDecl * D)70f4a2713aSLionel Sambuc void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
71f4a2713aSLionel Sambuc for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
72f4a2713aSLionel Sambuc if (D == *(I-1)) {
73f4a2713aSLionel Sambuc Decls.erase(I-1);
74f4a2713aSLionel Sambuc return;
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc }
77f4a2713aSLionel Sambuc
78f4a2713aSLionel Sambuc llvm_unreachable("Didn't find this decl on its identifier's chain!");
79f4a2713aSLionel Sambuc }
80f4a2713aSLionel Sambuc
81f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
82f4a2713aSLionel Sambuc // IdentifierResolver Implementation
83f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
84f4a2713aSLionel Sambuc
IdentifierResolver(Preprocessor & PP)85f4a2713aSLionel Sambuc IdentifierResolver::IdentifierResolver(Preprocessor &PP)
86f4a2713aSLionel Sambuc : LangOpt(PP.getLangOpts()), PP(PP),
87f4a2713aSLionel Sambuc IdDeclInfos(new IdDeclInfoMap) {
88f4a2713aSLionel Sambuc }
89f4a2713aSLionel Sambuc
~IdentifierResolver()90f4a2713aSLionel Sambuc IdentifierResolver::~IdentifierResolver() {
91f4a2713aSLionel Sambuc delete IdDeclInfos;
92f4a2713aSLionel Sambuc }
93f4a2713aSLionel Sambuc
94f4a2713aSLionel Sambuc /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
95f4a2713aSLionel Sambuc /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
96f4a2713aSLionel Sambuc /// true if 'D' belongs to the given declaration context.
isDeclInScope(Decl * D,DeclContext * Ctx,Scope * S,bool AllowInlineNamespace) const97f4a2713aSLionel Sambuc bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,
98*0a6a1f1dSLionel Sambuc bool AllowInlineNamespace) const {
99f4a2713aSLionel Sambuc Ctx = Ctx->getRedeclContext();
100f4a2713aSLionel Sambuc
101f4a2713aSLionel Sambuc if (Ctx->isFunctionOrMethod() || S->isFunctionPrototypeScope()) {
102f4a2713aSLionel Sambuc // Ignore the scopes associated within transparent declaration contexts.
103f4a2713aSLionel Sambuc while (S->getEntity() && S->getEntity()->isTransparentContext())
104f4a2713aSLionel Sambuc S = S->getParent();
105f4a2713aSLionel Sambuc
106f4a2713aSLionel Sambuc if (S->isDeclScope(D))
107f4a2713aSLionel Sambuc return true;
108f4a2713aSLionel Sambuc if (LangOpt.CPlusPlus) {
109f4a2713aSLionel Sambuc // C++ 3.3.2p3:
110f4a2713aSLionel Sambuc // The name declared in a catch exception-declaration is local to the
111f4a2713aSLionel Sambuc // handler and shall not be redeclared in the outermost block of the
112f4a2713aSLionel Sambuc // handler.
113f4a2713aSLionel Sambuc // C++ 3.3.2p4:
114f4a2713aSLionel Sambuc // Names declared in the for-init-statement, and in the condition of if,
115f4a2713aSLionel Sambuc // while, for, and switch statements are local to the if, while, for, or
116f4a2713aSLionel Sambuc // switch statement (including the controlled statement), and shall not be
117f4a2713aSLionel Sambuc // redeclared in a subsequent condition of that statement nor in the
118f4a2713aSLionel Sambuc // outermost block (or, for the if statement, any of the outermost blocks)
119f4a2713aSLionel Sambuc // of the controlled statement.
120f4a2713aSLionel Sambuc //
121f4a2713aSLionel Sambuc assert(S->getParent() && "No TUScope?");
122f4a2713aSLionel Sambuc if (S->getParent()->getFlags() & Scope::ControlScope) {
123f4a2713aSLionel Sambuc S = S->getParent();
124f4a2713aSLionel Sambuc if (S->isDeclScope(D))
125f4a2713aSLionel Sambuc return true;
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc if (S->getFlags() & Scope::FnTryCatchScope)
128f4a2713aSLionel Sambuc return S->getParent()->isDeclScope(D);
129f4a2713aSLionel Sambuc }
130f4a2713aSLionel Sambuc return false;
131f4a2713aSLionel Sambuc }
132f4a2713aSLionel Sambuc
133*0a6a1f1dSLionel Sambuc // FIXME: If D is a local extern declaration, this check doesn't make sense;
134*0a6a1f1dSLionel Sambuc // we should be checking its lexical context instead in that case, because
135*0a6a1f1dSLionel Sambuc // that is its scope.
136f4a2713aSLionel Sambuc DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
137*0a6a1f1dSLionel Sambuc return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)
138f4a2713aSLionel Sambuc : Ctx->Equals(DCtx);
139f4a2713aSLionel Sambuc }
140f4a2713aSLionel Sambuc
141f4a2713aSLionel Sambuc /// AddDecl - Link the decl to its shadowed decl chain.
AddDecl(NamedDecl * D)142f4a2713aSLionel Sambuc void IdentifierResolver::AddDecl(NamedDecl *D) {
143f4a2713aSLionel Sambuc DeclarationName Name = D->getDeclName();
144f4a2713aSLionel Sambuc if (IdentifierInfo *II = Name.getAsIdentifierInfo())
145f4a2713aSLionel Sambuc updatingIdentifier(*II);
146f4a2713aSLionel Sambuc
147f4a2713aSLionel Sambuc void *Ptr = Name.getFETokenInfo<void>();
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc if (!Ptr) {
150f4a2713aSLionel Sambuc Name.setFETokenInfo(D);
151f4a2713aSLionel Sambuc return;
152f4a2713aSLionel Sambuc }
153f4a2713aSLionel Sambuc
154f4a2713aSLionel Sambuc IdDeclInfo *IDI;
155f4a2713aSLionel Sambuc
156f4a2713aSLionel Sambuc if (isDeclPtr(Ptr)) {
157*0a6a1f1dSLionel Sambuc Name.setFETokenInfo(nullptr);
158f4a2713aSLionel Sambuc IDI = &(*IdDeclInfos)[Name];
159f4a2713aSLionel Sambuc NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
160f4a2713aSLionel Sambuc IDI->AddDecl(PrevD);
161f4a2713aSLionel Sambuc } else
162f4a2713aSLionel Sambuc IDI = toIdDeclInfo(Ptr);
163f4a2713aSLionel Sambuc
164f4a2713aSLionel Sambuc IDI->AddDecl(D);
165f4a2713aSLionel Sambuc }
166f4a2713aSLionel Sambuc
InsertDeclAfter(iterator Pos,NamedDecl * D)167f4a2713aSLionel Sambuc void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) {
168f4a2713aSLionel Sambuc DeclarationName Name = D->getDeclName();
169f4a2713aSLionel Sambuc if (IdentifierInfo *II = Name.getAsIdentifierInfo())
170f4a2713aSLionel Sambuc updatingIdentifier(*II);
171f4a2713aSLionel Sambuc
172f4a2713aSLionel Sambuc void *Ptr = Name.getFETokenInfo<void>();
173f4a2713aSLionel Sambuc
174f4a2713aSLionel Sambuc if (!Ptr) {
175f4a2713aSLionel Sambuc AddDecl(D);
176f4a2713aSLionel Sambuc return;
177f4a2713aSLionel Sambuc }
178f4a2713aSLionel Sambuc
179f4a2713aSLionel Sambuc if (isDeclPtr(Ptr)) {
180f4a2713aSLionel Sambuc // We only have a single declaration: insert before or after it,
181f4a2713aSLionel Sambuc // as appropriate.
182f4a2713aSLionel Sambuc if (Pos == iterator()) {
183f4a2713aSLionel Sambuc // Add the new declaration before the existing declaration.
184f4a2713aSLionel Sambuc NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
185f4a2713aSLionel Sambuc RemoveDecl(PrevD);
186f4a2713aSLionel Sambuc AddDecl(D);
187f4a2713aSLionel Sambuc AddDecl(PrevD);
188f4a2713aSLionel Sambuc } else {
189f4a2713aSLionel Sambuc // Add new declaration after the existing declaration.
190f4a2713aSLionel Sambuc AddDecl(D);
191f4a2713aSLionel Sambuc }
192f4a2713aSLionel Sambuc
193f4a2713aSLionel Sambuc return;
194f4a2713aSLionel Sambuc }
195f4a2713aSLionel Sambuc
196f4a2713aSLionel Sambuc // General case: insert the declaration at the appropriate point in the
197f4a2713aSLionel Sambuc // list, which already has at least two elements.
198f4a2713aSLionel Sambuc IdDeclInfo *IDI = toIdDeclInfo(Ptr);
199f4a2713aSLionel Sambuc if (Pos.isIterator()) {
200f4a2713aSLionel Sambuc IDI->InsertDecl(Pos.getIterator() + 1, D);
201f4a2713aSLionel Sambuc } else
202f4a2713aSLionel Sambuc IDI->InsertDecl(IDI->decls_begin(), D);
203f4a2713aSLionel Sambuc }
204f4a2713aSLionel Sambuc
205f4a2713aSLionel Sambuc /// RemoveDecl - Unlink the decl from its shadowed decl chain.
206f4a2713aSLionel Sambuc /// The decl must already be part of the decl chain.
RemoveDecl(NamedDecl * D)207f4a2713aSLionel Sambuc void IdentifierResolver::RemoveDecl(NamedDecl *D) {
208f4a2713aSLionel Sambuc assert(D && "null param passed");
209f4a2713aSLionel Sambuc DeclarationName Name = D->getDeclName();
210f4a2713aSLionel Sambuc if (IdentifierInfo *II = Name.getAsIdentifierInfo())
211f4a2713aSLionel Sambuc updatingIdentifier(*II);
212f4a2713aSLionel Sambuc
213f4a2713aSLionel Sambuc void *Ptr = Name.getFETokenInfo<void>();
214f4a2713aSLionel Sambuc
215f4a2713aSLionel Sambuc assert(Ptr && "Didn't find this decl on its identifier's chain!");
216f4a2713aSLionel Sambuc
217f4a2713aSLionel Sambuc if (isDeclPtr(Ptr)) {
218f4a2713aSLionel Sambuc assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
219*0a6a1f1dSLionel Sambuc Name.setFETokenInfo(nullptr);
220f4a2713aSLionel Sambuc return;
221f4a2713aSLionel Sambuc }
222f4a2713aSLionel Sambuc
223f4a2713aSLionel Sambuc return toIdDeclInfo(Ptr)->RemoveDecl(D);
224f4a2713aSLionel Sambuc }
225f4a2713aSLionel Sambuc
226f4a2713aSLionel Sambuc /// begin - Returns an iterator for decls with name 'Name'.
227f4a2713aSLionel Sambuc IdentifierResolver::iterator
begin(DeclarationName Name)228f4a2713aSLionel Sambuc IdentifierResolver::begin(DeclarationName Name) {
229f4a2713aSLionel Sambuc if (IdentifierInfo *II = Name.getAsIdentifierInfo())
230f4a2713aSLionel Sambuc readingIdentifier(*II);
231f4a2713aSLionel Sambuc
232f4a2713aSLionel Sambuc void *Ptr = Name.getFETokenInfo<void>();
233f4a2713aSLionel Sambuc if (!Ptr) return end();
234f4a2713aSLionel Sambuc
235f4a2713aSLionel Sambuc if (isDeclPtr(Ptr))
236f4a2713aSLionel Sambuc return iterator(static_cast<NamedDecl*>(Ptr));
237f4a2713aSLionel Sambuc
238f4a2713aSLionel Sambuc IdDeclInfo *IDI = toIdDeclInfo(Ptr);
239f4a2713aSLionel Sambuc
240f4a2713aSLionel Sambuc IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
241f4a2713aSLionel Sambuc if (I != IDI->decls_begin())
242f4a2713aSLionel Sambuc return iterator(I-1);
243f4a2713aSLionel Sambuc // No decls found.
244f4a2713aSLionel Sambuc return end();
245f4a2713aSLionel Sambuc }
246f4a2713aSLionel Sambuc
247f4a2713aSLionel Sambuc namespace {
248f4a2713aSLionel Sambuc enum DeclMatchKind {
249f4a2713aSLionel Sambuc DMK_Different,
250f4a2713aSLionel Sambuc DMK_Replace,
251f4a2713aSLionel Sambuc DMK_Ignore
252f4a2713aSLionel Sambuc };
253f4a2713aSLionel Sambuc }
254f4a2713aSLionel Sambuc
255f4a2713aSLionel Sambuc /// \brief Compare two declarations to see whether they are different or,
256f4a2713aSLionel Sambuc /// if they are the same, whether the new declaration should replace the
257f4a2713aSLionel Sambuc /// existing declaration.
compareDeclarations(NamedDecl * Existing,NamedDecl * New)258f4a2713aSLionel Sambuc static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New) {
259f4a2713aSLionel Sambuc // If the declarations are identical, ignore the new one.
260f4a2713aSLionel Sambuc if (Existing == New)
261f4a2713aSLionel Sambuc return DMK_Ignore;
262f4a2713aSLionel Sambuc
263f4a2713aSLionel Sambuc // If the declarations have different kinds, they're obviously different.
264f4a2713aSLionel Sambuc if (Existing->getKind() != New->getKind())
265f4a2713aSLionel Sambuc return DMK_Different;
266f4a2713aSLionel Sambuc
267f4a2713aSLionel Sambuc // If the declarations are redeclarations of each other, keep the newest one.
268f4a2713aSLionel Sambuc if (Existing->getCanonicalDecl() == New->getCanonicalDecl()) {
269f4a2713aSLionel Sambuc // If either of these is the most recent declaration, use it.
270f4a2713aSLionel Sambuc Decl *MostRecent = Existing->getMostRecentDecl();
271f4a2713aSLionel Sambuc if (Existing == MostRecent)
272f4a2713aSLionel Sambuc return DMK_Ignore;
273f4a2713aSLionel Sambuc
274f4a2713aSLionel Sambuc if (New == MostRecent)
275f4a2713aSLionel Sambuc return DMK_Replace;
276f4a2713aSLionel Sambuc
277f4a2713aSLionel Sambuc // If the existing declaration is somewhere in the previous declaration
278f4a2713aSLionel Sambuc // chain of the new declaration, then prefer the new declaration.
279*0a6a1f1dSLionel Sambuc for (auto RD : New->redecls()) {
280*0a6a1f1dSLionel Sambuc if (RD == Existing)
281f4a2713aSLionel Sambuc return DMK_Replace;
282f4a2713aSLionel Sambuc
283f4a2713aSLionel Sambuc if (RD->isCanonicalDecl())
284f4a2713aSLionel Sambuc break;
285f4a2713aSLionel Sambuc }
286f4a2713aSLionel Sambuc
287f4a2713aSLionel Sambuc return DMK_Ignore;
288f4a2713aSLionel Sambuc }
289f4a2713aSLionel Sambuc
290f4a2713aSLionel Sambuc return DMK_Different;
291f4a2713aSLionel Sambuc }
292f4a2713aSLionel Sambuc
tryAddTopLevelDecl(NamedDecl * D,DeclarationName Name)293f4a2713aSLionel Sambuc bool IdentifierResolver::tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name){
294f4a2713aSLionel Sambuc if (IdentifierInfo *II = Name.getAsIdentifierInfo())
295f4a2713aSLionel Sambuc readingIdentifier(*II);
296f4a2713aSLionel Sambuc
297f4a2713aSLionel Sambuc void *Ptr = Name.getFETokenInfo<void>();
298f4a2713aSLionel Sambuc
299f4a2713aSLionel Sambuc if (!Ptr) {
300f4a2713aSLionel Sambuc Name.setFETokenInfo(D);
301f4a2713aSLionel Sambuc return true;
302f4a2713aSLionel Sambuc }
303f4a2713aSLionel Sambuc
304f4a2713aSLionel Sambuc IdDeclInfo *IDI;
305f4a2713aSLionel Sambuc
306f4a2713aSLionel Sambuc if (isDeclPtr(Ptr)) {
307f4a2713aSLionel Sambuc NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
308f4a2713aSLionel Sambuc
309f4a2713aSLionel Sambuc switch (compareDeclarations(PrevD, D)) {
310f4a2713aSLionel Sambuc case DMK_Different:
311f4a2713aSLionel Sambuc break;
312f4a2713aSLionel Sambuc
313f4a2713aSLionel Sambuc case DMK_Ignore:
314f4a2713aSLionel Sambuc return false;
315f4a2713aSLionel Sambuc
316f4a2713aSLionel Sambuc case DMK_Replace:
317f4a2713aSLionel Sambuc Name.setFETokenInfo(D);
318f4a2713aSLionel Sambuc return true;
319f4a2713aSLionel Sambuc }
320f4a2713aSLionel Sambuc
321*0a6a1f1dSLionel Sambuc Name.setFETokenInfo(nullptr);
322f4a2713aSLionel Sambuc IDI = &(*IdDeclInfos)[Name];
323f4a2713aSLionel Sambuc
324f4a2713aSLionel Sambuc // If the existing declaration is not visible in translation unit scope,
325f4a2713aSLionel Sambuc // then add the new top-level declaration first.
326f4a2713aSLionel Sambuc if (!PrevD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
327f4a2713aSLionel Sambuc IDI->AddDecl(D);
328f4a2713aSLionel Sambuc IDI->AddDecl(PrevD);
329f4a2713aSLionel Sambuc } else {
330f4a2713aSLionel Sambuc IDI->AddDecl(PrevD);
331f4a2713aSLionel Sambuc IDI->AddDecl(D);
332f4a2713aSLionel Sambuc }
333f4a2713aSLionel Sambuc return true;
334f4a2713aSLionel Sambuc }
335f4a2713aSLionel Sambuc
336f4a2713aSLionel Sambuc IDI = toIdDeclInfo(Ptr);
337f4a2713aSLionel Sambuc
338f4a2713aSLionel Sambuc // See whether this declaration is identical to any existing declarations.
339f4a2713aSLionel Sambuc // If not, find the right place to insert it.
340f4a2713aSLionel Sambuc for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(),
341f4a2713aSLionel Sambuc IEnd = IDI->decls_end();
342f4a2713aSLionel Sambuc I != IEnd; ++I) {
343f4a2713aSLionel Sambuc
344f4a2713aSLionel Sambuc switch (compareDeclarations(*I, D)) {
345f4a2713aSLionel Sambuc case DMK_Different:
346f4a2713aSLionel Sambuc break;
347f4a2713aSLionel Sambuc
348f4a2713aSLionel Sambuc case DMK_Ignore:
349f4a2713aSLionel Sambuc return false;
350f4a2713aSLionel Sambuc
351f4a2713aSLionel Sambuc case DMK_Replace:
352f4a2713aSLionel Sambuc *I = D;
353f4a2713aSLionel Sambuc return true;
354f4a2713aSLionel Sambuc }
355f4a2713aSLionel Sambuc
356f4a2713aSLionel Sambuc if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
357f4a2713aSLionel Sambuc // We've found a declaration that is not visible from the translation
358f4a2713aSLionel Sambuc // unit (it's in an inner scope). Insert our declaration here.
359f4a2713aSLionel Sambuc IDI->InsertDecl(I, D);
360f4a2713aSLionel Sambuc return true;
361f4a2713aSLionel Sambuc }
362f4a2713aSLionel Sambuc }
363f4a2713aSLionel Sambuc
364f4a2713aSLionel Sambuc // Add the declaration to the end.
365f4a2713aSLionel Sambuc IDI->AddDecl(D);
366f4a2713aSLionel Sambuc return true;
367f4a2713aSLionel Sambuc }
368f4a2713aSLionel Sambuc
readingIdentifier(IdentifierInfo & II)369f4a2713aSLionel Sambuc void IdentifierResolver::readingIdentifier(IdentifierInfo &II) {
370f4a2713aSLionel Sambuc if (II.isOutOfDate())
371f4a2713aSLionel Sambuc PP.getExternalSource()->updateOutOfDateIdentifier(II);
372f4a2713aSLionel Sambuc }
373f4a2713aSLionel Sambuc
updatingIdentifier(IdentifierInfo & II)374f4a2713aSLionel Sambuc void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) {
375f4a2713aSLionel Sambuc if (II.isOutOfDate())
376f4a2713aSLionel Sambuc PP.getExternalSource()->updateOutOfDateIdentifier(II);
377f4a2713aSLionel Sambuc
378f4a2713aSLionel Sambuc if (II.isFromAST())
379f4a2713aSLionel Sambuc II.setChangedSinceDeserialization();
380f4a2713aSLionel Sambuc }
381f4a2713aSLionel Sambuc
382f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
383f4a2713aSLionel Sambuc // IdDeclInfoMap Implementation
384f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
385f4a2713aSLionel Sambuc
386f4a2713aSLionel Sambuc /// Returns the IdDeclInfo associated to the DeclarationName.
387f4a2713aSLionel Sambuc /// It creates a new IdDeclInfo if one was not created before for this id.
388f4a2713aSLionel Sambuc IdentifierResolver::IdDeclInfo &
operator [](DeclarationName Name)389f4a2713aSLionel Sambuc IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
390f4a2713aSLionel Sambuc void *Ptr = Name.getFETokenInfo<void>();
391f4a2713aSLionel Sambuc
392f4a2713aSLionel Sambuc if (Ptr) return *toIdDeclInfo(Ptr);
393f4a2713aSLionel Sambuc
394f4a2713aSLionel Sambuc if (CurIndex == POOL_SIZE) {
395f4a2713aSLionel Sambuc CurPool = new IdDeclInfoPool(CurPool);
396f4a2713aSLionel Sambuc CurIndex = 0;
397f4a2713aSLionel Sambuc }
398f4a2713aSLionel Sambuc IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
399f4a2713aSLionel Sambuc Name.setFETokenInfo(reinterpret_cast<void*>(
400f4a2713aSLionel Sambuc reinterpret_cast<uintptr_t>(IDI) | 0x1)
401f4a2713aSLionel Sambuc );
402f4a2713aSLionel Sambuc ++CurIndex;
403f4a2713aSLionel Sambuc return *IDI;
404f4a2713aSLionel Sambuc }
405f4a2713aSLionel Sambuc
incrementSlowCase()406f4a2713aSLionel Sambuc void IdentifierResolver::iterator::incrementSlowCase() {
407f4a2713aSLionel Sambuc NamedDecl *D = **this;
408f4a2713aSLionel Sambuc void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
409f4a2713aSLionel Sambuc assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
410f4a2713aSLionel Sambuc IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
411f4a2713aSLionel Sambuc
412f4a2713aSLionel Sambuc BaseIter I = getIterator();
413f4a2713aSLionel Sambuc if (I != Info->decls_begin())
414f4a2713aSLionel Sambuc *this = iterator(I-1);
415f4a2713aSLionel Sambuc else // No more decls.
416f4a2713aSLionel Sambuc *this = iterator();
417f4a2713aSLionel Sambuc }
418