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; DeclStatusDeclStatus47 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 clang()87 TypeSystemClang &clang() { return m_clang; } GetClangASTImporter()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