1 //===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ -*---===// 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 14 #ifndef LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H 15 #define LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H 16 17 #include "clang/AST/DeclBase.h" // lookup_result 18 #include "clang/AST/DeclarationName.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/SetVector.h" 21 22 namespace clang { 23 24 class ASTContext; 25 class NamedDecl; 26 class DeclContext; 27 28 // There are certain cases when normal C/C++ lookup (localUncachedLookup) 29 // does not find AST nodes. E.g.: 30 // Example 1: 31 // template <class T> 32 // struct X { 33 // friend void foo(); // this is never found in the DC of the TU. 34 // }; 35 // Example 2: 36 // // The fwd decl to Foo is not found in the lookupPtr of the DC of the 37 // // translation unit decl. 38 // // Here we could find the node by doing a traverse throught the list of 39 // // the Decls in the DC, but that would not scale. 40 // struct A { struct Foo *p; }; 41 // This is a severe problem because the importer decides if it has to create a 42 // new Decl or not based on the lookup results. 43 // To overcome these cases we need an importer specific lookup table which 44 // holds every node and we are not interested in any C/C++ specific visibility 45 // considerations. Simply, we must know if there is an existing Decl in a 46 // given DC. Once we found it then we can handle any visibility related tasks. 47 class ASTImporterLookupTable { 48 49 // We store a list of declarations for each name. 50 // And we collect these lists for each DeclContext. 51 // We could have a flat map with (DeclContext, Name) tuple as key, but a two 52 // level map seems easier to handle. 53 using DeclList = llvm::SmallSetVector<NamedDecl *, 2>; 54 using NameMap = llvm::SmallDenseMap<DeclarationName, DeclList, 4>; 55 using DCMap = llvm::DenseMap<DeclContext *, NameMap>; 56 57 void add(DeclContext *DC, NamedDecl *ND); 58 void remove(DeclContext *DC, NamedDecl *ND); 59 60 DCMap LookupTable; 61 62 public: 63 ASTImporterLookupTable(TranslationUnitDecl &TU); 64 void add(NamedDecl *ND); 65 void remove(NamedDecl *ND); 66 // Sometimes a declaration is created first with a temporarily value of decl 67 // context (often the translation unit) and later moved to the final context. 68 // This happens for declarations that are created before the final declaration 69 // context. In such cases the lookup table needs to be updated. 70 // (The declaration is in these cases not added to the temporary decl context, 71 // only its parent is set.) 72 // FIXME: It would be better to not add the declaration to the temporary 73 // context at all in the lookup table, but this requires big change in 74 // ASTImporter. 75 // The function should be called when the old context is definitely different 76 // from the new. 77 void update(NamedDecl *ND, DeclContext *OldDC); 78 using LookupResult = DeclList; 79 LookupResult lookup(DeclContext *DC, DeclarationName Name) const; 80 // Check if the `ND` is within the lookup table (with its current name) in 81 // context `DC`. This is intended for debug purposes when the DeclContext of a 82 // NamedDecl is changed. 83 bool contains(DeclContext *DC, NamedDecl *ND) const; 84 void dump(DeclContext *DC) const; 85 void dump() const; 86 }; 87 88 } // namespace clang 89 90 #endif // LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H 91