blob: 2c0c284c06ece991642bcca583bb14e3b001be17 [file] [log] [blame]
Gabor Marton54058b52018-12-17 13:53:12 +00001//===- ASTImporterLookupTable.cpp - ASTImporter specific lookup -----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Gabor Marton54058b52018-12-17 13:53:12 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the ASTImporterLookupTable class which implements a
10// lookup procedure for the import mechanism.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/ASTImporterLookupTable.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/RecursiveASTVisitor.h"
17
18namespace clang {
19
20namespace {
21
22struct Builder : RecursiveASTVisitor<Builder> {
23 ASTImporterLookupTable &LT;
24 Builder(ASTImporterLookupTable &LT) : LT(LT) {}
25 bool VisitNamedDecl(NamedDecl *D) {
26 LT.add(D);
27 return true;
28 }
29 bool VisitFriendDecl(FriendDecl *D) {
30 if (D->getFriendType()) {
31 QualType Ty = D->getFriendType()->getType();
32 // FIXME Can this be other than elaborated?
33 QualType NamedTy = cast<ElaboratedType>(Ty)->getNamedType();
34 if (!NamedTy->isDependentType()) {
35 if (const auto *RTy = dyn_cast<RecordType>(NamedTy))
36 LT.add(RTy->getAsCXXRecordDecl());
37 else if (const auto *SpecTy =
38 dyn_cast<TemplateSpecializationType>(NamedTy)) {
39 LT.add(SpecTy->getAsCXXRecordDecl());
40 }
41 }
42 }
43 return true;
44 }
45
46 // Override default settings of base.
47 bool shouldVisitTemplateInstantiations() const { return true; }
48 bool shouldVisitImplicitCode() const { return true; }
49};
50
51} // anonymous namespace
52
53ASTImporterLookupTable::ASTImporterLookupTable(TranslationUnitDecl &TU) {
54 Builder B(*this);
55 B.TraverseDecl(&TU);
56}
57
58void ASTImporterLookupTable::add(DeclContext *DC, NamedDecl *ND) {
59 DeclList &Decls = LookupTable[DC][ND->getDeclName()];
60 // Inserts if and only if there is no element in the container equal to it.
61 Decls.insert(ND);
62}
63
64void ASTImporterLookupTable::remove(DeclContext *DC, NamedDecl *ND) {
65 DeclList &Decls = LookupTable[DC][ND->getDeclName()];
66 bool EraseResult = Decls.remove(ND);
67 (void)EraseResult;
68 assert(EraseResult == true && "Trying to remove not contained Decl");
69}
70
71void ASTImporterLookupTable::add(NamedDecl *ND) {
72 assert(ND);
73 DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
74 add(DC, ND);
75 DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
76 if (DC != ReDC)
77 add(ReDC, ND);
78}
79
80void ASTImporterLookupTable::remove(NamedDecl *ND) {
81 assert(ND);
82 DeclContext *DC = ND->getDeclContext()->getPrimaryContext();
83 remove(DC, ND);
84 DeclContext *ReDC = DC->getRedeclContext()->getPrimaryContext();
85 if (DC != ReDC)
86 remove(ReDC, ND);
87}
88
89ASTImporterLookupTable::LookupResult
90ASTImporterLookupTable::lookup(DeclContext *DC, DeclarationName Name) const {
91 auto DCI = LookupTable.find(DC->getPrimaryContext());
92 if (DCI == LookupTable.end())
93 return {};
94
95 const auto &FoundNameMap = DCI->second;
96 auto NamesI = FoundNameMap.find(Name);
97 if (NamesI == FoundNameMap.end())
98 return {};
99
100 return NamesI->second;
101}
102
103void ASTImporterLookupTable::dump(DeclContext *DC) const {
104 auto DCI = LookupTable.find(DC->getPrimaryContext());
105 if (DCI == LookupTable.end())
106 llvm::errs() << "empty\n";
107 const auto &FoundNameMap = DCI->second;
108 for (const auto &Entry : FoundNameMap) {
109 DeclarationName Name = Entry.first;
110 llvm::errs() << "==== Name: ";
111 Name.dump();
112 const DeclList& List = Entry.second;
113 for (NamedDecl *ND : List) {
114 ND->dump();
115 }
116 }
117}
118
119void ASTImporterLookupTable::dump() const {
120 for (const auto &Entry : LookupTable) {
121 DeclContext *DC = Entry.first;
122 StringRef Primary = DC->getPrimaryContext() ? " primary" : "";
123 llvm::errs() << "== DC:" << cast<Decl>(DC) << Primary << "\n";
124 dump(DC);
125 }
126}
127
128} // namespace clang