10b57cec5SDimitry Andric #include "PdbAstBuilder.h" 20b57cec5SDimitry Andric 30b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 40b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" 50b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordName.h" 60b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 70b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 80b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" 90b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 100b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" 110b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiStream.h" 120b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PublicsStream.h" 130b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/SymbolStream.h" 140b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/TpiStream.h" 150b57cec5SDimitry Andric #include "llvm/Demangle/MicrosoftDemangle.h" 160b57cec5SDimitry Andric 1706c3fb27SDimitry Andric #include "PdbUtil.h" 185ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" 195ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangUtil.h" 200b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" 215ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 2206c3fb27SDimitry Andric #include "SymbolFileNativePDB.h" 2306c3fb27SDimitry Andric #include "UdtRecordCompleter.h" 240b57cec5SDimitry Andric #include "lldb/Core/Module.h" 250b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 260b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h" 27bdd1243dSDimitry Andric #include <optional> 2806c3fb27SDimitry Andric #include <string_view> 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric using namespace lldb_private; 310b57cec5SDimitry Andric using namespace lldb_private::npdb; 320b57cec5SDimitry Andric using namespace llvm::codeview; 330b57cec5SDimitry Andric using namespace llvm::pdb; 340b57cec5SDimitry Andric 350eae32dcSDimitry Andric namespace { 360eae32dcSDimitry Andric struct CreateMethodDecl : public TypeVisitorCallbacks { 370eae32dcSDimitry Andric CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang, 380eae32dcSDimitry Andric TypeIndex func_type_index, 390eae32dcSDimitry Andric clang::FunctionDecl *&function_decl, 400eae32dcSDimitry Andric lldb::opaque_compiler_type_t parent_ty, 410eae32dcSDimitry Andric llvm::StringRef proc_name, CompilerType func_ct) 420eae32dcSDimitry Andric : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index), 430eae32dcSDimitry Andric function_decl(function_decl), parent_ty(parent_ty), 440eae32dcSDimitry Andric proc_name(proc_name), func_ct(func_ct) {} 450eae32dcSDimitry Andric PdbIndex &m_index; 460eae32dcSDimitry Andric TypeSystemClang &m_clang; 470eae32dcSDimitry Andric TypeIndex func_type_index; 480eae32dcSDimitry Andric clang::FunctionDecl *&function_decl; 490eae32dcSDimitry Andric lldb::opaque_compiler_type_t parent_ty; 500eae32dcSDimitry Andric llvm::StringRef proc_name; 510eae32dcSDimitry Andric CompilerType func_ct; 520eae32dcSDimitry Andric 530eae32dcSDimitry Andric llvm::Error visitKnownMember(CVMemberRecord &cvr, 540eae32dcSDimitry Andric OverloadedMethodRecord &overloaded) override { 550eae32dcSDimitry Andric TypeIndex method_list_idx = overloaded.MethodList; 560eae32dcSDimitry Andric 570eae32dcSDimitry Andric CVType method_list_type = m_index.tpi().getType(method_list_idx); 580eae32dcSDimitry Andric assert(method_list_type.kind() == LF_METHODLIST); 590eae32dcSDimitry Andric 600eae32dcSDimitry Andric MethodOverloadListRecord method_list; 610eae32dcSDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>( 620eae32dcSDimitry Andric method_list_type, method_list)); 630eae32dcSDimitry Andric 640eae32dcSDimitry Andric for (const OneMethodRecord &method : method_list.Methods) { 650eae32dcSDimitry Andric if (method.getType().getIndex() == func_type_index.getIndex()) 660eae32dcSDimitry Andric AddMethod(overloaded.Name, method.getAccess(), method.getOptions(), 670eae32dcSDimitry Andric method.Attrs); 680eae32dcSDimitry Andric } 690eae32dcSDimitry Andric 700eae32dcSDimitry Andric return llvm::Error::success(); 710eae32dcSDimitry Andric } 720eae32dcSDimitry Andric 730eae32dcSDimitry Andric llvm::Error visitKnownMember(CVMemberRecord &cvr, 740eae32dcSDimitry Andric OneMethodRecord &record) override { 750eae32dcSDimitry Andric AddMethod(record.getName(), record.getAccess(), record.getOptions(), 760eae32dcSDimitry Andric record.Attrs); 770eae32dcSDimitry Andric return llvm::Error::success(); 780eae32dcSDimitry Andric } 790eae32dcSDimitry Andric 800eae32dcSDimitry Andric void AddMethod(llvm::StringRef name, MemberAccess access, 810eae32dcSDimitry Andric MethodOptions options, MemberAttributes attrs) { 820eae32dcSDimitry Andric if (name != proc_name || function_decl) 830eae32dcSDimitry Andric return; 840eae32dcSDimitry Andric lldb::AccessType access_type = TranslateMemberAccess(access); 850eae32dcSDimitry Andric bool is_virtual = attrs.isVirtual(); 860eae32dcSDimitry Andric bool is_static = attrs.isStatic(); 870eae32dcSDimitry Andric bool is_artificial = (options & MethodOptions::CompilerGenerated) == 880eae32dcSDimitry Andric MethodOptions::CompilerGenerated; 890eae32dcSDimitry Andric function_decl = m_clang.AddMethodToCXXRecordType( 900eae32dcSDimitry Andric parent_ty, proc_name, 910eae32dcSDimitry Andric /*mangled_name=*/nullptr, func_ct, /*access=*/access_type, 920eae32dcSDimitry Andric /*is_virtual=*/is_virtual, /*is_static=*/is_static, 930eae32dcSDimitry Andric /*is_inline=*/false, /*is_explicit=*/false, 940eae32dcSDimitry Andric /*is_attr_used=*/false, /*is_artificial=*/is_artificial); 950eae32dcSDimitry Andric } 960eae32dcSDimitry Andric }; 970eae32dcSDimitry Andric } // namespace 980eae32dcSDimitry Andric 990b57cec5SDimitry Andric static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) { 1000b57cec5SDimitry Andric switch (cr.Kind) { 1010b57cec5SDimitry Andric case TypeRecordKind::Class: 102*5f757f3fSDimitry Andric return clang::TagTypeKind::Class; 1030b57cec5SDimitry Andric case TypeRecordKind::Struct: 104*5f757f3fSDimitry Andric return clang::TagTypeKind::Struct; 1050b57cec5SDimitry Andric case TypeRecordKind::Union: 106*5f757f3fSDimitry Andric return clang::TagTypeKind::Union; 1070b57cec5SDimitry Andric case TypeRecordKind::Interface: 108*5f757f3fSDimitry Andric return clang::TagTypeKind::Interface; 1090b57cec5SDimitry Andric case TypeRecordKind::Enum: 110*5f757f3fSDimitry Andric return clang::TagTypeKind::Enum; 1110b57cec5SDimitry Andric default: 1120b57cec5SDimitry Andric lldbassert(false && "Invalid tag record kind!"); 113*5f757f3fSDimitry Andric return clang::TagTypeKind::Struct; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric static bool IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args) { 1180b57cec5SDimitry Andric if (args.empty()) 1190b57cec5SDimitry Andric return false; 1200b57cec5SDimitry Andric return args.back() == TypeIndex::None(); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric static bool 1240b57cec5SDimitry Andric AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) { 1250b57cec5SDimitry Andric for (llvm::ms_demangle::Node *n : scopes) { 1260b57cec5SDimitry Andric auto *idn = static_cast<llvm::ms_demangle::IdentifierNode *>(n); 1270b57cec5SDimitry Andric if (idn->TemplateParams) 1280b57cec5SDimitry Andric return true; 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric return false; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 133bdd1243dSDimitry Andric static std::optional<clang::CallingConv> 1340b57cec5SDimitry Andric TranslateCallingConvention(llvm::codeview::CallingConvention conv) { 1350b57cec5SDimitry Andric using CC = llvm::codeview::CallingConvention; 1360b57cec5SDimitry Andric switch (conv) { 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric case CC::NearC: 1390b57cec5SDimitry Andric case CC::FarC: 1400b57cec5SDimitry Andric return clang::CallingConv::CC_C; 1410b57cec5SDimitry Andric case CC::NearPascal: 1420b57cec5SDimitry Andric case CC::FarPascal: 1430b57cec5SDimitry Andric return clang::CallingConv::CC_X86Pascal; 1440b57cec5SDimitry Andric case CC::NearFast: 1450b57cec5SDimitry Andric case CC::FarFast: 1460b57cec5SDimitry Andric return clang::CallingConv::CC_X86FastCall; 1470b57cec5SDimitry Andric case CC::NearStdCall: 1480b57cec5SDimitry Andric case CC::FarStdCall: 1490b57cec5SDimitry Andric return clang::CallingConv::CC_X86StdCall; 1500b57cec5SDimitry Andric case CC::ThisCall: 1510b57cec5SDimitry Andric return clang::CallingConv::CC_X86ThisCall; 1520b57cec5SDimitry Andric case CC::NearVector: 1530b57cec5SDimitry Andric return clang::CallingConv::CC_X86VectorCall; 1540b57cec5SDimitry Andric default: 155bdd1243dSDimitry Andric return std::nullopt; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric static bool IsAnonymousNamespaceName(llvm::StringRef name) { 1600b57cec5SDimitry Andric return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 163bdd1243dSDimitry Andric PdbAstBuilder::PdbAstBuilder(TypeSystemClang &clang) : m_clang(clang) {} 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() { 1660b57cec5SDimitry Andric return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl()); 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric std::pair<clang::DeclContext *, std::string> 1700b57cec5SDimitry Andric PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { 171bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 172bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1730b57cec5SDimitry Andric // FIXME: Move this to GetDeclContextContainingUID. 1740b57cec5SDimitry Andric if (!record.hasUniqueName()) 1750b57cec5SDimitry Andric return CreateDeclInfoForUndecoratedName(record.Name); 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric llvm::ms_demangle::Demangler demangler; 17806c3fb27SDimitry Andric std::string_view sv(record.UniqueName.begin(), record.UniqueName.size()); 1790b57cec5SDimitry Andric llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); 1800b57cec5SDimitry Andric if (demangler.Error) 1815ffd83dbSDimitry Andric return {m_clang.GetTranslationUnitDecl(), std::string(record.UniqueName)}; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric llvm::ms_demangle::IdentifierNode *idn = 1840b57cec5SDimitry Andric ttn->QualifiedName->getUnqualifiedIdentifier(); 1850b57cec5SDimitry Andric std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric llvm::ms_demangle::NodeArrayNode *name_components = 1880b57cec5SDimitry Andric ttn->QualifiedName->Components; 1890b57cec5SDimitry Andric llvm::ArrayRef<llvm::ms_demangle::Node *> scopes(name_components->Nodes, 1900b57cec5SDimitry Andric name_components->Count - 1); 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric clang::DeclContext *context = m_clang.GetTranslationUnitDecl(); 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric // If this type doesn't have a parent type in the debug info, then the best we 1950b57cec5SDimitry Andric // can do is to say that it's either a series of namespaces (if the scope is 1960b57cec5SDimitry Andric // non-empty), or the translation unit (if the scope is empty). 197bdd1243dSDimitry Andric std::optional<TypeIndex> parent_index = pdb->GetParentType(ti); 198bdd1243dSDimitry Andric if (!parent_index) { 1990b57cec5SDimitry Andric if (scopes.empty()) 2000b57cec5SDimitry Andric return {context, uname}; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric // If there is no parent in the debug info, but some of the scopes have 2030b57cec5SDimitry Andric // template params, then this is a case of bad debug info. See, for 2040b57cec5SDimitry Andric // example, llvm.org/pr39607. We don't want to create an ambiguity between 2050b57cec5SDimitry Andric // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at 2060b57cec5SDimitry Andric // global scope with the fully qualified name. 2070b57cec5SDimitry Andric if (AnyScopesHaveTemplateParams(scopes)) 2085ffd83dbSDimitry Andric return {context, std::string(record.Name)}; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric for (llvm::ms_demangle::Node *scope : scopes) { 2110b57cec5SDimitry Andric auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope); 2120b57cec5SDimitry Andric std::string str = nii->toString(); 2130b57cec5SDimitry Andric context = GetOrCreateNamespaceDecl(str.c_str(), *context); 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric return {context, uname}; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric // Otherwise, all we need to do is get the parent type of this type and 2190b57cec5SDimitry Andric // recurse into our lazy type creation / AST reconstruction logic to get an 2200b57cec5SDimitry Andric // LLDB TypeSP for the parent. This will cause the AST to automatically get 2210b57cec5SDimitry Andric // the right DeclContext created for any parent. 222bdd1243dSDimitry Andric clang::QualType parent_qt = GetOrCreateType(*parent_index); 22381ad6265SDimitry Andric if (parent_qt.isNull()) 22481ad6265SDimitry Andric return {nullptr, ""}; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl()); 2270b57cec5SDimitry Andric return {context, uname}; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric static bool isLocalVariableType(SymbolKind K) { 2310b57cec5SDimitry Andric switch (K) { 2320b57cec5SDimitry Andric case S_REGISTER: 2330b57cec5SDimitry Andric case S_REGREL32: 2340b57cec5SDimitry Andric case S_LOCAL: 2350b57cec5SDimitry Andric return true; 2360b57cec5SDimitry Andric default: 2370b57cec5SDimitry Andric break; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric return false; 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) { 243bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 244bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 245bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 246bdd1243dSDimitry Andric CVSymbol cvs = index.ReadSymbolRecord(id); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric if (isLocalVariableType(cvs.kind())) { 2490b57cec5SDimitry Andric clang::DeclContext *scope = GetParentDeclContext(id); 250bdd1243dSDimitry Andric if (!scope) 251bdd1243dSDimitry Andric return nullptr; 2520b57cec5SDimitry Andric clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope); 25381ad6265SDimitry Andric PdbCompilandSymId scope_id = 25481ad6265SDimitry Andric PdbSymUid(m_decl_to_status[scope_decl].uid).asCompilandSym(); 2550b57cec5SDimitry Andric return GetOrCreateVariableDecl(scope_id, id); 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric switch (cvs.kind()) { 2590b57cec5SDimitry Andric case S_GPROC32: 2600b57cec5SDimitry Andric case S_LPROC32: 2610b57cec5SDimitry Andric return GetOrCreateFunctionDecl(id); 2620b57cec5SDimitry Andric case S_GDATA32: 2630b57cec5SDimitry Andric case S_LDATA32: 2640b57cec5SDimitry Andric case S_GTHREAD32: 2650b57cec5SDimitry Andric case S_CONSTANT: 2660b57cec5SDimitry Andric // global variable 2670b57cec5SDimitry Andric return nullptr; 2680b57cec5SDimitry Andric case S_BLOCK32: 2690b57cec5SDimitry Andric return GetOrCreateBlockDecl(id); 27081ad6265SDimitry Andric case S_INLINESITE: 27181ad6265SDimitry Andric return GetOrCreateInlinedFunctionDecl(id); 2720b57cec5SDimitry Andric default: 2730b57cec5SDimitry Andric return nullptr; 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 277bdd1243dSDimitry Andric std::optional<CompilerDecl> 278bdd1243dSDimitry Andric PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) { 2790b57cec5SDimitry Andric if (clang::Decl *result = TryGetDecl(uid)) 2809dba64beSDimitry Andric return ToCompilerDecl(*result); 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric clang::Decl *result = nullptr; 2830b57cec5SDimitry Andric switch (uid.kind()) { 2840b57cec5SDimitry Andric case PdbSymUidKind::CompilandSym: 2850b57cec5SDimitry Andric result = GetOrCreateSymbolForId(uid.asCompilandSym()); 2860b57cec5SDimitry Andric break; 2870b57cec5SDimitry Andric case PdbSymUidKind::Type: { 2880b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(uid.asTypeSym()); 28981ad6265SDimitry Andric if (qt.isNull()) 290bdd1243dSDimitry Andric return std::nullopt; 2910b57cec5SDimitry Andric if (auto *tag = qt->getAsTagDecl()) { 2920b57cec5SDimitry Andric result = tag; 2930b57cec5SDimitry Andric break; 2940b57cec5SDimitry Andric } 295bdd1243dSDimitry Andric return std::nullopt; 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric default: 298bdd1243dSDimitry Andric return std::nullopt; 2990b57cec5SDimitry Andric } 30081ad6265SDimitry Andric 30181ad6265SDimitry Andric if (!result) 302bdd1243dSDimitry Andric return std::nullopt; 3030b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(uid)] = result; 3049dba64beSDimitry Andric return ToCompilerDecl(*result); 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) { 3080b57cec5SDimitry Andric if (uid.kind() == PdbSymUidKind::CompilandSym) { 3090b57cec5SDimitry Andric if (uid.asCompilandSym().offset == 0) 3100b57cec5SDimitry Andric return FromCompilerDeclContext(GetTranslationUnitDecl()); 3110b57cec5SDimitry Andric } 3129dba64beSDimitry Andric auto option = GetOrCreateDeclForUid(uid); 3139dba64beSDimitry Andric if (!option) 3149dba64beSDimitry Andric return nullptr; 31581ad6265SDimitry Andric clang::Decl *decl = FromCompilerDecl(*option); 3160b57cec5SDimitry Andric if (!decl) 3170b57cec5SDimitry Andric return nullptr; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric return clang::Decl::castToDeclContext(decl); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric std::pair<clang::DeclContext *, std::string> 3230b57cec5SDimitry Andric PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { 324bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 325bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 326bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 3270b57cec5SDimitry Andric MSVCUndecoratedNameParser parser(name); 3280b57cec5SDimitry Andric llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 3290b57cec5SDimitry Andric 330bdd1243dSDimitry Andric auto *context = FromCompilerDeclContext(GetTranslationUnitDecl()); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric llvm::StringRef uname = specs.back().GetBaseName(); 3330b57cec5SDimitry Andric specs = specs.drop_back(); 3340b57cec5SDimitry Andric if (specs.empty()) 3355ffd83dbSDimitry Andric return {context, std::string(name)}; 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric llvm::StringRef scope_name = specs.back().GetFullName(); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric // It might be a class name, try that first. 340bdd1243dSDimitry Andric std::vector<TypeIndex> types = index.tpi().findRecordsByName(scope_name); 3410b57cec5SDimitry Andric while (!types.empty()) { 3420b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(types.back()); 34381ad6265SDimitry Andric if (qt.isNull()) 34481ad6265SDimitry Andric continue; 3450b57cec5SDimitry Andric clang::TagDecl *tag = qt->getAsTagDecl(); 3460b57cec5SDimitry Andric if (tag) 3475ffd83dbSDimitry Andric return {clang::TagDecl::castToDeclContext(tag), std::string(uname)}; 3480b57cec5SDimitry Andric types.pop_back(); 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric // If that fails, treat it as a series of namespaces. 3520b57cec5SDimitry Andric for (const MSVCUndecoratedNameSpecifier &spec : specs) { 3530b57cec5SDimitry Andric std::string ns_name = spec.GetBaseName().str(); 3540b57cec5SDimitry Andric context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context); 3550b57cec5SDimitry Andric } 3565ffd83dbSDimitry Andric return {context, std::string(uname)}; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) { 3600b57cec5SDimitry Andric // We must do this *without* calling GetOrCreate on the current uid, as 3610b57cec5SDimitry Andric // that would be an infinite recursion. 362bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 363bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 364bdd1243dSDimitry Andric PdbIndex& index = pdb->GetIndex(); 3650b57cec5SDimitry Andric switch (uid.kind()) { 3660b57cec5SDimitry Andric case PdbSymUidKind::CompilandSym: { 367bdd1243dSDimitry Andric std::optional<PdbCompilandSymId> scope = 368bdd1243dSDimitry Andric pdb->FindSymbolScope(uid.asCompilandSym()); 3690b57cec5SDimitry Andric if (scope) 3700b57cec5SDimitry Andric return GetOrCreateDeclContextForUid(*scope); 3710b57cec5SDimitry Andric 372bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(uid.asCompilandSym()); 373bdd1243dSDimitry Andric return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first; 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric case PdbSymUidKind::Type: { 3760b57cec5SDimitry Andric // It could be a namespace, class, or global. We don't support nested 3770b57cec5SDimitry Andric // functions yet. Anyway, we just need to consult the parent type map. 3780b57cec5SDimitry Andric PdbTypeSymId type_id = uid.asTypeSym(); 379bdd1243dSDimitry Andric std::optional<TypeIndex> parent_index = pdb->GetParentType(type_id.index); 380bdd1243dSDimitry Andric if (!parent_index) 3810b57cec5SDimitry Andric return FromCompilerDeclContext(GetTranslationUnitDecl()); 382bdd1243dSDimitry Andric return GetOrCreateDeclContextForUid(PdbTypeSymId(*parent_index)); 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric case PdbSymUidKind::FieldListMember: 3850b57cec5SDimitry Andric // In this case the parent DeclContext is the one for the class that this 3860b57cec5SDimitry Andric // member is inside of. 3870b57cec5SDimitry Andric break; 3880b57cec5SDimitry Andric case PdbSymUidKind::GlobalSym: { 3890b57cec5SDimitry Andric // If this refers to a compiland symbol, just recurse in with that symbol. 3900b57cec5SDimitry Andric // The only other possibilities are S_CONSTANT and S_UDT, in which case we 3910b57cec5SDimitry Andric // need to parse the undecorated name to figure out the scope, then look 3920b57cec5SDimitry Andric // that up in the TPI stream. If it's found, it's a type, othewrise it's 3930b57cec5SDimitry Andric // a series of namespaces. 3940b57cec5SDimitry Andric // FIXME: do this. 395bdd1243dSDimitry Andric CVSymbol global = index.ReadSymbolRecord(uid.asGlobalSym()); 3960b57cec5SDimitry Andric switch (global.kind()) { 3970b57cec5SDimitry Andric case SymbolKind::S_GDATA32: 3980b57cec5SDimitry Andric case SymbolKind::S_LDATA32: 399bdd1243dSDimitry Andric return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;; 4000b57cec5SDimitry Andric case SymbolKind::S_PROCREF: 4010b57cec5SDimitry Andric case SymbolKind::S_LPROCREF: { 4020b57cec5SDimitry Andric ProcRefSym ref{global.kind()}; 4030b57cec5SDimitry Andric llvm::cantFail( 4040b57cec5SDimitry Andric SymbolDeserializer::deserializeAs<ProcRefSym>(global, ref)); 4050b57cec5SDimitry Andric PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset}; 4060b57cec5SDimitry Andric return GetParentDeclContext(cu_sym_id); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric case SymbolKind::S_CONSTANT: 4090b57cec5SDimitry Andric case SymbolKind::S_UDT: 4100b57cec5SDimitry Andric return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first; 4110b57cec5SDimitry Andric default: 4120b57cec5SDimitry Andric break; 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric break; 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric default: 4170b57cec5SDimitry Andric break; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric return FromCompilerDeclContext(GetTranslationUnitDecl()); 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric bool PdbAstBuilder::CompleteType(clang::QualType qt) { 42381ad6265SDimitry Andric if (qt.isNull()) 42481ad6265SDimitry Andric return false; 4250b57cec5SDimitry Andric clang::TagDecl *tag = qt->getAsTagDecl(); 42681ad6265SDimitry Andric if (qt->isArrayType()) { 42781ad6265SDimitry Andric const clang::Type *element_type = qt->getArrayElementTypeNoTypeQual(); 42881ad6265SDimitry Andric tag = element_type->getAsTagDecl(); 42981ad6265SDimitry Andric } 4300b57cec5SDimitry Andric if (!tag) 4310b57cec5SDimitry Andric return false; 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric return CompleteTagDecl(*tag); 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { 4370b57cec5SDimitry Andric // If this is not in our map, it's an error. 4380b57cec5SDimitry Andric auto status_iter = m_decl_to_status.find(&tag); 4390b57cec5SDimitry Andric lldbassert(status_iter != m_decl_to_status.end()); 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric // If it's already complete, just return. 4420b57cec5SDimitry Andric DeclStatus &status = status_iter->second; 4430b57cec5SDimitry Andric if (status.resolved) 4440b57cec5SDimitry Andric return true; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym(); 447bdd1243dSDimitry Andric PdbIndex &index = static_cast<SymbolFileNativePDB *>( 448bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()) 449bdd1243dSDimitry Andric ->GetIndex(); 450bdd1243dSDimitry Andric lldbassert(IsTagRecord(type_id, index.tpi())); 4510b57cec5SDimitry Andric 452480093f4SDimitry Andric clang::QualType tag_qt = m_clang.getASTContext().getTypeDeclType(&tag); 4535ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false); 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric TypeIndex tag_ti = type_id.index; 456bdd1243dSDimitry Andric CVType cvt = index.tpi().getType(tag_ti); 4570b57cec5SDimitry Andric if (cvt.kind() == LF_MODIFIER) 4580b57cec5SDimitry Andric tag_ti = LookThroughModifierRecord(cvt); 4590b57cec5SDimitry Andric 460bdd1243dSDimitry Andric PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, index.tpi()); 461bdd1243dSDimitry Andric cvt = index.tpi().getType(best_ti.index); 4620b57cec5SDimitry Andric lldbassert(IsTagRecord(cvt)); 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric if (IsForwardRefUdt(cvt)) { 4650b57cec5SDimitry Andric // If we can't find a full decl for this forward ref anywhere in the debug 4660b57cec5SDimitry Andric // info, then we have no way to complete it. 4670b57cec5SDimitry Andric return false; 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric TypeIndex field_list_ti = GetFieldListIndex(cvt); 471bdd1243dSDimitry Andric CVType field_list_cvt = index.tpi().getType(field_list_ti); 4720b57cec5SDimitry Andric if (field_list_cvt.kind() != LF_FIELDLIST) 4730b57cec5SDimitry Andric return false; 47481ad6265SDimitry Andric FieldListRecord field_list; 47581ad6265SDimitry Andric if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( 47681ad6265SDimitry Andric field_list_cvt, field_list)) 47781ad6265SDimitry Andric llvm::consumeError(std::move(error)); 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric // Visit all members of this class, then perform any finalization necessary 4800b57cec5SDimitry Andric // to complete the class. 4810b57cec5SDimitry Andric CompilerType ct = ToCompilerType(tag_qt); 482bdd1243dSDimitry Andric UdtRecordCompleter completer(best_ti, ct, tag, *this, index, m_decl_to_status, 4830eae32dcSDimitry Andric m_cxx_record_map); 48481ad6265SDimitry Andric llvm::Error error = 48581ad6265SDimitry Andric llvm::codeview::visitMemberRecordStream(field_list.Data, completer); 4860b57cec5SDimitry Andric completer.complete(); 4870b57cec5SDimitry Andric 488bdd1243dSDimitry Andric m_decl_to_status[&tag].resolved = true; 48981ad6265SDimitry Andric if (error) { 4900b57cec5SDimitry Andric llvm::consumeError(std::move(error)); 4910b57cec5SDimitry Andric return false; 4920b57cec5SDimitry Andric } 49381ad6265SDimitry Andric return true; 49481ad6265SDimitry Andric } 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) { 4970b57cec5SDimitry Andric if (ti == TypeIndex::NullptrT()) 4980b57cec5SDimitry Andric return GetBasicType(lldb::eBasicTypeNullPtr); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric if (ti.getSimpleMode() != SimpleTypeMode::Direct) { 5010b57cec5SDimitry Andric clang::QualType direct_type = GetOrCreateType(ti.makeDirect()); 50281ad6265SDimitry Andric if (direct_type.isNull()) 50381ad6265SDimitry Andric return {}; 504480093f4SDimitry Andric return m_clang.getASTContext().getPointerType(direct_type); 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) 5080b57cec5SDimitry Andric return {}; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind()); 5110b57cec5SDimitry Andric if (bt == lldb::eBasicTypeInvalid) 5120b57cec5SDimitry Andric return {}; 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric return GetBasicType(bt); 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) { 5180b57cec5SDimitry Andric clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType); 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric // This can happen for pointers to LF_VTSHAPE records, which we shouldn't 5210b57cec5SDimitry Andric // create in the AST. 5220b57cec5SDimitry Andric if (pointee_type.isNull()) 5230b57cec5SDimitry Andric return {}; 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric if (pointer.isPointerToMember()) { 5260b57cec5SDimitry Andric MemberPointerInfo mpi = pointer.getMemberInfo(); 5270b57cec5SDimitry Andric clang::QualType class_type = GetOrCreateType(mpi.ContainingType); 52881ad6265SDimitry Andric if (class_type.isNull()) 52981ad6265SDimitry Andric return {}; 530fcaf7f86SDimitry Andric if (clang::TagDecl *tag = class_type->getAsTagDecl()) { 531fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling spelling; 532fcaf7f86SDimitry Andric switch (mpi.Representation) { 533fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::SingleInheritanceData: 534fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation:: 535fcaf7f86SDimitry Andric SingleInheritanceFunction: 536fcaf7f86SDimitry Andric spelling = 537fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance; 538fcaf7f86SDimitry Andric break; 539fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation:: 540fcaf7f86SDimitry Andric MultipleInheritanceData: 541fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation:: 542fcaf7f86SDimitry Andric MultipleInheritanceFunction: 543fcaf7f86SDimitry Andric spelling = 544fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_multiple_inheritance; 545fcaf7f86SDimitry Andric break; 546fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation:: 547fcaf7f86SDimitry Andric VirtualInheritanceData: 548fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation:: 549fcaf7f86SDimitry Andric VirtualInheritanceFunction: 550fcaf7f86SDimitry Andric spelling = 551fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_virtual_inheritance; 552fcaf7f86SDimitry Andric break; 553fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::Unknown: 554fcaf7f86SDimitry Andric spelling = 555fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_unspecified_inheritance; 556fcaf7f86SDimitry Andric break; 557fcaf7f86SDimitry Andric default: 558fcaf7f86SDimitry Andric spelling = clang::MSInheritanceAttr::Spelling::SpellingNotCalculated; 559fcaf7f86SDimitry Andric break; 560fcaf7f86SDimitry Andric } 561fcaf7f86SDimitry Andric tag->addAttr(clang::MSInheritanceAttr::CreateImplicit( 562fcaf7f86SDimitry Andric m_clang.getASTContext(), spelling)); 563fcaf7f86SDimitry Andric } 564480093f4SDimitry Andric return m_clang.getASTContext().getMemberPointerType( 5650b57cec5SDimitry Andric pointee_type, class_type.getTypePtr()); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric clang::QualType pointer_type; 5690b57cec5SDimitry Andric if (pointer.getMode() == PointerMode::LValueReference) 570480093f4SDimitry Andric pointer_type = m_clang.getASTContext().getLValueReferenceType(pointee_type); 5710b57cec5SDimitry Andric else if (pointer.getMode() == PointerMode::RValueReference) 572480093f4SDimitry Andric pointer_type = m_clang.getASTContext().getRValueReferenceType(pointee_type); 5730b57cec5SDimitry Andric else 574480093f4SDimitry Andric pointer_type = m_clang.getASTContext().getPointerType(pointee_type); 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric if ((pointer.getOptions() & PointerOptions::Const) != PointerOptions::None) 5770b57cec5SDimitry Andric pointer_type.addConst(); 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric if ((pointer.getOptions() & PointerOptions::Volatile) != PointerOptions::None) 5800b57cec5SDimitry Andric pointer_type.addVolatile(); 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric if ((pointer.getOptions() & PointerOptions::Restrict) != PointerOptions::None) 5830b57cec5SDimitry Andric pointer_type.addRestrict(); 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric return pointer_type; 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric clang::QualType 5890b57cec5SDimitry Andric PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) { 5900b57cec5SDimitry Andric clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType); 5910b57cec5SDimitry Andric if (unmodified_type.isNull()) 5920b57cec5SDimitry Andric return {}; 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None) 5950b57cec5SDimitry Andric unmodified_type.addConst(); 5960b57cec5SDimitry Andric if ((modifier.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None) 5970b57cec5SDimitry Andric unmodified_type.addVolatile(); 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric return unmodified_type; 6000b57cec5SDimitry Andric } 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, 6030b57cec5SDimitry Andric const TagRecord &record) { 6040b57cec5SDimitry Andric clang::DeclContext *context = nullptr; 6050b57cec5SDimitry Andric std::string uname; 6060b57cec5SDimitry Andric std::tie(context, uname) = CreateDeclInfoForType(record, id.index); 60781ad6265SDimitry Andric if (!context) 60881ad6265SDimitry Andric return {}; 60981ad6265SDimitry Andric 6100b57cec5SDimitry Andric clang::TagTypeKind ttk = TranslateUdtKind(record); 611*5f757f3fSDimitry Andric lldb::AccessType access = (ttk == clang::TagTypeKind::Class) 612*5f757f3fSDimitry Andric ? lldb::eAccessPrivate 613*5f757f3fSDimitry Andric : lldb::eAccessPublic; 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric ClangASTMetadata metadata; 6160b57cec5SDimitry Andric metadata.SetUserID(toOpaqueUid(id)); 6170b57cec5SDimitry Andric metadata.SetIsDynamicCXXType(false); 6180b57cec5SDimitry Andric 619*5f757f3fSDimitry Andric CompilerType ct = m_clang.CreateRecordType( 620*5f757f3fSDimitry Andric context, OptionalClangModuleID(), access, uname, llvm::to_underlying(ttk), 621*5f757f3fSDimitry Andric lldb::eLanguageTypeC_plus_plus, &metadata); 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric lldbassert(ct.IsValid()); 6240b57cec5SDimitry Andric 6255ffd83dbSDimitry Andric TypeSystemClang::StartTagDeclarationDefinition(ct); 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric // Even if it's possible, don't complete it at this point. Just mark it 6280b57cec5SDimitry Andric // forward resolved, and if/when LLDB needs the full definition, it can 6290b57cec5SDimitry Andric // ask us. 6300b57cec5SDimitry Andric clang::QualType result = 6310b57cec5SDimitry Andric clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); 6320b57cec5SDimitry Andric 6335ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true); 6340b57cec5SDimitry Andric return result; 6350b57cec5SDimitry Andric } 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const { 6380b57cec5SDimitry Andric auto iter = m_uid_to_decl.find(toOpaqueUid(uid)); 6390b57cec5SDimitry Andric if (iter != m_uid_to_decl.end()) 6400b57cec5SDimitry Andric return iter->second; 6410b57cec5SDimitry Andric return nullptr; 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric clang::NamespaceDecl * 6450b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name, 6460b57cec5SDimitry Andric clang::DeclContext &context) { 6470b57cec5SDimitry Andric return m_clang.GetUniqueNamespaceDeclaration( 6485ffd83dbSDimitry Andric IsAnonymousNamespaceName(name) ? nullptr : name, &context, 6495ffd83dbSDimitry Andric OptionalClangModuleID()); 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric clang::BlockDecl * 6530b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) { 6540b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(block_id)) 6550b57cec5SDimitry Andric return llvm::dyn_cast<clang::BlockDecl>(decl); 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric clang::DeclContext *scope = GetParentDeclContext(block_id); 6580b57cec5SDimitry Andric 6595ffd83dbSDimitry Andric clang::BlockDecl *block_decl = 6605ffd83dbSDimitry Andric m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID()); 6610b57cec5SDimitry Andric m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl}); 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric DeclStatus status; 6640b57cec5SDimitry Andric status.resolved = true; 6650b57cec5SDimitry Andric status.uid = toOpaqueUid(block_id); 6660b57cec5SDimitry Andric m_decl_to_status.insert({block_decl, status}); 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andric return block_decl; 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym, 6720b57cec5SDimitry Andric clang::DeclContext &scope) { 6730b57cec5SDimitry Andric VariableInfo var_info = GetVariableNameInfo(sym); 6740b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(var_info.type); 67581ad6265SDimitry Andric if (qt.isNull()) 67681ad6265SDimitry Andric return nullptr; 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( 6795ffd83dbSDimitry Andric &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt); 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(uid)] = var_decl; 6820b57cec5SDimitry Andric DeclStatus status; 6830b57cec5SDimitry Andric status.resolved = true; 6840b57cec5SDimitry Andric status.uid = toOpaqueUid(uid); 6850b57cec5SDimitry Andric m_decl_to_status.insert({var_decl, status}); 6860b57cec5SDimitry Andric return var_decl; 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric clang::VarDecl * 6900b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id, 6910b57cec5SDimitry Andric PdbCompilandSymId var_id) { 6920b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(var_id)) 6930b57cec5SDimitry Andric return llvm::dyn_cast<clang::VarDecl>(decl); 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id); 69681ad6265SDimitry Andric if (!scope) 69781ad6265SDimitry Andric return nullptr; 6980b57cec5SDimitry Andric 699bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 700bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 701bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 702bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(var_id); 7030b57cec5SDimitry Andric return CreateVariableDecl(PdbSymUid(var_id), sym, *scope); 7040b57cec5SDimitry Andric } 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) { 7070b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(var_id)) 7080b57cec5SDimitry Andric return llvm::dyn_cast<clang::VarDecl>(decl); 7090b57cec5SDimitry Andric 710bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 711bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 712bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 713bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(var_id); 7140b57cec5SDimitry Andric auto context = FromCompilerDeclContext(GetTranslationUnitDecl()); 7150b57cec5SDimitry Andric return CreateVariableDecl(PdbSymUid(var_id), sym, *context); 7160b57cec5SDimitry Andric } 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric clang::TypedefNameDecl * 7190b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) { 7200b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(id)) 7210b57cec5SDimitry Andric return llvm::dyn_cast<clang::TypedefNameDecl>(decl); 7220b57cec5SDimitry Andric 723bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 724bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 725bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 726bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(id); 7270b57cec5SDimitry Andric lldbassert(sym.kind() == S_UDT); 7280b57cec5SDimitry Andric UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric clang::DeclContext *scope = GetParentDeclContext(id); 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric PdbTypeSymId real_type_id{udt.Type, false}; 7330b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(real_type_id); 734bdd1243dSDimitry Andric if (qt.isNull() || !scope) 73581ad6265SDimitry Andric return nullptr; 7360b57cec5SDimitry Andric 7375ffd83dbSDimitry Andric std::string uname = std::string(DropNameScope(udt.Name)); 7380b57cec5SDimitry Andric 739e8d8bef9SDimitry Andric CompilerType ct = ToCompilerType(qt).CreateTypedef( 740e8d8bef9SDimitry Andric uname.c_str(), ToCompilerDeclContext(*scope), 0); 7410b57cec5SDimitry Andric clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct); 7420b57cec5SDimitry Andric DeclStatus status; 7430b57cec5SDimitry Andric status.resolved = true; 7440b57cec5SDimitry Andric status.uid = toOpaqueUid(id); 7450b57cec5SDimitry Andric m_decl_to_status.insert({tnd, status}); 7460b57cec5SDimitry Andric return tnd; 7470b57cec5SDimitry Andric } 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) { 7500b57cec5SDimitry Andric CompilerType ct = m_clang.GetBasicType(type); 7510b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) { 7550b57cec5SDimitry Andric if (type.index.isSimple()) 7560b57cec5SDimitry Andric return CreateSimpleType(type.index); 7570b57cec5SDimitry Andric 758bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 759bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 760bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 761bdd1243dSDimitry Andric CVType cvt = index.tpi().getType(type.index); 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric if (cvt.kind() == LF_MODIFIER) { 7640b57cec5SDimitry Andric ModifierRecord modifier; 7650b57cec5SDimitry Andric llvm::cantFail( 7660b57cec5SDimitry Andric TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)); 7670b57cec5SDimitry Andric return CreateModifierType(modifier); 7680b57cec5SDimitry Andric } 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andric if (cvt.kind() == LF_POINTER) { 7710b57cec5SDimitry Andric PointerRecord pointer; 7720b57cec5SDimitry Andric llvm::cantFail( 7730b57cec5SDimitry Andric TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)); 7740b57cec5SDimitry Andric return CreatePointerType(pointer); 7750b57cec5SDimitry Andric } 7760b57cec5SDimitry Andric 7770b57cec5SDimitry Andric if (IsTagRecord(cvt)) { 7780b57cec5SDimitry Andric CVTagRecord tag = CVTagRecord::create(cvt); 7790b57cec5SDimitry Andric if (tag.kind() == CVTagRecord::Union) 7800b57cec5SDimitry Andric return CreateRecordType(type.index, tag.asUnion()); 7810b57cec5SDimitry Andric if (tag.kind() == CVTagRecord::Enum) 7820b57cec5SDimitry Andric return CreateEnumType(type.index, tag.asEnum()); 7830b57cec5SDimitry Andric return CreateRecordType(type.index, tag.asClass()); 7840b57cec5SDimitry Andric } 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric if (cvt.kind() == LF_ARRAY) { 7870b57cec5SDimitry Andric ArrayRecord ar; 7880b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)); 7890b57cec5SDimitry Andric return CreateArrayType(ar); 7900b57cec5SDimitry Andric } 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric if (cvt.kind() == LF_PROCEDURE) { 7930b57cec5SDimitry Andric ProcedureRecord pr; 7940b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)); 7950b57cec5SDimitry Andric return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv); 7960b57cec5SDimitry Andric } 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric if (cvt.kind() == LF_MFUNCTION) { 7990b57cec5SDimitry Andric MemberFunctionRecord mfr; 8000b57cec5SDimitry Andric llvm::cantFail( 8010b57cec5SDimitry Andric TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)); 8020b57cec5SDimitry Andric return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv); 8030b57cec5SDimitry Andric } 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andric return {}; 8060b57cec5SDimitry Andric } 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { 80981ad6265SDimitry Andric if (type.index.isNoneType()) 81081ad6265SDimitry Andric return {}; 81181ad6265SDimitry Andric 8120b57cec5SDimitry Andric lldb::user_id_t uid = toOpaqueUid(type); 8130b57cec5SDimitry Andric auto iter = m_uid_to_type.find(uid); 8140b57cec5SDimitry Andric if (iter != m_uid_to_type.end()) 8150b57cec5SDimitry Andric return iter->second; 8160b57cec5SDimitry Andric 817bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 818bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 819bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 820bdd1243dSDimitry Andric PdbTypeSymId best_type = GetBestPossibleDecl(type, index.tpi()); 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric clang::QualType qt; 8230b57cec5SDimitry Andric if (best_type.index != type.index) { 8240b57cec5SDimitry Andric // This is a forward decl. Call GetOrCreate on the full decl, then map the 8250b57cec5SDimitry Andric // forward decl id to the full decl QualType. 8260b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(best_type); 82781ad6265SDimitry Andric if (qt.isNull()) 82881ad6265SDimitry Andric return {}; 8290b57cec5SDimitry Andric m_uid_to_type[toOpaqueUid(type)] = qt; 8300b57cec5SDimitry Andric return qt; 8310b57cec5SDimitry Andric } 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric // This is either a full decl, or a forward decl with no matching full decl 8340b57cec5SDimitry Andric // in the debug info. 8350b57cec5SDimitry Andric qt = CreateType(type); 83681ad6265SDimitry Andric if (qt.isNull()) 83781ad6265SDimitry Andric return {}; 83881ad6265SDimitry Andric 8390b57cec5SDimitry Andric m_uid_to_type[toOpaqueUid(type)] = qt; 840bdd1243dSDimitry Andric if (IsTagRecord(type, index.tpi())) { 8410b57cec5SDimitry Andric clang::TagDecl *tag = qt->getAsTagDecl(); 8420b57cec5SDimitry Andric lldbassert(m_decl_to_status.count(tag) == 0); 8430b57cec5SDimitry Andric 8440b57cec5SDimitry Andric DeclStatus &status = m_decl_to_status[tag]; 8450b57cec5SDimitry Andric status.uid = uid; 8460b57cec5SDimitry Andric status.resolved = false; 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric return qt; 8490b57cec5SDimitry Andric } 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric clang::FunctionDecl * 85281ad6265SDimitry Andric PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id, 85381ad6265SDimitry Andric llvm::StringRef func_name, TypeIndex func_ti, 85481ad6265SDimitry Andric CompilerType func_ct, uint32_t param_count, 85581ad6265SDimitry Andric clang::StorageClass func_storage, 85681ad6265SDimitry Andric bool is_inline, clang::DeclContext *parent) { 85781ad6265SDimitry Andric clang::FunctionDecl *function_decl = nullptr; 85881ad6265SDimitry Andric if (parent->isRecord()) { 859bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 860bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 861bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 86281ad6265SDimitry Andric clang::QualType parent_qt = llvm::cast<clang::TypeDecl>(parent) 86381ad6265SDimitry Andric ->getTypeForDecl() 86481ad6265SDimitry Andric ->getCanonicalTypeInternal(); 86581ad6265SDimitry Andric lldb::opaque_compiler_type_t parent_opaque_ty = 86681ad6265SDimitry Andric ToCompilerType(parent_qt).GetOpaqueQualType(); 86781ad6265SDimitry Andric // FIXME: Remove this workaround. 86881ad6265SDimitry Andric auto iter = m_cxx_record_map.find(parent_opaque_ty); 86981ad6265SDimitry Andric if (iter != m_cxx_record_map.end()) { 87081ad6265SDimitry Andric if (iter->getSecond().contains({func_name, func_ct})) { 87181ad6265SDimitry Andric return nullptr; 87281ad6265SDimitry Andric } 87381ad6265SDimitry Andric } 87481ad6265SDimitry Andric 875bdd1243dSDimitry Andric CVType cvt = index.tpi().getType(func_ti); 87681ad6265SDimitry Andric MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind())); 87781ad6265SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>( 87881ad6265SDimitry Andric cvt, func_record)); 87981ad6265SDimitry Andric TypeIndex class_index = func_record.getClassType(); 88081ad6265SDimitry Andric 881bdd1243dSDimitry Andric CVType parent_cvt = index.tpi().getType(class_index); 88281ad6265SDimitry Andric TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag(); 88381ad6265SDimitry Andric // If it's a forward reference, try to get the real TypeIndex. 88481ad6265SDimitry Andric if (tag_record.isForwardRef()) { 88581ad6265SDimitry Andric llvm::Expected<TypeIndex> eti = 886bdd1243dSDimitry Andric index.tpi().findFullDeclForForwardRef(class_index); 88781ad6265SDimitry Andric if (eti) { 888bdd1243dSDimitry Andric tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag(); 88981ad6265SDimitry Andric } 89081ad6265SDimitry Andric } 89181ad6265SDimitry Andric if (!tag_record.FieldList.isSimple()) { 892bdd1243dSDimitry Andric CVType field_list_cvt = index.tpi().getType(tag_record.FieldList); 89381ad6265SDimitry Andric FieldListRecord field_list; 89481ad6265SDimitry Andric if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( 89581ad6265SDimitry Andric field_list_cvt, field_list)) 89681ad6265SDimitry Andric llvm::consumeError(std::move(error)); 897bdd1243dSDimitry Andric CreateMethodDecl process(index, m_clang, func_ti, function_decl, 89881ad6265SDimitry Andric parent_opaque_ty, func_name, func_ct); 89981ad6265SDimitry Andric if (llvm::Error err = visitMemberRecordStream(field_list.Data, process)) 90081ad6265SDimitry Andric llvm::consumeError(std::move(err)); 90181ad6265SDimitry Andric } 90281ad6265SDimitry Andric 90381ad6265SDimitry Andric if (!function_decl) { 90481ad6265SDimitry Andric function_decl = m_clang.AddMethodToCXXRecordType( 90581ad6265SDimitry Andric parent_opaque_ty, func_name, 90681ad6265SDimitry Andric /*mangled_name=*/nullptr, func_ct, 90781ad6265SDimitry Andric /*access=*/lldb::AccessType::eAccessPublic, 90881ad6265SDimitry Andric /*is_virtual=*/false, /*is_static=*/false, 90981ad6265SDimitry Andric /*is_inline=*/false, /*is_explicit=*/false, 91081ad6265SDimitry Andric /*is_attr_used=*/false, /*is_artificial=*/false); 91181ad6265SDimitry Andric } 91281ad6265SDimitry Andric m_cxx_record_map[parent_opaque_ty].insert({func_name, func_ct}); 91381ad6265SDimitry Andric } else { 91481ad6265SDimitry Andric function_decl = m_clang.CreateFunctionDeclaration( 91581ad6265SDimitry Andric parent, OptionalClangModuleID(), func_name, func_ct, func_storage, 91681ad6265SDimitry Andric is_inline); 91781ad6265SDimitry Andric CreateFunctionParameters(func_id, *function_decl, param_count); 91881ad6265SDimitry Andric } 91981ad6265SDimitry Andric return function_decl; 92081ad6265SDimitry Andric } 92181ad6265SDimitry Andric 92281ad6265SDimitry Andric clang::FunctionDecl * 92381ad6265SDimitry Andric PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) { 924bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 925bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 926bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 92781ad6265SDimitry Andric CompilandIndexItem *cii = 928bdd1243dSDimitry Andric index.compilands().GetCompiland(inlinesite_id.modi); 92981ad6265SDimitry Andric CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset); 93081ad6265SDimitry Andric InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind())); 93181ad6265SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)); 93281ad6265SDimitry Andric 93381ad6265SDimitry Andric // Inlinee is the id index to the function id record that is inlined. 93481ad6265SDimitry Andric PdbTypeSymId func_id(inline_site.Inlinee, true); 93581ad6265SDimitry Andric // Look up the function decl by the id index to see if we have created a 93681ad6265SDimitry Andric // function decl for a different inlinesite that refers the same function. 93781ad6265SDimitry Andric if (clang::Decl *decl = TryGetDecl(func_id)) 93881ad6265SDimitry Andric return llvm::dyn_cast<clang::FunctionDecl>(decl); 93981ad6265SDimitry Andric clang::FunctionDecl *function_decl = 94081ad6265SDimitry Andric CreateFunctionDeclFromId(func_id, inlinesite_id); 94181ad6265SDimitry Andric if (function_decl == nullptr) 94281ad6265SDimitry Andric return nullptr; 94381ad6265SDimitry Andric 94481ad6265SDimitry Andric // Use inline site id in m_decl_to_status because it's expected to be a 94581ad6265SDimitry Andric // PdbCompilandSymId so that we can parse local variables info after it. 94681ad6265SDimitry Andric uint64_t inlinesite_uid = toOpaqueUid(inlinesite_id); 94781ad6265SDimitry Andric DeclStatus status; 94881ad6265SDimitry Andric status.resolved = true; 94981ad6265SDimitry Andric status.uid = inlinesite_uid; 95081ad6265SDimitry Andric m_decl_to_status.insert({function_decl, status}); 95181ad6265SDimitry Andric // Use the index in IPI stream as uid in m_uid_to_decl, because index in IPI 95281ad6265SDimitry Andric // stream are unique and there could be multiple inline sites (different ids) 95381ad6265SDimitry Andric // referring the same inline function. This avoid creating multiple same 95481ad6265SDimitry Andric // inline function delcs. 95581ad6265SDimitry Andric uint64_t func_uid = toOpaqueUid(func_id); 95681ad6265SDimitry Andric lldbassert(m_uid_to_decl.count(func_uid) == 0); 95781ad6265SDimitry Andric m_uid_to_decl[func_uid] = function_decl; 95881ad6265SDimitry Andric return function_decl; 95981ad6265SDimitry Andric } 96081ad6265SDimitry Andric 96181ad6265SDimitry Andric clang::FunctionDecl * 96281ad6265SDimitry Andric PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid, 96381ad6265SDimitry Andric PdbCompilandSymId func_sid) { 96481ad6265SDimitry Andric lldbassert(func_tid.is_ipi); 965bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 966bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 967bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 968bdd1243dSDimitry Andric CVType func_cvt = index.ipi().getType(func_tid.index); 96981ad6265SDimitry Andric llvm::StringRef func_name; 97081ad6265SDimitry Andric TypeIndex func_ti; 97181ad6265SDimitry Andric clang::DeclContext *parent = nullptr; 97281ad6265SDimitry Andric switch (func_cvt.kind()) { 97381ad6265SDimitry Andric case LF_MFUNC_ID: { 97481ad6265SDimitry Andric MemberFuncIdRecord mfr; 97581ad6265SDimitry Andric cantFail( 97681ad6265SDimitry Andric TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr)); 97781ad6265SDimitry Andric func_name = mfr.getName(); 97881ad6265SDimitry Andric func_ti = mfr.getFunctionType(); 97981ad6265SDimitry Andric PdbTypeSymId class_type_id(mfr.ClassType, false); 98081ad6265SDimitry Andric parent = GetOrCreateDeclContextForUid(class_type_id); 98181ad6265SDimitry Andric break; 98281ad6265SDimitry Andric } 98381ad6265SDimitry Andric case LF_FUNC_ID: { 98481ad6265SDimitry Andric FuncIdRecord fir; 98581ad6265SDimitry Andric cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir)); 98681ad6265SDimitry Andric func_name = fir.getName(); 98781ad6265SDimitry Andric func_ti = fir.getFunctionType(); 98881ad6265SDimitry Andric parent = FromCompilerDeclContext(GetTranslationUnitDecl()); 98981ad6265SDimitry Andric if (!fir.ParentScope.isNoneType()) { 990bdd1243dSDimitry Andric CVType parent_cvt = index.ipi().getType(fir.ParentScope); 99181ad6265SDimitry Andric if (parent_cvt.kind() == LF_STRING_ID) { 99281ad6265SDimitry Andric StringIdRecord sir; 99381ad6265SDimitry Andric cantFail( 99481ad6265SDimitry Andric TypeDeserializer::deserializeAs<StringIdRecord>(parent_cvt, sir)); 99581ad6265SDimitry Andric parent = GetOrCreateNamespaceDecl(sir.String.data(), *parent); 99681ad6265SDimitry Andric } 99781ad6265SDimitry Andric } 99881ad6265SDimitry Andric break; 99981ad6265SDimitry Andric } 100081ad6265SDimitry Andric default: 100181ad6265SDimitry Andric lldbassert(false && "Invalid function id type!"); 100281ad6265SDimitry Andric } 100381ad6265SDimitry Andric clang::QualType func_qt = GetOrCreateType(func_ti); 1004bdd1243dSDimitry Andric if (func_qt.isNull() || !parent) 100581ad6265SDimitry Andric return nullptr; 100681ad6265SDimitry Andric CompilerType func_ct = ToCompilerType(func_qt); 100781ad6265SDimitry Andric uint32_t param_count = 100881ad6265SDimitry Andric llvm::cast<clang::FunctionProtoType>(func_qt)->getNumParams(); 100981ad6265SDimitry Andric return CreateFunctionDecl(func_sid, func_name, func_ti, func_ct, param_count, 101081ad6265SDimitry Andric clang::SC_None, true, parent); 101181ad6265SDimitry Andric } 101281ad6265SDimitry Andric 101381ad6265SDimitry Andric clang::FunctionDecl * 10140b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { 10150b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(func_id)) 10160b57cec5SDimitry Andric return llvm::dyn_cast<clang::FunctionDecl>(decl); 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id)); 1019bdd1243dSDimitry Andric if (!parent) 1020bdd1243dSDimitry Andric return nullptr; 10210b57cec5SDimitry Andric std::string context_name; 10220b57cec5SDimitry Andric if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) { 10230b57cec5SDimitry Andric context_name = ns->getQualifiedNameAsString(); 10240b57cec5SDimitry Andric } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) { 10250b57cec5SDimitry Andric context_name = tag->getQualifiedNameAsString(); 10260b57cec5SDimitry Andric } 10270b57cec5SDimitry Andric 1028bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1029bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1030bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1031bdd1243dSDimitry Andric CVSymbol cvs = index.ReadSymbolRecord(func_id); 10320b57cec5SDimitry Andric ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind())); 10330b57cec5SDimitry Andric llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc)); 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andric PdbTypeSymId type_id(proc.FunctionType); 10360b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(type_id); 10370b57cec5SDimitry Andric if (qt.isNull()) 10380b57cec5SDimitry Andric return nullptr; 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric clang::StorageClass storage = clang::SC_None; 10410b57cec5SDimitry Andric if (proc.Kind == SymbolRecordKind::ProcSym) 10420b57cec5SDimitry Andric storage = clang::SC_Static; 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric const clang::FunctionProtoType *func_type = 10450b57cec5SDimitry Andric llvm::dyn_cast<clang::FunctionProtoType>(qt); 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric CompilerType func_ct = ToCompilerType(qt); 10480b57cec5SDimitry Andric 10490b57cec5SDimitry Andric llvm::StringRef proc_name = proc.Name; 10500b57cec5SDimitry Andric proc_name.consume_front(context_name); 10510b57cec5SDimitry Andric proc_name.consume_front("::"); 105281ad6265SDimitry Andric clang::FunctionDecl *function_decl = 105381ad6265SDimitry Andric CreateFunctionDecl(func_id, proc_name, proc.FunctionType, func_ct, 105481ad6265SDimitry Andric func_type->getNumParams(), storage, false, parent); 105581ad6265SDimitry Andric if (function_decl == nullptr) 10560eae32dcSDimitry Andric return nullptr; 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0); 10590b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(func_id)] = function_decl; 10600b57cec5SDimitry Andric DeclStatus status; 10610b57cec5SDimitry Andric status.resolved = true; 10620b57cec5SDimitry Andric status.uid = toOpaqueUid(func_id); 10630b57cec5SDimitry Andric m_decl_to_status.insert({function_decl, status}); 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric return function_decl; 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andric void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, 10690b57cec5SDimitry Andric clang::FunctionDecl &function_decl, 10700b57cec5SDimitry Andric uint32_t param_count) { 1071bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1072bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1073bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1074bdd1243dSDimitry Andric CompilandIndexItem *cii = index.compilands().GetCompiland(func_id.modi); 10750b57cec5SDimitry Andric CVSymbolArray scope = 10760b57cec5SDimitry Andric cii->m_debug_stream.getSymbolArrayForScope(func_id.offset); 10770b57cec5SDimitry Andric 107881ad6265SDimitry Andric scope.drop_front(); 10790b57cec5SDimitry Andric auto begin = scope.begin(); 10800b57cec5SDimitry Andric auto end = scope.end(); 10810b57cec5SDimitry Andric std::vector<clang::ParmVarDecl *> params; 108281ad6265SDimitry Andric for (uint32_t i = 0; i < param_count && begin != end;) { 10830b57cec5SDimitry Andric uint32_t record_offset = begin.offset(); 10840b57cec5SDimitry Andric CVSymbol sym = *begin++; 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric TypeIndex param_type; 10870b57cec5SDimitry Andric llvm::StringRef param_name; 10880b57cec5SDimitry Andric switch (sym.kind()) { 10890b57cec5SDimitry Andric case S_REGREL32: { 10900b57cec5SDimitry Andric RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); 10910b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg)); 10920b57cec5SDimitry Andric param_type = reg.Type; 10930b57cec5SDimitry Andric param_name = reg.Name; 10940b57cec5SDimitry Andric break; 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric case S_REGISTER: { 10970b57cec5SDimitry Andric RegisterSym reg(SymbolRecordKind::RegisterSym); 10980b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg)); 10990b57cec5SDimitry Andric param_type = reg.Index; 11000b57cec5SDimitry Andric param_name = reg.Name; 11010b57cec5SDimitry Andric break; 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric case S_LOCAL: { 11040b57cec5SDimitry Andric LocalSym local(SymbolRecordKind::LocalSym); 11050b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); 11060b57cec5SDimitry Andric if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None) 11070b57cec5SDimitry Andric continue; 11080b57cec5SDimitry Andric param_type = local.Type; 11090b57cec5SDimitry Andric param_name = local.Name; 11100b57cec5SDimitry Andric break; 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric case S_BLOCK32: 111381ad6265SDimitry Andric case S_INLINESITE: 111481ad6265SDimitry Andric case S_INLINESITE2: 111581ad6265SDimitry Andric // All parameters should come before the first block/inlinesite. If that 111681ad6265SDimitry Andric // isn't the case, then perhaps this is bad debug info that doesn't 111781ad6265SDimitry Andric // contain information about all parameters. 11180b57cec5SDimitry Andric return; 11190b57cec5SDimitry Andric default: 11200b57cec5SDimitry Andric continue; 11210b57cec5SDimitry Andric } 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric PdbCompilandSymId param_uid(func_id.modi, record_offset); 11240b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(param_type); 112581ad6265SDimitry Andric if (qt.isNull()) 112681ad6265SDimitry Andric return; 11270b57cec5SDimitry Andric 1128480093f4SDimitry Andric CompilerType param_type_ct = m_clang.GetType(qt); 11290b57cec5SDimitry Andric clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( 11305ffd83dbSDimitry Andric &function_decl, OptionalClangModuleID(), param_name.str().c_str(), 11315ffd83dbSDimitry Andric param_type_ct, clang::SC_None, true); 11320b57cec5SDimitry Andric lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(param_uid)] = param; 11350b57cec5SDimitry Andric params.push_back(param); 113681ad6265SDimitry Andric ++i; 11370b57cec5SDimitry Andric } 11380b57cec5SDimitry Andric 113981ad6265SDimitry Andric if (!params.empty() && params.size() == param_count) 1140fe6060f1SDimitry Andric m_clang.SetFunctionParameters(&function_decl, params); 11410b57cec5SDimitry Andric } 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, 11440b57cec5SDimitry Andric const EnumRecord &er) { 11450b57cec5SDimitry Andric clang::DeclContext *decl_context = nullptr; 11460b57cec5SDimitry Andric std::string uname; 11470b57cec5SDimitry Andric std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index); 114881ad6265SDimitry Andric if (!decl_context) 114981ad6265SDimitry Andric return {}; 115081ad6265SDimitry Andric 11510b57cec5SDimitry Andric clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType); 115281ad6265SDimitry Andric if (underlying_type.isNull()) 115381ad6265SDimitry Andric return {}; 11540b57cec5SDimitry Andric 11550b57cec5SDimitry Andric Declaration declaration; 11560b57cec5SDimitry Andric CompilerType enum_ct = m_clang.CreateEnumerationType( 1157349cc55cSDimitry Andric uname, decl_context, OptionalClangModuleID(), declaration, 11585ffd83dbSDimitry Andric ToCompilerType(underlying_type), er.isScoped()); 11590b57cec5SDimitry Andric 11605ffd83dbSDimitry Andric TypeSystemClang::StartTagDeclarationDefinition(enum_ct); 11615ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); 11620b57cec5SDimitry Andric 11630b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType()); 11640b57cec5SDimitry Andric } 11650b57cec5SDimitry Andric 11660b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) { 11670b57cec5SDimitry Andric clang::QualType element_type = GetOrCreateType(ar.ElementType); 11680b57cec5SDimitry Andric 1169bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1170bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1171bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1172bdd1243dSDimitry Andric uint64_t element_size = GetSizeOfType({ar.ElementType}, index.tpi()); 117381ad6265SDimitry Andric if (element_type.isNull() || element_size == 0) 117481ad6265SDimitry Andric return {}; 117581ad6265SDimitry Andric uint64_t element_count = ar.Size / element_size; 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andric CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type), 11780b57cec5SDimitry Andric element_count, false); 11790b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType()); 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateFunctionType( 11830b57cec5SDimitry Andric TypeIndex args_type_idx, TypeIndex return_type_idx, 11840b57cec5SDimitry Andric llvm::codeview::CallingConvention calling_convention) { 1185bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1186bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1187bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1188bdd1243dSDimitry Andric TpiStream &stream = index.tpi(); 11890b57cec5SDimitry Andric CVType args_cvt = stream.getType(args_type_idx); 11900b57cec5SDimitry Andric ArgListRecord args; 11910b57cec5SDimitry Andric llvm::cantFail( 11920b57cec5SDimitry Andric TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args)); 11930b57cec5SDimitry Andric 1194bdd1243dSDimitry Andric llvm::ArrayRef<TypeIndex> arg_indices = llvm::ArrayRef(args.ArgIndices); 11950b57cec5SDimitry Andric bool is_variadic = IsCVarArgsFunction(arg_indices); 11960b57cec5SDimitry Andric if (is_variadic) 11970b57cec5SDimitry Andric arg_indices = arg_indices.drop_back(); 11980b57cec5SDimitry Andric 11990b57cec5SDimitry Andric std::vector<CompilerType> arg_types; 12000b57cec5SDimitry Andric arg_types.reserve(arg_indices.size()); 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric for (TypeIndex arg_index : arg_indices) { 12030b57cec5SDimitry Andric clang::QualType arg_type = GetOrCreateType(arg_index); 120481ad6265SDimitry Andric if (arg_type.isNull()) 120581ad6265SDimitry Andric continue; 12060b57cec5SDimitry Andric arg_types.push_back(ToCompilerType(arg_type)); 12070b57cec5SDimitry Andric } 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andric clang::QualType return_type = GetOrCreateType(return_type_idx); 121081ad6265SDimitry Andric if (return_type.isNull()) 121181ad6265SDimitry Andric return {}; 12120b57cec5SDimitry Andric 1213bdd1243dSDimitry Andric std::optional<clang::CallingConv> cc = 12140b57cec5SDimitry Andric TranslateCallingConvention(calling_convention); 12150b57cec5SDimitry Andric if (!cc) 12160b57cec5SDimitry Andric return {}; 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric CompilerType return_ct = ToCompilerType(return_type); 12190b57cec5SDimitry Andric CompilerType func_sig_ast_type = m_clang.CreateFunctionType( 12200b57cec5SDimitry Andric return_ct, arg_types.data(), arg_types.size(), is_variadic, 0, *cc); 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr( 12230b57cec5SDimitry Andric func_sig_ast_type.GetOpaqueQualType()); 12240b57cec5SDimitry Andric } 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric static bool isTagDecl(clang::DeclContext &context) { 12270eae32dcSDimitry Andric return llvm::isa<clang::TagDecl>(&context); 12280b57cec5SDimitry Andric } 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric static bool isFunctionDecl(clang::DeclContext &context) { 12310eae32dcSDimitry Andric return llvm::isa<clang::FunctionDecl>(&context); 12320b57cec5SDimitry Andric } 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andric static bool isBlockDecl(clang::DeclContext &context) { 12350eae32dcSDimitry Andric return llvm::isa<clang::BlockDecl>(&context); 12360b57cec5SDimitry Andric } 12370b57cec5SDimitry Andric 1238bdd1243dSDimitry Andric void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) { 1239bdd1243dSDimitry Andric clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(&context); 1240bdd1243dSDimitry Andric if (m_parsed_namespaces.contains(ns)) 1241bdd1243dSDimitry Andric return; 1242bdd1243dSDimitry Andric std::string qname = ns->getQualifiedNameAsString(); 1243bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1244bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1245bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1246bdd1243dSDimitry Andric TypeIndex ti{index.tpi().TypeIndexBegin()}; 1247bdd1243dSDimitry Andric for (const CVType &cvt : index.tpi().typeArray()) { 12480b57cec5SDimitry Andric PdbTypeSymId tid{ti}; 12490b57cec5SDimitry Andric ++ti; 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric if (!IsTagRecord(cvt)) 12520b57cec5SDimitry Andric continue; 12530b57cec5SDimitry Andric 12540b57cec5SDimitry Andric CVTagRecord tag = CVTagRecord::create(cvt); 12550b57cec5SDimitry Andric 12560b57cec5SDimitry Andric // Call CreateDeclInfoForType unconditionally so that the namespace info 12570b57cec5SDimitry Andric // gets created. But only call CreateRecordType if the namespace name 12580b57cec5SDimitry Andric // matches. 12590b57cec5SDimitry Andric clang::DeclContext *context = nullptr; 12600b57cec5SDimitry Andric std::string uname; 12610b57cec5SDimitry Andric std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index); 126281ad6265SDimitry Andric if (!context || !context->isNamespace()) 12630b57cec5SDimitry Andric continue; 12640b57cec5SDimitry Andric 126504eeddc0SDimitry Andric clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context); 1266bdd1243dSDimitry Andric llvm::StringRef ns_name = ns->getName(); 1267*5f757f3fSDimitry Andric if (ns_name.starts_with(qname)) { 1268bdd1243dSDimitry Andric ns_name = ns_name.drop_front(qname.size()); 1269*5f757f3fSDimitry Andric if (ns_name.starts_with("::")) 1270bdd1243dSDimitry Andric GetOrCreateType(tid); 12710b57cec5SDimitry Andric } 12720b57cec5SDimitry Andric } 1273bdd1243dSDimitry Andric ParseAllFunctionsAndNonLocalVars(); 1274bdd1243dSDimitry Andric m_parsed_namespaces.insert(ns); 1275bdd1243dSDimitry Andric } 12760b57cec5SDimitry Andric 1277bdd1243dSDimitry Andric void PdbAstBuilder::ParseAllTypes() { 1278bdd1243dSDimitry Andric llvm::call_once(m_parse_all_types, [this]() { 1279bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1280bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1281bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1282bdd1243dSDimitry Andric TypeIndex ti{index.tpi().TypeIndexBegin()}; 1283bdd1243dSDimitry Andric for (const CVType &cvt : index.tpi().typeArray()) { 1284bdd1243dSDimitry Andric PdbTypeSymId tid{ti}; 1285bdd1243dSDimitry Andric ++ti; 1286bdd1243dSDimitry Andric 1287bdd1243dSDimitry Andric if (!IsTagRecord(cvt)) 1288bdd1243dSDimitry Andric continue; 1289bdd1243dSDimitry Andric 1290bdd1243dSDimitry Andric GetOrCreateType(tid); 1291bdd1243dSDimitry Andric } 1292bdd1243dSDimitry Andric }); 1293bdd1243dSDimitry Andric } 1294bdd1243dSDimitry Andric 1295bdd1243dSDimitry Andric void PdbAstBuilder::ParseAllFunctionsAndNonLocalVars() { 1296bdd1243dSDimitry Andric llvm::call_once(m_parse_functions_and_non_local_vars, [this]() { 1297bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1298bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1299bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1300bdd1243dSDimitry Andric uint32_t module_count = index.dbi().modules().getModuleCount(); 13010b57cec5SDimitry Andric for (uint16_t modi = 0; modi < module_count; ++modi) { 1302bdd1243dSDimitry Andric CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi); 13030b57cec5SDimitry Andric const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray(); 13040b57cec5SDimitry Andric auto iter = symbols.begin(); 13050b57cec5SDimitry Andric while (iter != symbols.end()) { 13060b57cec5SDimitry Andric PdbCompilandSymId sym_id{modi, iter.offset()}; 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric switch (iter->kind()) { 13090b57cec5SDimitry Andric case S_GPROC32: 13100b57cec5SDimitry Andric case S_LPROC32: 13110b57cec5SDimitry Andric GetOrCreateFunctionDecl(sym_id); 13120b57cec5SDimitry Andric iter = symbols.at(getScopeEndOffset(*iter)); 13130b57cec5SDimitry Andric break; 13140b57cec5SDimitry Andric case S_GDATA32: 13150b57cec5SDimitry Andric case S_GTHREAD32: 13160b57cec5SDimitry Andric case S_LDATA32: 13170b57cec5SDimitry Andric case S_LTHREAD32: 13180b57cec5SDimitry Andric GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id); 13190b57cec5SDimitry Andric ++iter; 13200b57cec5SDimitry Andric break; 13210b57cec5SDimitry Andric default: 13220b57cec5SDimitry Andric ++iter; 13230b57cec5SDimitry Andric continue; 13240b57cec5SDimitry Andric } 13250b57cec5SDimitry Andric } 13260b57cec5SDimitry Andric } 1327bdd1243dSDimitry Andric }); 13280b57cec5SDimitry Andric } 13290b57cec5SDimitry Andric 13300b57cec5SDimitry Andric static CVSymbolArray skipFunctionParameters(clang::Decl &decl, 13310b57cec5SDimitry Andric const CVSymbolArray &symbols) { 13320b57cec5SDimitry Andric clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>(&decl); 13330b57cec5SDimitry Andric if (!func_decl) 13340b57cec5SDimitry Andric return symbols; 13350b57cec5SDimitry Andric unsigned int params = func_decl->getNumParams(); 13360b57cec5SDimitry Andric if (params == 0) 13370b57cec5SDimitry Andric return symbols; 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric CVSymbolArray result = symbols; 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andric while (!result.empty()) { 13420b57cec5SDimitry Andric if (params == 0) 13430b57cec5SDimitry Andric return result; 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric CVSymbol sym = *result.begin(); 13460b57cec5SDimitry Andric result.drop_front(); 13470b57cec5SDimitry Andric 13480b57cec5SDimitry Andric if (!isLocalVariableType(sym.kind())) 13490b57cec5SDimitry Andric continue; 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric --params; 13520b57cec5SDimitry Andric } 13530b57cec5SDimitry Andric return result; 13540b57cec5SDimitry Andric } 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) { 1357bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( 1358bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile()); 1359bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex(); 1360bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(block_id); 13610b57cec5SDimitry Andric lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 || 136281ad6265SDimitry Andric sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE); 13630b57cec5SDimitry Andric CompilandIndexItem &cii = 1364bdd1243dSDimitry Andric index.compilands().GetOrCreateCompiland(block_id.modi); 13650b57cec5SDimitry Andric CVSymbolArray symbols = 13660b57cec5SDimitry Andric cii.m_debug_stream.getSymbolArrayForScope(block_id.offset); 13670b57cec5SDimitry Andric 13680b57cec5SDimitry Andric // Function parameters should already have been created when the function was 13690b57cec5SDimitry Andric // parsed. 13700b57cec5SDimitry Andric if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) 13710b57cec5SDimitry Andric symbols = 13720b57cec5SDimitry Andric skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols); 13730b57cec5SDimitry Andric 137481ad6265SDimitry Andric symbols.drop_front(); 13750b57cec5SDimitry Andric auto begin = symbols.begin(); 13760b57cec5SDimitry Andric while (begin != symbols.end()) { 13770b57cec5SDimitry Andric PdbCompilandSymId child_sym_id(block_id.modi, begin.offset()); 13780b57cec5SDimitry Andric GetOrCreateSymbolForId(child_sym_id); 137981ad6265SDimitry Andric if (begin->kind() == S_BLOCK32 || begin->kind() == S_INLINESITE) { 13800b57cec5SDimitry Andric ParseBlockChildren(child_sym_id); 13810b57cec5SDimitry Andric begin = symbols.at(getScopeEndOffset(*begin)); 13820b57cec5SDimitry Andric } 13830b57cec5SDimitry Andric ++begin; 13840b57cec5SDimitry Andric } 13850b57cec5SDimitry Andric } 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric void PdbAstBuilder::ParseDeclsForSimpleContext(clang::DeclContext &context) { 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric clang::Decl *decl = clang::Decl::castFromDeclContext(&context); 13900b57cec5SDimitry Andric lldbassert(decl); 13910b57cec5SDimitry Andric 13920b57cec5SDimitry Andric auto iter = m_decl_to_status.find(decl); 13930b57cec5SDimitry Andric lldbassert(iter != m_decl_to_status.end()); 13940b57cec5SDimitry Andric 13950b57cec5SDimitry Andric if (auto *tag = llvm::dyn_cast<clang::TagDecl>(&context)) { 13960b57cec5SDimitry Andric CompleteTagDecl(*tag); 13970b57cec5SDimitry Andric return; 13980b57cec5SDimitry Andric } 13990b57cec5SDimitry Andric 14000b57cec5SDimitry Andric if (isFunctionDecl(context) || isBlockDecl(context)) { 14010b57cec5SDimitry Andric PdbCompilandSymId block_id = PdbSymUid(iter->second.uid).asCompilandSym(); 14020b57cec5SDimitry Andric ParseBlockChildren(block_id); 14030b57cec5SDimitry Andric } 14040b57cec5SDimitry Andric } 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) { 14070b57cec5SDimitry Andric // Namespaces aren't explicitly represented in the debug info, and the only 14080b57cec5SDimitry Andric // way to parse them is to parse all type info, demangling every single type 14090b57cec5SDimitry Andric // and trying to reconstruct the DeclContext hierarchy this way. Since this 14100b57cec5SDimitry Andric // is an expensive operation, we have to special case it so that we do other 14110b57cec5SDimitry Andric // work (such as parsing the items that appear within the namespaces) at the 14120b57cec5SDimitry Andric // same time. 14130b57cec5SDimitry Andric if (context.isTranslationUnit()) { 1414bdd1243dSDimitry Andric ParseAllTypes(); 1415bdd1243dSDimitry Andric ParseAllFunctionsAndNonLocalVars(); 14160b57cec5SDimitry Andric return; 14170b57cec5SDimitry Andric } 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric if (context.isNamespace()) { 1420bdd1243dSDimitry Andric ParseNamespace(context); 14210b57cec5SDimitry Andric return; 14220b57cec5SDimitry Andric } 14230b57cec5SDimitry Andric 14240b57cec5SDimitry Andric if (isTagDecl(context) || isFunctionDecl(context) || isBlockDecl(context)) { 14250b57cec5SDimitry Andric ParseDeclsForSimpleContext(context); 14260b57cec5SDimitry Andric return; 14270b57cec5SDimitry Andric } 14280b57cec5SDimitry Andric } 14290b57cec5SDimitry Andric 14300b57cec5SDimitry Andric CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) { 14315ffd83dbSDimitry Andric return m_clang.GetCompilerDecl(&decl); 14320b57cec5SDimitry Andric } 14330b57cec5SDimitry Andric 14340b57cec5SDimitry Andric CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) { 1435bdd1243dSDimitry Andric return {m_clang.weak_from_this(), qt.getAsOpaquePtr()}; 14360b57cec5SDimitry Andric } 14370b57cec5SDimitry Andric 14380b57cec5SDimitry Andric CompilerDeclContext 14390b57cec5SDimitry Andric PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) { 1440480093f4SDimitry Andric return m_clang.CreateDeclContext(&context); 14410b57cec5SDimitry Andric } 14420b57cec5SDimitry Andric 14430b57cec5SDimitry Andric clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) { 14445ffd83dbSDimitry Andric return ClangUtil::GetDecl(decl); 14450b57cec5SDimitry Andric } 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andric clang::DeclContext * 14480b57cec5SDimitry Andric PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) { 14490b57cec5SDimitry Andric return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext()); 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric 1452349cc55cSDimitry Andric void PdbAstBuilder::Dump(Stream &stream) { 1453349cc55cSDimitry Andric m_clang.Dump(stream.AsRawOstream()); 1454349cc55cSDimitry Andric } 1455