1 //===- ASTImporterLookupTable.cpp - ASTImporter specific lookup -----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ASTImporterLookupTable class which implements a
11 // lookup procedure for the import mechanism.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/AST/ASTImporterLookupTable.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/RecursiveASTVisitor.h"
18
19 namespace clang {
20
21 namespace {
22
23 struct Builder : RecursiveASTVisitor<Builder> {
24 ASTImporterLookupTable <
Builderclang::__anon07aa5ddc0111::Builder25 Builder(ASTImporterLookupTable <) : LT(LT) {}
VisitNamedDeclclang::__anon07aa5ddc0111::Builder26 bool VisitNamedDecl(NamedDecl *D) {
27 LT.add(D);
28 return true;
29 }
VisitFriendDeclclang::__anon07aa5ddc0111::Builder30 bool VisitFriendDecl(FriendDecl *D) {
31 if (D->getFriendType()) {
32 QualType Ty = D->getFriendType()->getType();
33 // FIXME Can this be other than elaborated?
34 QualType NamedTy = cast<ElaboratedType>(Ty)->getNamedType();
35 if (!NamedTy->isDependentType()) {
36 if (const auto *RTy = dyn_cast<RecordType>(NamedTy))
37 LT.add(RTy->getAsCXXRecordDecl());
38 else if (const auto *SpecTy =
39 dyn_cast<TemplateSpecializationType>(NamedTy)) {
40 LT.add(SpecTy->getAsCXXRecordDecl());
41 }
42 }
43 }
44 return true;
45 }
46
47 // Override default settings of base.
shouldVisitTemplateInstantiationsclang::__anon07aa5ddc0111::Builder48 bool shouldVisitTemplateInstantiations() const { return true; }
shouldVisitImplicitCodeclang::__anon07aa5ddc0111::Builder49 bool shouldVisitImplicitCode() const { return true; }
50 };
51
52 } // anonymous namespace
53
ASTImporterLookupTable(TranslationUnitDecl & TU)54 ASTImporterLookupTable::ASTImporterLookupTable(TranslationUnitDecl &TU) {
55 Builder B(*this);
56 B.TraverseDecl(&TU);
57 }
58
add(DeclContext * DC,NamedDecl * ND)59 void ASTImporterLookupTable::add(DeclContext *DC, NamedDecl *ND) {
60 DeclList &Decls = LookupTable[DC][ND->getDeclName()];
61 // Inserts if and only if there is no element in the container equal to it.
62 Decls.insert(ND);
63 }
64
remove(DeclContext * DC,NamedDecl * ND)65 void ASTImporterLookupTable::remove(DeclContext *DC, NamedDecl *ND) {
66 DeclList &Decls = LookupTable[DC][ND->getDeclName()];
67 bool EraseResult = Decls.remove(ND);
68 (void)EraseResult;
69 assert(EraseResult == true && "Trying to remove not contained Decl");
70 }
71
add(NamedDecl * ND)72 void ASTImporterLookupTable::add(NamedDecl *ND) {
73 assert(ND);
74 DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
75 add(DC, ND);
76 DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
77 if (DC != ReDC)
78 add(ReDC, ND);
79 }
80
remove(NamedDecl * ND)81 void ASTImporterLookupTable::remove(NamedDecl *ND) {
82 assert(ND);
83 DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
84 remove(DC, ND);
85 DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
86 if (DC != ReDC)
87 remove(ReDC, ND);
88 }
89
90 ASTImporterLookupTable::LookupResult
lookup(DeclContext * DC,DeclarationName Name) const91 ASTImporterLookupTable::lookup(DeclContext *DC, DeclarationName Name) const {
92 auto DCI = LookupTable.find(DC->getPrimaryContext());
93 if (DCI == LookupTable.end())
94 return {};
95
96 const auto &FoundNameMap = DCI->second;
97 auto NamesI = FoundNameMap.find(Name);
98 if (NamesI == FoundNameMap.end())
99 return {};
100
101 return NamesI->second;
102 }
103
dump(DeclContext * DC) const104 void ASTImporterLookupTable::dump(DeclContext *DC) const {
105 auto DCI = LookupTable.find(DC->getPrimaryContext());
106 if (DCI == LookupTable.end())
107 llvm::errs() << "empty\n";
108 const auto &FoundNameMap = DCI->second;
109 for (const auto &Entry : FoundNameMap) {
110 DeclarationName Name = Entry.first;
111 llvm::errs() << "==== Name: ";
112 Name.dump();
113 const DeclList& List = Entry.second;
114 for (NamedDecl *ND : List) {
115 ND->dump();
116 }
117 }
118 }
119
dump() const120 void ASTImporterLookupTable::dump() const {
121 for (const auto &Entry : LookupTable) {
122 DeclContext *DC = Entry.first;
123 StringRef Primary = DC->getPrimaryContext() ? " primary" : "";
124 llvm::errs() << "== DC:" << cast<Decl>(DC) << Primary << "\n";
125 dump(DC);
126 }
127 }
128
129 } // namespace clang
130