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 #include "llvm/Support/Threading.h"
15 
16 #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
17 
18 #include "PdbIndex.h"
19 #include "PdbSymUid.h"
20 #include <optional>
21 
22 namespace clang {
23 class TagDecl;
24 class DeclContext;
25 class Decl;
26 class QualType;
27 class FunctionDecl;
28 class NamespaceDecl;
29 } // namespace clang
30 
31 namespace llvm {
32 namespace codeview {
33 class ProcSym;
34 }
35 } // namespace llvm
36 
37 namespace lldb_private {
38 class ClangASTImporter;
39 class ObjectFile;
40 
41 namespace npdb {
42 class PdbIndex;
43 struct VariableInfo;
44 
45 struct DeclStatus {
46   DeclStatus() = default;
47   DeclStatus(lldb::user_id_t uid, bool resolved)
48       : uid(uid), resolved(resolved) {}
49   lldb::user_id_t uid = 0;
50   bool resolved = false;
51 };
52 
53 class PdbAstBuilder {
54 public:
55   // Constructors and Destructors
56   PdbAstBuilder(TypeSystemClang &clang);
57 
58   lldb_private::CompilerDeclContext GetTranslationUnitDecl();
59 
60   std::optional<lldb_private::CompilerDecl>
61   GetOrCreateDeclForUid(PdbSymUid uid);
62   clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
63   clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
64 
65   clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
66   clang::FunctionDecl *
67   GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_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   clang::TypedefNameDecl *GetOrCreateTypedefDecl(PdbGlobalSymId id);
73   void ParseDeclsForContext(clang::DeclContext &context);
74 
75   clang::QualType GetBasicType(lldb::BasicType type);
76   clang::QualType GetOrCreateType(PdbTypeSymId type);
77 
78   bool CompleteTagDecl(clang::TagDecl &tag);
79   bool CompleteType(clang::QualType qt);
80 
81   CompilerDecl ToCompilerDecl(clang::Decl &decl);
82   CompilerType ToCompilerType(clang::QualType qt);
83   CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
84   clang::Decl *FromCompilerDecl(CompilerDecl decl);
85   clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
86 
87   TypeSystemClang &clang() { return m_clang; }
88   ClangASTImporter &GetClangASTImporter() { return m_importer; }
89 
90   void Dump(Stream &stream);
91 
92 private:
93   clang::Decl *TryGetDecl(PdbSymUid uid) const;
94 
95   using TypeIndex = llvm::codeview::TypeIndex;
96 
97   clang::QualType
98   CreatePointerType(const llvm::codeview::PointerRecord &pointer);
99   clang::QualType
100   CreateModifierType(const llvm::codeview::ModifierRecord &modifier);
101   clang::QualType CreateArrayType(const llvm::codeview::ArrayRecord &array);
102   clang::QualType CreateRecordType(PdbTypeSymId id,
103                                    const llvm::codeview::TagRecord &record);
104   clang::QualType CreateEnumType(PdbTypeSymId id,
105                                  const llvm::codeview::EnumRecord &record);
106   clang::QualType
107   CreateFunctionType(TypeIndex args_type_idx, TypeIndex return_type_idx,
108                      llvm::codeview::CallingConvention calling_convention);
109   clang::QualType CreateType(PdbTypeSymId type);
110 
111   void CreateFunctionParameters(PdbCompilandSymId func_id,
112                                 clang::FunctionDecl &function_decl,
113                                 uint32_t param_count);
114   clang::Decl *GetOrCreateSymbolForId(PdbCompilandSymId id);
115   clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
116                                      llvm::codeview::CVSymbol sym,
117                                      clang::DeclContext &scope);
118   clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
119                                                  clang::DeclContext &context);
120   clang::FunctionDecl *CreateFunctionDeclFromId(PdbTypeSymId func_tid,
121                                                 PdbCompilandSymId func_sid);
122   clang::FunctionDecl *
123   CreateFunctionDecl(PdbCompilandSymId func_id, llvm::StringRef func_name,
124                      TypeIndex func_ti, CompilerType func_ct,
125                      uint32_t param_count, clang::StorageClass func_storage,
126                      bool is_inline, clang::DeclContext *parent);
127   void ParseNamespace(clang::DeclContext &parent);
128   void ParseAllTypes();
129   void ParseAllFunctionsAndNonLocalVars();
130   void ParseDeclsForSimpleContext(clang::DeclContext &context);
131   void ParseBlockChildren(PdbCompilandSymId block_id);
132 
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   TypeSystemClang &m_clang;
140 
141   ClangASTImporter m_importer;
142   llvm::once_flag m_parse_functions_and_non_local_vars;
143   llvm::once_flag m_parse_all_types;
144   llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
145   llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
146   llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
147 
148   // From class/struct's opaque_compiler_type_t to a set containing the pairs of
149   // method's name and CompilerType.
150   llvm::DenseMap<lldb::opaque_compiler_type_t,
151                  llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
152       m_cxx_record_map;
153   llvm::DenseSet<clang::NamespaceDecl *> m_parsed_namespaces;
154 };
155 
156 } // namespace npdb
157 } // namespace lldb_private
158 
159 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
160