ClangASTImporter.h revision 314564
150276Speter//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===//
2184989Srafan//
350276Speter//                     The LLVM Compiler Infrastructure
450276Speter//
550276Speter// This file is distributed under the University of Illinois Open Source
650276Speter// License. See LICENSE.TXT for details.
750276Speter//
850276Speter//===----------------------------------------------------------------------===//
950276Speter
1050276Speter#ifndef liblldb_ClangASTImporter_h_
1150276Speter#define liblldb_ClangASTImporter_h_
1250276Speter
1350276Speter// C Includes
1450276Speter// C++ Includes
1550276Speter#include <map>
1650276Speter#include <memory>
1750276Speter#include <set>
1850276Speter#include <vector>
1950276Speter
2050276Speter// Other libraries and framework includes
2150276Speter#include "clang/AST/ASTImporter.h"
2250276Speter#include "clang/AST/CharUnits.h"
2350276Speter#include "clang/AST/Decl.h"
2450276Speter#include "clang/AST/DeclCXX.h"
2550276Speter#include "clang/Basic/FileManager.h"
2650276Speter#include "clang/Basic/FileSystemOptions.h"
2750276Speter
2850276Speter// Project includes
2950276Speter#include "lldb/Symbol/CompilerDeclContext.h"
3050276Speter#include "lldb/lldb-types.h"
3150276Speter
32166128Srafan#include "llvm/ADT/DenseMap.h"
3397052Speter
3497052Speternamespace lldb_private {
3597052Speter
36166128Srafanclass ClangASTMetrics {
3750276Speterpublic:
3850276Speter  static void DumpCounters(Log *log);
3956643Speter  static void ClearLocalCounters() { local_counters = {0, 0, 0, 0, 0, 0}; }
4056643Speter
4198507Speter  static void RegisterVisibleQuery() {
4250276Speter    ++global_counters.m_visible_query_count;
4350276Speter    ++local_counters.m_visible_query_count;
4450276Speter  }
4550276Speter
4697052Speter  static void RegisterLexicalQuery() {
4750276Speter    ++global_counters.m_lexical_query_count;
4850276Speter    ++local_counters.m_lexical_query_count;
4950276Speter  }
50184989Srafan
5150276Speter  static void RegisterLLDBImport() {
5297052Speter    ++global_counters.m_lldb_import_count;
5397052Speter    ++local_counters.m_lldb_import_count;
5450276Speter  }
5550620Speter
5650620Speter  static void RegisterClangImport() {
5750620Speter    ++global_counters.m_clang_import_count;
5850620Speter    ++local_counters.m_clang_import_count;
59174998Srafan  }
60174998Srafan
61174998Srafan  static void RegisterDeclCompletion() {
6297052Speter    ++global_counters.m_decls_completed_count;
63174998Srafan    ++local_counters.m_decls_completed_count;
64174998Srafan  }
65174998Srafan
66174998Srafan  static void RegisterRecordLayout() {
67174998Srafan    ++global_counters.m_record_layout_count;
6897052Speter    ++local_counters.m_record_layout_count;
6950276Speter  }
7050276Speter
7150276Speterprivate:
7250276Speter  struct Counters {
7350276Speter    uint64_t m_visible_query_count;
7450276Speter    uint64_t m_lexical_query_count;
7550276Speter    uint64_t m_lldb_import_count;
7650276Speter    uint64_t m_clang_import_count;
7750276Speter    uint64_t m_decls_completed_count;
7850276Speter    uint64_t m_record_layout_count;
7950276Speter  };
8050276Speter
8150276Speter  static Counters global_counters;
8250276Speter  static Counters local_counters;
8350276Speter
8476730Speter  static void DumpCounters(Log *log, Counters &counters);
85166128Srafan};
8650276Speter
8762453Speterclass ClangASTImporter {
88166128Srafanpublic:
89166128Srafan  struct LayoutInfo {
9050276Speter    LayoutInfo()
91166128Srafan        : bit_size(0), alignment(0), field_offsets(), base_offsets(),
9262453Speter          vbase_offsets() {}
9350276Speter    uint64_t bit_size;
94166128Srafan    uint64_t alignment;
9550276Speter    llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
96166128Srafan    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
97166128Srafan    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
98166128Srafan        vbase_offsets;
99166128Srafan  };
100166128Srafan
101174998Srafan  ClangASTImporter() : m_file_manager(clang::FileSystemOptions()) {}
102174998Srafan
103174998Srafan  clang::QualType CopyType(clang::ASTContext *dst_ctx,
104174998Srafan                           clang::ASTContext *src_ctx, clang::QualType type);
105174998Srafan
106174998Srafan  lldb::opaque_compiler_type_t CopyType(clang::ASTContext *dst_ctx,
107166128Srafan                                        clang::ASTContext *src_ctx,
108174998Srafan                                        lldb::opaque_compiler_type_t type);
109174998Srafan
110166128Srafan  CompilerType CopyType(ClangASTContext &dst, const CompilerType &src_type);
111174998Srafan
112166128Srafan  clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx,
113166128Srafan                        clang::Decl *decl);
114166128Srafan
115166128Srafan  lldb::opaque_compiler_type_t DeportType(clang::ASTContext *dst_ctx,
116166128Srafan                                          clang::ASTContext *src_ctx,
117166128Srafan                                          lldb::opaque_compiler_type_t type);
118166128Srafan
119166128Srafan  clang::Decl *DeportDecl(clang::ASTContext *dst_ctx,
120166128Srafan                          clang::ASTContext *src_ctx, clang::Decl *decl);
121174998Srafan
122166128Srafan  void InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout);
123166128Srafan
124174998Srafan  bool LayoutRecordType(
125166128Srafan      const clang::RecordDecl *record_decl, uint64_t &bit_size,
126166128Srafan      uint64_t &alignment,
127166128Srafan      llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
128166128Srafan      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
129166128Srafan          &base_offsets,
130166128Srafan      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
131166128Srafan          &vbase_offsets);
132166128Srafan
133174998Srafan  bool CanImport(const CompilerType &type);
134174998Srafan
135174998Srafan  bool Import(const CompilerType &type);
136166128Srafan
137166128Srafan  bool CompleteType(const CompilerType &compiler_type);
138174998Srafan
139166128Srafan  void CompleteDecl(clang::Decl *decl);
140166128Srafan
141174998Srafan  bool CompleteTagDecl(clang::TagDecl *decl);
142166128Srafan
14397052Speter  bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin);
14497052Speter
14597052Speter  bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl);
146166128Srafan
14797052Speter  bool CompleteAndFetchChildren(clang::QualType type);
14862453Speter
14950276Speter  bool RequireCompleteType(clang::QualType type);
15062453Speter
151184989Srafan  bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl,
15262453Speter                         clang::ASTContext **original_ctx) {
15350276Speter    DeclOrigin origin = GetDeclOrigin(decl);
15462453Speter
15562453Speter    if (original_decl)
15662453Speter      *original_decl = origin.decl;
15762453Speter
15862453Speter    if (original_ctx)
15962453Speter      *original_ctx = origin.ctx;
16062453Speter
16150276Speter    return origin.Valid();
162166128Srafan  }
163166128Srafan
164166128Srafan  void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl);
165166128Srafan
16697052Speter  ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl);
167166128Srafan
16897052Speter  //
16997052Speter  // Namespace maps
170166128Srafan  //
171174998Srafan
17297052Speter  typedef std::vector<std::pair<lldb::ModuleSP, CompilerDeclContext>>
173184989Srafan      NamespaceMap;
17462453Speter  typedef std::shared_ptr<NamespaceMap> NamespaceMapSP;
17550276Speter
17650276Speter  void RegisterNamespaceMap(const clang::NamespaceDecl *decl,
17750276Speter                            NamespaceMapSP &namespace_map);
17850276Speter
17950276Speter  NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl);
18050276Speter
18150276Speter  void BuildNamespaceMap(const clang::NamespaceDecl *decl);
18262455Speter
18362455Speter  //
18450620Speter  // Completers for maps
18562455Speter  //
18662455Speter
18762455Speter  class MapCompleter {
18862455Speter  public:
18962455Speter    virtual ~MapCompleter();
19062455Speter
19150620Speter    virtual void CompleteNamespaceMap(NamespaceMapSP &namespace_map,
19250620Speter                                      const ConstString &name,
19362453Speter                                      NamespaceMapSP &parent_map) const = 0;
19450276Speter  };
19550276Speter
19650276Speter  void InstallMapCompleter(clang::ASTContext *dst_ctx,
19750276Speter                           MapCompleter &completer) {
19850276Speter    ASTContextMetadataSP context_md;
19950276Speter    ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
20050276Speter
20150276Speter    if (context_md_iter == m_metadata_map.end()) {
20250276Speter      context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
20350276Speter      m_metadata_map[dst_ctx] = context_md;
20450276Speter    } else {
20576730Speter      context_md = context_md_iter->second;
20662453Speter    }
20750276Speter
208166128Srafan    context_md->m_map_completer = &completer;
20950276Speter  }
21062453Speter
21162453Speter  void ForgetDestination(clang::ASTContext *dst_ctx);
21262453Speter  void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
21362453Speter
21462453Speterprivate:
21562453Speter  struct DeclOrigin {
21662453Speter    DeclOrigin() : ctx(nullptr), decl(nullptr) {}
21762453Speter
21850276Speter    DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl)
21950276Speter        : ctx(_ctx), decl(_decl) {}
22062453Speter
22162453Speter    DeclOrigin(const DeclOrigin &rhs) {
22250276Speter      ctx = rhs.ctx;
22350276Speter      decl = rhs.decl;
22450276Speter    }
22550276Speter
22650276Speter    void operator=(const DeclOrigin &rhs) {
22750276Speter      ctx = rhs.ctx;
22850276Speter      decl = rhs.decl;
22950276Speter    }
23050276Speter
23150276Speter    bool Valid() { return (ctx != nullptr || decl != nullptr); }
23250276Speter
23376730Speter    clang::ASTContext *ctx;
23462453Speter    clang::Decl *decl;
23550276Speter  };
236166128Srafan
23750276Speter  typedef std::map<const clang::Decl *, DeclOrigin> OriginMap;
23862453Speter
23962453Speter  class Minion : public clang::ASTImporter {
24062453Speter  public:
24162453Speter    Minion(ClangASTImporter &master, clang::ASTContext *target_ctx,
24262453Speter           clang::ASTContext *source_ctx)
24362453Speter        : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx,
24462453Speter                             master.m_file_manager, true /*minimal*/),
24562453Speter          m_decls_to_deport(nullptr), m_decls_already_deported(nullptr),
24662453Speter          m_master(master), m_source_ctx(source_ctx) {}
24750276Speter
24850276Speter    // A call to "InitDeportWorkQueues" puts the minion into deport mode.
24962453Speter    // In deport mode, every copied Decl that could require completion is
25062453Speter    // recorded and placed into the decls_to_deport set.
25150276Speter    //
25250276Speter    // A call to "ExecuteDeportWorkQueues" completes all the Decls that
25350276Speter    // are in decls_to_deport, adding any Decls it sees along the way that
25450276Speter    // it hasn't already deported.  It proceeds until decls_to_deport is
25550276Speter    // empty.
25650276Speter    //
25750276Speter    // These calls must be paired.  Leaving a minion in deport mode or
25850276Speter    // trying to start deport minion with a new pair of queues will result
25950276Speter    // in an assertion failure.
26050276Speter
26150276Speter    void
26276730Speter    InitDeportWorkQueues(std::set<clang::NamedDecl *> *decls_to_deport,
26397052Speter                         std::set<clang::NamedDecl *> *decls_already_deported);
26450276Speter    void ExecuteDeportWorkQueues();
265166128Srafan
26697052Speter    void ImportDefinitionTo(clang::Decl *to, clang::Decl *from);
26750276Speter
26862453Speter    clang::Decl *Imported(clang::Decl *from, clang::Decl *to) override;
26962453Speter
27062453Speter    clang::Decl *GetOriginalDecl(clang::Decl *To) override;
27162453Speter
27262453Speter    std::set<clang::NamedDecl *> *m_decls_to_deport;
27362453Speter    std::set<clang::NamedDecl *> *m_decls_already_deported;
27497052Speter    ClangASTImporter &m_master;
27597052Speter    clang::ASTContext *m_source_ctx;
27662453Speter  };
27797052Speter
27897052Speter  typedef std::shared_ptr<Minion> MinionSP;
279166128Srafan  typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
280166128Srafan  typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP>
28197052Speter      NamespaceMetaMap;
28297052Speter
28397052Speter  struct ASTContextMetadata {
28497052Speter    ASTContextMetadata(clang::ASTContext *dst_ctx)
28597052Speter        : m_dst_ctx(dst_ctx), m_minions(), m_origins(), m_namespace_maps(),
286166128Srafan          m_map_completer(nullptr) {}
28797052Speter
28897052Speter    clang::ASTContext *m_dst_ctx;
28950276Speter    MinionMap m_minions;
29097052Speter    OriginMap m_origins;
29150276Speter
29250276Speter    NamespaceMetaMap m_namespace_maps;
29362453Speter    MapCompleter *m_map_completer;
29497052Speter  };
29550276Speter
296166128Srafan  typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
297166128Srafan  typedef std::map<const clang::ASTContext *, ASTContextMetadataSP>
298166128Srafan      ContextMetadataMap;
299166128Srafan
300166128Srafan  ContextMetadataMap m_metadata_map;
301174998Srafan
302166128Srafan  ASTContextMetadataSP GetContextMetadata(clang::ASTContext *dst_ctx) {
303174998Srafan    ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
304174998Srafan
305166128Srafan    if (context_md_iter == m_metadata_map.end()) {
306166128Srafan      ASTContextMetadataSP context_md =
307166128Srafan          ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
308      m_metadata_map[dst_ctx] = context_md;
309      return context_md;
310    } else {
311      return context_md_iter->second;
312    }
313  }
314
315  ASTContextMetadataSP MaybeGetContextMetadata(clang::ASTContext *dst_ctx) {
316    ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
317
318    if (context_md_iter != m_metadata_map.end())
319      return context_md_iter->second;
320    else
321      return ASTContextMetadataSP();
322  }
323
324  MinionSP GetMinion(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) {
325    ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
326
327    MinionMap &minions = context_md->m_minions;
328    MinionMap::iterator minion_iter = minions.find(src_ctx);
329
330    if (minion_iter == minions.end()) {
331      MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
332      minions[src_ctx] = minion;
333      return minion;
334    } else {
335      return minion_iter->second;
336    }
337  }
338
339  DeclOrigin GetDeclOrigin(const clang::Decl *decl);
340
341  clang::FileManager m_file_manager;
342  typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo>
343      RecordDeclToLayoutMap;
344
345  RecordDeclToLayoutMap m_record_decl_to_layout_map;
346};
347
348} // namespace lldb_private
349
350#endif // liblldb_ClangASTImporter_h_
351