clang  10.0.0svn
ASTImporterLookupTable.cpp
Go to the documentation of this file.
1 //===- ASTImporterLookupTable.cpp - ASTImporter specific lookup -----------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the ASTImporterLookupTable class which implements a
10 // lookup procedure for the import mechanism.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/Decl.h"
17 
18 namespace clang {
19 
20 namespace {
21 
22 struct 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  // In most cases the FriendDecl contains the declaration of the befriended
30  // class as a child node, so it is discovered during the recursive
31  // visitation. However, there are cases when the befriended class is not a
32  // child, thus it must be fetched explicitly from the FriendDecl, and only
33  // then can we add it to the lookup table.
34  bool VisitFriendDecl(FriendDecl *D) {
35  if (D->getFriendType()) {
36  QualType Ty = D->getFriendType()->getType();
37  if (isa<ElaboratedType>(Ty))
38  Ty = cast<ElaboratedType>(Ty)->getNamedType();
39  // A FriendDecl with a dependent type (e.g. ClassTemplateSpecialization)
40  // always has that decl as child node.
41  // However, there are non-dependent cases which does not have the
42  // type as a child node. We have to dig up that type now.
43  if (!Ty->isDependentType()) {
44  if (const auto *RTy = dyn_cast<RecordType>(Ty))
45  LT.add(RTy->getAsCXXRecordDecl());
46  else if (const auto *SpecTy = dyn_cast<TemplateSpecializationType>(Ty))
47  LT.add(SpecTy->getAsCXXRecordDecl());
48  else if (isa<TypedefType>(Ty)) {
49  // We do not put friend typedefs to the lookup table because
50  // ASTImporter does not organize typedefs into redecl chains.
51  } else {
52  llvm_unreachable("Unhandled type of friend class");
53  }
54  }
55  }
56  return true;
57  }
58 
59  // Override default settings of base.
60  bool shouldVisitTemplateInstantiations() const { return true; }
61  bool shouldVisitImplicitCode() const { return true; }
62 };
63 
64 } // anonymous namespace
65 
67  Builder B(*this);
68  B.TraverseDecl(&TU);
69 }
70 
71 void ASTImporterLookupTable::add(DeclContext *DC, NamedDecl *ND) {
72  DeclList &Decls = LookupTable[DC][ND->getDeclName()];
73  // Inserts if and only if there is no element in the container equal to it.
74  Decls.insert(ND);
75 }
76 
77 void ASTImporterLookupTable::remove(DeclContext *DC, NamedDecl *ND) {
78  DeclList &Decls = LookupTable[DC][ND->getDeclName()];
79  bool EraseResult = Decls.remove(ND);
80  (void)EraseResult;
81  assert(EraseResult == true && "Trying to remove not contained Decl");
82 }
83 
84 void ASTImporterLookupTable::add(NamedDecl *ND) {
85  assert(ND);
87  add(DC, ND);
89  if (DC != ReDC)
90  add(ReDC, ND);
91 }
92 
93 void ASTImporterLookupTable::remove(NamedDecl *ND) {
94  assert(ND);
96  remove(DC, ND);
98  if (DC != ReDC)
99  remove(ReDC, ND);
100 }
101 
104  auto DCI = LookupTable.find(DC->getPrimaryContext());
105  if (DCI == LookupTable.end())
106  return {};
107 
108  const auto &FoundNameMap = DCI->second;
109  auto NamesI = FoundNameMap.find(Name);
110  if (NamesI == FoundNameMap.end())
111  return {};
112 
113  return NamesI->second;
114 }
115 
117  auto DCI = LookupTable.find(DC->getPrimaryContext());
118  if (DCI == LookupTable.end())
119  llvm::errs() << "empty\n";
120  const auto &FoundNameMap = DCI->second;
121  for (const auto &Entry : FoundNameMap) {
122  DeclarationName Name = Entry.first;
123  llvm::errs() << "==== Name: ";
124  Name.dump();
125  const DeclList& List = Entry.second;
126  for (NamedDecl *ND : List) {
127  ND->dump();
128  }
129  }
130 }
131 
133  for (const auto &Entry : LookupTable) {
134  DeclContext *DC = Entry.first;
135  StringRef Primary = DC->getPrimaryContext() ? " primary" : "";
136  llvm::errs() << "== DC:" << cast<Decl>(DC) << Primary << "\n";
137  dump(DC);
138  }
139 }
140 
141 } // namespace clang
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:297
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
LookupResult lookup(DeclContext *DC, DeclarationName Name) const
DeclContext * getDeclContext()
Definition: DeclBase.h:438
ASTImporterLookupTable(TranslationUnitDecl &TU)
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1271
The name of a declaration.
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1737
ASTImporterLookupTable & LT
void dump() const
Definition: ASTDumper.cpp:179
The top declaration context.
Definition: Decl.h:107
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1162
This represents a decl that may have a name.
Definition: Decl.h:248