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