1 //===-- PdbAstBuilder.h -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
11 #define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
12 
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/StringRef.h"
15 
16 #include "lldb/Symbol/ClangASTImporter.h"
17 
18 #include "PdbIndex.h"
19 #include "PdbSymUid.h"
20 
21 namespace clang {
22 class TagDecl;
23 class DeclContext;
24 class Decl;
25 class QualType;
26 class FunctionDecl;
27 class NamespaceDecl;
28 } // namespace clang
29 
30 namespace llvm {
31 namespace codeview {
32 class ProcSym;
33 }
34 } // namespace llvm
35 
36 namespace lldb_private {
37 class ClangASTImporter;
38 class ObjectFile;
39 
40 namespace npdb {
41 class PdbIndex;
42 struct VariableInfo;
43 
44 struct DeclStatus {
45   DeclStatus() = default;
46   DeclStatus(lldb::user_id_t uid, bool resolved)
47       : uid(uid), resolved(resolved) {}
48   lldb::user_id_t uid = 0;
49   bool resolved = false;
50 };
51 
52 class PdbAstBuilder {
53 public:
54   //------------------------------------------------------------------
55   // Constructors and Destructors
56   //------------------------------------------------------------------
57   PdbAstBuilder(ObjectFile &obj, PdbIndex &index);
58 
59   clang::DeclContext &GetTranslationUnitDecl();
60 
61   clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid);
62   clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
63   clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
64 
65   clang::NamespaceDecl *GetOrCreateNamespaceDecl(llvm::StringRef name,
66                                                  clang::DeclContext &context);
67   clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
68   clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
69   clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
70                                           PdbCompilandSymId var_id);
71   clang::VarDecl *GetOrCreateVariableDecl(PdbGlobalSymId var_id);
72   void ParseDeclsForContext(clang::DeclContext &context);
73 
74   clang::QualType GetBasicType(lldb::BasicType type);
75   clang::QualType GetOrCreateType(PdbTypeSymId type);
76 
77   bool CompleteTagDecl(clang::TagDecl &tag);
78   bool CompleteType(clang::QualType qt);
79 
80   CompilerDecl ToCompilerDecl(clang::Decl &decl);
81   CompilerType ToCompilerType(clang::QualType qt);
82   CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
83   clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
84 
85   ClangASTContext &clang() { return m_clang; }
86   ClangASTImporter &importer() { return m_importer; }
87 
88   void Dump(Stream &stream);
89 
90 private:
91   clang::Decl *TryGetDecl(PdbSymUid uid) const;
92 
93   using TypeIndex = llvm::codeview::TypeIndex;
94 
95   clang::QualType
96   CreatePointerType(const llvm::codeview::PointerRecord &pointer);
97   clang::QualType
98   CreateModifierType(const llvm::codeview::ModifierRecord &modifier);
99   clang::QualType CreateArrayType(const llvm::codeview::ArrayRecord &array);
100   clang::QualType CreateRecordType(PdbTypeSymId id,
101                                    const llvm::codeview::TagRecord &record);
102   clang::QualType CreateEnumType(PdbTypeSymId id,
103                                  const llvm::codeview::EnumRecord &record);
104   clang::QualType
105   CreateProcedureType(const llvm::codeview::ProcedureRecord &proc);
106   clang::QualType CreateType(PdbTypeSymId type);
107 
108   void CreateFunctionParameters(PdbCompilandSymId func_id,
109                                 clang::FunctionDecl &function_decl,
110                                 uint32_t param_count);
111   clang::Decl *GetOrCreateSymbolForId(PdbCompilandSymId id);
112   clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
113                                      llvm::codeview::CVSymbol sym,
114                                      clang::DeclContext &scope);
115 
116   void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
117   void ParseDeclsForSimpleContext(clang::DeclContext &context);
118   void ParseBlockChildren(PdbCompilandSymId block_id);
119 
120   void BuildParentMap();
121   std::pair<clang::DeclContext *, std::string>
122   CreateDeclInfoForType(const llvm::codeview::TagRecord &record, TypeIndex ti);
123   clang::QualType CreateSimpleType(TypeIndex ti);
124 
125   PdbIndex &m_index;
126   ClangASTContext &m_clang;
127 
128   ClangASTImporter m_importer;
129 
130   llvm::DenseMap<TypeIndex, TypeIndex> m_parent_types;
131   llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
132   llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
133   llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
134 };
135 
136 } // namespace npdb
137 } // namespace lldb_private
138 
139 #endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
140