10b57cec5SDimitry Andric //===- IdentifierResolver.cpp - Lexical Scope Name lookup -----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the IdentifierResolver class, which is used for lexical
100b57cec5SDimitry Andric // scoped lookup, based on declaration names.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "clang/Sema/IdentifierResolver.h"
150b57cec5SDimitry Andric #include "clang/AST/Decl.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h"
180b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
190b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
200b57cec5SDimitry Andric #include "clang/Lex/ExternalPreprocessorSource.h"
210b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
220b57cec5SDimitry Andric #include "clang/Sema/Scope.h"
230b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
240b57cec5SDimitry Andric #include <cassert>
250b57cec5SDimitry Andric #include <cstdint>
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric using namespace clang;
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
300b57cec5SDimitry Andric // IdDeclInfoMap class
310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric /// IdDeclInfoMap - Associates IdDeclInfos with declaration names.
340b57cec5SDimitry Andric /// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
350b57cec5SDimitry Andric /// individual IdDeclInfo to heap.
360b57cec5SDimitry Andric class IdentifierResolver::IdDeclInfoMap {
370b57cec5SDimitry Andric static const unsigned int POOL_SIZE = 512;
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric /// We use our own linked-list implementation because it is sadly
400b57cec5SDimitry Andric /// impossible to add something to a pre-C++0x STL container without
410b57cec5SDimitry Andric /// a completely unnecessary copy.
420b57cec5SDimitry Andric struct IdDeclInfoPool {
430b57cec5SDimitry Andric IdDeclInfoPool *Next;
440b57cec5SDimitry Andric IdDeclInfo Pool[POOL_SIZE];
450b57cec5SDimitry Andric
IdDeclInfoPoolIdentifierResolver::IdDeclInfoMap::IdDeclInfoPool460b57cec5SDimitry Andric IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
470b57cec5SDimitry Andric };
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric IdDeclInfoPool *CurPool = nullptr;
500b57cec5SDimitry Andric unsigned int CurIndex = POOL_SIZE;
510b57cec5SDimitry Andric
520b57cec5SDimitry Andric public:
530b57cec5SDimitry Andric IdDeclInfoMap() = default;
540b57cec5SDimitry Andric
~IdDeclInfoMap()550b57cec5SDimitry Andric ~IdDeclInfoMap() {
560b57cec5SDimitry Andric IdDeclInfoPool *Cur = CurPool;
570b57cec5SDimitry Andric while (IdDeclInfoPool *P = Cur) {
580b57cec5SDimitry Andric Cur = Cur->Next;
590b57cec5SDimitry Andric delete P;
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric
63*5f757f3fSDimitry Andric IdDeclInfoMap(const IdDeclInfoMap &) = delete;
64*5f757f3fSDimitry Andric IdDeclInfoMap &operator=(const IdDeclInfoMap &) = delete;
65*5f757f3fSDimitry Andric
660b57cec5SDimitry Andric /// Returns the IdDeclInfo associated to the DeclarationName.
670b57cec5SDimitry Andric /// It creates a new IdDeclInfo if one was not created before for this id.
680b57cec5SDimitry Andric IdDeclInfo &operator[](DeclarationName Name);
690b57cec5SDimitry Andric };
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
720b57cec5SDimitry Andric // IdDeclInfo Implementation
730b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
740b57cec5SDimitry Andric
750b57cec5SDimitry Andric /// RemoveDecl - Remove the decl from the scope chain.
760b57cec5SDimitry Andric /// The decl must already be part of the decl chain.
RemoveDecl(NamedDecl * D)770b57cec5SDimitry Andric void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
780b57cec5SDimitry Andric for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
790b57cec5SDimitry Andric if (D == *(I-1)) {
800b57cec5SDimitry Andric Decls.erase(I-1);
810b57cec5SDimitry Andric return;
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric llvm_unreachable("Didn't find this decl on its identifier's chain!");
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
890b57cec5SDimitry Andric // IdentifierResolver Implementation
900b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
910b57cec5SDimitry Andric
IdentifierResolver(Preprocessor & PP)920b57cec5SDimitry Andric IdentifierResolver::IdentifierResolver(Preprocessor &PP)
930b57cec5SDimitry Andric : LangOpt(PP.getLangOpts()), PP(PP), IdDeclInfos(new IdDeclInfoMap) {}
940b57cec5SDimitry Andric
~IdentifierResolver()950b57cec5SDimitry Andric IdentifierResolver::~IdentifierResolver() {
960b57cec5SDimitry Andric delete IdDeclInfos;
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
1000b57cec5SDimitry Andric /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
1010b57cec5SDimitry Andric /// true if 'D' belongs to the given declaration context.
isDeclInScope(Decl * D,DeclContext * Ctx,Scope * S,bool AllowInlineNamespace) const1020b57cec5SDimitry Andric bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,
1030b57cec5SDimitry Andric bool AllowInlineNamespace) const {
1040b57cec5SDimitry Andric Ctx = Ctx->getRedeclContext();
105bdd1243dSDimitry Andric // The names for HLSL cbuffer/tbuffers only used by the CPU-side
106bdd1243dSDimitry Andric // reflection API which supports querying bindings. It will not have name
107bdd1243dSDimitry Andric // conflict with other Decls.
108bdd1243dSDimitry Andric if (LangOpt.HLSL && isa<HLSLBufferDecl>(D))
109bdd1243dSDimitry Andric return false;
1100b57cec5SDimitry Andric if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) {
1110b57cec5SDimitry Andric // Ignore the scopes associated within transparent declaration contexts.
112*5f757f3fSDimitry Andric while (S->getEntity() &&
113*5f757f3fSDimitry Andric (S->getEntity()->isTransparentContext() ||
114*5f757f3fSDimitry Andric (!LangOpt.CPlusPlus && isa<RecordDecl>(S->getEntity()))))
1150b57cec5SDimitry Andric S = S->getParent();
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric if (S->isDeclScope(D))
1180b57cec5SDimitry Andric return true;
1190b57cec5SDimitry Andric if (LangOpt.CPlusPlus) {
1200b57cec5SDimitry Andric // C++ 3.3.2p3:
1210b57cec5SDimitry Andric // The name declared in a catch exception-declaration is local to the
1220b57cec5SDimitry Andric // handler and shall not be redeclared in the outermost block of the
1230b57cec5SDimitry Andric // handler.
1240b57cec5SDimitry Andric // C++ 3.3.2p4:
1250b57cec5SDimitry Andric // Names declared in the for-init-statement, and in the condition of if,
1260b57cec5SDimitry Andric // while, for, and switch statements are local to the if, while, for, or
1270b57cec5SDimitry Andric // switch statement (including the controlled statement), and shall not be
1280b57cec5SDimitry Andric // redeclared in a subsequent condition of that statement nor in the
1290b57cec5SDimitry Andric // outermost block (or, for the if statement, any of the outermost blocks)
1300b57cec5SDimitry Andric // of the controlled statement.
1310b57cec5SDimitry Andric //
1320b57cec5SDimitry Andric assert(S->getParent() && "No TUScope?");
13381ad6265SDimitry Andric // If the current decl is in a lambda, we shouldn't consider this is a
13481ad6265SDimitry Andric // redefinition as lambda has its own scope.
13581ad6265SDimitry Andric if (S->getParent()->isControlScope() && !S->isFunctionScope()) {
1360b57cec5SDimitry Andric S = S->getParent();
1370b57cec5SDimitry Andric if (S->isDeclScope(D))
1380b57cec5SDimitry Andric return true;
1390b57cec5SDimitry Andric }
14081ad6265SDimitry Andric if (S->isFnTryCatchScope())
1410b57cec5SDimitry Andric return S->getParent()->isDeclScope(D);
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric return false;
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric // FIXME: If D is a local extern declaration, this check doesn't make sense;
1470b57cec5SDimitry Andric // we should be checking its lexical context instead in that case, because
1480b57cec5SDimitry Andric // that is its scope.
1490b57cec5SDimitry Andric DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
1500b57cec5SDimitry Andric return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)
1510b57cec5SDimitry Andric : Ctx->Equals(DCtx);
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric /// AddDecl - Link the decl to its shadowed decl chain.
AddDecl(NamedDecl * D)1550b57cec5SDimitry Andric void IdentifierResolver::AddDecl(NamedDecl *D) {
1560b57cec5SDimitry Andric DeclarationName Name = D->getDeclName();
1570b57cec5SDimitry Andric if (IdentifierInfo *II = Name.getAsIdentifierInfo())
1580b57cec5SDimitry Andric updatingIdentifier(*II);
1590b57cec5SDimitry Andric
1600b57cec5SDimitry Andric void *Ptr = Name.getFETokenInfo();
1610b57cec5SDimitry Andric
1620b57cec5SDimitry Andric if (!Ptr) {
1630b57cec5SDimitry Andric Name.setFETokenInfo(D);
1640b57cec5SDimitry Andric return;
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric IdDeclInfo *IDI;
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andric if (isDeclPtr(Ptr)) {
1700b57cec5SDimitry Andric Name.setFETokenInfo(nullptr);
1710b57cec5SDimitry Andric IDI = &(*IdDeclInfos)[Name];
1720b57cec5SDimitry Andric NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
1730b57cec5SDimitry Andric IDI->AddDecl(PrevD);
1740b57cec5SDimitry Andric } else
1750b57cec5SDimitry Andric IDI = toIdDeclInfo(Ptr);
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric IDI->AddDecl(D);
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric
InsertDeclAfter(iterator Pos,NamedDecl * D)1800b57cec5SDimitry Andric void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) {
1810b57cec5SDimitry Andric DeclarationName Name = D->getDeclName();
1820b57cec5SDimitry Andric if (IdentifierInfo *II = Name.getAsIdentifierInfo())
1830b57cec5SDimitry Andric updatingIdentifier(*II);
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andric void *Ptr = Name.getFETokenInfo();
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric if (!Ptr) {
1880b57cec5SDimitry Andric AddDecl(D);
1890b57cec5SDimitry Andric return;
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric
1920b57cec5SDimitry Andric if (isDeclPtr(Ptr)) {
1930b57cec5SDimitry Andric // We only have a single declaration: insert before or after it,
1940b57cec5SDimitry Andric // as appropriate.
1950b57cec5SDimitry Andric if (Pos == iterator()) {
1960b57cec5SDimitry Andric // Add the new declaration before the existing declaration.
1970b57cec5SDimitry Andric NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
1980b57cec5SDimitry Andric RemoveDecl(PrevD);
1990b57cec5SDimitry Andric AddDecl(D);
2000b57cec5SDimitry Andric AddDecl(PrevD);
2010b57cec5SDimitry Andric } else {
2020b57cec5SDimitry Andric // Add new declaration after the existing declaration.
2030b57cec5SDimitry Andric AddDecl(D);
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric return;
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andric // General case: insert the declaration at the appropriate point in the
2100b57cec5SDimitry Andric // list, which already has at least two elements.
2110b57cec5SDimitry Andric IdDeclInfo *IDI = toIdDeclInfo(Ptr);
2120b57cec5SDimitry Andric if (Pos.isIterator()) {
2130b57cec5SDimitry Andric IDI->InsertDecl(Pos.getIterator() + 1, D);
2140b57cec5SDimitry Andric } else
2150b57cec5SDimitry Andric IDI->InsertDecl(IDI->decls_begin(), D);
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric /// RemoveDecl - Unlink the decl from its shadowed decl chain.
2190b57cec5SDimitry Andric /// The decl must already be part of the decl chain.
RemoveDecl(NamedDecl * D)2200b57cec5SDimitry Andric void IdentifierResolver::RemoveDecl(NamedDecl *D) {
2210b57cec5SDimitry Andric assert(D && "null param passed");
2220b57cec5SDimitry Andric DeclarationName Name = D->getDeclName();
2230b57cec5SDimitry Andric if (IdentifierInfo *II = Name.getAsIdentifierInfo())
2240b57cec5SDimitry Andric updatingIdentifier(*II);
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric void *Ptr = Name.getFETokenInfo();
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andric assert(Ptr && "Didn't find this decl on its identifier's chain!");
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric if (isDeclPtr(Ptr)) {
2310b57cec5SDimitry Andric assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
2320b57cec5SDimitry Andric Name.setFETokenInfo(nullptr);
2330b57cec5SDimitry Andric return;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric return toIdDeclInfo(Ptr)->RemoveDecl(D);
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric
23906c3fb27SDimitry Andric llvm::iterator_range<IdentifierResolver::iterator>
decls(DeclarationName Name)24006c3fb27SDimitry Andric IdentifierResolver::decls(DeclarationName Name) {
24106c3fb27SDimitry Andric return {begin(Name), end()};
24206c3fb27SDimitry Andric }
24306c3fb27SDimitry Andric
begin(DeclarationName Name)24406c3fb27SDimitry Andric IdentifierResolver::iterator IdentifierResolver::begin(DeclarationName Name) {
2450b57cec5SDimitry Andric if (IdentifierInfo *II = Name.getAsIdentifierInfo())
2460b57cec5SDimitry Andric readingIdentifier(*II);
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric void *Ptr = Name.getFETokenInfo();
2490b57cec5SDimitry Andric if (!Ptr) return end();
2500b57cec5SDimitry Andric
2510b57cec5SDimitry Andric if (isDeclPtr(Ptr))
2520b57cec5SDimitry Andric return iterator(static_cast<NamedDecl*>(Ptr));
2530b57cec5SDimitry Andric
2540b57cec5SDimitry Andric IdDeclInfo *IDI = toIdDeclInfo(Ptr);
2550b57cec5SDimitry Andric
2560b57cec5SDimitry Andric IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
2570b57cec5SDimitry Andric if (I != IDI->decls_begin())
2580b57cec5SDimitry Andric return iterator(I-1);
2590b57cec5SDimitry Andric // No decls found.
2600b57cec5SDimitry Andric return end();
2610b57cec5SDimitry Andric }
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andric namespace {
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric enum DeclMatchKind {
2660b57cec5SDimitry Andric DMK_Different,
2670b57cec5SDimitry Andric DMK_Replace,
2680b57cec5SDimitry Andric DMK_Ignore
2690b57cec5SDimitry Andric };
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric } // namespace
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric /// Compare two declarations to see whether they are different or,
2740b57cec5SDimitry Andric /// if they are the same, whether the new declaration should replace the
2750b57cec5SDimitry Andric /// existing declaration.
compareDeclarations(NamedDecl * Existing,NamedDecl * New)2760b57cec5SDimitry Andric static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New) {
2770b57cec5SDimitry Andric // If the declarations are identical, ignore the new one.
2780b57cec5SDimitry Andric if (Existing == New)
2790b57cec5SDimitry Andric return DMK_Ignore;
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric // If the declarations have different kinds, they're obviously different.
2820b57cec5SDimitry Andric if (Existing->getKind() != New->getKind())
2830b57cec5SDimitry Andric return DMK_Different;
2840b57cec5SDimitry Andric
2850b57cec5SDimitry Andric // If the declarations are redeclarations of each other, keep the newest one.
2860b57cec5SDimitry Andric if (Existing->getCanonicalDecl() == New->getCanonicalDecl()) {
2870b57cec5SDimitry Andric // If we're adding an imported declaration, don't replace another imported
2880b57cec5SDimitry Andric // declaration.
2890b57cec5SDimitry Andric if (Existing->isFromASTFile() && New->isFromASTFile())
2900b57cec5SDimitry Andric return DMK_Different;
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andric // If either of these is the most recent declaration, use it.
2930b57cec5SDimitry Andric Decl *MostRecent = Existing->getMostRecentDecl();
2940b57cec5SDimitry Andric if (Existing == MostRecent)
2950b57cec5SDimitry Andric return DMK_Ignore;
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric if (New == MostRecent)
2980b57cec5SDimitry Andric return DMK_Replace;
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andric // If the existing declaration is somewhere in the previous declaration
3010b57cec5SDimitry Andric // chain of the new declaration, then prefer the new declaration.
302bdd1243dSDimitry Andric for (auto *RD : New->redecls()) {
3030b57cec5SDimitry Andric if (RD == Existing)
3040b57cec5SDimitry Andric return DMK_Replace;
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andric if (RD->isCanonicalDecl())
3070b57cec5SDimitry Andric break;
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andric return DMK_Ignore;
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andric return DMK_Different;
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric
tryAddTopLevelDecl(NamedDecl * D,DeclarationName Name)3160b57cec5SDimitry Andric bool IdentifierResolver::tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name){
3170b57cec5SDimitry Andric if (IdentifierInfo *II = Name.getAsIdentifierInfo())
3180b57cec5SDimitry Andric readingIdentifier(*II);
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric void *Ptr = Name.getFETokenInfo();
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andric if (!Ptr) {
3230b57cec5SDimitry Andric Name.setFETokenInfo(D);
3240b57cec5SDimitry Andric return true;
3250b57cec5SDimitry Andric }
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric IdDeclInfo *IDI;
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andric if (isDeclPtr(Ptr)) {
3300b57cec5SDimitry Andric NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric switch (compareDeclarations(PrevD, D)) {
3330b57cec5SDimitry Andric case DMK_Different:
3340b57cec5SDimitry Andric break;
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andric case DMK_Ignore:
3370b57cec5SDimitry Andric return false;
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric case DMK_Replace:
3400b57cec5SDimitry Andric Name.setFETokenInfo(D);
3410b57cec5SDimitry Andric return true;
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric Name.setFETokenInfo(nullptr);
3450b57cec5SDimitry Andric IDI = &(*IdDeclInfos)[Name];
3460b57cec5SDimitry Andric
3470b57cec5SDimitry Andric // If the existing declaration is not visible in translation unit scope,
3480b57cec5SDimitry Andric // then add the new top-level declaration first.
3490b57cec5SDimitry Andric if (!PrevD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
3500b57cec5SDimitry Andric IDI->AddDecl(D);
3510b57cec5SDimitry Andric IDI->AddDecl(PrevD);
3520b57cec5SDimitry Andric } else {
3530b57cec5SDimitry Andric IDI->AddDecl(PrevD);
3540b57cec5SDimitry Andric IDI->AddDecl(D);
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric return true;
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric IDI = toIdDeclInfo(Ptr);
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric // See whether this declaration is identical to any existing declarations.
3620b57cec5SDimitry Andric // If not, find the right place to insert it.
3630b57cec5SDimitry Andric for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(),
3640b57cec5SDimitry Andric IEnd = IDI->decls_end();
3650b57cec5SDimitry Andric I != IEnd; ++I) {
3660b57cec5SDimitry Andric
3670b57cec5SDimitry Andric switch (compareDeclarations(*I, D)) {
3680b57cec5SDimitry Andric case DMK_Different:
3690b57cec5SDimitry Andric break;
3700b57cec5SDimitry Andric
3710b57cec5SDimitry Andric case DMK_Ignore:
3720b57cec5SDimitry Andric return false;
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric case DMK_Replace:
3750b57cec5SDimitry Andric *I = D;
3760b57cec5SDimitry Andric return true;
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andric if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
3800b57cec5SDimitry Andric // We've found a declaration that is not visible from the translation
3810b57cec5SDimitry Andric // unit (it's in an inner scope). Insert our declaration here.
3820b57cec5SDimitry Andric IDI->InsertDecl(I, D);
3830b57cec5SDimitry Andric return true;
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric
3870b57cec5SDimitry Andric // Add the declaration to the end.
3880b57cec5SDimitry Andric IDI->AddDecl(D);
3890b57cec5SDimitry Andric return true;
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric
readingIdentifier(IdentifierInfo & II)3920b57cec5SDimitry Andric void IdentifierResolver::readingIdentifier(IdentifierInfo &II) {
3930b57cec5SDimitry Andric if (II.isOutOfDate())
3940b57cec5SDimitry Andric PP.getExternalSource()->updateOutOfDateIdentifier(II);
3950b57cec5SDimitry Andric }
3960b57cec5SDimitry Andric
updatingIdentifier(IdentifierInfo & II)3970b57cec5SDimitry Andric void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) {
3980b57cec5SDimitry Andric if (II.isOutOfDate())
3990b57cec5SDimitry Andric PP.getExternalSource()->updateOutOfDateIdentifier(II);
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andric if (II.isFromAST())
4020b57cec5SDimitry Andric II.setFETokenInfoChangedSinceDeserialization();
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4060b57cec5SDimitry Andric // IdDeclInfoMap Implementation
4070b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andric /// Returns the IdDeclInfo associated to the DeclarationName.
4100b57cec5SDimitry Andric /// It creates a new IdDeclInfo if one was not created before for this id.
4110b57cec5SDimitry Andric IdentifierResolver::IdDeclInfo &
operator [](DeclarationName Name)4120b57cec5SDimitry Andric IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
4130b57cec5SDimitry Andric void *Ptr = Name.getFETokenInfo();
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andric if (Ptr) return *toIdDeclInfo(Ptr);
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric if (CurIndex == POOL_SIZE) {
4180b57cec5SDimitry Andric CurPool = new IdDeclInfoPool(CurPool);
4190b57cec5SDimitry Andric CurIndex = 0;
4200b57cec5SDimitry Andric }
4210b57cec5SDimitry Andric IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
4220b57cec5SDimitry Andric Name.setFETokenInfo(reinterpret_cast<void*>(
4230b57cec5SDimitry Andric reinterpret_cast<uintptr_t>(IDI) | 0x1)
4240b57cec5SDimitry Andric );
4250b57cec5SDimitry Andric ++CurIndex;
4260b57cec5SDimitry Andric return *IDI;
4270b57cec5SDimitry Andric }
4280b57cec5SDimitry Andric
incrementSlowCase()4290b57cec5SDimitry Andric void IdentifierResolver::iterator::incrementSlowCase() {
4300b57cec5SDimitry Andric NamedDecl *D = **this;
4310b57cec5SDimitry Andric void *InfoPtr = D->getDeclName().getFETokenInfo();
4320b57cec5SDimitry Andric assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
4330b57cec5SDimitry Andric IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andric BaseIter I = getIterator();
4360b57cec5SDimitry Andric if (I != Info->decls_begin())
4370b57cec5SDimitry Andric *this = iterator(I-1);
4380b57cec5SDimitry Andric else // No more decls.
4390b57cec5SDimitry Andric *this = iterator();
4400b57cec5SDimitry Andric }
441