1*06f32e7eSjoerg //===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ -*---===// 2*06f32e7eSjoerg // 3*06f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 5*06f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06f32e7eSjoerg // 7*06f32e7eSjoerg //===----------------------------------------------------------------------===// 8*06f32e7eSjoerg // 9*06f32e7eSjoerg // This file defines the ASTImporterLookupTable class which implements a 10*06f32e7eSjoerg // lookup procedure for the import mechanism. 11*06f32e7eSjoerg // 12*06f32e7eSjoerg //===----------------------------------------------------------------------===// 13*06f32e7eSjoerg 14*06f32e7eSjoerg #ifndef LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H 15*06f32e7eSjoerg #define LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H 16*06f32e7eSjoerg 17*06f32e7eSjoerg #include "clang/AST/DeclBase.h" // lookup_result 18*06f32e7eSjoerg #include "clang/AST/DeclarationName.h" 19*06f32e7eSjoerg #include "llvm/ADT/DenseMap.h" 20*06f32e7eSjoerg #include "llvm/ADT/SetVector.h" 21*06f32e7eSjoerg 22*06f32e7eSjoerg namespace clang { 23*06f32e7eSjoerg 24*06f32e7eSjoerg class ASTContext; 25*06f32e7eSjoerg class NamedDecl; 26*06f32e7eSjoerg class DeclContext; 27*06f32e7eSjoerg 28*06f32e7eSjoerg // There are certain cases when normal C/C++ lookup (localUncachedLookup) 29*06f32e7eSjoerg // does not find AST nodes. E.g.: 30*06f32e7eSjoerg // Example 1: 31*06f32e7eSjoerg // template <class T> 32*06f32e7eSjoerg // struct X { 33*06f32e7eSjoerg // friend void foo(); // this is never found in the DC of the TU. 34*06f32e7eSjoerg // }; 35*06f32e7eSjoerg // Example 2: 36*06f32e7eSjoerg // // The fwd decl to Foo is not found in the lookupPtr of the DC of the 37*06f32e7eSjoerg // // translation unit decl. 38*06f32e7eSjoerg // // Here we could find the node by doing a traverse throught the list of 39*06f32e7eSjoerg // // the Decls in the DC, but that would not scale. 40*06f32e7eSjoerg // struct A { struct Foo *p; }; 41*06f32e7eSjoerg // This is a severe problem because the importer decides if it has to create a 42*06f32e7eSjoerg // new Decl or not based on the lookup results. 43*06f32e7eSjoerg // To overcome these cases we need an importer specific lookup table which 44*06f32e7eSjoerg // holds every node and we are not interested in any C/C++ specific visibility 45*06f32e7eSjoerg // considerations. Simply, we must know if there is an existing Decl in a 46*06f32e7eSjoerg // given DC. Once we found it then we can handle any visibility related tasks. 47*06f32e7eSjoerg class ASTImporterLookupTable { 48*06f32e7eSjoerg 49*06f32e7eSjoerg // We store a list of declarations for each name. 50*06f32e7eSjoerg // And we collect these lists for each DeclContext. 51*06f32e7eSjoerg // We could have a flat map with (DeclContext, Name) tuple as key, but a two 52*06f32e7eSjoerg // level map seems easier to handle. 53*06f32e7eSjoerg using DeclList = llvm::SmallSetVector<NamedDecl *, 2>; 54*06f32e7eSjoerg using NameMap = llvm::SmallDenseMap<DeclarationName, DeclList, 4>; 55*06f32e7eSjoerg using DCMap = llvm::DenseMap<DeclContext *, NameMap>; 56*06f32e7eSjoerg 57*06f32e7eSjoerg void add(DeclContext *DC, NamedDecl *ND); 58*06f32e7eSjoerg void remove(DeclContext *DC, NamedDecl *ND); 59*06f32e7eSjoerg 60*06f32e7eSjoerg DCMap LookupTable; 61*06f32e7eSjoerg 62*06f32e7eSjoerg public: 63*06f32e7eSjoerg ASTImporterLookupTable(TranslationUnitDecl &TU); 64*06f32e7eSjoerg void add(NamedDecl *ND); 65*06f32e7eSjoerg void remove(NamedDecl *ND); 66*06f32e7eSjoerg using LookupResult = DeclList; 67*06f32e7eSjoerg LookupResult lookup(DeclContext *DC, DeclarationName Name) const; 68*06f32e7eSjoerg void dump(DeclContext *DC) const; 69*06f32e7eSjoerg void dump() const; 70*06f32e7eSjoerg }; 71*06f32e7eSjoerg 72*06f32e7eSjoerg } // namespace clang 73*06f32e7eSjoerg 74*06f32e7eSjoerg #endif // LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H 75