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