blob: fbcd4f5cb341756099f944f00b4721c31ec71758 [file] [log] [blame]
Gabor Marton54058b52018-12-17 13:53:12 +00001//===- 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
19namespace clang {
20
21namespace {
22
23struct Builder : RecursiveASTVisitor<Builder> {
24 ASTImporterLookupTable &LT;
25 Builder(ASTImporterLookupTable &LT) : LT(LT) {}
26 bool VisitNamedDecl(NamedDecl *D) {
27 LT.add(D);
28 return true;
29 }
30 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.
48 bool shouldVisitTemplateInstantiations() const { return true; }
49 bool shouldVisitImplicitCode() const { return true; }
50};
51
52} // anonymous namespace
53
54ASTImporterLookupTable::ASTImporterLookupTable(TranslationUnitDecl &TU) {
55 Builder B(*this);
56 B.TraverseDecl(&TU);
57}
58
59void 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
65void 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
72void 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
81void 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
90ASTImporterLookupTable::LookupResult
91ASTImporterLookupTable::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
104void 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
120void 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