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