xref: /minix3/external/bsd/llvm/dist/clang/lib/Sema/IdentifierResolver.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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