1061da546Spatrick //===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H 11061da546Spatrick 12*f6aab3d8Srobert #include "lldb/Symbol/LineTable.h" 13061da546Spatrick #include "lldb/Symbol/SymbolFile.h" 14061da546Spatrick 15061da546Spatrick #include "llvm/ADT/DenseMap.h" 16061da546Spatrick #include "llvm/DebugInfo/CodeView/CVRecord.h" 17061da546Spatrick #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 18061da546Spatrick #include "llvm/DebugInfo/PDB/PDBTypes.h" 19061da546Spatrick 20061da546Spatrick #include "CompileUnitIndex.h" 21061da546Spatrick #include "PdbIndex.h" 22*f6aab3d8Srobert #include "PdbAstBuilder.h" 23*f6aab3d8Srobert #include <optional> 24061da546Spatrick 25061da546Spatrick namespace clang { 26061da546Spatrick class TagDecl; 27061da546Spatrick } 28061da546Spatrick 29061da546Spatrick namespace llvm { 30061da546Spatrick namespace codeview { 31061da546Spatrick class ClassRecord; 32061da546Spatrick class EnumRecord; 33061da546Spatrick class ModifierRecord; 34061da546Spatrick class PointerRecord; 35061da546Spatrick struct UnionRecord; 36061da546Spatrick } // namespace codeview 37061da546Spatrick } // namespace llvm 38061da546Spatrick 39061da546Spatrick namespace lldb_private { 40061da546Spatrick 41061da546Spatrick namespace npdb { 42061da546Spatrick 43*f6aab3d8Srobert class SymbolFileNativePDB : public SymbolFileCommon { 44061da546Spatrick friend class UdtRecordCompleter; 45061da546Spatrick 46061da546Spatrick /// LLVM RTTI support. 47061da546Spatrick static char ID; 48061da546Spatrick 49061da546Spatrick public: 50061da546Spatrick /// LLVM RTTI support. 51061da546Spatrick /// \{ isA(const void * ClassID)52061da546Spatrick bool isA(const void *ClassID) const override { 53*f6aab3d8Srobert return ClassID == &ID || SymbolFileCommon::isA(ClassID); 54061da546Spatrick } classof(const SymbolFile * obj)55061da546Spatrick static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } 56061da546Spatrick /// \} 57061da546Spatrick 58061da546Spatrick // Static Functions 59061da546Spatrick static void Initialize(); 60061da546Spatrick 61061da546Spatrick static void Terminate(); 62061da546Spatrick 63061da546Spatrick static void DebuggerInitialize(Debugger &debugger); 64061da546Spatrick GetPluginNameStatic()65*f6aab3d8Srobert static llvm::StringRef GetPluginNameStatic() { return "native-pdb"; } 66061da546Spatrick 67*f6aab3d8Srobert static llvm::StringRef GetPluginDescriptionStatic(); 68061da546Spatrick 69061da546Spatrick static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp); 70061da546Spatrick 71061da546Spatrick // Constructors and Destructors 72061da546Spatrick SymbolFileNativePDB(lldb::ObjectFileSP objfile_sp); 73061da546Spatrick 74061da546Spatrick ~SymbolFileNativePDB() override; 75061da546Spatrick 76061da546Spatrick uint32_t CalculateAbilities() override; 77061da546Spatrick 78061da546Spatrick void InitializeObject() override; 79061da546Spatrick 80*f6aab3d8Srobert uint64_t GetDebugInfoSize() override; 81*f6aab3d8Srobert 82061da546Spatrick // Compile Unit function calls 83061da546Spatrick 84061da546Spatrick void 85061da546Spatrick ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; 86061da546Spatrick 87061da546Spatrick lldb::LanguageType 88061da546Spatrick ParseLanguage(lldb_private::CompileUnit &comp_unit) override; 89061da546Spatrick 90061da546Spatrick size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; 91061da546Spatrick 92061da546Spatrick bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; 93061da546Spatrick 94061da546Spatrick bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; 95061da546Spatrick 96061da546Spatrick bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, 97061da546Spatrick FileSpecList &support_files) override; 98061da546Spatrick size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; 99061da546Spatrick 100061da546Spatrick bool ParseImportedModules( 101061da546Spatrick const SymbolContext &sc, 102061da546Spatrick std::vector<lldb_private::SourceModule> &imported_modules) override; 103061da546Spatrick 104061da546Spatrick size_t ParseBlocksRecursive(Function &func) override; 105061da546Spatrick 106061da546Spatrick void FindGlobalVariables(ConstString name, 107dda28197Spatrick const CompilerDeclContext &parent_decl_ctx, 108061da546Spatrick uint32_t max_matches, 109061da546Spatrick VariableList &variables) override; 110061da546Spatrick 111061da546Spatrick size_t ParseVariablesForContext(const SymbolContext &sc) override; 112061da546Spatrick 113061da546Spatrick void AddSymbols(Symtab &symtab) override; 114061da546Spatrick 115061da546Spatrick CompilerDecl GetDeclForUID(lldb::user_id_t uid) override; 116061da546Spatrick CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; 117061da546Spatrick CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override; 118061da546Spatrick Type *ResolveTypeUID(lldb::user_id_t type_uid) override; 119*f6aab3d8Srobert std::optional<ArrayInfo> GetDynamicArrayInfoForUID( 120061da546Spatrick lldb::user_id_t type_uid, 121061da546Spatrick const lldb_private::ExecutionContext *exe_ctx) override; 122061da546Spatrick 123061da546Spatrick bool CompleteType(CompilerType &compiler_type) override; 124061da546Spatrick uint32_t ResolveSymbolContext(const Address &so_addr, 125061da546Spatrick lldb::SymbolContextItem resolve_scope, 126061da546Spatrick SymbolContext &sc) override; 127be691f3bSpatrick uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec, 128061da546Spatrick lldb::SymbolContextItem resolve_scope, 129061da546Spatrick SymbolContextList &sc_list) override; 130061da546Spatrick 131061da546Spatrick void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, 132061da546Spatrick TypeList &type_list) override; 133061da546Spatrick 134*f6aab3d8Srobert void FindFunctions(const Module::LookupInfo &lookup_info, 135dda28197Spatrick const CompilerDeclContext &parent_decl_ctx, 136061da546Spatrick bool include_inlines, SymbolContextList &sc_list) override; 137061da546Spatrick 138061da546Spatrick void FindFunctions(const RegularExpression ®ex, bool include_inlines, 139061da546Spatrick SymbolContextList &sc_list) override; 140061da546Spatrick 141*f6aab3d8Srobert std::optional<PdbCompilandSymId> FindSymbolScope(PdbCompilandSymId id); 142*f6aab3d8Srobert 143dda28197Spatrick void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, 144061da546Spatrick uint32_t max_matches, 145061da546Spatrick llvm::DenseSet<SymbolFile *> &searched_symbol_files, 146061da546Spatrick TypeMap &types) override; 147061da546Spatrick 148061da546Spatrick void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, 149061da546Spatrick llvm::DenseSet<SymbolFile *> &searched_symbol_files, 150061da546Spatrick TypeMap &types) override; 151061da546Spatrick 152*f6aab3d8Srobert llvm::Expected<lldb::TypeSystemSP> 153061da546Spatrick GetTypeSystemForLanguage(lldb::LanguageType language) override; 154061da546Spatrick 155061da546Spatrick CompilerDeclContext 156061da546Spatrick FindNamespace(ConstString name, 157dda28197Spatrick const CompilerDeclContext &parent_decl_ctx) override; 158061da546Spatrick GetPluginName()159*f6aab3d8Srobert llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 160061da546Spatrick GetPDBFile()161061da546Spatrick llvm::pdb::PDBFile &GetPDBFile() { return m_index->pdb(); } GetPDBFile()162061da546Spatrick const llvm::pdb::PDBFile &GetPDBFile() const { return m_index->pdb(); } 163061da546Spatrick GetIndex()164*f6aab3d8Srobert PdbIndex &GetIndex() { return *m_index; }; 165*f6aab3d8Srobert 166061da546Spatrick void DumpClangAST(Stream &s) override; 167061da546Spatrick 168*f6aab3d8Srobert std::optional<llvm::codeview::TypeIndex> 169*f6aab3d8Srobert GetParentType(llvm::codeview::TypeIndex ti); 170*f6aab3d8Srobert 171061da546Spatrick private: 172*f6aab3d8Srobert struct LineTableEntryComparator { operatorLineTableEntryComparator173*f6aab3d8Srobert bool operator()(const lldb_private::LineTable::Entry &lhs, 174*f6aab3d8Srobert const lldb_private::LineTable::Entry &rhs) const { 175*f6aab3d8Srobert return lhs.file_addr < rhs.file_addr; 176*f6aab3d8Srobert } 177*f6aab3d8Srobert }; 178*f6aab3d8Srobert 179*f6aab3d8Srobert // From address range relative to function base to source line number. 180*f6aab3d8Srobert using RangeSourceLineVector = 181*f6aab3d8Srobert lldb_private::RangeDataVector<uint32_t, uint32_t, int32_t>; 182*f6aab3d8Srobert // InlineSite contains information in a S_INLINESITE record. 183*f6aab3d8Srobert struct InlineSite { 184*f6aab3d8Srobert PdbCompilandSymId parent_id; 185*f6aab3d8Srobert std::shared_ptr<InlineFunctionInfo> inline_function_info; 186*f6aab3d8Srobert RangeSourceLineVector ranges; 187*f6aab3d8Srobert std::vector<lldb_private::LineTable::Entry> line_entries; InlineSiteInlineSite188*f6aab3d8Srobert InlineSite(PdbCompilandSymId parent_id) : parent_id(parent_id){}; 189*f6aab3d8Srobert }; 190*f6aab3d8Srobert 191*f6aab3d8Srobert void BuildParentMap(); 192*f6aab3d8Srobert 193061da546Spatrick uint32_t CalculateNumCompileUnits() override; 194061da546Spatrick 195061da546Spatrick lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; 196061da546Spatrick 197061da546Spatrick void FindTypesByName(llvm::StringRef name, uint32_t max_matches, 198061da546Spatrick TypeMap &types); 199061da546Spatrick 200061da546Spatrick lldb::TypeSP CreateModifierType(PdbTypeSymId type_id, 201061da546Spatrick const llvm::codeview::ModifierRecord &mr, 202061da546Spatrick CompilerType ct); 203061da546Spatrick lldb::TypeSP CreatePointerType(PdbTypeSymId type_id, 204061da546Spatrick const llvm::codeview::PointerRecord &pr, 205061da546Spatrick CompilerType ct); 206061da546Spatrick lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti, CompilerType ct); 207061da546Spatrick lldb::TypeSP CreateTagType(PdbTypeSymId type_id, 208061da546Spatrick const llvm::codeview::ClassRecord &cr, 209061da546Spatrick CompilerType ct); 210061da546Spatrick lldb::TypeSP CreateTagType(PdbTypeSymId type_id, 211061da546Spatrick const llvm::codeview::EnumRecord &er, 212061da546Spatrick CompilerType ct); 213061da546Spatrick lldb::TypeSP CreateTagType(PdbTypeSymId type_id, 214061da546Spatrick const llvm::codeview::UnionRecord &ur, 215061da546Spatrick CompilerType ct); 216061da546Spatrick lldb::TypeSP CreateArrayType(PdbTypeSymId type_id, 217061da546Spatrick const llvm::codeview::ArrayRecord &ar, 218061da546Spatrick CompilerType ct); 219061da546Spatrick lldb::TypeSP CreateFunctionType(PdbTypeSymId type_id, 220061da546Spatrick const llvm::codeview::MemberFunctionRecord &pr, 221061da546Spatrick CompilerType ct); 222061da546Spatrick lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id, 223061da546Spatrick const llvm::codeview::ProcedureRecord &pr, 224061da546Spatrick CompilerType ct); 225061da546Spatrick lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id, 226061da546Spatrick const llvm::codeview::TagRecord &record, 227061da546Spatrick size_t size, CompilerType ct); 228061da546Spatrick 229061da546Spatrick lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id, 230061da546Spatrick CompileUnit &comp_unit); 231061da546Spatrick lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci); 232061da546Spatrick lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id); 233061da546Spatrick lldb::TypeSP GetOrCreateType(llvm::codeview::TypeIndex ti); 234061da546Spatrick lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id); 235061da546Spatrick Block &GetOrCreateBlock(PdbCompilandSymId block_id); 236061da546Spatrick lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id, 237061da546Spatrick PdbCompilandSymId var_id, 238061da546Spatrick bool is_param); 239061da546Spatrick lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id); 240061da546Spatrick 241061da546Spatrick lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id, 242061da546Spatrick CompileUnit &comp_unit); 243061da546Spatrick Block &CreateBlock(PdbCompilandSymId block_id); 244061da546Spatrick lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id, 245061da546Spatrick PdbCompilandSymId var_id, bool is_param); 246061da546Spatrick lldb::TypeSP CreateTypedef(PdbGlobalSymId id); 247061da546Spatrick lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci); 248061da546Spatrick lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct); 249061da546Spatrick lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id); 250061da546Spatrick lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id); 251061da546Spatrick lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id, 252061da546Spatrick const llvm::codeview::CVSymbol &cvs); 253061da546Spatrick size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit, 254061da546Spatrick VariableList &variables); 255061da546Spatrick size_t ParseVariablesForBlock(PdbCompilandSymId block_id); 256061da546Spatrick 257*f6aab3d8Srobert llvm::Expected<uint32_t> GetFileIndex(const CompilandIndexItem &cii, 258*f6aab3d8Srobert uint32_t file_id); 259*f6aab3d8Srobert 260*f6aab3d8Srobert size_t ParseSymbolArrayInScope( 261*f6aab3d8Srobert PdbCompilandSymId parent, 262*f6aab3d8Srobert llvm::function_ref<bool(llvm::codeview::SymbolKind, PdbCompilandSymId)> 263*f6aab3d8Srobert fn); 264*f6aab3d8Srobert 265*f6aab3d8Srobert void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr); 266*f6aab3d8Srobert 267061da546Spatrick llvm::BumpPtrAllocator m_allocator; 268061da546Spatrick 269061da546Spatrick lldb::addr_t m_obj_load_address = 0; 270061da546Spatrick bool m_done_full_type_scan = false; 271*f6aab3d8Srobert // UID for anonymous union and anonymous struct as they don't have entities in 272*f6aab3d8Srobert // pdb debug info. 273*f6aab3d8Srobert lldb::user_id_t anonymous_id = LLDB_INVALID_UID - 1; 274061da546Spatrick 275be691f3bSpatrick std::unique_ptr<llvm::pdb::PDBFile> m_file_up; 276061da546Spatrick std::unique_ptr<PdbIndex> m_index; 277061da546Spatrick 278061da546Spatrick llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_global_vars; 279061da546Spatrick llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_local_variables; 280061da546Spatrick llvm::DenseMap<lldb::user_id_t, lldb::BlockSP> m_blocks; 281061da546Spatrick llvm::DenseMap<lldb::user_id_t, lldb::FunctionSP> m_functions; 282061da546Spatrick llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands; 283061da546Spatrick llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types; 284*f6aab3d8Srobert llvm::DenseMap<lldb::user_id_t, std::shared_ptr<InlineSite>> m_inline_sites; 285*f6aab3d8Srobert llvm::DenseMap<llvm::codeview::TypeIndex, llvm::codeview::TypeIndex> 286*f6aab3d8Srobert m_parent_types; 287061da546Spatrick }; 288061da546Spatrick 289061da546Spatrick } // namespace npdb 290061da546Spatrick } // namespace lldb_private 291061da546Spatrick 292dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H 293