1307f5ae8SZachary Turner //===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===// 2307f5ae8SZachary Turner // 3307f5ae8SZachary Turner // The LLVM Compiler Infrastructure 4307f5ae8SZachary Turner // 5307f5ae8SZachary Turner // This file is distributed under the University of Illinois Open Source 6307f5ae8SZachary Turner // License. See LICENSE.TXT for details. 7307f5ae8SZachary Turner // 8307f5ae8SZachary Turner //===----------------------------------------------------------------------===// 9307f5ae8SZachary Turner 10307f5ae8SZachary Turner #include "SymbolFileNativePDB.h" 11307f5ae8SZachary Turner 122f7efbc9SZachary Turner #include "clang/AST/Attr.h" 132f7efbc9SZachary Turner #include "clang/AST/CharUnits.h" 142f7efbc9SZachary Turner #include "clang/AST/Decl.h" 152f7efbc9SZachary Turner #include "clang/AST/DeclCXX.h" 16056e4ab4SZachary Turner #include "clang/AST/Type.h" 172f7efbc9SZachary Turner 18307f5ae8SZachary Turner #include "lldb/Core/Module.h" 19307f5ae8SZachary Turner #include "lldb/Core/PluginManager.h" 209f727950SZachary Turner #include "lldb/Core/StreamBuffer.h" 21056e4ab4SZachary Turner #include "lldb/Core/StreamFile.h" 222f7efbc9SZachary Turner #include "lldb/Symbol/ClangASTContext.h" 232f7efbc9SZachary Turner #include "lldb/Symbol/ClangASTImporter.h" 242f7efbc9SZachary Turner #include "lldb/Symbol/ClangExternalASTSourceCommon.h" 25056e4ab4SZachary Turner #include "lldb/Symbol/ClangUtil.h" 26307f5ae8SZachary Turner #include "lldb/Symbol/CompileUnit.h" 27307f5ae8SZachary Turner #include "lldb/Symbol/LineTable.h" 28307f5ae8SZachary Turner #include "lldb/Symbol/ObjectFile.h" 29307f5ae8SZachary Turner #include "lldb/Symbol/SymbolContext.h" 30307f5ae8SZachary Turner #include "lldb/Symbol/SymbolVendor.h" 319f727950SZachary Turner #include "lldb/Symbol/Variable.h" 329f727950SZachary Turner #include "lldb/Symbol/VariableList.h" 33307f5ae8SZachary Turner 34307f5ae8SZachary Turner #include "llvm/DebugInfo/CodeView/CVRecord.h" 352f7efbc9SZachary Turner #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 36307f5ae8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" 372f7efbc9SZachary Turner #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" 38307f5ae8SZachary Turner #include "llvm/DebugInfo/CodeView/RecordName.h" 39307f5ae8SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 40a42bbe39SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" 412f7efbc9SZachary Turner #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 42307f5ae8SZachary Turner #include "llvm/DebugInfo/PDB/Native/DbiStream.h" 43307f5ae8SZachary Turner #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" 44307f5ae8SZachary Turner #include "llvm/DebugInfo/PDB/Native/InfoStream.h" 45307f5ae8SZachary Turner #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" 46307f5ae8SZachary Turner #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 47307f5ae8SZachary Turner #include "llvm/DebugInfo/PDB/Native/SymbolStream.h" 482f7efbc9SZachary Turner #include "llvm/DebugInfo/PDB/Native/TpiStream.h" 49307f5ae8SZachary Turner #include "llvm/DebugInfo/PDB/PDBTypes.h" 50056e4ab4SZachary Turner #include "llvm/Demangle/MicrosoftDemangle.h" 51307f5ae8SZachary Turner #include "llvm/Object/COFF.h" 52307f5ae8SZachary Turner #include "llvm/Support/Allocator.h" 53307f5ae8SZachary Turner #include "llvm/Support/BinaryStreamReader.h" 54056e4ab4SZachary Turner #include "llvm/Support/Error.h" 55307f5ae8SZachary Turner #include "llvm/Support/ErrorOr.h" 56307f5ae8SZachary Turner #include "llvm/Support/MemoryBuffer.h" 57307f5ae8SZachary Turner 58a93458b0SZachary Turner #include "DWARFLocationExpression.h" 59307f5ae8SZachary Turner #include "PdbSymUid.h" 60307f5ae8SZachary Turner #include "PdbUtil.h" 612f7efbc9SZachary Turner #include "UdtRecordCompleter.h" 62307f5ae8SZachary Turner 63307f5ae8SZachary Turner using namespace lldb; 64307f5ae8SZachary Turner using namespace lldb_private; 652f7efbc9SZachary Turner using namespace npdb; 66307f5ae8SZachary Turner using namespace llvm::codeview; 67307f5ae8SZachary Turner using namespace llvm::pdb; 68307f5ae8SZachary Turner 69*d3d2b9b8SZachary Turner namespace { 70*d3d2b9b8SZachary Turner struct VariableInfo { 71*d3d2b9b8SZachary Turner llvm::StringRef name; 72*d3d2b9b8SZachary Turner TypeIndex type; 73*d3d2b9b8SZachary Turner llvm::Optional<DWARFExpression> location; 74*d3d2b9b8SZachary Turner llvm::Optional<Variable::RangeList> ranges; 75*d3d2b9b8SZachary Turner }; 76*d3d2b9b8SZachary Turner } // namespace 77*d3d2b9b8SZachary Turner 78307f5ae8SZachary Turner static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { 79307f5ae8SZachary Turner switch (lang) { 80307f5ae8SZachary Turner case PDB_Lang::Cpp: 81307f5ae8SZachary Turner return lldb::LanguageType::eLanguageTypeC_plus_plus; 82307f5ae8SZachary Turner case PDB_Lang::C: 83307f5ae8SZachary Turner return lldb::LanguageType::eLanguageTypeC; 84307f5ae8SZachary Turner default: 85307f5ae8SZachary Turner return lldb::LanguageType::eLanguageTypeUnknown; 86307f5ae8SZachary Turner } 87307f5ae8SZachary Turner } 88307f5ae8SZachary Turner 89307f5ae8SZachary Turner static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath, 90307f5ae8SZachary Turner llvm::BumpPtrAllocator &Allocator) { 91307f5ae8SZachary Turner llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer = 92307f5ae8SZachary Turner llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1, 93307f5ae8SZachary Turner /*RequiresNullTerminator=*/false); 94307f5ae8SZachary Turner if (!ErrorOrBuffer) 95307f5ae8SZachary Turner return nullptr; 96307f5ae8SZachary Turner std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer); 97307f5ae8SZachary Turner 98307f5ae8SZachary Turner llvm::StringRef Path = Buffer->getBufferIdentifier(); 99307f5ae8SZachary Turner auto Stream = llvm::make_unique<llvm::MemoryBufferByteStream>( 100307f5ae8SZachary Turner std::move(Buffer), llvm::support::little); 101307f5ae8SZachary Turner 102307f5ae8SZachary Turner auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), Allocator); 1038040eea9SZachary Turner if (auto EC = File->parseFileHeaders()) { 1048040eea9SZachary Turner llvm::consumeError(std::move(EC)); 105307f5ae8SZachary Turner return nullptr; 1068040eea9SZachary Turner } 1078040eea9SZachary Turner if (auto EC = File->parseStreamData()) { 1088040eea9SZachary Turner llvm::consumeError(std::move(EC)); 109307f5ae8SZachary Turner return nullptr; 1108040eea9SZachary Turner } 111307f5ae8SZachary Turner 112307f5ae8SZachary Turner return File; 113307f5ae8SZachary Turner } 114307f5ae8SZachary Turner 115307f5ae8SZachary Turner static std::unique_ptr<PDBFile> 116307f5ae8SZachary Turner loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { 117307f5ae8SZachary Turner // Try to find a matching PDB for an EXE. 118307f5ae8SZachary Turner using namespace llvm::object; 119307f5ae8SZachary Turner auto expected_binary = createBinary(exe_path); 120307f5ae8SZachary Turner 121307f5ae8SZachary Turner // If the file isn't a PE/COFF executable, fail. 122307f5ae8SZachary Turner if (!expected_binary) { 123307f5ae8SZachary Turner llvm::consumeError(expected_binary.takeError()); 124307f5ae8SZachary Turner return nullptr; 125307f5ae8SZachary Turner } 126307f5ae8SZachary Turner OwningBinary<Binary> binary = std::move(*expected_binary); 127307f5ae8SZachary Turner 128307f5ae8SZachary Turner auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary()); 129307f5ae8SZachary Turner if (!obj) 130307f5ae8SZachary Turner return nullptr; 131307f5ae8SZachary Turner const llvm::codeview::DebugInfo *pdb_info = nullptr; 132307f5ae8SZachary Turner 133307f5ae8SZachary Turner // If it doesn't have a debug directory, fail. 134307f5ae8SZachary Turner llvm::StringRef pdb_file; 135307f5ae8SZachary Turner auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file); 136307f5ae8SZachary Turner if (ec) 137307f5ae8SZachary Turner return nullptr; 138307f5ae8SZachary Turner 139307f5ae8SZachary Turner // if the file doesn't exist, is not a pdb, or doesn't have a matching guid, 140307f5ae8SZachary Turner // fail. 141307f5ae8SZachary Turner llvm::file_magic magic; 142307f5ae8SZachary Turner ec = llvm::identify_magic(pdb_file, magic); 143307f5ae8SZachary Turner if (ec || magic != llvm::file_magic::pdb) 144307f5ae8SZachary Turner return nullptr; 145307f5ae8SZachary Turner std::unique_ptr<PDBFile> pdb = loadPDBFile(pdb_file, allocator); 1468040eea9SZachary Turner if (!pdb) 1478040eea9SZachary Turner return nullptr; 1488040eea9SZachary Turner 149307f5ae8SZachary Turner auto expected_info = pdb->getPDBInfoStream(); 150307f5ae8SZachary Turner if (!expected_info) { 151307f5ae8SZachary Turner llvm::consumeError(expected_info.takeError()); 152307f5ae8SZachary Turner return nullptr; 153307f5ae8SZachary Turner } 154307f5ae8SZachary Turner llvm::codeview::GUID guid; 155307f5ae8SZachary Turner memcpy(&guid, pdb_info->PDB70.Signature, 16); 156307f5ae8SZachary Turner 157307f5ae8SZachary Turner if (expected_info->getGuid() != guid) 158307f5ae8SZachary Turner return nullptr; 159307f5ae8SZachary Turner return pdb; 160307f5ae8SZachary Turner } 161307f5ae8SZachary Turner 162307f5ae8SZachary Turner static bool IsFunctionPrologue(const CompilandIndexItem &cci, 163307f5ae8SZachary Turner lldb::addr_t addr) { 164307f5ae8SZachary Turner // FIXME: Implement this. 165307f5ae8SZachary Turner return false; 166307f5ae8SZachary Turner } 167307f5ae8SZachary Turner 168307f5ae8SZachary Turner static bool IsFunctionEpilogue(const CompilandIndexItem &cci, 169307f5ae8SZachary Turner lldb::addr_t addr) { 170307f5ae8SZachary Turner // FIXME: Implement this. 171307f5ae8SZachary Turner return false; 172307f5ae8SZachary Turner } 173307f5ae8SZachary Turner 1742f7efbc9SZachary Turner static clang::MSInheritanceAttr::Spelling 1752f7efbc9SZachary Turner GetMSInheritance(LazyRandomTypeCollection &tpi, const ClassRecord &record) { 1762f7efbc9SZachary Turner if (record.DerivationList == TypeIndex::None()) 1772f7efbc9SZachary Turner return clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance; 1782f7efbc9SZachary Turner 1792f7efbc9SZachary Turner CVType bases = tpi.getType(record.DerivationList); 1802f7efbc9SZachary Turner ArgListRecord base_list; 1812f7efbc9SZachary Turner cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(bases, base_list)); 1822f7efbc9SZachary Turner if (base_list.ArgIndices.empty()) 1832f7efbc9SZachary Turner return clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance; 1842f7efbc9SZachary Turner 1852f7efbc9SZachary Turner int base_count = 0; 1862f7efbc9SZachary Turner for (TypeIndex ti : base_list.ArgIndices) { 1872f7efbc9SZachary Turner CVType base = tpi.getType(ti); 1882f7efbc9SZachary Turner if (base.kind() == LF_VBCLASS || base.kind() == LF_IVBCLASS) 1892f7efbc9SZachary Turner return clang::MSInheritanceAttr::Spelling::Keyword_virtual_inheritance; 1902f7efbc9SZachary Turner ++base_count; 1912f7efbc9SZachary Turner } 1922f7efbc9SZachary Turner 1932f7efbc9SZachary Turner if (base_count > 1) 1942f7efbc9SZachary Turner return clang::MSInheritanceAttr::Keyword_multiple_inheritance; 1952f7efbc9SZachary Turner return clang::MSInheritanceAttr::Keyword_single_inheritance; 1962f7efbc9SZachary Turner } 1972f7efbc9SZachary Turner 1982f7efbc9SZachary Turner static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) { 1992f7efbc9SZachary Turner switch (kind) { 2002f7efbc9SZachary Turner case SimpleTypeKind::Boolean128: 2012f7efbc9SZachary Turner case SimpleTypeKind::Boolean16: 2022f7efbc9SZachary Turner case SimpleTypeKind::Boolean32: 2032f7efbc9SZachary Turner case SimpleTypeKind::Boolean64: 2042f7efbc9SZachary Turner case SimpleTypeKind::Boolean8: 2052f7efbc9SZachary Turner return "bool"; 2062f7efbc9SZachary Turner case SimpleTypeKind::Byte: 2072f7efbc9SZachary Turner case SimpleTypeKind::UnsignedCharacter: 2082f7efbc9SZachary Turner return "unsigned char"; 2092f7efbc9SZachary Turner case SimpleTypeKind::NarrowCharacter: 2102f7efbc9SZachary Turner return "char"; 2112f7efbc9SZachary Turner case SimpleTypeKind::SignedCharacter: 2122f7efbc9SZachary Turner case SimpleTypeKind::SByte: 21371ebb721SZachary Turner return "signed char"; 2142f7efbc9SZachary Turner case SimpleTypeKind::Character16: 2152f7efbc9SZachary Turner return "char16_t"; 2162f7efbc9SZachary Turner case SimpleTypeKind::Character32: 2172f7efbc9SZachary Turner return "char32_t"; 2182f7efbc9SZachary Turner case SimpleTypeKind::Complex80: 2192f7efbc9SZachary Turner case SimpleTypeKind::Complex64: 2202f7efbc9SZachary Turner case SimpleTypeKind::Complex32: 2212f7efbc9SZachary Turner return "complex"; 2222f7efbc9SZachary Turner case SimpleTypeKind::Float128: 2232f7efbc9SZachary Turner case SimpleTypeKind::Float80: 2242f7efbc9SZachary Turner return "long double"; 2252f7efbc9SZachary Turner case SimpleTypeKind::Float64: 2262f7efbc9SZachary Turner return "double"; 2272f7efbc9SZachary Turner case SimpleTypeKind::Float32: 2282f7efbc9SZachary Turner return "float"; 2292f7efbc9SZachary Turner case SimpleTypeKind::Float16: 2302f7efbc9SZachary Turner return "single"; 2312f7efbc9SZachary Turner case SimpleTypeKind::Int128: 2322f7efbc9SZachary Turner return "__int128"; 2332f7efbc9SZachary Turner case SimpleTypeKind::Int64: 2342f7efbc9SZachary Turner case SimpleTypeKind::Int64Quad: 23571ebb721SZachary Turner return "int64_t"; 2362f7efbc9SZachary Turner case SimpleTypeKind::Int32: 2372f7efbc9SZachary Turner return "int"; 2382f7efbc9SZachary Turner case SimpleTypeKind::Int16: 2392f7efbc9SZachary Turner return "short"; 2402f7efbc9SZachary Turner case SimpleTypeKind::UInt128: 2412f7efbc9SZachary Turner return "unsigned __int128"; 2422f7efbc9SZachary Turner case SimpleTypeKind::UInt64: 2432f7efbc9SZachary Turner case SimpleTypeKind::UInt64Quad: 24471ebb721SZachary Turner return "uint64_t"; 2452f7efbc9SZachary Turner case SimpleTypeKind::HResult: 2462f7efbc9SZachary Turner return "HRESULT"; 2472f7efbc9SZachary Turner case SimpleTypeKind::UInt32: 2482f7efbc9SZachary Turner return "unsigned"; 2492f7efbc9SZachary Turner case SimpleTypeKind::UInt16: 2502f7efbc9SZachary Turner case SimpleTypeKind::UInt16Short: 2512f7efbc9SZachary Turner return "unsigned short"; 2522f7efbc9SZachary Turner case SimpleTypeKind::Int32Long: 2532f7efbc9SZachary Turner return "long"; 2542f7efbc9SZachary Turner case SimpleTypeKind::UInt32Long: 2552f7efbc9SZachary Turner return "unsigned long"; 2562f7efbc9SZachary Turner case SimpleTypeKind::Void: 2572f7efbc9SZachary Turner return "void"; 2582f7efbc9SZachary Turner case SimpleTypeKind::WideCharacter: 2592f7efbc9SZachary Turner return "wchar_t"; 2602f7efbc9SZachary Turner default: 2612f7efbc9SZachary Turner return ""; 2622f7efbc9SZachary Turner } 2632f7efbc9SZachary Turner } 2642f7efbc9SZachary Turner 2652f7efbc9SZachary Turner static bool IsClassRecord(TypeLeafKind kind) { 2662f7efbc9SZachary Turner switch (kind) { 2672f7efbc9SZachary Turner case LF_STRUCTURE: 2682f7efbc9SZachary Turner case LF_CLASS: 2692f7efbc9SZachary Turner case LF_INTERFACE: 2702f7efbc9SZachary Turner return true; 2712f7efbc9SZachary Turner default: 2722f7efbc9SZachary Turner return false; 2732f7efbc9SZachary Turner } 2742f7efbc9SZachary Turner } 2752f7efbc9SZachary Turner 276544a66d8SZachary Turner static bool IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args) { 277544a66d8SZachary Turner if (args.empty()) 278544a66d8SZachary Turner return false; 279544a66d8SZachary Turner return args.back() == TypeIndex::None(); 280544a66d8SZachary Turner } 281544a66d8SZachary Turner 2822f7efbc9SZachary Turner static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) { 2832f7efbc9SZachary Turner switch (cr.Kind) { 2842f7efbc9SZachary Turner case TypeRecordKind::Class: 2852f7efbc9SZachary Turner return clang::TTK_Class; 2862f7efbc9SZachary Turner case TypeRecordKind::Struct: 2872f7efbc9SZachary Turner return clang::TTK_Struct; 2882f7efbc9SZachary Turner case TypeRecordKind::Union: 2892f7efbc9SZachary Turner return clang::TTK_Union; 2902f7efbc9SZachary Turner case TypeRecordKind::Interface: 2912f7efbc9SZachary Turner return clang::TTK_Interface; 2922f7efbc9SZachary Turner case TypeRecordKind::Enum: 2932f7efbc9SZachary Turner return clang::TTK_Enum; 2942f7efbc9SZachary Turner default: 2952f7efbc9SZachary Turner lldbassert(false && "Invalid tag record kind!"); 2962f7efbc9SZachary Turner return clang::TTK_Struct; 2972f7efbc9SZachary Turner } 2982f7efbc9SZachary Turner } 2992f7efbc9SZachary Turner 300544a66d8SZachary Turner static llvm::Optional<clang::CallingConv> 301544a66d8SZachary Turner TranslateCallingConvention(llvm::codeview::CallingConvention conv) { 302544a66d8SZachary Turner using CC = llvm::codeview::CallingConvention; 303544a66d8SZachary Turner switch (conv) { 304544a66d8SZachary Turner 305544a66d8SZachary Turner case CC::NearC: 306544a66d8SZachary Turner case CC::FarC: 307544a66d8SZachary Turner return clang::CallingConv::CC_C; 308544a66d8SZachary Turner case CC::NearPascal: 309544a66d8SZachary Turner case CC::FarPascal: 310544a66d8SZachary Turner return clang::CallingConv::CC_X86Pascal; 311544a66d8SZachary Turner case CC::NearFast: 312544a66d8SZachary Turner case CC::FarFast: 313544a66d8SZachary Turner return clang::CallingConv::CC_X86FastCall; 314544a66d8SZachary Turner case CC::NearStdCall: 315544a66d8SZachary Turner case CC::FarStdCall: 316544a66d8SZachary Turner return clang::CallingConv::CC_X86StdCall; 317544a66d8SZachary Turner case CC::ThisCall: 318544a66d8SZachary Turner return clang::CallingConv::CC_X86ThisCall; 319544a66d8SZachary Turner case CC::NearVector: 320544a66d8SZachary Turner return clang::CallingConv::CC_X86VectorCall; 321544a66d8SZachary Turner default: 322544a66d8SZachary Turner return llvm::None; 323544a66d8SZachary Turner } 324544a66d8SZachary Turner } 325544a66d8SZachary Turner 326*d3d2b9b8SZachary Turner static Variable::RangeList 327*d3d2b9b8SZachary Turner MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, 328*d3d2b9b8SZachary Turner llvm::ArrayRef<LocalVariableAddrGap> gaps) { 329*d3d2b9b8SZachary Turner lldb::addr_t start = 330*d3d2b9b8SZachary Turner index.MakeVirtualAddress(range.ISectStart, range.OffsetStart); 331*d3d2b9b8SZachary Turner lldb::addr_t end = start + range.Range; 332*d3d2b9b8SZachary Turner 333*d3d2b9b8SZachary Turner Variable::RangeList result; 334*d3d2b9b8SZachary Turner while (!gaps.empty()) { 335*d3d2b9b8SZachary Turner const LocalVariableAddrGap &gap = gaps.front(); 336*d3d2b9b8SZachary Turner 337*d3d2b9b8SZachary Turner lldb::addr_t size = gap.GapStartOffset - start; 338*d3d2b9b8SZachary Turner result.Append(start, size); 339*d3d2b9b8SZachary Turner start += gap.Range; 340*d3d2b9b8SZachary Turner gaps = gaps.drop_front(); 341*d3d2b9b8SZachary Turner } 342*d3d2b9b8SZachary Turner 343*d3d2b9b8SZachary Turner result.Append(start, end); 344*d3d2b9b8SZachary Turner return result; 345*d3d2b9b8SZachary Turner } 346*d3d2b9b8SZachary Turner 347*d3d2b9b8SZachary Turner static VariableInfo GetVariableInformation(PdbIndex &index, 348*d3d2b9b8SZachary Turner PdbCompilandSymId var_id, 349*d3d2b9b8SZachary Turner ModuleSP module, 350*d3d2b9b8SZachary Turner bool get_location_info) { 351*d3d2b9b8SZachary Turner VariableInfo result; 352*d3d2b9b8SZachary Turner CVSymbol sym = index.ReadSymbolRecord(var_id); 353*d3d2b9b8SZachary Turner 354*d3d2b9b8SZachary Turner if (sym.kind() == S_REGREL32) { 355*d3d2b9b8SZachary Turner RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); 356*d3d2b9b8SZachary Turner cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg)); 357*d3d2b9b8SZachary Turner result.type = reg.Type; 358*d3d2b9b8SZachary Turner result.name = reg.Name; 359*d3d2b9b8SZachary Turner if (get_location_info) { 360*d3d2b9b8SZachary Turner result.location = 361*d3d2b9b8SZachary Turner MakeRegRelLocationExpression(reg.Register, reg.Offset, module); 362*d3d2b9b8SZachary Turner result.ranges.emplace(); 363*d3d2b9b8SZachary Turner } 364*d3d2b9b8SZachary Turner return result; 365*d3d2b9b8SZachary Turner } 366*d3d2b9b8SZachary Turner 367*d3d2b9b8SZachary Turner if (sym.kind() == S_REGISTER) { 368*d3d2b9b8SZachary Turner RegisterSym reg(SymbolRecordKind::RegisterSym); 369*d3d2b9b8SZachary Turner cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg)); 370*d3d2b9b8SZachary Turner result.type = reg.Index; 371*d3d2b9b8SZachary Turner result.name = reg.Name; 372*d3d2b9b8SZachary Turner if (get_location_info) { 373*d3d2b9b8SZachary Turner result.location = 374*d3d2b9b8SZachary Turner MakeEnregisteredLocationExpression(reg.Register, module); 375*d3d2b9b8SZachary Turner result.ranges.emplace(); 376*d3d2b9b8SZachary Turner } 377*d3d2b9b8SZachary Turner return result; 378*d3d2b9b8SZachary Turner } 379*d3d2b9b8SZachary Turner 380*d3d2b9b8SZachary Turner if (sym.kind() == S_LOCAL) { 381*d3d2b9b8SZachary Turner LocalSym local(SymbolRecordKind::LocalSym); 382*d3d2b9b8SZachary Turner cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); 383*d3d2b9b8SZachary Turner result.type = local.Type; 384*d3d2b9b8SZachary Turner result.name = local.Name; 385*d3d2b9b8SZachary Turner 386*d3d2b9b8SZachary Turner if (!get_location_info) 387*d3d2b9b8SZachary Turner return result; 388*d3d2b9b8SZachary Turner 389*d3d2b9b8SZachary Turner PdbCompilandSymId loc_specifier_id(var_id.modi, 390*d3d2b9b8SZachary Turner var_id.offset + sym.RecordData.size()); 391*d3d2b9b8SZachary Turner CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); 392*d3d2b9b8SZachary Turner if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) { 393*d3d2b9b8SZachary Turner DefRangeFramePointerRelSym loc( 394*d3d2b9b8SZachary Turner SymbolRecordKind::DefRangeFramePointerRelSym); 395*d3d2b9b8SZachary Turner cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>( 396*d3d2b9b8SZachary Turner loc_specifier_cvs, loc)); 397*d3d2b9b8SZachary Turner // FIXME: The register needs to come from the S_FRAMEPROC symbol. 398*d3d2b9b8SZachary Turner result.location = 399*d3d2b9b8SZachary Turner MakeRegRelLocationExpression(RegisterId::RSP, loc.Offset, module); 400*d3d2b9b8SZachary Turner result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); 401*d3d2b9b8SZachary Turner } else { 402*d3d2b9b8SZachary Turner // FIXME: Handle other kinds 403*d3d2b9b8SZachary Turner llvm::APSInt value; 404*d3d2b9b8SZachary Turner value = 42; 405*d3d2b9b8SZachary Turner result.location = MakeConstantLocationExpression( 406*d3d2b9b8SZachary Turner TypeIndex::Int32(), index.tpi(), value, module); 407*d3d2b9b8SZachary Turner } 408*d3d2b9b8SZachary Turner return result; 409*d3d2b9b8SZachary Turner } 410*d3d2b9b8SZachary Turner llvm_unreachable("Symbol is not a local variable!"); 411*d3d2b9b8SZachary Turner return result; 412*d3d2b9b8SZachary Turner } 413*d3d2b9b8SZachary Turner 414307f5ae8SZachary Turner void SymbolFileNativePDB::Initialize() { 415307f5ae8SZachary Turner PluginManager::RegisterPlugin(GetPluginNameStatic(), 416307f5ae8SZachary Turner GetPluginDescriptionStatic(), CreateInstance, 417307f5ae8SZachary Turner DebuggerInitialize); 418307f5ae8SZachary Turner } 419307f5ae8SZachary Turner 420307f5ae8SZachary Turner void SymbolFileNativePDB::Terminate() { 421307f5ae8SZachary Turner PluginManager::UnregisterPlugin(CreateInstance); 422307f5ae8SZachary Turner } 423307f5ae8SZachary Turner 424b96181c2SZachary Turner void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {} 425307f5ae8SZachary Turner 426b96181c2SZachary Turner ConstString SymbolFileNativePDB::GetPluginNameStatic() { 427307f5ae8SZachary Turner static ConstString g_name("native-pdb"); 428307f5ae8SZachary Turner return g_name; 429307f5ae8SZachary Turner } 430307f5ae8SZachary Turner 431307f5ae8SZachary Turner const char *SymbolFileNativePDB::GetPluginDescriptionStatic() { 432307f5ae8SZachary Turner return "Microsoft PDB debug symbol cross-platform file reader."; 433307f5ae8SZachary Turner } 434307f5ae8SZachary Turner 435b96181c2SZachary Turner SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFile *obj_file) { 436307f5ae8SZachary Turner return new SymbolFileNativePDB(obj_file); 437307f5ae8SZachary Turner } 438307f5ae8SZachary Turner 439b96181c2SZachary Turner SymbolFileNativePDB::SymbolFileNativePDB(ObjectFile *object_file) 440307f5ae8SZachary Turner : SymbolFile(object_file) {} 441307f5ae8SZachary Turner 442307f5ae8SZachary Turner SymbolFileNativePDB::~SymbolFileNativePDB() {} 443307f5ae8SZachary Turner 444307f5ae8SZachary Turner uint32_t SymbolFileNativePDB::CalculateAbilities() { 445307f5ae8SZachary Turner uint32_t abilities = 0; 446307f5ae8SZachary Turner if (!m_obj_file) 447307f5ae8SZachary Turner return 0; 448307f5ae8SZachary Turner 449307f5ae8SZachary Turner if (!m_index) { 450307f5ae8SZachary Turner // Lazily load and match the PDB file, but only do this once. 451307f5ae8SZachary Turner std::unique_ptr<PDBFile> file_up = 452307f5ae8SZachary Turner loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator); 453307f5ae8SZachary Turner 454307f5ae8SZachary Turner if (!file_up) { 455307f5ae8SZachary Turner auto module_sp = m_obj_file->GetModule(); 456307f5ae8SZachary Turner if (!module_sp) 457307f5ae8SZachary Turner return 0; 458307f5ae8SZachary Turner // See if any symbol file is specified through `--symfile` option. 459307f5ae8SZachary Turner FileSpec symfile = module_sp->GetSymbolFileFileSpec(); 460307f5ae8SZachary Turner if (!symfile) 461307f5ae8SZachary Turner return 0; 462307f5ae8SZachary Turner file_up = loadPDBFile(symfile.GetPath(), m_allocator); 463307f5ae8SZachary Turner } 464307f5ae8SZachary Turner 465307f5ae8SZachary Turner if (!file_up) 466307f5ae8SZachary Turner return 0; 467307f5ae8SZachary Turner 468307f5ae8SZachary Turner auto expected_index = PdbIndex::create(std::move(file_up)); 469307f5ae8SZachary Turner if (!expected_index) { 470307f5ae8SZachary Turner llvm::consumeError(expected_index.takeError()); 471307f5ae8SZachary Turner return 0; 472307f5ae8SZachary Turner } 473307f5ae8SZachary Turner m_index = std::move(*expected_index); 474307f5ae8SZachary Turner } 475307f5ae8SZachary Turner if (!m_index) 476307f5ae8SZachary Turner return 0; 477307f5ae8SZachary Turner 478307f5ae8SZachary Turner // We don't especially have to be precise here. We only distinguish between 479307f5ae8SZachary Turner // stripped and not stripped. 480307f5ae8SZachary Turner abilities = kAllAbilities; 481307f5ae8SZachary Turner 482307f5ae8SZachary Turner if (m_index->dbi().isStripped()) 483307f5ae8SZachary Turner abilities &= ~(Blocks | LocalVariables); 484307f5ae8SZachary Turner return abilities; 485307f5ae8SZachary Turner } 486307f5ae8SZachary Turner 487307f5ae8SZachary Turner void SymbolFileNativePDB::InitializeObject() { 488307f5ae8SZachary Turner m_obj_load_address = m_obj_file->GetFileOffset(); 489307f5ae8SZachary Turner m_index->SetLoadAddress(m_obj_load_address); 490307f5ae8SZachary Turner m_index->ParseSectionContribs(); 4912f7efbc9SZachary Turner 4922f7efbc9SZachary Turner TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); 4932f7efbc9SZachary Turner m_clang = llvm::dyn_cast_or_null<ClangASTContext>(ts); 4942f7efbc9SZachary Turner m_importer = llvm::make_unique<ClangASTImporter>(); 495056e4ab4SZachary Turner 496056e4ab4SZachary Turner PreprocessTpiStream(); 4972f7efbc9SZachary Turner lldbassert(m_clang); 498307f5ae8SZachary Turner } 499307f5ae8SZachary Turner 50003a24052SZachary Turner static llvm::Optional<CVTagRecord> 50103a24052SZachary Turner GetNestedTagRecord(const NestedTypeRecord &Record, const CVTagRecord &parent, 50203a24052SZachary Turner TpiStream &tpi) { 50303a24052SZachary Turner // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it 50403a24052SZachary Turner // is also used to indicate the primary definition of a nested class. That is 50503a24052SZachary Turner // to say, if you have: 50603a24052SZachary Turner // struct A { 50703a24052SZachary Turner // struct B {}; 50803a24052SZachary Turner // using C = B; 50903a24052SZachary Turner // }; 51003a24052SZachary Turner // Then in the debug info, this will appear as: 51103a24052SZachary Turner // LF_STRUCTURE `A::B` [type index = N] 51203a24052SZachary Turner // LF_STRUCTURE `A` 51303a24052SZachary Turner // LF_NESTTYPE [name = `B`, index = N] 51403a24052SZachary Turner // LF_NESTTYPE [name = `C`, index = N] 51503a24052SZachary Turner // In order to accurately reconstruct the decl context hierarchy, we need to 51603a24052SZachary Turner // know which ones are actual definitions and which ones are just aliases. 51703a24052SZachary Turner 51803a24052SZachary Turner // If it's a simple type, then this is something like `using foo = int`. 51903a24052SZachary Turner if (Record.Type.isSimple()) 52003a24052SZachary Turner return llvm::None; 52103a24052SZachary Turner 5222af34166SZachary Turner CVType cvt = tpi.getType(Record.Type); 5232af34166SZachary Turner 5242af34166SZachary Turner if (!IsTagRecord(cvt)) 5252af34166SZachary Turner return llvm::None; 5262af34166SZachary Turner 52703a24052SZachary Turner // If it's an inner definition, then treat whatever name we have here as a 52803a24052SZachary Turner // single component of a mangled name. So we can inject it into the parent's 52903a24052SZachary Turner // mangled name to see if it matches. 5302af34166SZachary Turner CVTagRecord child = CVTagRecord::create(cvt); 53103a24052SZachary Turner std::string qname = parent.asTag().getUniqueName(); 53203a24052SZachary Turner if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4) 53303a24052SZachary Turner return llvm::None; 53403a24052SZachary Turner 53503a24052SZachary Turner // qname[3] is the tag type identifier (struct, class, union, etc). Since the 53603a24052SZachary Turner // inner tag type is not necessarily the same as the outer tag type, re-write 53703a24052SZachary Turner // it to match the inner tag type. 53803a24052SZachary Turner qname[3] = child.asTag().getUniqueName()[3]; 53903a24052SZachary Turner std::string piece = Record.Name; 54003a24052SZachary Turner piece.push_back('@'); 54103a24052SZachary Turner qname.insert(4, std::move(piece)); 54203a24052SZachary Turner if (qname != child.asTag().UniqueName) 54303a24052SZachary Turner return llvm::None; 54403a24052SZachary Turner 54503a24052SZachary Turner return std::move(child); 54603a24052SZachary Turner } 54703a24052SZachary Turner 548056e4ab4SZachary Turner void SymbolFileNativePDB::PreprocessTpiStream() { 549056e4ab4SZachary Turner LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); 550056e4ab4SZachary Turner 551056e4ab4SZachary Turner for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { 552056e4ab4SZachary Turner CVType type = types.getType(*ti); 553056e4ab4SZachary Turner if (!IsTagRecord(type)) 554056e4ab4SZachary Turner continue; 555056e4ab4SZachary Turner 556056e4ab4SZachary Turner CVTagRecord tag = CVTagRecord::create(type); 557056e4ab4SZachary Turner // We're looking for LF_NESTTYPE records in the field list, so ignore 558056e4ab4SZachary Turner // forward references (no field list), and anything without a nested class 559056e4ab4SZachary Turner // (since there won't be any LF_NESTTYPE records). 560056e4ab4SZachary Turner if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass()) 561056e4ab4SZachary Turner continue; 562056e4ab4SZachary Turner 563056e4ab4SZachary Turner struct ProcessTpiStream : public TypeVisitorCallbacks { 564056e4ab4SZachary Turner ProcessTpiStream(PdbIndex &index, TypeIndex parent, 56503a24052SZachary Turner const CVTagRecord &parent_cvt, 566056e4ab4SZachary Turner llvm::DenseMap<TypeIndex, TypeIndex> &parents) 56703a24052SZachary Turner : index(index), parents(parents), parent(parent), 56803a24052SZachary Turner parent_cvt(parent_cvt) {} 569056e4ab4SZachary Turner 570056e4ab4SZachary Turner PdbIndex &index; 571056e4ab4SZachary Turner llvm::DenseMap<TypeIndex, TypeIndex> &parents; 572056e4ab4SZachary Turner TypeIndex parent; 57303a24052SZachary Turner const CVTagRecord &parent_cvt; 574056e4ab4SZachary Turner 575056e4ab4SZachary Turner llvm::Error visitKnownMember(CVMemberRecord &CVR, 576056e4ab4SZachary Turner NestedTypeRecord &Record) override { 57703a24052SZachary Turner llvm::Optional<CVTagRecord> tag = 57803a24052SZachary Turner GetNestedTagRecord(Record, parent_cvt, index.tpi()); 57903a24052SZachary Turner if (!tag) 580056e4ab4SZachary Turner return llvm::ErrorSuccess(); 58103a24052SZachary Turner 58203a24052SZachary Turner parents[Record.Type] = parent; 58303a24052SZachary Turner if (!tag->asTag().isForwardRef()) 58403a24052SZachary Turner return llvm::ErrorSuccess(); 58503a24052SZachary Turner 586056e4ab4SZachary Turner llvm::Expected<TypeIndex> full_decl = 587056e4ab4SZachary Turner index.tpi().findFullDeclForForwardRef(Record.Type); 588056e4ab4SZachary Turner if (!full_decl) { 589056e4ab4SZachary Turner llvm::consumeError(full_decl.takeError()); 590056e4ab4SZachary Turner return llvm::ErrorSuccess(); 591056e4ab4SZachary Turner } 592056e4ab4SZachary Turner parents[*full_decl] = parent; 593056e4ab4SZachary Turner return llvm::ErrorSuccess(); 594056e4ab4SZachary Turner } 595056e4ab4SZachary Turner }; 596056e4ab4SZachary Turner 597056e4ab4SZachary Turner CVType field_list = m_index->tpi().getType(tag.asTag().FieldList); 59803a24052SZachary Turner ProcessTpiStream process(*m_index, *ti, tag, m_parent_types); 599056e4ab4SZachary Turner llvm::Error error = visitMemberRecordStream(field_list.data(), process); 600056e4ab4SZachary Turner if (error) 601056e4ab4SZachary Turner llvm::consumeError(std::move(error)); 602056e4ab4SZachary Turner } 603056e4ab4SZachary Turner } 604056e4ab4SZachary Turner 605307f5ae8SZachary Turner uint32_t SymbolFileNativePDB::GetNumCompileUnits() { 606307f5ae8SZachary Turner const DbiModuleList &modules = m_index->dbi().modules(); 607307f5ae8SZachary Turner uint32_t count = modules.getModuleCount(); 608307f5ae8SZachary Turner if (count == 0) 609307f5ae8SZachary Turner return count; 610307f5ae8SZachary Turner 611307f5ae8SZachary Turner // The linker can inject an additional "dummy" compilation unit into the 612307f5ae8SZachary Turner // PDB. Ignore this special compile unit for our purposes, if it is there. 613307f5ae8SZachary Turner // It is always the last one. 614307f5ae8SZachary Turner DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1); 615307f5ae8SZachary Turner if (last.getModuleName() == "* Linker *") 616307f5ae8SZachary Turner --count; 617307f5ae8SZachary Turner return count; 618307f5ae8SZachary Turner } 619307f5ae8SZachary Turner 620*d3d2b9b8SZachary Turner Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { 621*d3d2b9b8SZachary Turner CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 622*d3d2b9b8SZachary Turner CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 623*d3d2b9b8SZachary Turner clang::DeclContext *parent_decl_ctx = m_clang->GetTranslationUnitDecl(); 624*d3d2b9b8SZachary Turner 625*d3d2b9b8SZachary Turner if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) { 626*d3d2b9b8SZachary Turner // This is a function. It must be global. Creating the Function entry for 627*d3d2b9b8SZachary Turner // it automatically creates a block for it. 628*d3d2b9b8SZachary Turner CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); 629*d3d2b9b8SZachary Turner return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false); 630*d3d2b9b8SZachary Turner } 631*d3d2b9b8SZachary Turner 632*d3d2b9b8SZachary Turner lldbassert(sym.kind() == S_BLOCK32); 633*d3d2b9b8SZachary Turner 634*d3d2b9b8SZachary Turner // This is a block. Its parent is either a function or another block. In 635*d3d2b9b8SZachary Turner // either case, its parent can be viewed as a block (e.g. a function contains 636*d3d2b9b8SZachary Turner // 1 big block. So just get the parent block and add this block to it. 637*d3d2b9b8SZachary Turner BlockSym block(static_cast<SymbolRecordKind>(sym.kind())); 638*d3d2b9b8SZachary Turner cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block)); 639*d3d2b9b8SZachary Turner lldbassert(block.Parent != 0); 640*d3d2b9b8SZachary Turner PdbCompilandSymId parent_id(block_id.modi, block.Parent); 641*d3d2b9b8SZachary Turner Block &parent_block = GetOrCreateBlock(parent_id); 642*d3d2b9b8SZachary Turner 643*d3d2b9b8SZachary Turner lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id); 644*d3d2b9b8SZachary Turner BlockSP child_block = std::make_shared<Block>(opaque_block_uid); 645*d3d2b9b8SZachary Turner parent_block.AddChild(child_block); 646*d3d2b9b8SZachary Turner CompilerDeclContext cdc = GetDeclContextForUID(parent_block.GetID()); 647*d3d2b9b8SZachary Turner parent_decl_ctx = 648*d3d2b9b8SZachary Turner static_cast<clang::DeclContext *>(cdc.GetOpaqueDeclContext()); 649*d3d2b9b8SZachary Turner clang::BlockDecl *block_decl = 650*d3d2b9b8SZachary Turner m_clang->CreateBlockDeclaration(parent_decl_ctx); 651*d3d2b9b8SZachary Turner 652*d3d2b9b8SZachary Turner m_blocks.insert({opaque_block_uid, child_block}); 653*d3d2b9b8SZachary Turner m_uid_to_decl.insert({opaque_block_uid, block_decl}); 654*d3d2b9b8SZachary Turner return *child_block; 655*d3d2b9b8SZachary Turner } 656*d3d2b9b8SZachary Turner 6576284aee9SZachary Turner lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, 658*d3d2b9b8SZachary Turner CompileUnit &comp_unit) { 6596284aee9SZachary Turner const CompilandIndexItem *cci = 6606284aee9SZachary Turner m_index->compilands().GetCompiland(func_id.modi); 661307f5ae8SZachary Turner lldbassert(cci); 6626284aee9SZachary Turner CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset); 663307f5ae8SZachary Turner 664307f5ae8SZachary Turner lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); 665307f5ae8SZachary Turner SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); 666307f5ae8SZachary Turner 667307f5ae8SZachary Turner auto file_vm_addr = m_index->MakeVirtualAddress(sol.so); 668307f5ae8SZachary Turner if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 669307f5ae8SZachary Turner return nullptr; 670307f5ae8SZachary Turner 671307f5ae8SZachary Turner AddressRange func_range(file_vm_addr, sol.length, 672*d3d2b9b8SZachary Turner comp_unit.GetModule()->GetSectionList()); 673307f5ae8SZachary Turner if (!func_range.GetBaseAddress().IsValid()) 674307f5ae8SZachary Turner return nullptr; 675307f5ae8SZachary Turner 676a42bbe39SZachary Turner ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind())); 677a42bbe39SZachary Turner cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)); 678a42bbe39SZachary Turner TypeSP func_type = GetOrCreateType(proc.FunctionType); 679307f5ae8SZachary Turner 680a42bbe39SZachary Turner PdbTypeSymId sig_id(proc.FunctionType, false); 681a42bbe39SZachary Turner Mangled mangled(proc.Name); 682307f5ae8SZachary Turner FunctionSP func_sp = std::make_shared<Function>( 683*d3d2b9b8SZachary Turner &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled, 684a42bbe39SZachary Turner func_type.get(), func_range); 685307f5ae8SZachary Turner 686*d3d2b9b8SZachary Turner comp_unit.AddFunction(func_sp); 687*d3d2b9b8SZachary Turner 688*d3d2b9b8SZachary Turner user_id_t opaque_func_uid = toOpaqueUid(func_id); 689a42bbe39SZachary Turner 690a42bbe39SZachary Turner clang::StorageClass storage = clang::SC_None; 691a42bbe39SZachary Turner if (sym_record.kind() == S_LPROC32) 692a42bbe39SZachary Turner storage = clang::SC_Static; 693a42bbe39SZachary Turner 694*d3d2b9b8SZachary Turner // The function signature only tells us the number of types of arguments, but 695*d3d2b9b8SZachary Turner // not the names. So we need to iterate the symbol stream looking for the 696*d3d2b9b8SZachary Turner // corresponding symbol records to properly construct the AST. 697a42bbe39SZachary Turner CVType sig_cvt; 698a42bbe39SZachary Turner ProcedureRecord sig_record; 699a42bbe39SZachary Turner 700a42bbe39SZachary Turner sig_cvt = m_index->tpi().getType(proc.FunctionType); 701a42bbe39SZachary Turner if (sig_cvt.kind() != LF_PROCEDURE) 702a42bbe39SZachary Turner return func_sp; 703a42bbe39SZachary Turner cantFail( 704a42bbe39SZachary Turner TypeDeserializer::deserializeAs<ProcedureRecord>(sig_cvt, sig_record)); 705a42bbe39SZachary Turner 706*d3d2b9b8SZachary Turner CompilerDeclContext context = GetDeclContextContainingUID(opaque_func_uid); 707a42bbe39SZachary Turner 708a42bbe39SZachary Turner clang::DeclContext *decl_context = 709a42bbe39SZachary Turner static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext()); 710a42bbe39SZachary Turner clang::FunctionDecl *function_decl = m_clang->CreateFunctionDeclaration( 711a42bbe39SZachary Turner decl_context, proc.Name.str().c_str(), 712a42bbe39SZachary Turner func_type->GetForwardCompilerType(), storage, false); 713a42bbe39SZachary Turner 714*d3d2b9b8SZachary Turner lldbassert(m_uid_to_decl.count(opaque_func_uid) == 0); 715*d3d2b9b8SZachary Turner m_uid_to_decl[opaque_func_uid] = function_decl; 716*d3d2b9b8SZachary Turner 717a42bbe39SZachary Turner CVSymbolArray scope = limitSymbolArrayToScope( 718a42bbe39SZachary Turner cci->m_debug_stream.getSymbolArray(), func_id.offset); 719a42bbe39SZachary Turner 720a42bbe39SZachary Turner uint32_t params_remaining = sig_record.getParameterCount(); 721a42bbe39SZachary Turner auto begin = scope.begin(); 722a42bbe39SZachary Turner auto end = scope.end(); 723a42bbe39SZachary Turner std::vector<clang::ParmVarDecl *> params; 724a42bbe39SZachary Turner while (begin != end && params_remaining > 0) { 725*d3d2b9b8SZachary Turner CVSymbol sym = *begin; 726a42bbe39SZachary Turner switch (sym.kind()) { 727*d3d2b9b8SZachary Turner case S_REGREL32: 728*d3d2b9b8SZachary Turner case S_REGISTER: 729*d3d2b9b8SZachary Turner case S_LOCAL: 730a42bbe39SZachary Turner break; 731a42bbe39SZachary Turner case S_BLOCK32: 732a42bbe39SZachary Turner params_remaining = 0; 733a42bbe39SZachary Turner continue; 734a42bbe39SZachary Turner default: 735*d3d2b9b8SZachary Turner ++begin; 736a42bbe39SZachary Turner continue; 737a42bbe39SZachary Turner } 738*d3d2b9b8SZachary Turner PdbCompilandSymId param_uid(func_id.modi, begin.offset()); 739*d3d2b9b8SZachary Turner VariableInfo var_info = GetVariableInformation( 740*d3d2b9b8SZachary Turner *m_index, param_uid, GetObjectFile()->GetModule(), false); 741a42bbe39SZachary Turner 742*d3d2b9b8SZachary Turner TypeSP type_sp = GetOrCreateType(var_info.type); 743a42bbe39SZachary Turner clang::ParmVarDecl *param = m_clang->CreateParameterDeclaration( 744*d3d2b9b8SZachary Turner function_decl, var_info.name.str().c_str(), 7456753d2d1SZachary Turner type_sp->GetForwardCompilerType(), clang::SC_None); 746a42bbe39SZachary Turner lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); 747a42bbe39SZachary Turner 748a42bbe39SZachary Turner m_uid_to_decl[toOpaqueUid(param_uid)] = param; 749a42bbe39SZachary Turner params.push_back(param); 750a42bbe39SZachary Turner --params_remaining; 751*d3d2b9b8SZachary Turner ++begin; 752a42bbe39SZachary Turner } 753a42bbe39SZachary Turner if (!params.empty()) 754a42bbe39SZachary Turner m_clang->SetFunctionParameters(function_decl, params.data(), params.size()); 755a42bbe39SZachary Turner 756307f5ae8SZachary Turner return func_sp; 757307f5ae8SZachary Turner } 758307f5ae8SZachary Turner 759307f5ae8SZachary Turner CompUnitSP 760307f5ae8SZachary Turner SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { 761307f5ae8SZachary Turner lldb::LanguageType lang = 762307f5ae8SZachary Turner cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage()) 763307f5ae8SZachary Turner : lldb::eLanguageTypeUnknown; 764307f5ae8SZachary Turner 765307f5ae8SZachary Turner LazyBool optimized = eLazyBoolNo; 766307f5ae8SZachary Turner if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations()) 767307f5ae8SZachary Turner optimized = eLazyBoolYes; 768307f5ae8SZachary Turner 769307f5ae8SZachary Turner llvm::StringRef source_file_name = 770307f5ae8SZachary Turner m_index->compilands().GetMainSourceFile(cci); 7718f3be7a3SJonas Devlieghere FileSpec fs(source_file_name); 772307f5ae8SZachary Turner 773307f5ae8SZachary Turner CompUnitSP cu_sp = 774307f5ae8SZachary Turner std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, fs, 7756284aee9SZachary Turner toOpaqueUid(cci.m_id), lang, optimized); 776307f5ae8SZachary Turner 7776284aee9SZachary Turner m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( 7786284aee9SZachary Turner cci.m_id.modi, cu_sp); 779307f5ae8SZachary Turner return cu_sp; 780307f5ae8SZachary Turner } 781307f5ae8SZachary Turner 7826284aee9SZachary Turner lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, 7832f7efbc9SZachary Turner const ModifierRecord &mr) { 7842f7efbc9SZachary Turner TpiStream &stream = m_index->tpi(); 7852f7efbc9SZachary Turner 7862f7efbc9SZachary Turner TypeSP t = GetOrCreateType(mr.ModifiedType); 7872f7efbc9SZachary Turner CompilerType ct = t->GetForwardCompilerType(); 7882f7efbc9SZachary Turner if ((mr.Modifiers & ModifierOptions::Const) != ModifierOptions::None) 7892f7efbc9SZachary Turner ct = ct.AddConstModifier(); 7902f7efbc9SZachary Turner if ((mr.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None) 7912f7efbc9SZachary Turner ct = ct.AddVolatileModifier(); 7922f7efbc9SZachary Turner std::string name; 7932f7efbc9SZachary Turner if (mr.ModifiedType.isSimple()) 7942f7efbc9SZachary Turner name = GetSimpleTypeName(mr.ModifiedType.getSimpleKind()); 7952f7efbc9SZachary Turner else 7962f7efbc9SZachary Turner name = computeTypeName(stream.typeCollection(), mr.ModifiedType); 7972f7efbc9SZachary Turner Declaration decl; 7986284aee9SZachary Turner return std::make_shared<Type>(toOpaqueUid(type_id), m_clang->GetSymbolFile(), 7992f7efbc9SZachary Turner ConstString(name), t->GetByteSize(), nullptr, 8002f7efbc9SZachary Turner LLDB_INVALID_UID, Type::eEncodingIsUID, decl, 8012f7efbc9SZachary Turner ct, Type::eResolveStateFull); 8022f7efbc9SZachary Turner } 8032f7efbc9SZachary Turner 8042f7efbc9SZachary Turner lldb::TypeSP SymbolFileNativePDB::CreatePointerType( 8056284aee9SZachary Turner PdbTypeSymId type_id, const llvm::codeview::PointerRecord &pr) { 8062f7efbc9SZachary Turner TypeSP pointee = GetOrCreateType(pr.ReferentType); 807544a66d8SZachary Turner if (!pointee) 808544a66d8SZachary Turner return nullptr; 8092f7efbc9SZachary Turner CompilerType pointee_ct = pointee->GetForwardCompilerType(); 8102f7efbc9SZachary Turner lldbassert(pointee_ct); 8112f7efbc9SZachary Turner Declaration decl; 8122f7efbc9SZachary Turner 8132f7efbc9SZachary Turner if (pr.isPointerToMember()) { 8142f7efbc9SZachary Turner MemberPointerInfo mpi = pr.getMemberInfo(); 8152f7efbc9SZachary Turner TypeSP class_type = GetOrCreateType(mpi.ContainingType); 8162f7efbc9SZachary Turner 8172f7efbc9SZachary Turner CompilerType ct = ClangASTContext::CreateMemberPointerType( 8182f7efbc9SZachary Turner class_type->GetLayoutCompilerType(), pointee_ct); 8192f7efbc9SZachary Turner 8202f7efbc9SZachary Turner return std::make_shared<Type>( 8216284aee9SZachary Turner toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(), 8222f7efbc9SZachary Turner pr.getSize(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, 8232f7efbc9SZachary Turner Type::eResolveStateFull); 8242f7efbc9SZachary Turner } 8252f7efbc9SZachary Turner 8262f7efbc9SZachary Turner CompilerType pointer_ct = pointee_ct; 8272f7efbc9SZachary Turner if (pr.getMode() == PointerMode::LValueReference) 8282f7efbc9SZachary Turner pointer_ct = pointer_ct.GetLValueReferenceType(); 8292f7efbc9SZachary Turner else if (pr.getMode() == PointerMode::RValueReference) 8302f7efbc9SZachary Turner pointer_ct = pointer_ct.GetRValueReferenceType(); 8312f7efbc9SZachary Turner else 8322f7efbc9SZachary Turner pointer_ct = pointer_ct.GetPointerType(); 8332f7efbc9SZachary Turner 8342f7efbc9SZachary Turner if ((pr.getOptions() & PointerOptions::Const) != PointerOptions::None) 8352f7efbc9SZachary Turner pointer_ct = pointer_ct.AddConstModifier(); 8362f7efbc9SZachary Turner 8372f7efbc9SZachary Turner if ((pr.getOptions() & PointerOptions::Volatile) != PointerOptions::None) 8382f7efbc9SZachary Turner pointer_ct = pointer_ct.AddVolatileModifier(); 8392f7efbc9SZachary Turner 8402f7efbc9SZachary Turner if ((pr.getOptions() & PointerOptions::Restrict) != PointerOptions::None) 8412f7efbc9SZachary Turner pointer_ct = pointer_ct.AddRestrictModifier(); 8422f7efbc9SZachary Turner 8436284aee9SZachary Turner return std::make_shared<Type>(toOpaqueUid(type_id), m_clang->GetSymbolFile(), 8442f7efbc9SZachary Turner ConstString(), pr.getSize(), nullptr, 8452f7efbc9SZachary Turner LLDB_INVALID_UID, Type::eEncodingIsUID, decl, 8462f7efbc9SZachary Turner pointer_ct, Type::eResolveStateFull); 8472f7efbc9SZachary Turner } 8482f7efbc9SZachary Turner 8492f7efbc9SZachary Turner lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti) { 8509fbf9350SZachary Turner uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false)); 851544a66d8SZachary Turner if (ti == TypeIndex::NullptrT()) { 852544a66d8SZachary Turner CompilerType ct = m_clang->GetBasicType(eBasicTypeNullPtr); 853544a66d8SZachary Turner Declaration decl; 8546284aee9SZachary Turner return std::make_shared<Type>( 8556284aee9SZachary Turner uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID, 8566284aee9SZachary Turner Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull); 857544a66d8SZachary Turner } 858544a66d8SZachary Turner 8592f7efbc9SZachary Turner if (ti.getSimpleMode() != SimpleTypeMode::Direct) { 8602f7efbc9SZachary Turner TypeSP direct_sp = GetOrCreateType(ti.makeDirect()); 8612f7efbc9SZachary Turner CompilerType ct = direct_sp->GetFullCompilerType(); 8622f7efbc9SZachary Turner ct = ct.GetPointerType(); 86371ebb721SZachary Turner uint32_t pointer_size = 0; 8642f7efbc9SZachary Turner switch (ti.getSimpleMode()) { 8652f7efbc9SZachary Turner case SimpleTypeMode::FarPointer32: 8662f7efbc9SZachary Turner case SimpleTypeMode::NearPointer32: 8672f7efbc9SZachary Turner pointer_size = 4; 8682f7efbc9SZachary Turner break; 8692f7efbc9SZachary Turner case SimpleTypeMode::NearPointer64: 8702f7efbc9SZachary Turner pointer_size = 8; 8712f7efbc9SZachary Turner break; 8722f7efbc9SZachary Turner default: 8732f7efbc9SZachary Turner // 128-bit and 16-bit pointers unsupported. 8742f7efbc9SZachary Turner return nullptr; 8752f7efbc9SZachary Turner } 8762f7efbc9SZachary Turner Declaration decl; 8776284aee9SZachary Turner return std::make_shared<Type>(uid, m_clang->GetSymbolFile(), ConstString(), 8786284aee9SZachary Turner pointer_size, nullptr, LLDB_INVALID_UID, 8796284aee9SZachary Turner Type::eEncodingIsUID, decl, ct, 8806284aee9SZachary Turner Type::eResolveStateFull); 8812f7efbc9SZachary Turner } 8822f7efbc9SZachary Turner 8832f7efbc9SZachary Turner if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) 8842f7efbc9SZachary Turner return nullptr; 8852f7efbc9SZachary Turner 8862f7efbc9SZachary Turner lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind()); 887544a66d8SZachary Turner if (bt == lldb::eBasicTypeInvalid) 888544a66d8SZachary Turner return nullptr; 8892f7efbc9SZachary Turner CompilerType ct = m_clang->GetBasicType(bt); 8902f7efbc9SZachary Turner size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind()); 8912f7efbc9SZachary Turner 8922f7efbc9SZachary Turner llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind()); 8932f7efbc9SZachary Turner 8942f7efbc9SZachary Turner Declaration decl; 8956284aee9SZachary Turner return std::make_shared<Type>(uid, m_clang->GetSymbolFile(), 8962f7efbc9SZachary Turner ConstString(type_name), size, nullptr, 8972f7efbc9SZachary Turner LLDB_INVALID_UID, Type::eEncodingIsUID, decl, 8982f7efbc9SZachary Turner ct, Type::eResolveStateFull); 8992f7efbc9SZachary Turner } 9002f7efbc9SZachary Turner 901056e4ab4SZachary Turner static std::string RenderDemanglerNode(llvm::ms_demangle::Node *n) { 902056e4ab4SZachary Turner OutputStream OS; 903056e4ab4SZachary Turner initializeOutputStream(nullptr, nullptr, OS, 1024); 904056e4ab4SZachary Turner n->output(OS, llvm::ms_demangle::OF_Default); 905056e4ab4SZachary Turner OS << '\0'; 906056e4ab4SZachary Turner return {OS.getBuffer()}; 907056e4ab4SZachary Turner } 908056e4ab4SZachary Turner 90903a24052SZachary Turner static bool 91003a24052SZachary Turner AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) { 91103a24052SZachary Turner for (llvm::ms_demangle::Node *n : scopes) { 91203a24052SZachary Turner auto *idn = static_cast<llvm::ms_demangle::IdentifierNode *>(n); 91303a24052SZachary Turner if (idn->TemplateParams) 91403a24052SZachary Turner return true; 91503a24052SZachary Turner } 91603a24052SZachary Turner return false; 91703a24052SZachary Turner } 91803a24052SZachary Turner 919056e4ab4SZachary Turner std::pair<clang::DeclContext *, std::string> 920056e4ab4SZachary Turner SymbolFileNativePDB::CreateDeclInfoForType(const TagRecord &record, 921056e4ab4SZachary Turner TypeIndex ti) { 922a42bbe39SZachary Turner // FIXME: Move this to GetDeclContextContainingUID. 923a42bbe39SZachary Turner 924056e4ab4SZachary Turner llvm::ms_demangle::Demangler demangler; 925056e4ab4SZachary Turner StringView sv(record.UniqueName.begin(), record.UniqueName.size()); 926056e4ab4SZachary Turner llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); 927056e4ab4SZachary Turner llvm::ms_demangle::IdentifierNode *idn = 928056e4ab4SZachary Turner ttn->QualifiedName->getUnqualifiedIdentifier(); 929056e4ab4SZachary Turner std::string uname = RenderDemanglerNode(idn); 930056e4ab4SZachary Turner 931056e4ab4SZachary Turner llvm::ms_demangle::NodeArrayNode *name_components = 932056e4ab4SZachary Turner ttn->QualifiedName->Components; 933056e4ab4SZachary Turner llvm::ArrayRef<llvm::ms_demangle::Node *> scopes(name_components->Nodes, 934056e4ab4SZachary Turner name_components->Count - 1); 935056e4ab4SZachary Turner 936056e4ab4SZachary Turner clang::DeclContext *context = m_clang->GetTranslationUnitDecl(); 937056e4ab4SZachary Turner 938056e4ab4SZachary Turner // If this type doesn't have a parent type in the debug info, then the best we 939056e4ab4SZachary Turner // can do is to say that it's either a series of namespaces (if the scope is 940056e4ab4SZachary Turner // non-empty), or the translation unit (if the scope is empty). 941056e4ab4SZachary Turner auto parent_iter = m_parent_types.find(ti); 942056e4ab4SZachary Turner if (parent_iter == m_parent_types.end()) { 943056e4ab4SZachary Turner if (scopes.empty()) 944056e4ab4SZachary Turner return {context, uname}; 945056e4ab4SZachary Turner 94603a24052SZachary Turner // If there is no parent in the debug info, but some of the scopes have 94703a24052SZachary Turner // template params, then this is a case of bad debug info. See, for 94803a24052SZachary Turner // example, llvm.org/pr39607. We don't want to create an ambiguity between 94903a24052SZachary Turner // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at 95003a24052SZachary Turner // global scope with the fully qualified name. 95103a24052SZachary Turner if (AnyScopesHaveTemplateParams(scopes)) 95203a24052SZachary Turner return {context, record.Name}; 95303a24052SZachary Turner 954056e4ab4SZachary Turner for (llvm::ms_demangle::Node *scope : scopes) { 955056e4ab4SZachary Turner auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope); 956056e4ab4SZachary Turner std::string str = RenderDemanglerNode(nii); 957056e4ab4SZachary Turner context = m_clang->GetUniqueNamespaceDeclaration(str.c_str(), context); 958056e4ab4SZachary Turner } 959056e4ab4SZachary Turner return {context, uname}; 960056e4ab4SZachary Turner } 961056e4ab4SZachary Turner 962056e4ab4SZachary Turner // Otherwise, all we need to do is get the parent type of this type and 963056e4ab4SZachary Turner // recurse into our lazy type creation / AST reconstruction logic to get an 964056e4ab4SZachary Turner // LLDB TypeSP for the parent. This will cause the AST to automatically get 965056e4ab4SZachary Turner // the right DeclContext created for any parent. 966056e4ab4SZachary Turner TypeSP parent = GetOrCreateType(parent_iter->second); 967056e4ab4SZachary Turner if (!parent) 968056e4ab4SZachary Turner return {context, uname}; 969056e4ab4SZachary Turner CompilerType parent_ct = parent->GetForwardCompilerType(); 970056e4ab4SZachary Turner clang::QualType qt = ClangUtil::GetCanonicalQualType(parent_ct); 971056e4ab4SZachary Turner context = clang::TagDecl::castToDeclContext(qt->getAsTagDecl()); 972056e4ab4SZachary Turner return {context, uname}; 973056e4ab4SZachary Turner } 974056e4ab4SZachary Turner 9752f7efbc9SZachary Turner lldb::TypeSP SymbolFileNativePDB::CreateClassStructUnion( 9766284aee9SZachary Turner PdbTypeSymId type_id, const llvm::codeview::TagRecord &record, size_t size, 9772f7efbc9SZachary Turner clang::TagTypeKind ttk, clang::MSInheritanceAttr::Spelling inheritance) { 9782f7efbc9SZachary Turner 979056e4ab4SZachary Turner clang::DeclContext *decl_context = nullptr; 980056e4ab4SZachary Turner std::string uname; 9816284aee9SZachary Turner std::tie(decl_context, uname) = CreateDeclInfoForType(record, type_id.index); 9822f7efbc9SZachary Turner 9832f7efbc9SZachary Turner lldb::AccessType access = 9842f7efbc9SZachary Turner (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic; 9852f7efbc9SZachary Turner 9862f7efbc9SZachary Turner ClangASTMetadata metadata; 9876284aee9SZachary Turner metadata.SetUserID(toOpaqueUid(type_id)); 9882f7efbc9SZachary Turner metadata.SetIsDynamicCXXType(false); 9892f7efbc9SZachary Turner 9902f7efbc9SZachary Turner CompilerType ct = 991056e4ab4SZachary Turner m_clang->CreateRecordType(decl_context, access, uname.c_str(), ttk, 9922f7efbc9SZachary Turner lldb::eLanguageTypeC_plus_plus, &metadata); 993056e4ab4SZachary Turner 9942f7efbc9SZachary Turner lldbassert(ct.IsValid()); 9952f7efbc9SZachary Turner 9962f7efbc9SZachary Turner clang::CXXRecordDecl *record_decl = 9972f7efbc9SZachary Turner m_clang->GetAsCXXRecordDecl(ct.GetOpaqueQualType()); 9982f7efbc9SZachary Turner lldbassert(record_decl); 9992f7efbc9SZachary Turner 10002f7efbc9SZachary Turner clang::MSInheritanceAttr *attr = clang::MSInheritanceAttr::CreateImplicit( 10012f7efbc9SZachary Turner *m_clang->getASTContext(), inheritance); 10022f7efbc9SZachary Turner record_decl->addAttr(attr); 10032f7efbc9SZachary Turner 10042f7efbc9SZachary Turner ClangASTContext::StartTagDeclarationDefinition(ct); 10052f7efbc9SZachary Turner 10062f7efbc9SZachary Turner // Even if it's possible, don't complete it at this point. Just mark it 10072f7efbc9SZachary Turner // forward resolved, and if/when LLDB needs the full definition, it can 10082f7efbc9SZachary Turner // ask us. 10092f7efbc9SZachary Turner ClangASTContext::SetHasExternalStorage(ct.GetOpaqueQualType(), true); 10102f7efbc9SZachary Turner 10112f7efbc9SZachary Turner // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE. 10122f7efbc9SZachary Turner Declaration decl; 10136284aee9SZachary Turner return std::make_shared<Type>(toOpaqueUid(type_id), m_clang->GetSymbolFile(), 1014056e4ab4SZachary Turner ConstString(uname), size, nullptr, 10152f7efbc9SZachary Turner LLDB_INVALID_UID, Type::eEncodingIsUID, decl, 10162f7efbc9SZachary Turner ct, Type::eResolveStateForward); 10172f7efbc9SZachary Turner } 10182f7efbc9SZachary Turner 10196284aee9SZachary Turner lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 10202f7efbc9SZachary Turner const ClassRecord &cr) { 10212f7efbc9SZachary Turner clang::TagTypeKind ttk = TranslateUdtKind(cr); 10222f7efbc9SZachary Turner 10232f7efbc9SZachary Turner clang::MSInheritanceAttr::Spelling inheritance = 10242f7efbc9SZachary Turner GetMSInheritance(m_index->tpi().typeCollection(), cr); 10256284aee9SZachary Turner return CreateClassStructUnion(type_id, cr, cr.getSize(), ttk, inheritance); 10262f7efbc9SZachary Turner } 10272f7efbc9SZachary Turner 10286284aee9SZachary Turner lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 10292f7efbc9SZachary Turner const UnionRecord &ur) { 10302f7efbc9SZachary Turner return CreateClassStructUnion( 10316284aee9SZachary Turner type_id, ur, ur.getSize(), clang::TTK_Union, 10322f7efbc9SZachary Turner clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance); 10332f7efbc9SZachary Turner } 10342f7efbc9SZachary Turner 10356284aee9SZachary Turner lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 10362f7efbc9SZachary Turner const EnumRecord &er) { 10372af34166SZachary Turner clang::DeclContext *decl_context = nullptr; 10382af34166SZachary Turner std::string uname; 10396284aee9SZachary Turner std::tie(decl_context, uname) = CreateDeclInfoForType(er, type_id.index); 10402f7efbc9SZachary Turner 10412f7efbc9SZachary Turner Declaration decl; 10422f7efbc9SZachary Turner TypeSP underlying_type = GetOrCreateType(er.UnderlyingType); 10432f7efbc9SZachary Turner CompilerType enum_ct = m_clang->CreateEnumerationType( 10442af34166SZachary Turner uname.c_str(), decl_context, decl, underlying_type->GetFullCompilerType(), 10452af34166SZachary Turner er.isScoped()); 10462f7efbc9SZachary Turner 10472f7efbc9SZachary Turner ClangASTContext::StartTagDeclarationDefinition(enum_ct); 104812abab57SZachary Turner ClangASTContext::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); 10492f7efbc9SZachary Turner 10502f7efbc9SZachary Turner // We're just going to forward resolve this for now. We'll complete 10512f7efbc9SZachary Turner // it only if the user requests. 10522f7efbc9SZachary Turner return std::make_shared<lldb_private::Type>( 10536284aee9SZachary Turner toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(uname), 10542f7efbc9SZachary Turner underlying_type->GetByteSize(), nullptr, LLDB_INVALID_UID, 10552f7efbc9SZachary Turner lldb_private::Type::eEncodingIsUID, decl, enum_ct, 10562f7efbc9SZachary Turner lldb_private::Type::eResolveStateForward); 10572f7efbc9SZachary Turner } 10582f7efbc9SZachary Turner 10596284aee9SZachary Turner TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id, 1060511bff21SZachary Turner const ArrayRecord &ar) { 1061511bff21SZachary Turner TypeSP element_type = GetOrCreateType(ar.ElementType); 1062511bff21SZachary Turner uint64_t element_count = ar.Size / element_type->GetByteSize(); 1063511bff21SZachary Turner 1064511bff21SZachary Turner CompilerType element_ct = element_type->GetFullCompilerType(); 1065511bff21SZachary Turner 1066511bff21SZachary Turner CompilerType array_ct = 1067511bff21SZachary Turner m_clang->CreateArrayType(element_ct, element_count, false); 1068511bff21SZachary Turner 1069511bff21SZachary Turner Declaration decl; 1070511bff21SZachary Turner TypeSP array_sp = std::make_shared<lldb_private::Type>( 10716284aee9SZachary Turner toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(), ar.Size, 1072511bff21SZachary Turner nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 1073511bff21SZachary Turner array_ct, lldb_private::Type::eResolveStateFull); 1074511bff21SZachary Turner array_sp->SetEncodingType(element_type.get()); 1075511bff21SZachary Turner return array_sp; 1076511bff21SZachary Turner } 1077511bff21SZachary Turner 10786284aee9SZachary Turner TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, 1079544a66d8SZachary Turner const ProcedureRecord &pr) { 1080544a66d8SZachary Turner TpiStream &stream = m_index->tpi(); 1081544a66d8SZachary Turner CVType args_cvt = stream.getType(pr.ArgumentList); 1082544a66d8SZachary Turner ArgListRecord args; 1083544a66d8SZachary Turner llvm::cantFail( 1084544a66d8SZachary Turner TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args)); 1085544a66d8SZachary Turner 1086544a66d8SZachary Turner llvm::ArrayRef<TypeIndex> arg_indices = llvm::makeArrayRef(args.ArgIndices); 1087544a66d8SZachary Turner bool is_variadic = IsCVarArgsFunction(arg_indices); 1088544a66d8SZachary Turner if (is_variadic) 1089544a66d8SZachary Turner arg_indices = arg_indices.drop_back(); 1090544a66d8SZachary Turner 1091544a66d8SZachary Turner std::vector<CompilerType> arg_list; 1092544a66d8SZachary Turner arg_list.reserve(arg_list.size()); 1093544a66d8SZachary Turner 1094544a66d8SZachary Turner for (TypeIndex arg_index : arg_indices) { 1095544a66d8SZachary Turner TypeSP arg_sp = GetOrCreateType(arg_index); 1096544a66d8SZachary Turner if (!arg_sp) 1097544a66d8SZachary Turner return nullptr; 1098544a66d8SZachary Turner arg_list.push_back(arg_sp->GetFullCompilerType()); 1099544a66d8SZachary Turner } 1100544a66d8SZachary Turner 1101544a66d8SZachary Turner TypeSP return_type_sp = GetOrCreateType(pr.ReturnType); 1102544a66d8SZachary Turner if (!return_type_sp) 1103544a66d8SZachary Turner return nullptr; 1104544a66d8SZachary Turner 1105544a66d8SZachary Turner llvm::Optional<clang::CallingConv> cc = 1106544a66d8SZachary Turner TranslateCallingConvention(pr.CallConv); 1107544a66d8SZachary Turner if (!cc) 1108544a66d8SZachary Turner return nullptr; 1109544a66d8SZachary Turner 1110544a66d8SZachary Turner CompilerType return_ct = return_type_sp->GetFullCompilerType(); 1111544a66d8SZachary Turner CompilerType func_sig_ast_type = m_clang->CreateFunctionType( 1112544a66d8SZachary Turner return_ct, arg_list.data(), arg_list.size(), is_variadic, 0, *cc); 1113544a66d8SZachary Turner 1114544a66d8SZachary Turner Declaration decl; 1115544a66d8SZachary Turner return std::make_shared<lldb_private::Type>( 11166284aee9SZachary Turner toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, 1117544a66d8SZachary Turner lldb_private::Type::eEncodingIsUID, decl, func_sig_ast_type, 1118544a66d8SZachary Turner lldb_private::Type::eResolveStateFull); 1119544a66d8SZachary Turner } 1120544a66d8SZachary Turner 11216284aee9SZachary Turner TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id) { 11226284aee9SZachary Turner if (type_id.index.isSimple()) 11236284aee9SZachary Turner return CreateSimpleType(type_id.index); 11242f7efbc9SZachary Turner 11256284aee9SZachary Turner TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi(); 11266284aee9SZachary Turner CVType cvt = stream.getType(type_id.index); 11272f7efbc9SZachary Turner 11282f7efbc9SZachary Turner if (cvt.kind() == LF_MODIFIER) { 11292f7efbc9SZachary Turner ModifierRecord modifier; 11302f7efbc9SZachary Turner llvm::cantFail( 11312f7efbc9SZachary Turner TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)); 11326284aee9SZachary Turner return CreateModifierType(type_id, modifier); 11332f7efbc9SZachary Turner } 11342f7efbc9SZachary Turner 11352f7efbc9SZachary Turner if (cvt.kind() == LF_POINTER) { 11362f7efbc9SZachary Turner PointerRecord pointer; 11372f7efbc9SZachary Turner llvm::cantFail( 11382f7efbc9SZachary Turner TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)); 11396284aee9SZachary Turner return CreatePointerType(type_id, pointer); 11402f7efbc9SZachary Turner } 11412f7efbc9SZachary Turner 11422f7efbc9SZachary Turner if (IsClassRecord(cvt.kind())) { 11432f7efbc9SZachary Turner ClassRecord cr; 11442f7efbc9SZachary Turner llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 11456284aee9SZachary Turner return CreateTagType(type_id, cr); 11462f7efbc9SZachary Turner } 11472f7efbc9SZachary Turner 11482f7efbc9SZachary Turner if (cvt.kind() == LF_ENUM) { 11492f7efbc9SZachary Turner EnumRecord er; 11502f7efbc9SZachary Turner llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 11516284aee9SZachary Turner return CreateTagType(type_id, er); 11522f7efbc9SZachary Turner } 11532f7efbc9SZachary Turner 11542f7efbc9SZachary Turner if (cvt.kind() == LF_UNION) { 11552f7efbc9SZachary Turner UnionRecord ur; 11562f7efbc9SZachary Turner llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 11576284aee9SZachary Turner return CreateTagType(type_id, ur); 11582f7efbc9SZachary Turner } 11592f7efbc9SZachary Turner 1160511bff21SZachary Turner if (cvt.kind() == LF_ARRAY) { 1161511bff21SZachary Turner ArrayRecord ar; 1162511bff21SZachary Turner llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)); 11636284aee9SZachary Turner return CreateArrayType(type_id, ar); 1164511bff21SZachary Turner } 1165511bff21SZachary Turner 1166544a66d8SZachary Turner if (cvt.kind() == LF_PROCEDURE) { 1167544a66d8SZachary Turner ProcedureRecord pr; 1168544a66d8SZachary Turner llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)); 11696284aee9SZachary Turner return CreateProcedureType(type_id, pr); 1170544a66d8SZachary Turner } 1171544a66d8SZachary Turner 11722f7efbc9SZachary Turner return nullptr; 11732f7efbc9SZachary Turner } 11742f7efbc9SZachary Turner 11756284aee9SZachary Turner TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { 11762f7efbc9SZachary Turner // If they search for a UDT which is a forward ref, try and resolve the full 11772f7efbc9SZachary Turner // decl and just map the forward ref uid to the full decl record. 11786284aee9SZachary Turner llvm::Optional<PdbTypeSymId> full_decl_uid; 11796284aee9SZachary Turner if (IsForwardRefUdt(type_id, m_index->tpi())) { 11806284aee9SZachary Turner auto expected_full_ti = 11816284aee9SZachary Turner m_index->tpi().findFullDeclForForwardRef(type_id.index); 11822f7efbc9SZachary Turner if (!expected_full_ti) 11832f7efbc9SZachary Turner llvm::consumeError(expected_full_ti.takeError()); 11846284aee9SZachary Turner else if (*expected_full_ti != type_id.index) { 11859fbf9350SZachary Turner full_decl_uid = PdbTypeSymId(*expected_full_ti, false); 11862f7efbc9SZachary Turner 11872f7efbc9SZachary Turner // It's possible that a lookup would occur for the full decl causing it 11882f7efbc9SZachary Turner // to be cached, then a second lookup would occur for the forward decl. 11892f7efbc9SZachary Turner // We don't want to create a second full decl, so make sure the full 11902f7efbc9SZachary Turner // decl hasn't already been cached. 11916284aee9SZachary Turner auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid)); 11922f7efbc9SZachary Turner if (full_iter != m_types.end()) { 11932f7efbc9SZachary Turner TypeSP result = full_iter->second; 11942f7efbc9SZachary Turner // Map the forward decl to the TypeSP for the full decl so we can take 11952f7efbc9SZachary Turner // the fast path next time. 11966284aee9SZachary Turner m_types[toOpaqueUid(type_id)] = result; 11972f7efbc9SZachary Turner return result; 11982f7efbc9SZachary Turner } 11992f7efbc9SZachary Turner } 12002f7efbc9SZachary Turner } 12012f7efbc9SZachary Turner 12026284aee9SZachary Turner PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; 12036284aee9SZachary Turner TypeSP result = CreateType(best_decl_id); 1204544a66d8SZachary Turner if (!result) 1205544a66d8SZachary Turner return nullptr; 12066284aee9SZachary Turner 12076284aee9SZachary Turner uint64_t best_uid = toOpaqueUid(best_decl_id); 12086284aee9SZachary Turner m_types[best_uid] = result; 12092f7efbc9SZachary Turner // If we had both a forward decl and a full decl, make both point to the new 12102f7efbc9SZachary Turner // type. 12112f7efbc9SZachary Turner if (full_decl_uid) 12126284aee9SZachary Turner m_types[toOpaqueUid(type_id)] = result; 12132f7efbc9SZachary Turner 12146284aee9SZachary Turner if (IsTagRecord(best_decl_id, m_index->tpi())) { 12152f7efbc9SZachary Turner clang::TagDecl *record_decl = 12162f7efbc9SZachary Turner m_clang->GetAsTagDecl(result->GetForwardCompilerType()); 12172f7efbc9SZachary Turner lldbassert(record_decl); 12182f7efbc9SZachary Turner 12196284aee9SZachary Turner m_uid_to_decl[best_uid] = record_decl; 12202f7efbc9SZachary Turner m_decl_to_status[record_decl] = 12216284aee9SZachary Turner DeclStatus(best_uid, Type::eResolveStateForward); 12222f7efbc9SZachary Turner } 12232f7efbc9SZachary Turner return result; 12242f7efbc9SZachary Turner } 12252f7efbc9SZachary Turner 12266284aee9SZachary Turner TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) { 12272f7efbc9SZachary Turner // We can't use try_emplace / overwrite here because the process of creating 12282f7efbc9SZachary Turner // a type could create nested types, which could invalidate iterators. So 12292f7efbc9SZachary Turner // we have to do a 2-phase lookup / insert. 12306284aee9SZachary Turner auto iter = m_types.find(toOpaqueUid(type_id)); 12312f7efbc9SZachary Turner if (iter != m_types.end()) 12322f7efbc9SZachary Turner return iter->second; 12332f7efbc9SZachary Turner 12346284aee9SZachary Turner return CreateAndCacheType(type_id); 12352f7efbc9SZachary Turner } 12362f7efbc9SZachary Turner 12376284aee9SZachary Turner VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { 12386284aee9SZachary Turner CVSymbol sym = m_index->symrecords().readRecord(var_id.offset); 12392af34166SZachary Turner if (sym.kind() == S_CONSTANT) 12406284aee9SZachary Turner return CreateConstantSymbol(var_id, sym); 12412af34166SZachary Turner 12429f727950SZachary Turner lldb::ValueType scope = eValueTypeInvalid; 12439f727950SZachary Turner TypeIndex ti; 12449f727950SZachary Turner llvm::StringRef name; 12459f727950SZachary Turner lldb::addr_t addr = 0; 12469f727950SZachary Turner uint16_t section = 0; 12479f727950SZachary Turner uint32_t offset = 0; 12489f727950SZachary Turner bool is_external = false; 12499f727950SZachary Turner switch (sym.kind()) { 12509f727950SZachary Turner case S_GDATA32: 12519f727950SZachary Turner is_external = true; 12529f727950SZachary Turner LLVM_FALLTHROUGH; 12539f727950SZachary Turner case S_LDATA32: { 12549f727950SZachary Turner DataSym ds(sym.kind()); 12559f727950SZachary Turner llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds)); 12569f727950SZachary Turner ti = ds.Type; 12579f727950SZachary Turner scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal 12589f727950SZachary Turner : eValueTypeVariableStatic; 12599f727950SZachary Turner name = ds.Name; 12609f727950SZachary Turner section = ds.Segment; 12619f727950SZachary Turner offset = ds.DataOffset; 12629f727950SZachary Turner addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset); 12639f727950SZachary Turner break; 12649f727950SZachary Turner } 12659f727950SZachary Turner case S_GTHREAD32: 12669f727950SZachary Turner is_external = true; 12679f727950SZachary Turner LLVM_FALLTHROUGH; 12689f727950SZachary Turner case S_LTHREAD32: { 12699f727950SZachary Turner ThreadLocalDataSym tlds(sym.kind()); 12709f727950SZachary Turner llvm::cantFail( 12719f727950SZachary Turner SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)); 12729f727950SZachary Turner ti = tlds.Type; 12739f727950SZachary Turner name = tlds.Name; 12749f727950SZachary Turner section = tlds.Segment; 12759f727950SZachary Turner offset = tlds.DataOffset; 12769f727950SZachary Turner addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset); 12779f727950SZachary Turner scope = eValueTypeVariableThreadLocal; 12789f727950SZachary Turner break; 12799f727950SZachary Turner } 12809f727950SZachary Turner default: 12819f727950SZachary Turner llvm_unreachable("unreachable!"); 12829f727950SZachary Turner } 12839f727950SZachary Turner 12849f727950SZachary Turner CompUnitSP comp_unit; 12859f727950SZachary Turner llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr); 12869f727950SZachary Turner if (modi) { 12876284aee9SZachary Turner CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); 12889f727950SZachary Turner comp_unit = GetOrCreateCompileUnit(cci); 12899f727950SZachary Turner } 12909f727950SZachary Turner 12919f727950SZachary Turner Declaration decl; 12929fbf9350SZachary Turner PdbTypeSymId tid(ti, false); 12939f727950SZachary Turner SymbolFileTypeSP type_sp = 12946284aee9SZachary Turner std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 12959f727950SZachary Turner Variable::RangeList ranges; 12969f727950SZachary Turner 12979f727950SZachary Turner DWARFExpression location = MakeGlobalLocationExpression( 12989f727950SZachary Turner section, offset, GetObjectFile()->GetModule()); 12999f727950SZachary Turner 13009f727950SZachary Turner std::string global_name("::"); 13019f727950SZachary Turner global_name += name; 13029f727950SZachary Turner VariableSP var_sp = std::make_shared<Variable>( 13036284aee9SZachary Turner toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, 13049f727950SZachary Turner scope, comp_unit.get(), ranges, &decl, location, is_external, false, 13059f727950SZachary Turner false); 13069f727950SZachary Turner var_sp->SetLocationIsConstantValueData(false); 13079f727950SZachary Turner 13089f727950SZachary Turner return var_sp; 13099f727950SZachary Turner } 13109f727950SZachary Turner 13112af34166SZachary Turner lldb::VariableSP 13126284aee9SZachary Turner SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, 13132af34166SZachary Turner const CVSymbol &cvs) { 13142af34166SZachary Turner TpiStream &tpi = m_index->tpi(); 13152af34166SZachary Turner ConstantSym constant(cvs.kind()); 13162af34166SZachary Turner 13172af34166SZachary Turner llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)); 13182af34166SZachary Turner std::string global_name("::"); 13192af34166SZachary Turner global_name += constant.Name; 13209fbf9350SZachary Turner PdbTypeSymId tid(constant.Type, false); 13212af34166SZachary Turner SymbolFileTypeSP type_sp = 13226284aee9SZachary Turner std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 13232af34166SZachary Turner 13242af34166SZachary Turner Declaration decl; 13252af34166SZachary Turner Variable::RangeList ranges; 13262af34166SZachary Turner ModuleSP module = GetObjectFile()->GetModule(); 1327a93458b0SZachary Turner DWARFExpression location = MakeConstantLocationExpression( 1328a93458b0SZachary Turner constant.Type, tpi, constant.Value, module); 13292af34166SZachary Turner 13302af34166SZachary Turner VariableSP var_sp = std::make_shared<Variable>( 13316284aee9SZachary Turner toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), 13322af34166SZachary Turner type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, 13332af34166SZachary Turner false, false, false); 13342af34166SZachary Turner var_sp->SetLocationIsConstantValueData(true); 13352af34166SZachary Turner return var_sp; 13362af34166SZachary Turner } 13372af34166SZachary Turner 13386284aee9SZachary Turner VariableSP 13396284aee9SZachary Turner SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { 13406284aee9SZachary Turner auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); 13419f727950SZachary Turner if (emplace_result.second) 13426284aee9SZachary Turner emplace_result.first->second = CreateGlobalVariable(var_id); 13439f727950SZachary Turner 13449f727950SZachary Turner return emplace_result.first->second; 13459f727950SZachary Turner } 13469f727950SZachary Turner 13476284aee9SZachary Turner lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) { 13489fbf9350SZachary Turner return GetOrCreateType(PdbTypeSymId(ti, false)); 13492f7efbc9SZachary Turner } 13502f7efbc9SZachary Turner 13516284aee9SZachary Turner FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id, 1352*d3d2b9b8SZachary Turner CompileUnit &comp_unit) { 13536284aee9SZachary Turner auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr); 1354307f5ae8SZachary Turner if (emplace_result.second) 1355*d3d2b9b8SZachary Turner emplace_result.first->second = CreateFunction(func_id, comp_unit); 1356307f5ae8SZachary Turner 1357307f5ae8SZachary Turner lldbassert(emplace_result.first->second); 1358307f5ae8SZachary Turner return emplace_result.first->second; 1359307f5ae8SZachary Turner } 1360307f5ae8SZachary Turner 1361307f5ae8SZachary Turner CompUnitSP 1362307f5ae8SZachary Turner SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) { 13636284aee9SZachary Turner 1364307f5ae8SZachary Turner auto emplace_result = 13656284aee9SZachary Turner m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr); 1366307f5ae8SZachary Turner if (emplace_result.second) 1367307f5ae8SZachary Turner emplace_result.first->second = CreateCompileUnit(cci); 1368307f5ae8SZachary Turner 1369307f5ae8SZachary Turner lldbassert(emplace_result.first->second); 1370307f5ae8SZachary Turner return emplace_result.first->second; 1371307f5ae8SZachary Turner } 1372307f5ae8SZachary Turner 1373*d3d2b9b8SZachary Turner Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) { 1374*d3d2b9b8SZachary Turner auto iter = m_blocks.find(toOpaqueUid(block_id)); 1375*d3d2b9b8SZachary Turner if (iter != m_blocks.end()) 1376*d3d2b9b8SZachary Turner return *iter->second; 1377*d3d2b9b8SZachary Turner 1378*d3d2b9b8SZachary Turner return CreateBlock(block_id); 1379*d3d2b9b8SZachary Turner } 1380*d3d2b9b8SZachary Turner 1381307f5ae8SZachary Turner lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) { 1382307f5ae8SZachary Turner if (index >= GetNumCompileUnits()) 1383307f5ae8SZachary Turner return CompUnitSP(); 1384307f5ae8SZachary Turner lldbassert(index < UINT16_MAX); 1385307f5ae8SZachary Turner if (index >= UINT16_MAX) 1386307f5ae8SZachary Turner return nullptr; 1387307f5ae8SZachary Turner 1388307f5ae8SZachary Turner CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index); 1389307f5ae8SZachary Turner 1390307f5ae8SZachary Turner return GetOrCreateCompileUnit(item); 1391307f5ae8SZachary Turner } 1392307f5ae8SZachary Turner 1393b96181c2SZachary Turner lldb::LanguageType 1394b96181c2SZachary Turner SymbolFileNativePDB::ParseCompileUnitLanguage(const SymbolContext &sc) { 1395307f5ae8SZachary Turner // What fields should I expect to be filled out on the SymbolContext? Is it 1396307f5ae8SZachary Turner // safe to assume that `sc.comp_unit` is valid? 1397307f5ae8SZachary Turner if (!sc.comp_unit) 1398307f5ae8SZachary Turner return lldb::eLanguageTypeUnknown; 13996284aee9SZachary Turner PdbSymUid uid(sc.comp_unit->GetID()); 14006284aee9SZachary Turner lldbassert(uid.kind() == PdbSymUidKind::Compiland); 1401307f5ae8SZachary Turner 14026284aee9SZachary Turner CompilandIndexItem *item = 14036284aee9SZachary Turner m_index->compilands().GetCompiland(uid.asCompiland().modi); 1404307f5ae8SZachary Turner lldbassert(item); 1405307f5ae8SZachary Turner if (!item->m_compile_opts) 1406307f5ae8SZachary Turner return lldb::eLanguageTypeUnknown; 1407307f5ae8SZachary Turner 1408307f5ae8SZachary Turner return TranslateLanguage(item->m_compile_opts->getLanguage()); 1409307f5ae8SZachary Turner } 1410307f5ae8SZachary Turner 1411b96181c2SZachary Turner size_t SymbolFileNativePDB::ParseCompileUnitFunctions(const SymbolContext &sc) { 1412307f5ae8SZachary Turner lldbassert(sc.comp_unit); 1413307f5ae8SZachary Turner return false; 1414307f5ae8SZachary Turner } 1415307f5ae8SZachary Turner 1416307f5ae8SZachary Turner static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) { 1417307f5ae8SZachary Turner // If any of these flags are set, we need to resolve the compile unit. 1418307f5ae8SZachary Turner uint32_t flags = eSymbolContextCompUnit; 1419307f5ae8SZachary Turner flags |= eSymbolContextVariable; 1420307f5ae8SZachary Turner flags |= eSymbolContextFunction; 1421307f5ae8SZachary Turner flags |= eSymbolContextBlock; 1422307f5ae8SZachary Turner flags |= eSymbolContextLineEntry; 1423307f5ae8SZachary Turner return (resolve_scope & flags) != 0; 1424307f5ae8SZachary Turner } 1425307f5ae8SZachary Turner 1426991e4453SZachary Turner uint32_t SymbolFileNativePDB::ResolveSymbolContext( 1427991e4453SZachary Turner const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) { 1428307f5ae8SZachary Turner uint32_t resolved_flags = 0; 1429307f5ae8SZachary Turner lldb::addr_t file_addr = addr.GetFileAddress(); 1430307f5ae8SZachary Turner 1431307f5ae8SZachary Turner if (NeedsResolvedCompileUnit(resolve_scope)) { 1432307f5ae8SZachary Turner llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr); 1433307f5ae8SZachary Turner if (!modi) 1434307f5ae8SZachary Turner return 0; 14356284aee9SZachary Turner CompilandIndexItem *cci = m_index->compilands().GetCompiland(*modi); 1436307f5ae8SZachary Turner if (!cci) 1437307f5ae8SZachary Turner return 0; 1438307f5ae8SZachary Turner 1439307f5ae8SZachary Turner sc.comp_unit = GetOrCreateCompileUnit(*cci).get(); 1440307f5ae8SZachary Turner resolved_flags |= eSymbolContextCompUnit; 1441307f5ae8SZachary Turner } 1442307f5ae8SZachary Turner 1443*d3d2b9b8SZachary Turner if (resolve_scope & eSymbolContextFunction || 1444*d3d2b9b8SZachary Turner resolve_scope & eSymbolContextBlock) { 1445307f5ae8SZachary Turner lldbassert(sc.comp_unit); 1446307f5ae8SZachary Turner std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr); 1447*d3d2b9b8SZachary Turner // Search the matches in reverse. This way if there are multiple matches 1448*d3d2b9b8SZachary Turner // (for example we are 3 levels deep in a nested scope) it will find the 1449*d3d2b9b8SZachary Turner // innermost one first. 1450*d3d2b9b8SZachary Turner for (const auto &match : llvm::reverse(matches)) { 14516284aee9SZachary Turner if (match.uid.kind() != PdbSymUidKind::CompilandSym) 1452307f5ae8SZachary Turner continue; 1453*d3d2b9b8SZachary Turner 14546284aee9SZachary Turner PdbCompilandSymId csid = match.uid.asCompilandSym(); 14556284aee9SZachary Turner CVSymbol cvs = m_index->ReadSymbolRecord(csid); 1456*d3d2b9b8SZachary Turner PDB_SymType type = CVSymToPDBSym(cvs.kind()); 1457*d3d2b9b8SZachary Turner if (type != PDB_SymType::Function && type != PDB_SymType::Block) 14586284aee9SZachary Turner continue; 1459*d3d2b9b8SZachary Turner if (type == PDB_SymType::Function) { 1460*d3d2b9b8SZachary Turner sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get(); 1461*d3d2b9b8SZachary Turner sc.block = sc.GetFunctionBlock(); 1462*d3d2b9b8SZachary Turner } 1463*d3d2b9b8SZachary Turner 1464*d3d2b9b8SZachary Turner if (type == PDB_SymType::Block) { 1465*d3d2b9b8SZachary Turner sc.block = &GetOrCreateBlock(csid); 1466*d3d2b9b8SZachary Turner sc.function = sc.block->CalculateSymbolContextFunction(); 1467307f5ae8SZachary Turner } 1468307f5ae8SZachary Turner resolved_flags |= eSymbolContextFunction; 1469*d3d2b9b8SZachary Turner resolved_flags |= eSymbolContextBlock; 1470*d3d2b9b8SZachary Turner break; 1471*d3d2b9b8SZachary Turner } 1472307f5ae8SZachary Turner } 1473307f5ae8SZachary Turner 1474307f5ae8SZachary Turner if (resolve_scope & eSymbolContextLineEntry) { 1475307f5ae8SZachary Turner lldbassert(sc.comp_unit); 1476307f5ae8SZachary Turner if (auto *line_table = sc.comp_unit->GetLineTable()) { 1477307f5ae8SZachary Turner if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) 1478307f5ae8SZachary Turner resolved_flags |= eSymbolContextLineEntry; 1479307f5ae8SZachary Turner } 1480307f5ae8SZachary Turner } 1481307f5ae8SZachary Turner 1482307f5ae8SZachary Turner return resolved_flags; 1483307f5ae8SZachary Turner } 1484307f5ae8SZachary Turner 1485307f5ae8SZachary Turner static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence, 1486307f5ae8SZachary Turner const CompilandIndexItem &cci, 1487307f5ae8SZachary Turner lldb::addr_t base_addr, 1488307f5ae8SZachary Turner uint32_t file_number, 1489307f5ae8SZachary Turner const LineFragmentHeader &block, 1490307f5ae8SZachary Turner const LineNumberEntry &cur) { 1491307f5ae8SZachary Turner LineInfo cur_info(cur.Flags); 1492307f5ae8SZachary Turner 1493307f5ae8SZachary Turner if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) 1494307f5ae8SZachary Turner return; 1495307f5ae8SZachary Turner 1496307f5ae8SZachary Turner uint64_t addr = base_addr + cur.Offset; 1497307f5ae8SZachary Turner 1498307f5ae8SZachary Turner bool is_statement = cur_info.isStatement(); 1499307f5ae8SZachary Turner bool is_prologue = IsFunctionPrologue(cci, addr); 1500307f5ae8SZachary Turner bool is_epilogue = IsFunctionEpilogue(cci, addr); 1501307f5ae8SZachary Turner 1502307f5ae8SZachary Turner uint32_t lno = cur_info.getStartLine(); 1503307f5ae8SZachary Turner 1504307f5ae8SZachary Turner table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number, 1505307f5ae8SZachary Turner is_statement, false, is_prologue, is_epilogue, 1506307f5ae8SZachary Turner false); 1507307f5ae8SZachary Turner } 1508307f5ae8SZachary Turner 1509307f5ae8SZachary Turner static void TerminateLineSequence(LineTable &table, 1510307f5ae8SZachary Turner const LineFragmentHeader &block, 1511307f5ae8SZachary Turner lldb::addr_t base_addr, uint32_t file_number, 1512307f5ae8SZachary Turner uint32_t last_line, 1513307f5ae8SZachary Turner std::unique_ptr<LineSequence> seq) { 1514307f5ae8SZachary Turner // The end is always a terminal entry, so insert it regardless. 1515307f5ae8SZachary Turner table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize, 1516307f5ae8SZachary Turner last_line, 0, file_number, false, false, 1517307f5ae8SZachary Turner false, false, true); 1518307f5ae8SZachary Turner table.InsertSequence(seq.release()); 1519307f5ae8SZachary Turner } 1520307f5ae8SZachary Turner 1521b96181c2SZachary Turner bool SymbolFileNativePDB::ParseCompileUnitLineTable(const SymbolContext &sc) { 1522307f5ae8SZachary Turner // Unfortunately LLDB is set up to parse the entire compile unit line table 1523307f5ae8SZachary Turner // all at once, even if all it really needs is line info for a specific 1524307f5ae8SZachary Turner // function. In the future it would be nice if it could set the sc.m_function 1525307f5ae8SZachary Turner // member, and we could only get the line info for the function in question. 1526307f5ae8SZachary Turner lldbassert(sc.comp_unit); 15276284aee9SZachary Turner PdbSymUid cu_id(sc.comp_unit->GetID()); 15286284aee9SZachary Turner lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 15296284aee9SZachary Turner CompilandIndexItem *cci = 15306284aee9SZachary Turner m_index->compilands().GetCompiland(cu_id.asCompiland().modi); 1531307f5ae8SZachary Turner lldbassert(cci); 1532307f5ae8SZachary Turner auto line_table = llvm::make_unique<LineTable>(sc.comp_unit); 1533307f5ae8SZachary Turner 1534307f5ae8SZachary Turner // This is basically a copy of the .debug$S subsections from all original COFF 1535307f5ae8SZachary Turner // object files merged together with address relocations applied. We are 1536307f5ae8SZachary Turner // looking for all DEBUG_S_LINES subsections. 1537307f5ae8SZachary Turner for (const DebugSubsectionRecord &dssr : 1538307f5ae8SZachary Turner cci->m_debug_stream.getSubsectionsArray()) { 1539307f5ae8SZachary Turner if (dssr.kind() != DebugSubsectionKind::Lines) 1540307f5ae8SZachary Turner continue; 1541307f5ae8SZachary Turner 1542307f5ae8SZachary Turner DebugLinesSubsectionRef lines; 1543307f5ae8SZachary Turner llvm::BinaryStreamReader reader(dssr.getRecordData()); 1544307f5ae8SZachary Turner if (auto EC = lines.initialize(reader)) { 1545307f5ae8SZachary Turner llvm::consumeError(std::move(EC)); 1546307f5ae8SZachary Turner return false; 1547307f5ae8SZachary Turner } 1548307f5ae8SZachary Turner 1549307f5ae8SZachary Turner const LineFragmentHeader *lfh = lines.header(); 1550307f5ae8SZachary Turner uint64_t virtual_addr = 1551307f5ae8SZachary Turner m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); 1552307f5ae8SZachary Turner 1553307f5ae8SZachary Turner const auto &checksums = cci->m_strings.checksums().getArray(); 1554307f5ae8SZachary Turner const auto &strings = cci->m_strings.strings(); 1555307f5ae8SZachary Turner for (const LineColumnEntry &group : lines) { 1556307f5ae8SZachary Turner // Indices in this structure are actually offsets of records in the 1557307f5ae8SZachary Turner // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index 1558307f5ae8SZachary Turner // into the global PDB string table. 1559307f5ae8SZachary Turner auto iter = checksums.at(group.NameIndex); 1560307f5ae8SZachary Turner if (iter == checksums.end()) 1561307f5ae8SZachary Turner continue; 1562307f5ae8SZachary Turner 1563307f5ae8SZachary Turner llvm::Expected<llvm::StringRef> efn = 1564307f5ae8SZachary Turner strings.getString(iter->FileNameOffset); 1565307f5ae8SZachary Turner if (!efn) { 1566307f5ae8SZachary Turner llvm::consumeError(efn.takeError()); 1567307f5ae8SZachary Turner continue; 1568307f5ae8SZachary Turner } 1569307f5ae8SZachary Turner 1570307f5ae8SZachary Turner // LLDB wants the index of the file in the list of support files. 1571307f5ae8SZachary Turner auto fn_iter = llvm::find(cci->m_file_list, *efn); 1572307f5ae8SZachary Turner lldbassert(fn_iter != cci->m_file_list.end()); 1573307f5ae8SZachary Turner uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter); 1574307f5ae8SZachary Turner 1575307f5ae8SZachary Turner std::unique_ptr<LineSequence> sequence( 1576307f5ae8SZachary Turner line_table->CreateLineSequenceContainer()); 1577307f5ae8SZachary Turner lldbassert(!group.LineNumbers.empty()); 1578307f5ae8SZachary Turner 1579307f5ae8SZachary Turner for (const LineNumberEntry &entry : group.LineNumbers) { 1580307f5ae8SZachary Turner AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr, 1581307f5ae8SZachary Turner file_index, *lfh, entry); 1582307f5ae8SZachary Turner } 1583307f5ae8SZachary Turner LineInfo last_line(group.LineNumbers.back().Flags); 1584307f5ae8SZachary Turner TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index, 1585307f5ae8SZachary Turner last_line.getEndLine(), std::move(sequence)); 1586307f5ae8SZachary Turner } 1587307f5ae8SZachary Turner } 1588307f5ae8SZachary Turner 1589307f5ae8SZachary Turner if (line_table->GetSize() == 0) 1590307f5ae8SZachary Turner return false; 1591307f5ae8SZachary Turner 1592307f5ae8SZachary Turner sc.comp_unit->SetLineTable(line_table.release()); 1593307f5ae8SZachary Turner return true; 1594307f5ae8SZachary Turner } 1595307f5ae8SZachary Turner 1596b96181c2SZachary Turner bool SymbolFileNativePDB::ParseCompileUnitDebugMacros(const SymbolContext &sc) { 1597307f5ae8SZachary Turner // PDB doesn't contain information about macros 1598307f5ae8SZachary Turner return false; 1599307f5ae8SZachary Turner } 1600307f5ae8SZachary Turner 1601307f5ae8SZachary Turner bool SymbolFileNativePDB::ParseCompileUnitSupportFiles( 1602b96181c2SZachary Turner const SymbolContext &sc, FileSpecList &support_files) { 1603307f5ae8SZachary Turner lldbassert(sc.comp_unit); 1604307f5ae8SZachary Turner 16056284aee9SZachary Turner PdbSymUid cu_id(sc.comp_unit->GetID()); 16066284aee9SZachary Turner lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 16076284aee9SZachary Turner CompilandIndexItem *cci = 16086284aee9SZachary Turner m_index->compilands().GetCompiland(cu_id.asCompiland().modi); 1609307f5ae8SZachary Turner lldbassert(cci); 1610307f5ae8SZachary Turner 1611307f5ae8SZachary Turner for (llvm::StringRef f : cci->m_file_list) { 1612307f5ae8SZachary Turner FileSpec::Style style = 1613307f5ae8SZachary Turner f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows; 16148f3be7a3SJonas Devlieghere FileSpec spec(f, style); 1615307f5ae8SZachary Turner support_files.Append(spec); 1616307f5ae8SZachary Turner } 1617307f5ae8SZachary Turner 1618307f5ae8SZachary Turner return true; 1619307f5ae8SZachary Turner } 1620307f5ae8SZachary Turner 1621307f5ae8SZachary Turner bool SymbolFileNativePDB::ParseImportedModules( 1622b96181c2SZachary Turner const SymbolContext &sc, std::vector<ConstString> &imported_modules) { 1623307f5ae8SZachary Turner // PDB does not yet support module debug info 1624307f5ae8SZachary Turner return false; 1625307f5ae8SZachary Turner } 1626307f5ae8SZachary Turner 1627b96181c2SZachary Turner size_t SymbolFileNativePDB::ParseFunctionBlocks(const SymbolContext &sc) { 1628307f5ae8SZachary Turner lldbassert(sc.comp_unit && sc.function); 1629*d3d2b9b8SZachary Turner GetOrCreateBlock(PdbSymUid(sc.function->GetID()).asCompilandSym()); 1630*d3d2b9b8SZachary Turner // FIXME: Parse child blocks 1631*d3d2b9b8SZachary Turner return 1; 1632307f5ae8SZachary Turner } 1633307f5ae8SZachary Turner 16344911023fSZachary Turner void SymbolFileNativePDB::DumpClangAST(Stream &s) { 16354911023fSZachary Turner if (!m_clang) 16364911023fSZachary Turner return; 16374911023fSZachary Turner m_clang->Dump(s); 16384911023fSZachary Turner } 16394911023fSZachary Turner 16409f727950SZachary Turner uint32_t SymbolFileNativePDB::FindGlobalVariables( 16419f727950SZachary Turner const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 16429f727950SZachary Turner uint32_t max_matches, VariableList &variables) { 16439f727950SZachary Turner using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 16449f727950SZachary Turner 16459f727950SZachary Turner std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName( 16469f727950SZachary Turner name.GetStringRef(), m_index->symrecords()); 16479f727950SZachary Turner for (const SymbolAndOffset &result : results) { 16489f727950SZachary Turner VariableSP var; 16499f727950SZachary Turner switch (result.second.kind()) { 16509f727950SZachary Turner case SymbolKind::S_GDATA32: 16519f727950SZachary Turner case SymbolKind::S_LDATA32: 16529f727950SZachary Turner case SymbolKind::S_GTHREAD32: 16532af34166SZachary Turner case SymbolKind::S_LTHREAD32: 16542af34166SZachary Turner case SymbolKind::S_CONSTANT: { 16559fbf9350SZachary Turner PdbGlobalSymId global(result.first, false); 16566284aee9SZachary Turner var = GetOrCreateGlobalVariable(global); 16579f727950SZachary Turner variables.AddVariable(var); 16589f727950SZachary Turner break; 16599f727950SZachary Turner } 16609f727950SZachary Turner default: 16619f727950SZachary Turner continue; 16629f727950SZachary Turner } 16639f727950SZachary Turner } 16649f727950SZachary Turner return variables.GetSize(); 16659f727950SZachary Turner } 16669f727950SZachary Turner 1667307f5ae8SZachary Turner uint32_t SymbolFileNativePDB::FindFunctions( 1668b96181c2SZachary Turner const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 1669117b1fa1SZachary Turner FunctionNameType name_type_mask, bool include_inlines, bool append, 1670b96181c2SZachary Turner SymbolContextList &sc_list) { 1671307f5ae8SZachary Turner // For now we only support lookup by method name. 1672307f5ae8SZachary Turner if (!(name_type_mask & eFunctionNameTypeMethod)) 1673307f5ae8SZachary Turner return 0; 1674307f5ae8SZachary Turner 1675307f5ae8SZachary Turner using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 1676307f5ae8SZachary Turner 1677307f5ae8SZachary Turner std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName( 1678307f5ae8SZachary Turner name.GetStringRef(), m_index->symrecords()); 1679307f5ae8SZachary Turner for (const SymbolAndOffset &match : matches) { 1680307f5ae8SZachary Turner if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF) 1681307f5ae8SZachary Turner continue; 1682307f5ae8SZachary Turner ProcRefSym proc(match.second.kind()); 1683307f5ae8SZachary Turner cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc)); 1684307f5ae8SZachary Turner 1685307f5ae8SZachary Turner if (!IsValidRecord(proc)) 1686307f5ae8SZachary Turner continue; 1687307f5ae8SZachary Turner 16886284aee9SZachary Turner CompilandIndexItem &cci = 16896284aee9SZachary Turner m_index->compilands().GetOrCreateCompiland(proc.modi()); 1690b96181c2SZachary Turner SymbolContext sc; 1691307f5ae8SZachary Turner 1692307f5ae8SZachary Turner sc.comp_unit = GetOrCreateCompileUnit(cci).get(); 16939fbf9350SZachary Turner PdbCompilandSymId func_id(proc.modi(), proc.SymOffset); 1694*d3d2b9b8SZachary Turner sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get(); 1695307f5ae8SZachary Turner 1696307f5ae8SZachary Turner sc_list.Append(sc); 1697307f5ae8SZachary Turner } 1698307f5ae8SZachary Turner 1699307f5ae8SZachary Turner return sc_list.GetSize(); 1700307f5ae8SZachary Turner } 1701307f5ae8SZachary Turner 1702b96181c2SZachary Turner uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, 1703307f5ae8SZachary Turner bool include_inlines, bool append, 1704b96181c2SZachary Turner SymbolContextList &sc_list) { 1705307f5ae8SZachary Turner return 0; 1706307f5ae8SZachary Turner } 1707307f5ae8SZachary Turner 1708b96181c2SZachary Turner uint32_t SymbolFileNativePDB::FindTypes( 1709b96181c2SZachary Turner const SymbolContext &sc, const ConstString &name, 1710b96181c2SZachary Turner const CompilerDeclContext *parent_decl_ctx, bool append, 1711b96181c2SZachary Turner uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, 1712b96181c2SZachary Turner TypeMap &types) { 17132f7efbc9SZachary Turner if (!append) 17142f7efbc9SZachary Turner types.Clear(); 17152f7efbc9SZachary Turner if (!name) 1716b96181c2SZachary Turner return 0; 17172f7efbc9SZachary Turner 17182f7efbc9SZachary Turner searched_symbol_files.clear(); 17192f7efbc9SZachary Turner searched_symbol_files.insert(this); 17202f7efbc9SZachary Turner 17212f7efbc9SZachary Turner // There is an assumption 'name' is not a regex 17222f7efbc9SZachary Turner size_t match_count = FindTypesByName(name.GetStringRef(), max_matches, types); 17232f7efbc9SZachary Turner 17242f7efbc9SZachary Turner return match_count; 1725b96181c2SZachary Turner } 1726b96181c2SZachary Turner 1727b96181c2SZachary Turner size_t 1728b96181c2SZachary Turner SymbolFileNativePDB::FindTypes(const std::vector<CompilerContext> &context, 1729b96181c2SZachary Turner bool append, TypeMap &types) { 1730b96181c2SZachary Turner return 0; 1731b96181c2SZachary Turner } 1732b96181c2SZachary Turner 17332f7efbc9SZachary Turner size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name, 17342f7efbc9SZachary Turner uint32_t max_matches, 17352f7efbc9SZachary Turner TypeMap &types) { 17362f7efbc9SZachary Turner 17372f7efbc9SZachary Turner size_t match_count = 0; 17382f7efbc9SZachary Turner std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name); 17392f7efbc9SZachary Turner if (max_matches > 0 && max_matches < matches.size()) 17402f7efbc9SZachary Turner matches.resize(max_matches); 17412f7efbc9SZachary Turner 17422f7efbc9SZachary Turner for (TypeIndex ti : matches) { 17432f7efbc9SZachary Turner TypeSP type = GetOrCreateType(ti); 17442f7efbc9SZachary Turner if (!type) 17452f7efbc9SZachary Turner continue; 17462f7efbc9SZachary Turner 17472f7efbc9SZachary Turner types.Insert(type); 17482f7efbc9SZachary Turner ++match_count; 17492f7efbc9SZachary Turner } 17502f7efbc9SZachary Turner return match_count; 17512f7efbc9SZachary Turner } 17522f7efbc9SZachary Turner 1753b96181c2SZachary Turner size_t SymbolFileNativePDB::ParseTypes(const SymbolContext &sc) { return 0; } 1754b96181c2SZachary Turner 1755*d3d2b9b8SZachary Turner size_t 1756*d3d2b9b8SZachary Turner SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit, 1757*d3d2b9b8SZachary Turner VariableList &variables) { 1758*d3d2b9b8SZachary Turner PdbSymUid sym_uid(comp_unit.GetID()); 1759*d3d2b9b8SZachary Turner lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland); 1760*d3d2b9b8SZachary Turner return 0; 1761*d3d2b9b8SZachary Turner } 1762*d3d2b9b8SZachary Turner 1763*d3d2b9b8SZachary Turner VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, 1764*d3d2b9b8SZachary Turner PdbCompilandSymId var_id, 1765*d3d2b9b8SZachary Turner bool is_param) { 1766*d3d2b9b8SZachary Turner ModuleSP module = GetObjectFile()->GetModule(); 1767*d3d2b9b8SZachary Turner VariableInfo var_info = 1768*d3d2b9b8SZachary Turner GetVariableInformation(*m_index, var_id, module, true); 1769*d3d2b9b8SZachary Turner 1770*d3d2b9b8SZachary Turner CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi); 1771*d3d2b9b8SZachary Turner CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii); 1772*d3d2b9b8SZachary Turner TypeSP type_sp = GetOrCreateType(var_info.type); 1773*d3d2b9b8SZachary Turner std::string name = var_info.name.str(); 1774*d3d2b9b8SZachary Turner Declaration decl; 1775*d3d2b9b8SZachary Turner SymbolFileTypeSP sftype = 1776*d3d2b9b8SZachary Turner std::make_shared<SymbolFileType>(*this, type_sp->GetID()); 1777*d3d2b9b8SZachary Turner 1778*d3d2b9b8SZachary Turner ValueType var_scope = 1779*d3d2b9b8SZachary Turner is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal; 1780*d3d2b9b8SZachary Turner VariableSP var_sp = std::make_shared<Variable>( 1781*d3d2b9b8SZachary Turner toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, 1782*d3d2b9b8SZachary Turner comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false, 1783*d3d2b9b8SZachary Turner false, false); 1784*d3d2b9b8SZachary Turner 1785*d3d2b9b8SZachary Turner CompilerDeclContext cdc = GetDeclContextForUID(toOpaqueUid(scope_id)); 1786*d3d2b9b8SZachary Turner clang::DeclContext *decl_ctx = 1787*d3d2b9b8SZachary Turner static_cast<clang::DeclContext *>(cdc.GetOpaqueDeclContext()); 1788*d3d2b9b8SZachary Turner 1789*d3d2b9b8SZachary Turner // Parameter info should have already been added to the AST. 1790*d3d2b9b8SZachary Turner if (!is_param) { 1791*d3d2b9b8SZachary Turner clang::QualType qt = 1792*d3d2b9b8SZachary Turner ClangUtil::GetCanonicalQualType(type_sp->GetForwardCompilerType()); 1793*d3d2b9b8SZachary Turner 1794*d3d2b9b8SZachary Turner clang::VarDecl *var_decl = 1795*d3d2b9b8SZachary Turner m_clang->CreateVariableDeclaration(decl_ctx, name.c_str(), qt); 1796*d3d2b9b8SZachary Turner lldbassert(m_uid_to_decl.count(toOpaqueUid(var_id)) == 0); 1797*d3d2b9b8SZachary Turner m_uid_to_decl[toOpaqueUid(var_id)] = var_decl; 1798*d3d2b9b8SZachary Turner } 1799*d3d2b9b8SZachary Turner 1800*d3d2b9b8SZachary Turner m_local_variables[toOpaqueUid(var_id)] = var_sp; 1801*d3d2b9b8SZachary Turner return var_sp; 1802*d3d2b9b8SZachary Turner } 1803*d3d2b9b8SZachary Turner 1804*d3d2b9b8SZachary Turner VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable( 1805*d3d2b9b8SZachary Turner PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) { 1806*d3d2b9b8SZachary Turner auto iter = m_local_variables.find(toOpaqueUid(var_id)); 1807*d3d2b9b8SZachary Turner if (iter != m_local_variables.end()) 1808*d3d2b9b8SZachary Turner return iter->second; 1809*d3d2b9b8SZachary Turner 1810*d3d2b9b8SZachary Turner return CreateLocalVariable(scope_id, var_id, is_param); 1811*d3d2b9b8SZachary Turner } 1812*d3d2b9b8SZachary Turner 1813*d3d2b9b8SZachary Turner size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { 1814*d3d2b9b8SZachary Turner Block &block = GetOrCreateBlock(block_id); 1815*d3d2b9b8SZachary Turner 1816*d3d2b9b8SZachary Turner size_t count = 0; 1817*d3d2b9b8SZachary Turner 1818*d3d2b9b8SZachary Turner CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 1819*d3d2b9b8SZachary Turner CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 1820*d3d2b9b8SZachary Turner uint32_t params_remaining = 0; 1821*d3d2b9b8SZachary Turner switch (sym.kind()) { 1822*d3d2b9b8SZachary Turner case S_GPROC32: 1823*d3d2b9b8SZachary Turner case S_LPROC32: { 1824*d3d2b9b8SZachary Turner ProcSym proc(static_cast<SymbolRecordKind>(sym.kind())); 1825*d3d2b9b8SZachary Turner cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)); 1826*d3d2b9b8SZachary Turner CVType signature = m_index->tpi().getType(proc.FunctionType); 1827*d3d2b9b8SZachary Turner ProcedureRecord sig; 1828*d3d2b9b8SZachary Turner cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(signature, sig)); 1829*d3d2b9b8SZachary Turner params_remaining = sig.getParameterCount(); 1830*d3d2b9b8SZachary Turner break; 1831*d3d2b9b8SZachary Turner } 1832*d3d2b9b8SZachary Turner case S_BLOCK32: 1833*d3d2b9b8SZachary Turner break; 1834*d3d2b9b8SZachary Turner default: 1835*d3d2b9b8SZachary Turner lldbassert(false && "Symbol is not a block!"); 1836*d3d2b9b8SZachary Turner return 0; 1837*d3d2b9b8SZachary Turner } 1838*d3d2b9b8SZachary Turner 1839*d3d2b9b8SZachary Turner VariableListSP variables = block.GetBlockVariableList(false); 1840*d3d2b9b8SZachary Turner if (!variables) { 1841*d3d2b9b8SZachary Turner variables = std::make_shared<VariableList>(); 1842*d3d2b9b8SZachary Turner block.SetVariableList(variables); 1843*d3d2b9b8SZachary Turner } 1844*d3d2b9b8SZachary Turner 1845*d3d2b9b8SZachary Turner CVSymbolArray syms = limitSymbolArrayToScope( 1846*d3d2b9b8SZachary Turner cii->m_debug_stream.getSymbolArray(), block_id.offset); 1847*d3d2b9b8SZachary Turner 1848*d3d2b9b8SZachary Turner // Skip the first record since it's a PROC32 or BLOCK32, and there's 1849*d3d2b9b8SZachary Turner // no point examining it since we know it's not a local variable. 1850*d3d2b9b8SZachary Turner syms.drop_front(); 1851*d3d2b9b8SZachary Turner auto iter = syms.begin(); 1852*d3d2b9b8SZachary Turner auto end = syms.end(); 1853*d3d2b9b8SZachary Turner 1854*d3d2b9b8SZachary Turner while (iter != end) { 1855*d3d2b9b8SZachary Turner uint32_t record_offset = iter.offset(); 1856*d3d2b9b8SZachary Turner CVSymbol variable_cvs = *iter; 1857*d3d2b9b8SZachary Turner PdbCompilandSymId child_sym_id(block_id.modi, record_offset); 1858*d3d2b9b8SZachary Turner ++iter; 1859*d3d2b9b8SZachary Turner 1860*d3d2b9b8SZachary Turner // If this is a block, recurse into its children and then skip it. 1861*d3d2b9b8SZachary Turner if (variable_cvs.kind() == S_BLOCK32) { 1862*d3d2b9b8SZachary Turner uint32_t block_end = getScopeEndOffset(variable_cvs); 1863*d3d2b9b8SZachary Turner count += ParseVariablesForBlock(child_sym_id); 1864*d3d2b9b8SZachary Turner iter = syms.at(block_end); 1865*d3d2b9b8SZachary Turner continue; 1866*d3d2b9b8SZachary Turner } 1867*d3d2b9b8SZachary Turner 1868*d3d2b9b8SZachary Turner bool is_param = params_remaining > 0; 1869*d3d2b9b8SZachary Turner VariableSP variable; 1870*d3d2b9b8SZachary Turner switch (variable_cvs.kind()) { 1871*d3d2b9b8SZachary Turner case S_REGREL32: 1872*d3d2b9b8SZachary Turner case S_REGISTER: 1873*d3d2b9b8SZachary Turner case S_LOCAL: 1874*d3d2b9b8SZachary Turner variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param); 1875*d3d2b9b8SZachary Turner if (is_param) 1876*d3d2b9b8SZachary Turner --params_remaining; 1877*d3d2b9b8SZachary Turner variables->AddVariableIfUnique(variable); 1878*d3d2b9b8SZachary Turner break; 1879*d3d2b9b8SZachary Turner default: 1880*d3d2b9b8SZachary Turner break; 1881*d3d2b9b8SZachary Turner } 1882*d3d2b9b8SZachary Turner } 1883*d3d2b9b8SZachary Turner 1884*d3d2b9b8SZachary Turner // Pass false for set_children, since we call this recursively so that the 1885*d3d2b9b8SZachary Turner // children will call this for themselves. 1886*d3d2b9b8SZachary Turner block.SetDidParseVariables(true, false); 1887*d3d2b9b8SZachary Turner 1888*d3d2b9b8SZachary Turner return count; 1889*d3d2b9b8SZachary Turner } 1890*d3d2b9b8SZachary Turner 1891*d3d2b9b8SZachary Turner size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) { 1892*d3d2b9b8SZachary Turner lldbassert(sc.function || sc.comp_unit); 1893*d3d2b9b8SZachary Turner 1894*d3d2b9b8SZachary Turner VariableListSP variables; 1895*d3d2b9b8SZachary Turner PdbSymUid sym_uid; 1896*d3d2b9b8SZachary Turner if (sc.block) { 1897*d3d2b9b8SZachary Turner PdbSymUid block_id(sc.block->GetID()); 1898*d3d2b9b8SZachary Turner 1899*d3d2b9b8SZachary Turner size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 1900*d3d2b9b8SZachary Turner return count; 1901*d3d2b9b8SZachary Turner } 1902*d3d2b9b8SZachary Turner 1903*d3d2b9b8SZachary Turner if (sc.function) { 1904*d3d2b9b8SZachary Turner PdbSymUid block_id(sc.function->GetID()); 1905*d3d2b9b8SZachary Turner 1906*d3d2b9b8SZachary Turner size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 1907*d3d2b9b8SZachary Turner return count; 1908*d3d2b9b8SZachary Turner } 1909*d3d2b9b8SZachary Turner 1910*d3d2b9b8SZachary Turner if (sc.comp_unit) { 1911*d3d2b9b8SZachary Turner variables = sc.comp_unit->GetVariableList(false); 1912*d3d2b9b8SZachary Turner if (!variables) { 1913*d3d2b9b8SZachary Turner variables = std::make_shared<VariableList>(); 1914*d3d2b9b8SZachary Turner sc.comp_unit->SetVariableList(variables); 1915*d3d2b9b8SZachary Turner } 1916*d3d2b9b8SZachary Turner return ParseVariablesForCompileUnit(*sc.comp_unit, *variables); 1917*d3d2b9b8SZachary Turner } 1918*d3d2b9b8SZachary Turner 1919*d3d2b9b8SZachary Turner llvm_unreachable("Unreachable!"); 1920*d3d2b9b8SZachary Turner } 1921*d3d2b9b8SZachary Turner 1922*d3d2b9b8SZachary Turner CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) { 1923*d3d2b9b8SZachary Turner auto iter = m_uid_to_decl.find(uid); 1924*d3d2b9b8SZachary Turner if (iter == m_uid_to_decl.end()) 1925*d3d2b9b8SZachary Turner return CompilerDecl(); 1926*d3d2b9b8SZachary Turner 1927*d3d2b9b8SZachary Turner return {m_clang, iter->second}; 1928*d3d2b9b8SZachary Turner } 1929*d3d2b9b8SZachary Turner 1930*d3d2b9b8SZachary Turner CompilerDeclContext 1931*d3d2b9b8SZachary Turner SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) { 1932*d3d2b9b8SZachary Turner CompilerDecl compiler_decl = GetDeclForUID(uid); 1933*d3d2b9b8SZachary Turner clang::Decl *decl = static_cast<clang::Decl *>(compiler_decl.GetOpaqueDecl()); 1934*d3d2b9b8SZachary Turner return {m_clang, clang::Decl::castToDeclContext(decl)}; 1935*d3d2b9b8SZachary Turner } 1936*d3d2b9b8SZachary Turner 1937a42bbe39SZachary Turner CompilerDeclContext 1938a42bbe39SZachary Turner SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { 1939a42bbe39SZachary Turner // FIXME: This should look up the uid, decide if it's a symbol or a type, and 1940a42bbe39SZachary Turner // depending which it is, find the appropriate DeclContext. Possibilities: 1941a42bbe39SZachary Turner // For classes and typedefs: 1942a42bbe39SZachary Turner // * Function 1943a42bbe39SZachary Turner // * Namespace 1944a42bbe39SZachary Turner // * Global 1945a42bbe39SZachary Turner // * Block 1946a42bbe39SZachary Turner // * Class 1947a42bbe39SZachary Turner // For field list members: 1948a42bbe39SZachary Turner // * Class 1949a42bbe39SZachary Turner // For variables: 1950a42bbe39SZachary Turner // * Function 1951a42bbe39SZachary Turner // * Namespace 1952a42bbe39SZachary Turner // * Global 1953a42bbe39SZachary Turner // * Block 1954a42bbe39SZachary Turner // For functions: 1955a42bbe39SZachary Turner // * Namespace 1956a42bbe39SZachary Turner // * Global 1957a42bbe39SZachary Turner // * Class 1958a42bbe39SZachary Turner // 1959a42bbe39SZachary Turner // It is an error to call this function with a uid for any other symbol type. 1960a42bbe39SZachary Turner return {m_clang, m_clang->GetTranslationUnitDecl()}; 1961a42bbe39SZachary Turner } 1962a42bbe39SZachary Turner 1963b96181c2SZachary Turner Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) { 19642f7efbc9SZachary Turner auto iter = m_types.find(type_uid); 19652f7efbc9SZachary Turner // lldb should not be passing us non-sensical type uids. the only way it 19662f7efbc9SZachary Turner // could have a type uid in the first place is if we handed it out, in which 19679f727950SZachary Turner // case we should know about the type. However, that doesn't mean we've 19689f727950SZachary Turner // instantiated it yet. We can vend out a UID for a future type. So if the 19699f727950SZachary Turner // type doesn't exist, let's instantiate it now. 19709f727950SZachary Turner if (iter != m_types.end()) 19712f7efbc9SZachary Turner return &*iter->second; 19729f727950SZachary Turner 19736284aee9SZachary Turner PdbSymUid uid(type_uid); 19746284aee9SZachary Turner lldbassert(uid.kind() == PdbSymUidKind::Type); 19756284aee9SZachary Turner PdbTypeSymId type_id = uid.asTypeSym(); 19766284aee9SZachary Turner if (type_id.index.isNoneType()) 19779f727950SZachary Turner return nullptr; 19789f727950SZachary Turner 19796284aee9SZachary Turner TypeSP type_sp = CreateAndCacheType(type_id); 19809f727950SZachary Turner return &*type_sp; 1981b96181c2SZachary Turner } 1982b96181c2SZachary Turner 1983eca07c59SAdrian Prantl llvm::Optional<SymbolFile::ArrayInfo> 1984eca07c59SAdrian Prantl SymbolFileNativePDB::GetDynamicArrayInfoForUID( 1985eca07c59SAdrian Prantl lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 1986eca07c59SAdrian Prantl return llvm::None; 1987eca07c59SAdrian Prantl } 1988eca07c59SAdrian Prantl 1989eca07c59SAdrian Prantl 1990b96181c2SZachary Turner bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { 19912f7efbc9SZachary Turner // If this is not in our map, it's an error. 19922f7efbc9SZachary Turner clang::TagDecl *tag_decl = m_clang->GetAsTagDecl(compiler_type); 19932f7efbc9SZachary Turner lldbassert(tag_decl); 19942f7efbc9SZachary Turner auto status_iter = m_decl_to_status.find(tag_decl); 19952f7efbc9SZachary Turner lldbassert(status_iter != m_decl_to_status.end()); 19962f7efbc9SZachary Turner 19972f7efbc9SZachary Turner // If it's already complete, just return. 19982f7efbc9SZachary Turner DeclStatus &status = status_iter->second; 19992f7efbc9SZachary Turner if (status.status == Type::eResolveStateFull) 20002f7efbc9SZachary Turner return true; 20012f7efbc9SZachary Turner 20026284aee9SZachary Turner PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym(); 20032f7efbc9SZachary Turner 20046284aee9SZachary Turner lldbassert(IsTagRecord(type_id, m_index->tpi())); 20052f7efbc9SZachary Turner 20062f7efbc9SZachary Turner ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), 20072f7efbc9SZachary Turner false); 20082f7efbc9SZachary Turner 20092f7efbc9SZachary Turner // In CreateAndCacheType, we already go out of our way to resolve forward 20102f7efbc9SZachary Turner // ref UDTs to full decls, and the uids we vend out always refer to full 20112f7efbc9SZachary Turner // decls if a full decl exists in the debug info. So if we don't have a full 20122f7efbc9SZachary Turner // decl here, it means one doesn't exist in the debug info, and we can't 20132f7efbc9SZachary Turner // complete the type. 20142f7efbc9SZachary Turner CVType cvt = m_index->tpi().getType(TypeIndex(type_id.index)); 20152f7efbc9SZachary Turner if (IsForwardRefUdt(cvt)) 20162f7efbc9SZachary Turner return false; 20172f7efbc9SZachary Turner 20186284aee9SZachary Turner auto types_iter = m_types.find(status.uid); 20192f7efbc9SZachary Turner lldbassert(types_iter != m_types.end()); 20202f7efbc9SZachary Turner 2021511bff21SZachary Turner if (cvt.kind() == LF_MODIFIER) { 2022511bff21SZachary Turner TypeIndex unmodified_type = LookThroughModifierRecord(cvt); 2023511bff21SZachary Turner cvt = m_index->tpi().getType(unmodified_type); 2024511bff21SZachary Turner // LF_MODIFIERS usually point to forward decls, so this is the one case 2025511bff21SZachary Turner // where we won't have been able to resolve a forward decl to a full decl 2026511bff21SZachary Turner // earlier on. So we need to do that now. 2027511bff21SZachary Turner if (IsForwardRefUdt(cvt)) { 2028511bff21SZachary Turner llvm::Expected<TypeIndex> expected_full_ti = 2029511bff21SZachary Turner m_index->tpi().findFullDeclForForwardRef(unmodified_type); 2030511bff21SZachary Turner if (!expected_full_ti) { 2031511bff21SZachary Turner llvm::consumeError(expected_full_ti.takeError()); 2032511bff21SZachary Turner return false; 2033511bff21SZachary Turner } 2034511bff21SZachary Turner cvt = m_index->tpi().getType(*expected_full_ti); 2035511bff21SZachary Turner lldbassert(!IsForwardRefUdt(cvt)); 2036511bff21SZachary Turner unmodified_type = *expected_full_ti; 2037511bff21SZachary Turner } 20389fbf9350SZachary Turner type_id = PdbTypeSymId(unmodified_type, false); 2039511bff21SZachary Turner } 20402f7efbc9SZachary Turner TypeIndex field_list_ti = GetFieldListIndex(cvt); 20412f7efbc9SZachary Turner CVType field_list_cvt = m_index->tpi().getType(field_list_ti); 20422f7efbc9SZachary Turner if (field_list_cvt.kind() != LF_FIELDLIST) 20432f7efbc9SZachary Turner return false; 20442f7efbc9SZachary Turner 20452f7efbc9SZachary Turner // Visit all members of this class, then perform any finalization necessary 20462f7efbc9SZachary Turner // to complete the class. 20476284aee9SZachary Turner UdtRecordCompleter completer(type_id, compiler_type, *tag_decl, *this); 20482f7efbc9SZachary Turner auto error = 20492f7efbc9SZachary Turner llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); 20502f7efbc9SZachary Turner completer.complete(); 20512f7efbc9SZachary Turner 20522f7efbc9SZachary Turner status.status = Type::eResolveStateFull; 20532f7efbc9SZachary Turner if (!error) 20542f7efbc9SZachary Turner return true; 20552f7efbc9SZachary Turner 20562f7efbc9SZachary Turner llvm::consumeError(std::move(error)); 2057b96181c2SZachary Turner return false; 2058b96181c2SZachary Turner } 2059b96181c2SZachary Turner 2060b96181c2SZachary Turner size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, 2061117b1fa1SZachary Turner TypeClass type_mask, 2062b96181c2SZachary Turner lldb_private::TypeList &type_list) { 2063b96181c2SZachary Turner return 0; 2064b96181c2SZachary Turner } 2065b96181c2SZachary Turner 2066b96181c2SZachary Turner CompilerDeclContext 2067b96181c2SZachary Turner SymbolFileNativePDB::FindNamespace(const SymbolContext &sc, 2068b96181c2SZachary Turner const ConstString &name, 2069b96181c2SZachary Turner const CompilerDeclContext *parent_decl_ctx) { 2070307f5ae8SZachary Turner return {}; 2071307f5ae8SZachary Turner } 2072307f5ae8SZachary Turner 2073b96181c2SZachary Turner TypeSystem * 2074307f5ae8SZachary Turner SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { 2075307f5ae8SZachary Turner auto type_system = 2076307f5ae8SZachary Turner m_obj_file->GetModule()->GetTypeSystemForLanguage(language); 2077307f5ae8SZachary Turner if (type_system) 2078307f5ae8SZachary Turner type_system->SetSymbolFile(this); 2079307f5ae8SZachary Turner return type_system; 2080307f5ae8SZachary Turner } 2081307f5ae8SZachary Turner 2082b96181c2SZachary Turner ConstString SymbolFileNativePDB::GetPluginName() { 2083307f5ae8SZachary Turner static ConstString g_name("pdb"); 2084307f5ae8SZachary Turner return g_name; 2085307f5ae8SZachary Turner } 2086307f5ae8SZachary Turner 2087307f5ae8SZachary Turner uint32_t SymbolFileNativePDB::GetPluginVersion() { return 1; } 2088