1 //===-- PdbAstBuilder.h -----------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
11 
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/StringRef.h"
14 
15 #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
16 
17 #include "PdbIndex.h"
18 #include "PdbSymUid.h"
19 
20 namespace clang {
21 class TagDecl;
22 class DeclContext;
23 class Decl;
24 class QualType;
25 class FunctionDecl;
26 class NamespaceDecl;
27 } // namespace clang
28 
29 namespace llvm {
30 namespace codeview {
31 class ProcSym;
32 }
33 } // namespace llvm
34 
35 namespace lldb_private {
36 class ClangASTImporter;
37 class ObjectFile;
38 
39 namespace npdb {
40 class PdbIndex;
41 struct VariableInfo;
42 
43 struct DeclStatus {
44   DeclStatus() = default;
45   DeclStatus(lldb::user_id_t uid, bool resolved)
46       : uid(uid), resolved(resolved) {}
47   lldb::user_id_t uid = 0;
48   bool resolved = false;
49 };
50 
51 class PdbAstBuilder {
52 public:
53   // Constructors and Destructors
54   PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang);
55 
56   lldb_private::CompilerDeclContext GetTranslationUnitDecl();
57 
58   llvm::Optional<lldb_private::CompilerDecl>
59   GetOrCreateDeclForUid(PdbSymUid uid);
60   clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
61   clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
62 
63   clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
64   clang::FunctionDecl *
65   GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id);
66   clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
67   clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
68                                           PdbCompilandSymId var_id);
69   clang::VarDecl *GetOrCreateVariableDecl(PdbGlobalSymId var_id);
70   clang::TypedefNameDecl *GetOrCreateTypedefDecl(PdbGlobalSymId id);
71   void ParseDeclsForContext(clang::DeclContext &context);
72 
73   clang::QualType GetBasicType(lldb::BasicType type);
74   clang::QualType GetOrCreateType(PdbTypeSymId type);
75 
76   bool CompleteTagDecl(clang::TagDecl &tag);
77   bool CompleteType(clang::QualType qt);
78 
79   CompilerDecl ToCompilerDecl(clang::Decl &decl);
80   CompilerType ToCompilerType(clang::QualType qt);
81   CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
82   clang::Decl *FromCompilerDecl(CompilerDecl decl);
83   clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
84 
85   TypeSystemClang &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   CreateFunctionType(TypeIndex args_type_idx, TypeIndex return_type_idx,
106                      llvm::codeview::CallingConvention calling_convention);
107   clang::QualType CreateType(PdbTypeSymId type);
108 
109   void CreateFunctionParameters(PdbCompilandSymId func_id,
110                                 clang::FunctionDecl &function_decl,
111                                 uint32_t param_count);
112   clang::Decl *GetOrCreateSymbolForId(PdbCompilandSymId id);
113   clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
114                                      llvm::codeview::CVSymbol sym,
115                                      clang::DeclContext &scope);
116   clang::DeclContext *
117   GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);
118 
119   clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
120                                                  clang::DeclContext &context);
121   clang::FunctionDecl *CreateFunctionDeclFromId(PdbTypeSymId func_tid,
122                                                 PdbCompilandSymId func_sid);
123   clang::FunctionDecl *
124   CreateFunctionDecl(PdbCompilandSymId func_id, llvm::StringRef func_name,
125                      TypeIndex func_ti, CompilerType func_ct,
126                      uint32_t param_count, clang::StorageClass func_storage,
127                      bool is_inline, clang::DeclContext *parent);
128   void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
129   void ParseDeclsForSimpleContext(clang::DeclContext &context);
130   void ParseBlockChildren(PdbCompilandSymId block_id);
131 
132   void BuildParentMap();
133   std::pair<clang::DeclContext *, std::string>
134   CreateDeclInfoForType(const llvm::codeview::TagRecord &record, TypeIndex ti);
135   std::pair<clang::DeclContext *, std::string>
136   CreateDeclInfoForUndecoratedName(llvm::StringRef uname);
137   clang::QualType CreateSimpleType(TypeIndex ti);
138 
139   PdbIndex &m_index;
140   TypeSystemClang &m_clang;
141 
142   ClangASTImporter m_importer;
143 
144   llvm::DenseMap<TypeIndex, TypeIndex> m_parent_types;
145   llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
146   llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
147   llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
148 
149   // From class/struct's opaque_compiler_type_t to a set containing the pairs of
150   // method's name and CompilerType.
151   llvm::DenseMap<lldb::opaque_compiler_type_t,
152                  llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
153       m_cxx_record_map;
154 };
155 
156 } // namespace npdb
157 } // namespace lldb_private
158 
159 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
160