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 < 25 Builder(ASTImporterLookupTable <) : 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 54 ASTImporterLookupTable::ASTImporterLookupTable(TranslationUnitDecl &TU) { 55 Builder B(*this); 56 B.TraverseDecl(&TU); 57 } 58 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 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 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 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 91 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 104 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 120 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