reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
//===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ -*---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines the ASTImporterLookupTable class which implements a
//  lookup procedure for the import mechanism.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
#define LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H

#include "clang/AST/DeclBase.h" // lookup_result
#include "clang/AST/DeclarationName.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"

namespace clang {

class ASTContext;
class NamedDecl;
class DeclContext;

// There are certain cases when normal C/C++ lookup (localUncachedLookup)
// does not find AST nodes. E.g.:
// Example 1:
//   template <class T>
//   struct X {
//     friend void foo(); // this is never found in the DC of the TU.
//   };
// Example 2:
//   // The fwd decl to Foo is not found in the lookupPtr of the DC of the
//   // translation unit decl.
//   // Here we could find the node by doing a traverse throught the list of
//   // the Decls in the DC, but that would not scale.
//   struct A { struct Foo *p; };
// This is a severe problem because the importer decides if it has to create a
// new Decl or not based on the lookup results.
// To overcome these cases we need an importer specific lookup table which
// holds every node and we are not interested in any C/C++ specific visibility
// considerations. Simply, we must know if there is an existing Decl in a
// given DC. Once we found it then we can handle any visibility related tasks.
class ASTImporterLookupTable {

  // We store a list of declarations for each name.
  // And we collect these lists for each DeclContext.
  // We could have a flat map with (DeclContext, Name) tuple as key, but a two
  // level map seems easier to handle.
  using DeclList = llvm::SmallSetVector<NamedDecl *, 2>;
  using NameMap = llvm::SmallDenseMap<DeclarationName, DeclList, 4>;
  using DCMap = llvm::DenseMap<DeclContext *, NameMap>;

  void add(DeclContext *DC, NamedDecl *ND);
  void remove(DeclContext *DC, NamedDecl *ND);

  DCMap LookupTable;

public:
  ASTImporterLookupTable(TranslationUnitDecl &TU);
  void add(NamedDecl *ND);
  void remove(NamedDecl *ND);
  using LookupResult = DeclList;
  LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
  void dump(DeclContext *DC) const;
  void dump() const;
};

} // namespace clang

#endif // LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H