15ffd83dbSDimitry Andric //===-- PDBASTParser.cpp --------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "PDBASTParser.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "SymbolFilePDB.h" 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "clang/AST/CharUnits.h" 140b57cec5SDimitry Andric #include "clang/AST/Decl.h" 150b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 160b57cec5SDimitry Andric 175ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" 185ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangUtil.h" 195ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 20fe6060f1SDimitry Andric #include "lldb/Core/Declaration.h" 210b57cec5SDimitry Andric #include "lldb/Core/Module.h" 220b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h" 230b57cec5SDimitry Andric #include "lldb/Symbol/TypeMap.h" 240b57cec5SDimitry Andric #include "lldb/Symbol/TypeSystem.h" 2581ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 2681ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" 270b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" 280b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 290b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbol.h" 300b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolData.h" 310b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 320b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" 3381ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" 340b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" 350b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 360b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" 370b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 380b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" 390b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" 400b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" 43bdd1243dSDimitry Andric #include <optional> 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric using namespace lldb; 460b57cec5SDimitry Andric using namespace lldb_private; 470b57cec5SDimitry Andric using namespace llvm::pdb; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric static int TranslateUdtKind(PDB_UdtType pdb_kind) { 500b57cec5SDimitry Andric switch (pdb_kind) { 510b57cec5SDimitry Andric case PDB_UdtType::Class: 525f757f3fSDimitry Andric return llvm::to_underlying(clang::TagTypeKind::Class); 530b57cec5SDimitry Andric case PDB_UdtType::Struct: 545f757f3fSDimitry Andric return llvm::to_underlying(clang::TagTypeKind::Struct); 550b57cec5SDimitry Andric case PDB_UdtType::Union: 565f757f3fSDimitry Andric return llvm::to_underlying(clang::TagTypeKind::Union); 570b57cec5SDimitry Andric case PDB_UdtType::Interface: 585f757f3fSDimitry Andric return llvm::to_underlying(clang::TagTypeKind::Interface); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric llvm_unreachable("unsuported PDB UDT type"); 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { 640b57cec5SDimitry Andric switch (type) { 650b57cec5SDimitry Andric case PDB_BuiltinType::Float: 660b57cec5SDimitry Andric return lldb::eEncodingIEEE754; 670b57cec5SDimitry Andric case PDB_BuiltinType::Int: 680b57cec5SDimitry Andric case PDB_BuiltinType::Long: 690b57cec5SDimitry Andric case PDB_BuiltinType::Char: 700b57cec5SDimitry Andric return lldb::eEncodingSint; 710b57cec5SDimitry Andric case PDB_BuiltinType::Bool: 720b57cec5SDimitry Andric case PDB_BuiltinType::Char16: 730b57cec5SDimitry Andric case PDB_BuiltinType::Char32: 740b57cec5SDimitry Andric case PDB_BuiltinType::UInt: 750b57cec5SDimitry Andric case PDB_BuiltinType::ULong: 760b57cec5SDimitry Andric case PDB_BuiltinType::HResult: 770b57cec5SDimitry Andric case PDB_BuiltinType::WCharT: 780b57cec5SDimitry Andric return lldb::eEncodingUint; 790b57cec5SDimitry Andric default: 800b57cec5SDimitry Andric return lldb::eEncodingInvalid; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { 850b57cec5SDimitry Andric switch (type) { 860b57cec5SDimitry Andric case PDB_VariantType::Int8: 870b57cec5SDimitry Andric case PDB_VariantType::Int16: 880b57cec5SDimitry Andric case PDB_VariantType::Int32: 890b57cec5SDimitry Andric case PDB_VariantType::Int64: 900b57cec5SDimitry Andric return lldb::eEncodingSint; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric case PDB_VariantType::UInt8: 930b57cec5SDimitry Andric case PDB_VariantType::UInt16: 940b57cec5SDimitry Andric case PDB_VariantType::UInt32: 950b57cec5SDimitry Andric case PDB_VariantType::UInt64: 960b57cec5SDimitry Andric return lldb::eEncodingUint; 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric default: 990b57cec5SDimitry Andric break; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric return lldb::eEncodingSint; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric static CompilerType 1065ffd83dbSDimitry Andric GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast, 1070b57cec5SDimitry Andric const PDBSymbolTypeBuiltin &pdb_type, 1080b57cec5SDimitry Andric Encoding encoding, uint32_t width) { 109480093f4SDimitry Andric clang::ASTContext &ast = clang_ast.getASTContext(); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric switch (pdb_type.getBuiltinType()) { 1120b57cec5SDimitry Andric default: 1130b57cec5SDimitry Andric break; 1140b57cec5SDimitry Andric case PDB_BuiltinType::None: 1150b57cec5SDimitry Andric return CompilerType(); 1160b57cec5SDimitry Andric case PDB_BuiltinType::Void: 1170b57cec5SDimitry Andric return clang_ast.GetBasicType(eBasicTypeVoid); 1180b57cec5SDimitry Andric case PDB_BuiltinType::Char: 1190b57cec5SDimitry Andric return clang_ast.GetBasicType(eBasicTypeChar); 1200b57cec5SDimitry Andric case PDB_BuiltinType::Bool: 1210b57cec5SDimitry Andric return clang_ast.GetBasicType(eBasicTypeBool); 1220b57cec5SDimitry Andric case PDB_BuiltinType::Long: 123480093f4SDimitry Andric if (width == ast.getTypeSize(ast.LongTy)) 124bdd1243dSDimitry Andric return CompilerType(clang_ast.weak_from_this(), 125bdd1243dSDimitry Andric ast.LongTy.getAsOpaquePtr()); 126480093f4SDimitry Andric if (width == ast.getTypeSize(ast.LongLongTy)) 127bdd1243dSDimitry Andric return CompilerType(clang_ast.weak_from_this(), 128bdd1243dSDimitry Andric ast.LongLongTy.getAsOpaquePtr()); 1290b57cec5SDimitry Andric break; 1300b57cec5SDimitry Andric case PDB_BuiltinType::ULong: 131480093f4SDimitry Andric if (width == ast.getTypeSize(ast.UnsignedLongTy)) 132bdd1243dSDimitry Andric return CompilerType(clang_ast.weak_from_this(), 133bdd1243dSDimitry Andric ast.UnsignedLongTy.getAsOpaquePtr()); 134480093f4SDimitry Andric if (width == ast.getTypeSize(ast.UnsignedLongLongTy)) 135bdd1243dSDimitry Andric return CompilerType(clang_ast.weak_from_this(), 136bdd1243dSDimitry Andric ast.UnsignedLongLongTy.getAsOpaquePtr()); 1370b57cec5SDimitry Andric break; 1380b57cec5SDimitry Andric case PDB_BuiltinType::WCharT: 139480093f4SDimitry Andric if (width == ast.getTypeSize(ast.WCharTy)) 140bdd1243dSDimitry Andric return CompilerType(clang_ast.weak_from_this(), 141bdd1243dSDimitry Andric ast.WCharTy.getAsOpaquePtr()); 1420b57cec5SDimitry Andric break; 1430b57cec5SDimitry Andric case PDB_BuiltinType::Char16: 144bdd1243dSDimitry Andric return CompilerType(clang_ast.weak_from_this(), 145bdd1243dSDimitry Andric ast.Char16Ty.getAsOpaquePtr()); 1460b57cec5SDimitry Andric case PDB_BuiltinType::Char32: 147bdd1243dSDimitry Andric return CompilerType(clang_ast.weak_from_this(), 148bdd1243dSDimitry Andric ast.Char32Ty.getAsOpaquePtr()); 1490b57cec5SDimitry Andric case PDB_BuiltinType::Float: 1500b57cec5SDimitry Andric // Note: types `long double` and `double` have same bit size in MSVC and 1510b57cec5SDimitry Andric // there is no information in the PDB to distinguish them. So when falling 1520b57cec5SDimitry Andric // back to default search, the compiler type of `long double` will be 1530b57cec5SDimitry Andric // represented by the one generated for `double`. 1540b57cec5SDimitry Andric break; 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric // If there is no match on PDB_BuiltinType, fall back to default search by 1570b57cec5SDimitry Andric // encoding and width only 1580b57cec5SDimitry Andric return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width); 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type, 1620b57cec5SDimitry Andric CompilerType &compiler_type) { 1630b57cec5SDimitry Andric PDB_BuiltinType kind = pdb_type.getBuiltinType(); 1640b57cec5SDimitry Andric switch (kind) { 1650b57cec5SDimitry Andric default: 1660b57cec5SDimitry Andric break; 1670b57cec5SDimitry Andric case PDB_BuiltinType::Currency: 1680b57cec5SDimitry Andric return ConstString("CURRENCY"); 1690b57cec5SDimitry Andric case PDB_BuiltinType::Date: 1700b57cec5SDimitry Andric return ConstString("DATE"); 1710b57cec5SDimitry Andric case PDB_BuiltinType::Variant: 1720b57cec5SDimitry Andric return ConstString("VARIANT"); 1730b57cec5SDimitry Andric case PDB_BuiltinType::Complex: 1740b57cec5SDimitry Andric return ConstString("complex"); 1750b57cec5SDimitry Andric case PDB_BuiltinType::Bitfield: 1760b57cec5SDimitry Andric return ConstString("bitfield"); 1770b57cec5SDimitry Andric case PDB_BuiltinType::BSTR: 1780b57cec5SDimitry Andric return ConstString("BSTR"); 1790b57cec5SDimitry Andric case PDB_BuiltinType::HResult: 1800b57cec5SDimitry Andric return ConstString("HRESULT"); 1810b57cec5SDimitry Andric case PDB_BuiltinType::BCD: 1820b57cec5SDimitry Andric return ConstString("BCD"); 1830b57cec5SDimitry Andric case PDB_BuiltinType::Char16: 1840b57cec5SDimitry Andric return ConstString("char16_t"); 1850b57cec5SDimitry Andric case PDB_BuiltinType::Char32: 1860b57cec5SDimitry Andric return ConstString("char32_t"); 1870b57cec5SDimitry Andric case PDB_BuiltinType::None: 1880b57cec5SDimitry Andric return ConstString("..."); 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric return compiler_type.GetTypeName(); 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 19306c3fb27SDimitry Andric static bool AddSourceInfoToDecl(const PDBSymbol &symbol, Declaration &decl) { 1940b57cec5SDimitry Andric auto &raw_sym = symbol.getRawSymbol(); 1950b57cec5SDimitry Andric auto first_line_up = raw_sym.getSrcLineOnTypeDefn(); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric if (!first_line_up) { 1980b57cec5SDimitry Andric auto lines_up = symbol.getSession().findLineNumbersByAddress( 1990b57cec5SDimitry Andric raw_sym.getVirtualAddress(), raw_sym.getLength()); 2000b57cec5SDimitry Andric if (!lines_up) 2010b57cec5SDimitry Andric return false; 2020b57cec5SDimitry Andric first_line_up = lines_up->getNext(); 2030b57cec5SDimitry Andric if (!first_line_up) 2040b57cec5SDimitry Andric return false; 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric uint32_t src_file_id = first_line_up->getSourceFileId(); 2070b57cec5SDimitry Andric auto src_file_up = symbol.getSession().getSourceFileById(src_file_id); 2080b57cec5SDimitry Andric if (!src_file_up) 2090b57cec5SDimitry Andric return false; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric FileSpec spec(src_file_up->getFileName()); 2120b57cec5SDimitry Andric decl.SetFile(spec); 2130b57cec5SDimitry Andric decl.SetColumn(first_line_up->getColumnNumber()); 2140b57cec5SDimitry Andric decl.SetLine(first_line_up->getLineNumber()); 2150b57cec5SDimitry Andric return true; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric static AccessType TranslateMemberAccess(PDB_MemberAccess access) { 2190b57cec5SDimitry Andric switch (access) { 2200b57cec5SDimitry Andric case PDB_MemberAccess::Private: 2210b57cec5SDimitry Andric return eAccessPrivate; 2220b57cec5SDimitry Andric case PDB_MemberAccess::Protected: 2230b57cec5SDimitry Andric return eAccessProtected; 2240b57cec5SDimitry Andric case PDB_MemberAccess::Public: 2250b57cec5SDimitry Andric return eAccessPublic; 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric return eAccessNone; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric static AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) { 2310b57cec5SDimitry Andric switch (udt_kind) { 2320b57cec5SDimitry Andric case PDB_UdtType::Struct: 2330b57cec5SDimitry Andric case PDB_UdtType::Union: 2340b57cec5SDimitry Andric return eAccessPublic; 2350b57cec5SDimitry Andric case PDB_UdtType::Class: 2360b57cec5SDimitry Andric case PDB_UdtType::Interface: 2370b57cec5SDimitry Andric return eAccessPrivate; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric llvm_unreachable("unsupported PDB UDT type"); 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric static AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) { 2430b57cec5SDimitry Andric AccessType access = TranslateMemberAccess(udt.getAccess()); 2440b57cec5SDimitry Andric if (access != lldb::eAccessNone || !udt.isNested()) 2450b57cec5SDimitry Andric return access; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric auto parent = udt.getClassParent(); 2480b57cec5SDimitry Andric if (!parent) 2490b57cec5SDimitry Andric return lldb::eAccessNone; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric auto parent_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(parent.get()); 2520b57cec5SDimitry Andric if (!parent_udt) 2530b57cec5SDimitry Andric return lldb::eAccessNone; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind()); 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric static clang::MSInheritanceAttr::Spelling 2590b57cec5SDimitry Andric GetMSInheritance(const PDBSymbolTypeUDT &udt) { 2600b57cec5SDimitry Andric int base_count = 0; 2610b57cec5SDimitry Andric bool has_virtual = false; 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>(); 2640b57cec5SDimitry Andric if (bases_enum) { 2650b57cec5SDimitry Andric while (auto base = bases_enum->getNext()) { 2660b57cec5SDimitry Andric base_count++; 2670b57cec5SDimitry Andric has_virtual |= base->isVirtualBaseClass(); 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric if (has_virtual) 2720b57cec5SDimitry Andric return clang::MSInheritanceAttr::Keyword_virtual_inheritance; 2730b57cec5SDimitry Andric if (base_count > 1) 2740b57cec5SDimitry Andric return clang::MSInheritanceAttr::Keyword_multiple_inheritance; 2750b57cec5SDimitry Andric return clang::MSInheritanceAttr::Keyword_single_inheritance; 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric static std::unique_ptr<llvm::pdb::PDBSymbol> 2790b57cec5SDimitry Andric GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) { 2800b57cec5SDimitry Andric const IPDBSession &session = symbol.getSession(); 2810b57cec5SDimitry Andric const IPDBRawSymbol &raw = symbol.getRawSymbol(); 2820b57cec5SDimitry Andric auto tag = symbol.getSymTag(); 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric // For items that are nested inside of a class, return the class that it is 2850b57cec5SDimitry Andric // nested inside of. 2860b57cec5SDimitry Andric // Note that only certain items can be nested inside of classes. 2870b57cec5SDimitry Andric switch (tag) { 2880b57cec5SDimitry Andric case PDB_SymType::Function: 2890b57cec5SDimitry Andric case PDB_SymType::Data: 2900b57cec5SDimitry Andric case PDB_SymType::UDT: 2910b57cec5SDimitry Andric case PDB_SymType::Enum: 2920b57cec5SDimitry Andric case PDB_SymType::FunctionSig: 2930b57cec5SDimitry Andric case PDB_SymType::Typedef: 2940b57cec5SDimitry Andric case PDB_SymType::BaseClass: 2950b57cec5SDimitry Andric case PDB_SymType::VTable: { 2960b57cec5SDimitry Andric auto class_parent_id = raw.getClassParentId(); 2970b57cec5SDimitry Andric if (auto class_parent = session.getSymbolById(class_parent_id)) 2980b57cec5SDimitry Andric return class_parent; 2990b57cec5SDimitry Andric break; 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric default: 3020b57cec5SDimitry Andric break; 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric // Otherwise, if it is nested inside of a function, return the function. 3060b57cec5SDimitry Andric // Note that only certain items can be nested inside of functions. 3070b57cec5SDimitry Andric switch (tag) { 3080b57cec5SDimitry Andric case PDB_SymType::Block: 3090b57cec5SDimitry Andric case PDB_SymType::Data: { 3100b57cec5SDimitry Andric auto lexical_parent_id = raw.getLexicalParentId(); 3110b57cec5SDimitry Andric auto lexical_parent = session.getSymbolById(lexical_parent_id); 3120b57cec5SDimitry Andric if (!lexical_parent) 3130b57cec5SDimitry Andric return nullptr; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric auto lexical_parent_tag = lexical_parent->getSymTag(); 3160b57cec5SDimitry Andric if (lexical_parent_tag == PDB_SymType::Function) 3170b57cec5SDimitry Andric return lexical_parent; 3180b57cec5SDimitry Andric if (lexical_parent_tag == PDB_SymType::Exe) 3190b57cec5SDimitry Andric return nullptr; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric return GetClassOrFunctionParent(*lexical_parent); 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric default: 3240b57cec5SDimitry Andric return nullptr; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric static clang::NamedDecl * 3290b57cec5SDimitry Andric GetDeclFromContextByName(const clang::ASTContext &ast, 3300b57cec5SDimitry Andric const clang::DeclContext &decl_context, 3310b57cec5SDimitry Andric llvm::StringRef name) { 3320b57cec5SDimitry Andric clang::IdentifierInfo &ident = ast.Idents.get(name); 3330b57cec5SDimitry Andric clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident); 3340b57cec5SDimitry Andric clang::DeclContext::lookup_result result = decl_context.lookup(decl_name); 3350b57cec5SDimitry Andric if (result.empty()) 3360b57cec5SDimitry Andric return nullptr; 3370b57cec5SDimitry Andric 338fe6060f1SDimitry Andric return *result.begin(); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric static bool IsAnonymousNamespaceName(llvm::StringRef name) { 3420b57cec5SDimitry Andric return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { 3460b57cec5SDimitry Andric switch (pdb_cc) { 3470b57cec5SDimitry Andric case llvm::codeview::CallingConvention::NearC: 3480b57cec5SDimitry Andric return clang::CC_C; 3490b57cec5SDimitry Andric case llvm::codeview::CallingConvention::NearStdCall: 3500b57cec5SDimitry Andric return clang::CC_X86StdCall; 3510b57cec5SDimitry Andric case llvm::codeview::CallingConvention::NearFast: 3520b57cec5SDimitry Andric return clang::CC_X86FastCall; 3530b57cec5SDimitry Andric case llvm::codeview::CallingConvention::ThisCall: 3540b57cec5SDimitry Andric return clang::CC_X86ThisCall; 3550b57cec5SDimitry Andric case llvm::codeview::CallingConvention::NearVector: 3560b57cec5SDimitry Andric return clang::CC_X86VectorCall; 3570b57cec5SDimitry Andric case llvm::codeview::CallingConvention::NearPascal: 3580b57cec5SDimitry Andric return clang::CC_X86Pascal; 3590b57cec5SDimitry Andric default: 3600b57cec5SDimitry Andric assert(false && "Unknown calling convention"); 3610b57cec5SDimitry Andric return clang::CC_C; 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 3655ffd83dbSDimitry Andric PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {} 3660b57cec5SDimitry Andric 367fe6060f1SDimitry Andric PDBASTParser::~PDBASTParser() = default; 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric // DebugInfoASTParser interface 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { 3720b57cec5SDimitry Andric Declaration decl; 3730b57cec5SDimitry Andric switch (type.getSymTag()) { 3740b57cec5SDimitry Andric case PDB_SymType::BaseClass: { 3750b57cec5SDimitry Andric auto symbol_file = m_ast.GetSymbolFile(); 3760b57cec5SDimitry Andric if (!symbol_file) 3770b57cec5SDimitry Andric return nullptr; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId()); 3800b57cec5SDimitry Andric return ty ? ty->shared_from_this() : nullptr; 3810b57cec5SDimitry Andric } break; 3820b57cec5SDimitry Andric case PDB_SymType::UDT: { 3830b57cec5SDimitry Andric auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type); 3840b57cec5SDimitry Andric assert(udt); 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol 3870b57cec5SDimitry Andric // other than a Typedef symbol in PDB. For example, 3880b57cec5SDimitry Andric // typedef union { short Row; short Col; } Union; 3890b57cec5SDimitry Andric // is generated as a named UDT in PDB: 3900b57cec5SDimitry Andric // union Union { short Row; short Col; } 3910b57cec5SDimitry Andric // Such symbols will be handled here. 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric // Some UDT with trival ctor has zero length. Just ignore. 3940b57cec5SDimitry Andric if (udt->getLength() == 0) 3950b57cec5SDimitry Andric return nullptr; 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric // Ignore unnamed-tag UDTs. 3985ffd83dbSDimitry Andric std::string name = 3995ffd83dbSDimitry Andric std::string(MSVCUndecoratedNameParser::DropScope(udt->getName())); 4000b57cec5SDimitry Andric if (name.empty()) 4010b57cec5SDimitry Andric return nullptr; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric auto decl_context = GetDeclContextContainingSymbol(type); 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric // Check if such an UDT already exists in the current context. 4060b57cec5SDimitry Andric // This may occur with const or volatile types. There are separate type 4070b57cec5SDimitry Andric // symbols in PDB for types with const or volatile modifiers, but we need 4080b57cec5SDimitry Andric // to create only one declaration for them all. 409480093f4SDimitry Andric Type::ResolveState type_resolve_state; 41006c3fb27SDimitry Andric CompilerType clang_type = 41106c3fb27SDimitry Andric m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>(name, decl_context); 4120b57cec5SDimitry Andric if (!clang_type.IsValid()) { 4130b57cec5SDimitry Andric auto access = GetAccessibilityForUdt(*udt); 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric auto tag_type_kind = TranslateUdtKind(udt->getUdtKind()); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric ClangASTMetadata metadata; 4180b57cec5SDimitry Andric metadata.SetUserID(type.getSymIndexId()); 4190b57cec5SDimitry Andric metadata.SetIsDynamicCXXType(false); 4200b57cec5SDimitry Andric 4215ffd83dbSDimitry Andric clang_type = m_ast.CreateRecordType( 4225ffd83dbSDimitry Andric decl_context, OptionalClangModuleID(), access, name, tag_type_kind, 4230b57cec5SDimitry Andric lldb::eLanguageTypeC_plus_plus, &metadata); 4240b57cec5SDimitry Andric assert(clang_type.IsValid()); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric auto record_decl = 4270b57cec5SDimitry Andric m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); 4280b57cec5SDimitry Andric assert(record_decl); 4290b57cec5SDimitry Andric m_uid_to_decl[type.getSymIndexId()] = record_decl; 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit( 432480093f4SDimitry Andric m_ast.getASTContext(), GetMSInheritance(*udt)); 4330b57cec5SDimitry Andric record_decl->addAttr(inheritance_attr); 4340b57cec5SDimitry Andric 4355ffd83dbSDimitry Andric TypeSystemClang::StartTagDeclarationDefinition(clang_type); 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric auto children = udt->findAllChildren(); 4380b57cec5SDimitry Andric if (!children || children->getChildCount() == 0) { 4390b57cec5SDimitry Andric // PDB does not have symbol of forwarder. We assume we get an udt w/o 4400b57cec5SDimitry Andric // any fields. Just complete it at this point. 4415ffd83dbSDimitry Andric TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); 4420b57cec5SDimitry Andric 4435ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), 4440b57cec5SDimitry Andric false); 4450b57cec5SDimitry Andric 446480093f4SDimitry Andric type_resolve_state = Type::ResolveState::Full; 4470b57cec5SDimitry Andric } else { 4480b57cec5SDimitry Andric // Add the type to the forward declarations. It will help us to avoid 4490b57cec5SDimitry Andric // an endless recursion in CompleteTypeFromUdt function. 4500b57cec5SDimitry Andric m_forward_decl_to_uid[record_decl] = type.getSymIndexId(); 4510b57cec5SDimitry Andric 4525ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), 4530b57cec5SDimitry Andric true); 4540b57cec5SDimitry Andric 455480093f4SDimitry Andric type_resolve_state = Type::ResolveState::Forward; 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric } else 458480093f4SDimitry Andric type_resolve_state = Type::ResolveState::Forward; 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric if (udt->isConstType()) 4610b57cec5SDimitry Andric clang_type = clang_type.AddConstModifier(); 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric if (udt->isVolatileType()) 4640b57cec5SDimitry Andric clang_type = clang_type.AddVolatileModifier(); 4650b57cec5SDimitry Andric 46606c3fb27SDimitry Andric AddSourceInfoToDecl(type, decl); 467bdd1243dSDimitry Andric return m_ast.GetSymbolFile()->MakeType( 468bdd1243dSDimitry Andric type.getSymIndexId(), ConstString(name), udt->getLength(), nullptr, 469bdd1243dSDimitry Andric LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type, 470480093f4SDimitry Andric type_resolve_state); 4710b57cec5SDimitry Andric } break; 4720b57cec5SDimitry Andric case PDB_SymType::Enum: { 4730b57cec5SDimitry Andric auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type); 4740b57cec5SDimitry Andric assert(enum_type); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric std::string name = 4775ffd83dbSDimitry Andric std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName())); 4780b57cec5SDimitry Andric auto decl_context = GetDeclContextContainingSymbol(type); 4790b57cec5SDimitry Andric uint64_t bytes = enum_type->getLength(); 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric // Check if such an enum already exists in the current context 48206c3fb27SDimitry Andric CompilerType ast_enum = 48306c3fb27SDimitry Andric m_ast.GetTypeForIdentifier<clang::EnumDecl>(name, decl_context); 4840b57cec5SDimitry Andric if (!ast_enum.IsValid()) { 4850b57cec5SDimitry Andric auto underlying_type_up = enum_type->getUnderlyingType(); 4860b57cec5SDimitry Andric if (!underlying_type_up) 4870b57cec5SDimitry Andric return nullptr; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric lldb::Encoding encoding = 4900b57cec5SDimitry Andric TranslateBuiltinEncoding(underlying_type_up->getBuiltinType()); 4910b57cec5SDimitry Andric // FIXME: Type of underlying builtin is always `Int`. We correct it with 4920b57cec5SDimitry Andric // the very first enumerator's encoding if any. 4930b57cec5SDimitry Andric auto first_child = enum_type->findOneChild<PDBSymbolData>(); 4940b57cec5SDimitry Andric if (first_child) 4950b57cec5SDimitry Andric encoding = TranslateEnumEncoding(first_child->getValue().Type); 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric CompilerType builtin_type; 4980b57cec5SDimitry Andric if (bytes > 0) 4990b57cec5SDimitry Andric builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize( 5000b57cec5SDimitry Andric m_ast, *underlying_type_up, encoding, bytes * 8); 5010b57cec5SDimitry Andric else 5020b57cec5SDimitry Andric builtin_type = m_ast.GetBasicType(eBasicTypeInt); 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric // FIXME: PDB does not have information about scoped enumeration (Enum 5050b57cec5SDimitry Andric // Class). Set it false for now. 5060b57cec5SDimitry Andric bool isScoped = false; 5070b57cec5SDimitry Andric 508349cc55cSDimitry Andric ast_enum = m_ast.CreateEnumerationType(name, decl_context, 5095ffd83dbSDimitry Andric OptionalClangModuleID(), decl, 5100b57cec5SDimitry Andric builtin_type, isScoped); 5110b57cec5SDimitry Andric 5125ffd83dbSDimitry Andric auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum); 5130b57cec5SDimitry Andric assert(enum_decl); 5140b57cec5SDimitry Andric m_uid_to_decl[type.getSymIndexId()] = enum_decl; 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric auto enum_values = enum_type->findAllChildren<PDBSymbolData>(); 5170b57cec5SDimitry Andric if (enum_values) { 5180b57cec5SDimitry Andric while (auto enum_value = enum_values->getNext()) { 5190b57cec5SDimitry Andric if (enum_value->getDataKind() != PDB_DataKind::Constant) 5200b57cec5SDimitry Andric continue; 5210b57cec5SDimitry Andric AddEnumValue(ast_enum, *enum_value); 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric 5255ffd83dbSDimitry Andric if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum)) 5265ffd83dbSDimitry Andric TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum); 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric if (enum_type->isConstType()) 5300b57cec5SDimitry Andric ast_enum = ast_enum.AddConstModifier(); 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric if (enum_type->isVolatileType()) 5330b57cec5SDimitry Andric ast_enum = ast_enum.AddVolatileModifier(); 5340b57cec5SDimitry Andric 53506c3fb27SDimitry Andric AddSourceInfoToDecl(type, decl); 536bdd1243dSDimitry Andric return m_ast.GetSymbolFile()->MakeType( 537bdd1243dSDimitry Andric type.getSymIndexId(), ConstString(name), bytes, nullptr, 538bdd1243dSDimitry Andric LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ast_enum, 539bdd1243dSDimitry Andric lldb_private::Type::ResolveState::Full); 5400b57cec5SDimitry Andric } break; 5410b57cec5SDimitry Andric case PDB_SymType::Typedef: { 5420b57cec5SDimitry Andric auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type); 5430b57cec5SDimitry Andric assert(type_def); 5440b57cec5SDimitry Andric 545fe6060f1SDimitry Andric SymbolFile *symbol_file = m_ast.GetSymbolFile(); 546fe6060f1SDimitry Andric if (!symbol_file) 547fe6060f1SDimitry Andric return nullptr; 548fe6060f1SDimitry Andric 5490b57cec5SDimitry Andric lldb_private::Type *target_type = 550fe6060f1SDimitry Andric symbol_file->ResolveTypeUID(type_def->getTypeId()); 5510b57cec5SDimitry Andric if (!target_type) 5520b57cec5SDimitry Andric return nullptr; 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric std::string name = 5555ffd83dbSDimitry Andric std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName())); 5560b57cec5SDimitry Andric auto decl_ctx = GetDeclContextContainingSymbol(type); 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric // Check if such a typedef already exists in the current context 5590b57cec5SDimitry Andric CompilerType ast_typedef = 56006c3fb27SDimitry Andric m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(name, decl_ctx); 5610b57cec5SDimitry Andric if (!ast_typedef.IsValid()) { 5620b57cec5SDimitry Andric CompilerType target_ast_type = target_type->GetFullCompilerType(); 5630b57cec5SDimitry Andric 564e8d8bef9SDimitry Andric ast_typedef = target_ast_type.CreateTypedef( 565e8d8bef9SDimitry Andric name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0); 5660b57cec5SDimitry Andric if (!ast_typedef) 5670b57cec5SDimitry Andric return nullptr; 5680b57cec5SDimitry Andric 5695ffd83dbSDimitry Andric auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef); 5700b57cec5SDimitry Andric assert(typedef_decl); 5710b57cec5SDimitry Andric m_uid_to_decl[type.getSymIndexId()] = typedef_decl; 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric if (type_def->isConstType()) 5750b57cec5SDimitry Andric ast_typedef = ast_typedef.AddConstModifier(); 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric if (type_def->isVolatileType()) 5780b57cec5SDimitry Andric ast_typedef = ast_typedef.AddVolatileModifier(); 5790b57cec5SDimitry Andric 58006c3fb27SDimitry Andric AddSourceInfoToDecl(type, decl); 581bdd1243dSDimitry Andric std::optional<uint64_t> size; 5820b57cec5SDimitry Andric if (type_def->getLength()) 5830b57cec5SDimitry Andric size = type_def->getLength(); 584bdd1243dSDimitry Andric return m_ast.GetSymbolFile()->MakeType( 585bdd1243dSDimitry Andric type_def->getSymIndexId(), ConstString(name), size, nullptr, 586bdd1243dSDimitry Andric target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, decl, 587bdd1243dSDimitry Andric ast_typedef, lldb_private::Type::ResolveState::Full); 5880b57cec5SDimitry Andric } break; 5890b57cec5SDimitry Andric case PDB_SymType::Function: 5900b57cec5SDimitry Andric case PDB_SymType::FunctionSig: { 5910b57cec5SDimitry Andric std::string name; 5920b57cec5SDimitry Andric PDBSymbolTypeFunctionSig *func_sig = nullptr; 5930b57cec5SDimitry Andric if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) { 5940b57cec5SDimitry Andric if (pdb_func->isCompilerGenerated()) 5950b57cec5SDimitry Andric return nullptr; 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric auto sig = pdb_func->getSignature(); 5980b57cec5SDimitry Andric if (!sig) 5990b57cec5SDimitry Andric return nullptr; 6000b57cec5SDimitry Andric func_sig = sig.release(); 6010b57cec5SDimitry Andric // Function type is named. 6025ffd83dbSDimitry Andric name = std::string( 6035ffd83dbSDimitry Andric MSVCUndecoratedNameParser::DropScope(pdb_func->getName())); 6040b57cec5SDimitry Andric } else if (auto pdb_func_sig = 6050b57cec5SDimitry Andric llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) { 6060b57cec5SDimitry Andric func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig); 6070b57cec5SDimitry Andric } else 6080b57cec5SDimitry Andric llvm_unreachable("Unexpected PDB symbol!"); 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric auto arg_enum = func_sig->getArguments(); 6110b57cec5SDimitry Andric uint32_t num_args = arg_enum->getChildCount(); 6120b57cec5SDimitry Andric std::vector<CompilerType> arg_list; 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric bool is_variadic = func_sig->isCVarArgs(); 6150b57cec5SDimitry Andric // Drop last variadic argument. 6160b57cec5SDimitry Andric if (is_variadic) 6170b57cec5SDimitry Andric --num_args; 6180b57cec5SDimitry Andric for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) { 6190b57cec5SDimitry Andric auto arg = arg_enum->getChildAtIndex(arg_idx); 6200b57cec5SDimitry Andric if (!arg) 6210b57cec5SDimitry Andric break; 622fe6060f1SDimitry Andric 623fe6060f1SDimitry Andric SymbolFile *symbol_file = m_ast.GetSymbolFile(); 624fe6060f1SDimitry Andric if (!symbol_file) 625fe6060f1SDimitry Andric return nullptr; 626fe6060f1SDimitry Andric 6270b57cec5SDimitry Andric lldb_private::Type *arg_type = 628fe6060f1SDimitry Andric symbol_file->ResolveTypeUID(arg->getSymIndexId()); 6290b57cec5SDimitry Andric // If there's some error looking up one of the dependent types of this 6300b57cec5SDimitry Andric // function signature, bail. 6310b57cec5SDimitry Andric if (!arg_type) 6320b57cec5SDimitry Andric return nullptr; 6330b57cec5SDimitry Andric CompilerType arg_ast_type = arg_type->GetFullCompilerType(); 6340b57cec5SDimitry Andric arg_list.push_back(arg_ast_type); 6350b57cec5SDimitry Andric } 6360b57cec5SDimitry Andric lldbassert(arg_list.size() <= num_args); 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric auto pdb_return_type = func_sig->getReturnType(); 639fe6060f1SDimitry Andric SymbolFile *symbol_file = m_ast.GetSymbolFile(); 640fe6060f1SDimitry Andric if (!symbol_file) 641fe6060f1SDimitry Andric return nullptr; 642fe6060f1SDimitry Andric 6430b57cec5SDimitry Andric lldb_private::Type *return_type = 644fe6060f1SDimitry Andric symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId()); 6450b57cec5SDimitry Andric // If there's some error looking up one of the dependent types of this 6460b57cec5SDimitry Andric // function signature, bail. 6470b57cec5SDimitry Andric if (!return_type) 6480b57cec5SDimitry Andric return nullptr; 6490b57cec5SDimitry Andric CompilerType return_ast_type = return_type->GetFullCompilerType(); 6500b57cec5SDimitry Andric uint32_t type_quals = 0; 6510b57cec5SDimitry Andric if (func_sig->isConstType()) 6520b57cec5SDimitry Andric type_quals |= clang::Qualifiers::Const; 6530b57cec5SDimitry Andric if (func_sig->isVolatileType()) 6540b57cec5SDimitry Andric type_quals |= clang::Qualifiers::Volatile; 6550b57cec5SDimitry Andric auto cc = TranslateCallingConvention(func_sig->getCallingConvention()); 6560b57cec5SDimitry Andric CompilerType func_sig_ast_type = 6570b57cec5SDimitry Andric m_ast.CreateFunctionType(return_ast_type, arg_list.data(), 6580b57cec5SDimitry Andric arg_list.size(), is_variadic, type_quals, cc); 6590b57cec5SDimitry Andric 66006c3fb27SDimitry Andric AddSourceInfoToDecl(type, decl); 661bdd1243dSDimitry Andric return m_ast.GetSymbolFile()->MakeType( 662bdd1243dSDimitry Andric type.getSymIndexId(), ConstString(name), std::nullopt, nullptr, 663bdd1243dSDimitry Andric LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 664bdd1243dSDimitry Andric func_sig_ast_type, lldb_private::Type::ResolveState::Full); 6650b57cec5SDimitry Andric } break; 6660b57cec5SDimitry Andric case PDB_SymType::ArrayType: { 6670b57cec5SDimitry Andric auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type); 6680b57cec5SDimitry Andric assert(array_type); 6690b57cec5SDimitry Andric uint32_t num_elements = array_type->getCount(); 6700b57cec5SDimitry Andric uint32_t element_uid = array_type->getElementTypeId(); 671bdd1243dSDimitry Andric std::optional<uint64_t> bytes; 6720b57cec5SDimitry Andric if (uint64_t size = array_type->getLength()) 6730b57cec5SDimitry Andric bytes = size; 6740b57cec5SDimitry Andric 675fe6060f1SDimitry Andric SymbolFile *symbol_file = m_ast.GetSymbolFile(); 676fe6060f1SDimitry Andric if (!symbol_file) 677fe6060f1SDimitry Andric return nullptr; 678fe6060f1SDimitry Andric 6790b57cec5SDimitry Andric // If array rank > 0, PDB gives the element type at N=0. So element type 6800b57cec5SDimitry Andric // will parsed in the order N=0, N=1,..., N=rank sequentially. 681fe6060f1SDimitry Andric lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid); 6820b57cec5SDimitry Andric if (!element_type) 6830b57cec5SDimitry Andric return nullptr; 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andric CompilerType element_ast_type = element_type->GetForwardCompilerType(); 6860b57cec5SDimitry Andric // If element type is UDT, it needs to be complete. 6875ffd83dbSDimitry Andric if (TypeSystemClang::IsCXXClassType(element_ast_type) && 6880b57cec5SDimitry Andric !element_ast_type.GetCompleteType()) { 6895ffd83dbSDimitry Andric if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) { 6905ffd83dbSDimitry Andric TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type); 6910b57cec5SDimitry Andric } else { 692bdd1243dSDimitry Andric // We are not able to start definition. 6930b57cec5SDimitry Andric return nullptr; 6940b57cec5SDimitry Andric } 6950b57cec5SDimitry Andric } 6960b57cec5SDimitry Andric CompilerType array_ast_type = m_ast.CreateArrayType( 6970b57cec5SDimitry Andric element_ast_type, num_elements, /*is_gnu_vector*/ false); 698bdd1243dSDimitry Andric TypeSP type_sp = m_ast.GetSymbolFile()->MakeType( 699bdd1243dSDimitry Andric array_type->getSymIndexId(), ConstString(), bytes, nullptr, 700bdd1243dSDimitry Andric LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 701bdd1243dSDimitry Andric array_ast_type, lldb_private::Type::ResolveState::Full); 7020b57cec5SDimitry Andric type_sp->SetEncodingType(element_type); 7030b57cec5SDimitry Andric return type_sp; 7040b57cec5SDimitry Andric } break; 7050b57cec5SDimitry Andric case PDB_SymType::BuiltinType: { 7060b57cec5SDimitry Andric auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type); 7070b57cec5SDimitry Andric assert(builtin_type); 7080b57cec5SDimitry Andric PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType(); 7090b57cec5SDimitry Andric if (builtin_kind == PDB_BuiltinType::None) 7100b57cec5SDimitry Andric return nullptr; 7110b57cec5SDimitry Andric 712bdd1243dSDimitry Andric std::optional<uint64_t> bytes; 7130b57cec5SDimitry Andric if (uint64_t size = builtin_type->getLength()) 7140b57cec5SDimitry Andric bytes = size; 7150b57cec5SDimitry Andric Encoding encoding = TranslateBuiltinEncoding(builtin_kind); 7160b57cec5SDimitry Andric CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize( 71781ad6265SDimitry Andric m_ast, *builtin_type, encoding, bytes.value_or(0) * 8); 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric if (builtin_type->isConstType()) 7200b57cec5SDimitry Andric builtin_ast_type = builtin_ast_type.AddConstModifier(); 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric if (builtin_type->isVolatileType()) 7230b57cec5SDimitry Andric builtin_ast_type = builtin_ast_type.AddVolatileModifier(); 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andric auto type_name = GetPDBBuiltinTypeName(*builtin_type, builtin_ast_type); 7260b57cec5SDimitry Andric 727bdd1243dSDimitry Andric return m_ast.GetSymbolFile()->MakeType( 728bdd1243dSDimitry Andric builtin_type->getSymIndexId(), type_name, bytes, nullptr, 729bdd1243dSDimitry Andric LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 730480093f4SDimitry Andric builtin_ast_type, lldb_private::Type::ResolveState::Full); 7310b57cec5SDimitry Andric } break; 7320b57cec5SDimitry Andric case PDB_SymType::PointerType: { 7330b57cec5SDimitry Andric auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type); 7340b57cec5SDimitry Andric assert(pointer_type); 735fe6060f1SDimitry Andric 736fe6060f1SDimitry Andric SymbolFile *symbol_file = m_ast.GetSymbolFile(); 737fe6060f1SDimitry Andric if (!symbol_file) 738fe6060f1SDimitry Andric return nullptr; 739fe6060f1SDimitry Andric 740fe6060f1SDimitry Andric Type *pointee_type = symbol_file->ResolveTypeUID( 7410b57cec5SDimitry Andric pointer_type->getPointeeType()->getSymIndexId()); 7420b57cec5SDimitry Andric if (!pointee_type) 7430b57cec5SDimitry Andric return nullptr; 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric if (pointer_type->isPointerToDataMember() || 7460b57cec5SDimitry Andric pointer_type->isPointerToMemberFunction()) { 7470b57cec5SDimitry Andric auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId(); 748fe6060f1SDimitry Andric auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid); 7490b57cec5SDimitry Andric assert(class_parent_type); 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric CompilerType pointer_ast_type; 7525ffd83dbSDimitry Andric pointer_ast_type = TypeSystemClang::CreateMemberPointerType( 7530b57cec5SDimitry Andric class_parent_type->GetLayoutCompilerType(), 7540b57cec5SDimitry Andric pointee_type->GetForwardCompilerType()); 7550b57cec5SDimitry Andric assert(pointer_ast_type); 7560b57cec5SDimitry Andric 757bdd1243dSDimitry Andric return m_ast.GetSymbolFile()->MakeType( 758bdd1243dSDimitry Andric pointer_type->getSymIndexId(), ConstString(), 7590b57cec5SDimitry Andric pointer_type->getLength(), nullptr, LLDB_INVALID_UID, 7600b57cec5SDimitry Andric lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type, 761480093f4SDimitry Andric lldb_private::Type::ResolveState::Forward); 7620b57cec5SDimitry Andric } 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric CompilerType pointer_ast_type; 7650b57cec5SDimitry Andric pointer_ast_type = pointee_type->GetFullCompilerType(); 7660b57cec5SDimitry Andric if (pointer_type->isReference()) 7670b57cec5SDimitry Andric pointer_ast_type = pointer_ast_type.GetLValueReferenceType(); 7680b57cec5SDimitry Andric else if (pointer_type->isRValueReference()) 7690b57cec5SDimitry Andric pointer_ast_type = pointer_ast_type.GetRValueReferenceType(); 7700b57cec5SDimitry Andric else 7710b57cec5SDimitry Andric pointer_ast_type = pointer_ast_type.GetPointerType(); 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric if (pointer_type->isConstType()) 7740b57cec5SDimitry Andric pointer_ast_type = pointer_ast_type.AddConstModifier(); 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric if (pointer_type->isVolatileType()) 7770b57cec5SDimitry Andric pointer_ast_type = pointer_ast_type.AddVolatileModifier(); 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric if (pointer_type->isRestrictedType()) 7800b57cec5SDimitry Andric pointer_ast_type = pointer_ast_type.AddRestrictModifier(); 7810b57cec5SDimitry Andric 782bdd1243dSDimitry Andric return m_ast.GetSymbolFile()->MakeType( 783bdd1243dSDimitry Andric pointer_type->getSymIndexId(), ConstString(), pointer_type->getLength(), 784bdd1243dSDimitry Andric nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 785bdd1243dSDimitry Andric pointer_ast_type, lldb_private::Type::ResolveState::Full); 7860b57cec5SDimitry Andric } break; 7870b57cec5SDimitry Andric default: 7880b57cec5SDimitry Andric break; 7890b57cec5SDimitry Andric } 7900b57cec5SDimitry Andric return nullptr; 7910b57cec5SDimitry Andric } 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric bool PDBASTParser::CompleteTypeFromPDB( 7940b57cec5SDimitry Andric lldb_private::CompilerType &compiler_type) { 7950b57cec5SDimitry Andric if (GetClangASTImporter().CanImport(compiler_type)) 7960b57cec5SDimitry Andric return GetClangASTImporter().CompleteType(compiler_type); 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric // Remove the type from the forward declarations to avoid 7990b57cec5SDimitry Andric // an endless recursion for types like a linked list. 8000b57cec5SDimitry Andric clang::CXXRecordDecl *record_decl = 8010b57cec5SDimitry Andric m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); 8020b57cec5SDimitry Andric auto uid_it = m_forward_decl_to_uid.find(record_decl); 8030b57cec5SDimitry Andric if (uid_it == m_forward_decl_to_uid.end()) 8040b57cec5SDimitry Andric return true; 8050b57cec5SDimitry Andric 80681ad6265SDimitry Andric auto symbol_file = static_cast<SymbolFilePDB *>( 80781ad6265SDimitry Andric m_ast.GetSymbolFile()->GetBackingSymbolFile()); 8080b57cec5SDimitry Andric if (!symbol_file) 8090b57cec5SDimitry Andric return false; 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric std::unique_ptr<PDBSymbol> symbol = 8120b57cec5SDimitry Andric symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond()); 8130b57cec5SDimitry Andric if (!symbol) 8140b57cec5SDimitry Andric return false; 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric m_forward_decl_to_uid.erase(uid_it); 8170b57cec5SDimitry Andric 8185ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), 8190b57cec5SDimitry Andric false); 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric switch (symbol->getSymTag()) { 8220b57cec5SDimitry Andric case PDB_SymType::UDT: { 8230b57cec5SDimitry Andric auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(symbol.get()); 8240b57cec5SDimitry Andric if (!udt) 8250b57cec5SDimitry Andric return false; 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt); 8280b57cec5SDimitry Andric } 8290b57cec5SDimitry Andric default: 8300b57cec5SDimitry Andric llvm_unreachable("not a forward clang type decl!"); 8310b57cec5SDimitry Andric } 8320b57cec5SDimitry Andric } 8330b57cec5SDimitry Andric 8340b57cec5SDimitry Andric clang::Decl * 8350b57cec5SDimitry Andric PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { 8360b57cec5SDimitry Andric uint32_t sym_id = symbol.getSymIndexId(); 8370b57cec5SDimitry Andric auto it = m_uid_to_decl.find(sym_id); 8380b57cec5SDimitry Andric if (it != m_uid_to_decl.end()) 8390b57cec5SDimitry Andric return it->second; 8400b57cec5SDimitry Andric 84181ad6265SDimitry Andric auto symbol_file = static_cast<SymbolFilePDB *>( 84281ad6265SDimitry Andric m_ast.GetSymbolFile()->GetBackingSymbolFile()); 8430b57cec5SDimitry Andric if (!symbol_file) 8440b57cec5SDimitry Andric return nullptr; 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric // First of all, check if the symbol is a member of a class. Resolve the full 8470b57cec5SDimitry Andric // class type and return the declaration from the cache if so. 8480b57cec5SDimitry Andric auto tag = symbol.getSymTag(); 8490b57cec5SDimitry Andric if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) { 8500b57cec5SDimitry Andric const IPDBSession &session = symbol.getSession(); 8510b57cec5SDimitry Andric const IPDBRawSymbol &raw = symbol.getRawSymbol(); 8520b57cec5SDimitry Andric 8530b57cec5SDimitry Andric auto class_parent_id = raw.getClassParentId(); 8540b57cec5SDimitry Andric if (std::unique_ptr<PDBSymbol> class_parent = 8550b57cec5SDimitry Andric session.getSymbolById(class_parent_id)) { 8560b57cec5SDimitry Andric auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id); 8570b57cec5SDimitry Andric if (!class_parent_type) 8580b57cec5SDimitry Andric return nullptr; 8590b57cec5SDimitry Andric 8600b57cec5SDimitry Andric CompilerType class_parent_ct = class_parent_type->GetFullCompilerType(); 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric // Look a declaration up in the cache after completing the class 8630b57cec5SDimitry Andric clang::Decl *decl = m_uid_to_decl.lookup(sym_id); 8640b57cec5SDimitry Andric if (decl) 8650b57cec5SDimitry Andric return decl; 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric // A declaration was not found in the cache. It means that the symbol 8680b57cec5SDimitry Andric // has the class parent, but the class doesn't have the symbol in its 8690b57cec5SDimitry Andric // children list. 8700b57cec5SDimitry Andric if (auto func = llvm::dyn_cast_or_null<PDBSymbolFunc>(&symbol)) { 8710b57cec5SDimitry Andric // Try to find a class child method with the same RVA and use its 8720b57cec5SDimitry Andric // declaration if found. 8730b57cec5SDimitry Andric if (uint32_t rva = func->getRelativeVirtualAddress()) { 8740b57cec5SDimitry Andric if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolFunc>> 8750b57cec5SDimitry Andric methods_enum = 8760b57cec5SDimitry Andric class_parent->findAllChildren<PDBSymbolFunc>()) { 8770b57cec5SDimitry Andric while (std::unique_ptr<PDBSymbolFunc> method = 8780b57cec5SDimitry Andric methods_enum->getNext()) { 8790b57cec5SDimitry Andric if (method->getRelativeVirtualAddress() == rva) { 8800b57cec5SDimitry Andric decl = m_uid_to_decl.lookup(method->getSymIndexId()); 8810b57cec5SDimitry Andric if (decl) 8820b57cec5SDimitry Andric break; 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric } 8850b57cec5SDimitry Andric } 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric // If no class methods with the same RVA were found, then create a new 8890b57cec5SDimitry Andric // method. It is possible for template methods. 8900b57cec5SDimitry Andric if (!decl) 8910b57cec5SDimitry Andric decl = AddRecordMethod(*symbol_file, class_parent_ct, *func); 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric if (decl) 8950b57cec5SDimitry Andric m_uid_to_decl[sym_id] = decl; 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric return decl; 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric } 9000b57cec5SDimitry Andric 9010b57cec5SDimitry Andric // If we are here, then the symbol is not belonging to a class and is not 9020b57cec5SDimitry Andric // contained in the cache. So create a declaration for it. 9030b57cec5SDimitry Andric switch (symbol.getSymTag()) { 9040b57cec5SDimitry Andric case PDB_SymType::Data: { 9050b57cec5SDimitry Andric auto data = llvm::dyn_cast<PDBSymbolData>(&symbol); 9060b57cec5SDimitry Andric assert(data); 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric auto decl_context = GetDeclContextContainingSymbol(symbol); 9090b57cec5SDimitry Andric assert(decl_context); 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric // May be the current context is a class really, but we haven't found 9120b57cec5SDimitry Andric // any class parent. This happens e.g. in the case of class static 9130b57cec5SDimitry Andric // variables - they has two symbols, one is a child of the class when 9140b57cec5SDimitry Andric // another is a child of the exe. So always complete the parent and use 9150b57cec5SDimitry Andric // an existing declaration if possible. 9160b57cec5SDimitry Andric if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context)) 9170b57cec5SDimitry Andric m_ast.GetCompleteDecl(parent_decl); 9180b57cec5SDimitry Andric 9195ffd83dbSDimitry Andric std::string name = 9205ffd83dbSDimitry Andric std::string(MSVCUndecoratedNameParser::DropScope(data->getName())); 9210b57cec5SDimitry Andric 9220b57cec5SDimitry Andric // Check if the current context already contains the symbol with the name. 9230b57cec5SDimitry Andric clang::Decl *decl = 924480093f4SDimitry Andric GetDeclFromContextByName(m_ast.getASTContext(), *decl_context, name); 9250b57cec5SDimitry Andric if (!decl) { 9260b57cec5SDimitry Andric auto type = symbol_file->ResolveTypeUID(data->getTypeId()); 9270b57cec5SDimitry Andric if (!type) 9280b57cec5SDimitry Andric return nullptr; 9290b57cec5SDimitry Andric 9300b57cec5SDimitry Andric decl = m_ast.CreateVariableDeclaration( 9315ffd83dbSDimitry Andric decl_context, OptionalClangModuleID(), name.c_str(), 9320b57cec5SDimitry Andric ClangUtil::GetQualType(type->GetLayoutCompilerType())); 9330b57cec5SDimitry Andric } 9340b57cec5SDimitry Andric 9350b57cec5SDimitry Andric m_uid_to_decl[sym_id] = decl; 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric return decl; 9380b57cec5SDimitry Andric } 9390b57cec5SDimitry Andric case PDB_SymType::Function: { 9400b57cec5SDimitry Andric auto func = llvm::dyn_cast<PDBSymbolFunc>(&symbol); 9410b57cec5SDimitry Andric assert(func); 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric auto decl_context = GetDeclContextContainingSymbol(symbol); 9440b57cec5SDimitry Andric assert(decl_context); 9450b57cec5SDimitry Andric 9465ffd83dbSDimitry Andric std::string name = 9475ffd83dbSDimitry Andric std::string(MSVCUndecoratedNameParser::DropScope(func->getName())); 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric Type *type = symbol_file->ResolveTypeUID(sym_id); 9500b57cec5SDimitry Andric if (!type) 9510b57cec5SDimitry Andric return nullptr; 9520b57cec5SDimitry Andric 9530b57cec5SDimitry Andric auto storage = func->isStatic() ? clang::StorageClass::SC_Static 9540b57cec5SDimitry Andric : clang::StorageClass::SC_None; 9550b57cec5SDimitry Andric 9560b57cec5SDimitry Andric auto decl = m_ast.CreateFunctionDeclaration( 957e8d8bef9SDimitry Andric decl_context, OptionalClangModuleID(), name, 9585ffd83dbSDimitry Andric type->GetForwardCompilerType(), storage, func->hasInlineAttribute()); 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric std::vector<clang::ParmVarDecl *> params; 9610b57cec5SDimitry Andric if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) { 9620b57cec5SDimitry Andric if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>> 9630b57cec5SDimitry Andric arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) { 9640b57cec5SDimitry Andric while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg = 9650b57cec5SDimitry Andric arg_enum->getNext()) { 9660b57cec5SDimitry Andric Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId()); 9670b57cec5SDimitry Andric if (!arg_type) 9680b57cec5SDimitry Andric continue; 9690b57cec5SDimitry Andric 9700b57cec5SDimitry Andric clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( 9715ffd83dbSDimitry Andric decl, OptionalClangModuleID(), nullptr, 9725ffd83dbSDimitry Andric arg_type->GetForwardCompilerType(), clang::SC_None, true); 9730b57cec5SDimitry Andric if (param) 9740b57cec5SDimitry Andric params.push_back(param); 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric } 9770b57cec5SDimitry Andric } 9780b57cec5SDimitry Andric if (params.size()) 979fe6060f1SDimitry Andric m_ast.SetFunctionParameters(decl, params); 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andric m_uid_to_decl[sym_id] = decl; 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric return decl; 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric default: { 9860b57cec5SDimitry Andric // It's not a variable and not a function, check if it's a type 9870b57cec5SDimitry Andric Type *type = symbol_file->ResolveTypeUID(sym_id); 9880b57cec5SDimitry Andric if (!type) 9890b57cec5SDimitry Andric return nullptr; 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric return m_uid_to_decl.lookup(sym_id); 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric } 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric clang::DeclContext * 9970b57cec5SDimitry Andric PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) { 9980b57cec5SDimitry Andric if (symbol.getSymTag() == PDB_SymType::Function) { 9990b57cec5SDimitry Andric clang::DeclContext *result = 10000b57cec5SDimitry Andric llvm::dyn_cast_or_null<clang::FunctionDecl>(GetDeclForSymbol(symbol)); 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric if (result) 10030b57cec5SDimitry Andric m_decl_context_to_uid[result] = symbol.getSymIndexId(); 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric return result; 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric 100881ad6265SDimitry Andric auto symbol_file = static_cast<SymbolFilePDB *>( 100981ad6265SDimitry Andric m_ast.GetSymbolFile()->GetBackingSymbolFile()); 10100b57cec5SDimitry Andric if (!symbol_file) 10110b57cec5SDimitry Andric return nullptr; 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andric auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId()); 10140b57cec5SDimitry Andric if (!type) 10150b57cec5SDimitry Andric return nullptr; 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric clang::DeclContext *result = 10180b57cec5SDimitry Andric m_ast.GetDeclContextForType(type->GetForwardCompilerType()); 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andric if (result) 10210b57cec5SDimitry Andric m_decl_context_to_uid[result] = symbol.getSymIndexId(); 10220b57cec5SDimitry Andric 10230b57cec5SDimitry Andric return result; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( 10270b57cec5SDimitry Andric const llvm::pdb::PDBSymbol &symbol) { 10280b57cec5SDimitry Andric auto parent = GetClassOrFunctionParent(symbol); 10290b57cec5SDimitry Andric while (parent) { 10300b57cec5SDimitry Andric if (auto parent_context = GetDeclContextForSymbol(*parent)) 10310b57cec5SDimitry Andric return parent_context; 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric parent = GetClassOrFunctionParent(*parent); 10340b57cec5SDimitry Andric } 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric // We can't find any class or function parent of the symbol. So analyze 10370b57cec5SDimitry Andric // the full symbol name. The symbol may be belonging to a namespace 10380b57cec5SDimitry Andric // or function (or even to a class if it's e.g. a static variable symbol). 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric // TODO: Make clang to emit full names for variables in namespaces 10410b57cec5SDimitry Andric // (as MSVC does) 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric std::string name(symbol.getRawSymbol().getName()); 10440b57cec5SDimitry Andric MSVCUndecoratedNameParser parser(name); 10450b57cec5SDimitry Andric llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 10460b57cec5SDimitry Andric if (specs.empty()) 10470b57cec5SDimitry Andric return m_ast.GetTranslationUnitDecl(); 10480b57cec5SDimitry Andric 104981ad6265SDimitry Andric auto symbol_file = static_cast<SymbolFilePDB *>( 105081ad6265SDimitry Andric m_ast.GetSymbolFile()->GetBackingSymbolFile()); 10510b57cec5SDimitry Andric if (!symbol_file) 10520b57cec5SDimitry Andric return m_ast.GetTranslationUnitDecl(); 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric auto global = symbol_file->GetPDBSession().getGlobalScope(); 10550b57cec5SDimitry Andric if (!global) 10560b57cec5SDimitry Andric return m_ast.GetTranslationUnitDecl(); 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric bool has_type_or_function_parent = false; 10590b57cec5SDimitry Andric clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl(); 10600b57cec5SDimitry Andric for (std::size_t i = 0; i < specs.size() - 1; i++) { 10610b57cec5SDimitry Andric // Check if there is a function or a type with the current context's name. 10620b57cec5SDimitry Andric if (std::unique_ptr<IPDBEnumSymbols> children_enum = global->findChildren( 10630b57cec5SDimitry Andric PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) { 10640b57cec5SDimitry Andric while (IPDBEnumChildren<PDBSymbol>::ChildTypePtr child = 10650b57cec5SDimitry Andric children_enum->getNext()) { 10660b57cec5SDimitry Andric if (clang::DeclContext *child_context = 10670b57cec5SDimitry Andric GetDeclContextForSymbol(*child)) { 10680b57cec5SDimitry Andric // Note that `GetDeclContextForSymbol' retrieves 10690b57cec5SDimitry Andric // a declaration context for functions and types only, 10700b57cec5SDimitry Andric // so if we are here then `child_context' is guaranteed 10710b57cec5SDimitry Andric // a function or a type declaration context. 10720b57cec5SDimitry Andric has_type_or_function_parent = true; 10730b57cec5SDimitry Andric curr_context = child_context; 10740b57cec5SDimitry Andric } 10750b57cec5SDimitry Andric } 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric // If there were no functions or types above then retrieve a namespace with 10790b57cec5SDimitry Andric // the current context's name. There can be no namespaces inside a function 10800b57cec5SDimitry Andric // or a type. We check it to avoid fake namespaces such as `__l2': 10810b57cec5SDimitry Andric // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct' 10820b57cec5SDimitry Andric if (!has_type_or_function_parent) { 10835ffd83dbSDimitry Andric std::string namespace_name = std::string(specs[i].GetBaseName()); 10840b57cec5SDimitry Andric const char *namespace_name_c_str = 10850b57cec5SDimitry Andric IsAnonymousNamespaceName(namespace_name) ? nullptr 10860b57cec5SDimitry Andric : namespace_name.data(); 10870b57cec5SDimitry Andric clang::NamespaceDecl *namespace_decl = 10885ffd83dbSDimitry Andric m_ast.GetUniqueNamespaceDeclaration( 10895ffd83dbSDimitry Andric namespace_name_c_str, curr_context, OptionalClangModuleID()); 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric m_parent_to_namespaces[curr_context].insert(namespace_decl); 10920b57cec5SDimitry Andric m_namespaces.insert(namespace_decl); 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric curr_context = namespace_decl; 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric } 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andric return curr_context; 10990b57cec5SDimitry Andric } 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric void PDBASTParser::ParseDeclsForDeclContext( 11020b57cec5SDimitry Andric const clang::DeclContext *decl_context) { 110381ad6265SDimitry Andric auto symbol_file = static_cast<SymbolFilePDB *>( 110481ad6265SDimitry Andric m_ast.GetSymbolFile()->GetBackingSymbolFile()); 11050b57cec5SDimitry Andric if (!symbol_file) 11060b57cec5SDimitry Andric return; 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric IPDBSession &session = symbol_file->GetPDBSession(); 11090b57cec5SDimitry Andric auto symbol_up = 11100b57cec5SDimitry Andric session.getSymbolById(m_decl_context_to_uid.lookup(decl_context)); 11110b57cec5SDimitry Andric auto global_up = session.getGlobalScope(); 11120b57cec5SDimitry Andric 11130b57cec5SDimitry Andric PDBSymbol *symbol; 11140b57cec5SDimitry Andric if (symbol_up) 11150b57cec5SDimitry Andric symbol = symbol_up.get(); 11160b57cec5SDimitry Andric else if (global_up) 11170b57cec5SDimitry Andric symbol = global_up.get(); 11180b57cec5SDimitry Andric else 11190b57cec5SDimitry Andric return; 11200b57cec5SDimitry Andric 11210b57cec5SDimitry Andric if (auto children = symbol->findAllChildren()) 11220b57cec5SDimitry Andric while (auto child = children->getNext()) 11230b57cec5SDimitry Andric GetDeclForSymbol(*child); 11240b57cec5SDimitry Andric } 11250b57cec5SDimitry Andric 11260b57cec5SDimitry Andric clang::NamespaceDecl * 11270b57cec5SDimitry Andric PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent, 11280b57cec5SDimitry Andric llvm::StringRef name) { 11290b57cec5SDimitry Andric NamespacesSet *set; 11300b57cec5SDimitry Andric if (parent) { 11310b57cec5SDimitry Andric auto pit = m_parent_to_namespaces.find(parent); 11320b57cec5SDimitry Andric if (pit == m_parent_to_namespaces.end()) 11330b57cec5SDimitry Andric return nullptr; 11340b57cec5SDimitry Andric 11350b57cec5SDimitry Andric set = &pit->second; 11360b57cec5SDimitry Andric } else { 11370b57cec5SDimitry Andric set = &m_namespaces; 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric assert(set); 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric for (clang::NamespaceDecl *namespace_decl : *set) 1142*0fca6ea1SDimitry Andric if (namespace_decl->getName() == name) 11430b57cec5SDimitry Andric return namespace_decl; 11440b57cec5SDimitry Andric 11450b57cec5SDimitry Andric for (clang::NamespaceDecl *namespace_decl : *set) 11460b57cec5SDimitry Andric if (namespace_decl->isAnonymousNamespace()) 11470b57cec5SDimitry Andric return FindNamespaceDecl(namespace_decl, name); 11480b57cec5SDimitry Andric 11490b57cec5SDimitry Andric return nullptr; 11500b57cec5SDimitry Andric } 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric bool PDBASTParser::AddEnumValue(CompilerType enum_type, 11530b57cec5SDimitry Andric const PDBSymbolData &enum_value) { 11540b57cec5SDimitry Andric Declaration decl; 11550b57cec5SDimitry Andric Variant v = enum_value.getValue(); 11565ffd83dbSDimitry Andric std::string name = 11575ffd83dbSDimitry Andric std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName())); 11580b57cec5SDimitry Andric int64_t raw_value; 11590b57cec5SDimitry Andric switch (v.Type) { 11600b57cec5SDimitry Andric case PDB_VariantType::Int8: 11610b57cec5SDimitry Andric raw_value = v.Value.Int8; 11620b57cec5SDimitry Andric break; 11630b57cec5SDimitry Andric case PDB_VariantType::Int16: 11640b57cec5SDimitry Andric raw_value = v.Value.Int16; 11650b57cec5SDimitry Andric break; 11660b57cec5SDimitry Andric case PDB_VariantType::Int32: 11670b57cec5SDimitry Andric raw_value = v.Value.Int32; 11680b57cec5SDimitry Andric break; 11690b57cec5SDimitry Andric case PDB_VariantType::Int64: 11700b57cec5SDimitry Andric raw_value = v.Value.Int64; 11710b57cec5SDimitry Andric break; 11720b57cec5SDimitry Andric case PDB_VariantType::UInt8: 11730b57cec5SDimitry Andric raw_value = v.Value.UInt8; 11740b57cec5SDimitry Andric break; 11750b57cec5SDimitry Andric case PDB_VariantType::UInt16: 11760b57cec5SDimitry Andric raw_value = v.Value.UInt16; 11770b57cec5SDimitry Andric break; 11780b57cec5SDimitry Andric case PDB_VariantType::UInt32: 11790b57cec5SDimitry Andric raw_value = v.Value.UInt32; 11800b57cec5SDimitry Andric break; 11810b57cec5SDimitry Andric case PDB_VariantType::UInt64: 11820b57cec5SDimitry Andric raw_value = v.Value.UInt64; 11830b57cec5SDimitry Andric break; 11840b57cec5SDimitry Andric default: 11850b57cec5SDimitry Andric return false; 11860b57cec5SDimitry Andric } 11875ffd83dbSDimitry Andric CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type); 1188480093f4SDimitry Andric uint32_t byte_size = m_ast.getASTContext().getTypeSize( 11890b57cec5SDimitry Andric ClangUtil::GetQualType(underlying_type)); 11900b57cec5SDimitry Andric auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType( 11910b57cec5SDimitry Andric enum_type, decl, name.c_str(), raw_value, byte_size * 8); 11920b57cec5SDimitry Andric if (!enum_constant_decl) 11930b57cec5SDimitry Andric return false; 11940b57cec5SDimitry Andric 11950b57cec5SDimitry Andric m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl; 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric return true; 11980b57cec5SDimitry Andric } 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric bool PDBASTParser::CompleteTypeFromUDT( 12010b57cec5SDimitry Andric lldb_private::SymbolFile &symbol_file, 12020b57cec5SDimitry Andric lldb_private::CompilerType &compiler_type, 12030b57cec5SDimitry Andric llvm::pdb::PDBSymbolTypeUDT &udt) { 12040b57cec5SDimitry Andric ClangASTImporter::LayoutInfo layout_info; 12050b57cec5SDimitry Andric layout_info.bit_size = udt.getLength() * 8; 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andric auto nested_enums = udt.findAllChildren<PDBSymbolTypeUDT>(); 12080b57cec5SDimitry Andric if (nested_enums) 12090b57cec5SDimitry Andric while (auto nested = nested_enums->getNext()) 12100b57cec5SDimitry Andric symbol_file.ResolveTypeUID(nested->getSymIndexId()); 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>(); 12130b57cec5SDimitry Andric if (bases_enum) 12140b57cec5SDimitry Andric AddRecordBases(symbol_file, compiler_type, 12150b57cec5SDimitry Andric TranslateUdtKind(udt.getUdtKind()), *bases_enum, 12160b57cec5SDimitry Andric layout_info); 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric auto members_enum = udt.findAllChildren<PDBSymbolData>(); 12190b57cec5SDimitry Andric if (members_enum) 12200b57cec5SDimitry Andric AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info); 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric auto methods_enum = udt.findAllChildren<PDBSymbolFunc>(); 12230b57cec5SDimitry Andric if (methods_enum) 12240b57cec5SDimitry Andric AddRecordMethods(symbol_file, compiler_type, *methods_enum); 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType()); 12275ffd83dbSDimitry Andric TypeSystemClang::BuildIndirectFields(compiler_type); 12285ffd83dbSDimitry Andric TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric clang::CXXRecordDecl *record_decl = 12310b57cec5SDimitry Andric m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); 12320b57cec5SDimitry Andric if (!record_decl) 12330b57cec5SDimitry Andric return static_cast<bool>(compiler_type); 12340b57cec5SDimitry Andric 1235480093f4SDimitry Andric GetClangASTImporter().SetRecordLayout(record_decl, layout_info); 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric return static_cast<bool>(compiler_type); 12380b57cec5SDimitry Andric } 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric void PDBASTParser::AddRecordMembers( 12410b57cec5SDimitry Andric lldb_private::SymbolFile &symbol_file, 12420b57cec5SDimitry Andric lldb_private::CompilerType &record_type, 12430b57cec5SDimitry Andric PDBDataSymbolEnumerator &members_enum, 12440b57cec5SDimitry Andric lldb_private::ClangASTImporter::LayoutInfo &layout_info) { 12450b57cec5SDimitry Andric while (auto member = members_enum.getNext()) { 12460b57cec5SDimitry Andric if (member->isCompilerGenerated()) 12470b57cec5SDimitry Andric continue; 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric auto member_name = member->getName(); 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric auto member_type = symbol_file.ResolveTypeUID(member->getTypeId()); 12520b57cec5SDimitry Andric if (!member_type) 12530b57cec5SDimitry Andric continue; 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andric auto member_comp_type = member_type->GetLayoutCompilerType(); 12560b57cec5SDimitry Andric if (!member_comp_type.GetCompleteType()) { 12570b57cec5SDimitry Andric symbol_file.GetObjectFile()->GetModule()->ReportError( 1258bdd1243dSDimitry Andric ":: Class '{0}' has a member '{1}' of type '{2}' " 12590b57cec5SDimitry Andric "which does not have a complete definition.", 12600b57cec5SDimitry Andric record_type.GetTypeName().GetCString(), member_name.c_str(), 12610b57cec5SDimitry Andric member_comp_type.GetTypeName().GetCString()); 12625ffd83dbSDimitry Andric if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type)) 12635ffd83dbSDimitry Andric TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type); 12640b57cec5SDimitry Andric } 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric auto access = TranslateMemberAccess(member->getAccess()); 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric switch (member->getDataKind()) { 12690b57cec5SDimitry Andric case PDB_DataKind::Member: { 12700b57cec5SDimitry Andric auto location_type = member->getLocationType(); 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric auto bit_size = member->getLength(); 12730b57cec5SDimitry Andric if (location_type == PDB_LocType::ThisRel) 12740b57cec5SDimitry Andric bit_size *= 8; 12750b57cec5SDimitry Andric 12765ffd83dbSDimitry Andric auto decl = TypeSystemClang::AddFieldToRecordType( 12770b57cec5SDimitry Andric record_type, member_name.c_str(), member_comp_type, access, bit_size); 12780b57cec5SDimitry Andric if (!decl) 12790b57cec5SDimitry Andric continue; 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric m_uid_to_decl[member->getSymIndexId()] = decl; 12820b57cec5SDimitry Andric 12830b57cec5SDimitry Andric auto offset = member->getOffset() * 8; 12840b57cec5SDimitry Andric if (location_type == PDB_LocType::BitField) 12850b57cec5SDimitry Andric offset += member->getBitPosition(); 12860b57cec5SDimitry Andric 12870b57cec5SDimitry Andric layout_info.field_offsets.insert(std::make_pair(decl, offset)); 12880b57cec5SDimitry Andric 12890b57cec5SDimitry Andric break; 12900b57cec5SDimitry Andric } 12910b57cec5SDimitry Andric case PDB_DataKind::StaticMember: { 12925ffd83dbSDimitry Andric auto decl = TypeSystemClang::AddVariableToRecordType( 12930b57cec5SDimitry Andric record_type, member_name.c_str(), member_comp_type, access); 12940b57cec5SDimitry Andric if (!decl) 12950b57cec5SDimitry Andric continue; 12960b57cec5SDimitry Andric 12975ffd83dbSDimitry Andric // Static constant members may be a const[expr] declaration. 12985ffd83dbSDimitry Andric // Query the symbol's value as the variable initializer if valid. 12995ffd83dbSDimitry Andric if (member_comp_type.IsConst()) { 13005ffd83dbSDimitry Andric auto value = member->getValue(); 130106c3fb27SDimitry Andric if (value.Type == llvm::pdb::Empty) { 130206c3fb27SDimitry Andric LLDB_LOG(GetLog(LLDBLog::AST), 130306c3fb27SDimitry Andric "Class '{0}' has member '{1}' of type '{2}' with an unknown " 130406c3fb27SDimitry Andric "constant size.", 130506c3fb27SDimitry Andric record_type.GetTypeName(), member_name, 130606c3fb27SDimitry Andric member_comp_type.GetTypeName()); 130706c3fb27SDimitry Andric continue; 130806c3fb27SDimitry Andric } 130906c3fb27SDimitry Andric 13105ffd83dbSDimitry Andric clang::QualType qual_type = decl->getType(); 13115ffd83dbSDimitry Andric unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type); 13125ffd83dbSDimitry Andric unsigned constant_width = value.getBitWidth(); 13135ffd83dbSDimitry Andric 13145ffd83dbSDimitry Andric if (qual_type->isIntegralOrEnumerationType()) { 13155ffd83dbSDimitry Andric if (type_width >= constant_width) { 13165ffd83dbSDimitry Andric TypeSystemClang::SetIntegerInitializerForVariable( 13175ffd83dbSDimitry Andric decl, value.toAPSInt().extOrTrunc(type_width)); 13185ffd83dbSDimitry Andric } else { 131981ad6265SDimitry Andric LLDB_LOG(GetLog(LLDBLog::AST), 13205ffd83dbSDimitry Andric "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " 13215ffd83dbSDimitry Andric "which resolves to a wider constant value ({4} bits). " 13225ffd83dbSDimitry Andric "Ignoring constant.", 13235ffd83dbSDimitry Andric record_type.GetTypeName(), member_name, 13245ffd83dbSDimitry Andric member_comp_type.GetTypeName(), type_width, 13255ffd83dbSDimitry Andric constant_width); 13265ffd83dbSDimitry Andric } 13275ffd83dbSDimitry Andric } else { 13285ffd83dbSDimitry Andric switch (member_comp_type.GetBasicTypeEnumeration()) { 13295ffd83dbSDimitry Andric case lldb::eBasicTypeFloat: 13305ffd83dbSDimitry Andric case lldb::eBasicTypeDouble: 13315ffd83dbSDimitry Andric case lldb::eBasicTypeLongDouble: 13325ffd83dbSDimitry Andric if (type_width == constant_width) { 13335ffd83dbSDimitry Andric TypeSystemClang::SetFloatingInitializerForVariable( 13345ffd83dbSDimitry Andric decl, value.toAPFloat()); 13355ffd83dbSDimitry Andric decl->setConstexpr(true); 13365ffd83dbSDimitry Andric } else { 133781ad6265SDimitry Andric LLDB_LOG(GetLog(LLDBLog::AST), 13385ffd83dbSDimitry Andric "Class '{0}' has a member '{1}' of type '{2}' ({3} " 13395ffd83dbSDimitry Andric "bits) which resolves to a constant value of mismatched " 13405ffd83dbSDimitry Andric "width ({4} bits). Ignoring constant.", 13415ffd83dbSDimitry Andric record_type.GetTypeName(), member_name, 13425ffd83dbSDimitry Andric member_comp_type.GetTypeName(), type_width, 13435ffd83dbSDimitry Andric constant_width); 13445ffd83dbSDimitry Andric } 13455ffd83dbSDimitry Andric break; 13465ffd83dbSDimitry Andric default: 13475ffd83dbSDimitry Andric break; 13485ffd83dbSDimitry Andric } 13495ffd83dbSDimitry Andric } 13505ffd83dbSDimitry Andric } 13515ffd83dbSDimitry Andric 13520b57cec5SDimitry Andric m_uid_to_decl[member->getSymIndexId()] = decl; 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric break; 13550b57cec5SDimitry Andric } 13560b57cec5SDimitry Andric default: 13570b57cec5SDimitry Andric llvm_unreachable("unsupported PDB data kind"); 13580b57cec5SDimitry Andric } 13590b57cec5SDimitry Andric } 13600b57cec5SDimitry Andric } 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andric void PDBASTParser::AddRecordBases( 13630b57cec5SDimitry Andric lldb_private::SymbolFile &symbol_file, 13640b57cec5SDimitry Andric lldb_private::CompilerType &record_type, int record_kind, 13650b57cec5SDimitry Andric PDBBaseClassSymbolEnumerator &bases_enum, 13660b57cec5SDimitry Andric lldb_private::ClangASTImporter::LayoutInfo &layout_info) const { 13670b57cec5SDimitry Andric std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> base_classes; 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric while (auto base = bases_enum.getNext()) { 13700b57cec5SDimitry Andric auto base_type = symbol_file.ResolveTypeUID(base->getTypeId()); 13710b57cec5SDimitry Andric if (!base_type) 13720b57cec5SDimitry Andric continue; 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andric auto base_comp_type = base_type->GetFullCompilerType(); 13750b57cec5SDimitry Andric if (!base_comp_type.GetCompleteType()) { 13760b57cec5SDimitry Andric symbol_file.GetObjectFile()->GetModule()->ReportError( 1377bdd1243dSDimitry Andric ":: Class '{0}' has a base class '{1}' " 13780b57cec5SDimitry Andric "which does not have a complete definition.", 13790b57cec5SDimitry Andric record_type.GetTypeName().GetCString(), 13800b57cec5SDimitry Andric base_comp_type.GetTypeName().GetCString()); 13815ffd83dbSDimitry Andric if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type)) 13825ffd83dbSDimitry Andric TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type); 13830b57cec5SDimitry Andric } 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric auto access = TranslateMemberAccess(base->getAccess()); 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric auto is_virtual = base->isVirtualBaseClass(); 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric std::unique_ptr<clang::CXXBaseSpecifier> base_spec = 13905f757f3fSDimitry Andric m_ast.CreateBaseClassSpecifier( 13915f757f3fSDimitry Andric base_comp_type.GetOpaqueQualType(), access, is_virtual, 13925f757f3fSDimitry Andric record_kind == llvm::to_underlying(clang::TagTypeKind::Class)); 13930b57cec5SDimitry Andric lldbassert(base_spec); 13940b57cec5SDimitry Andric 13950b57cec5SDimitry Andric base_classes.push_back(std::move(base_spec)); 13960b57cec5SDimitry Andric 13970b57cec5SDimitry Andric if (is_virtual) 13980b57cec5SDimitry Andric continue; 13990b57cec5SDimitry Andric 14000b57cec5SDimitry Andric auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType()); 14010b57cec5SDimitry Andric if (!decl) 14020b57cec5SDimitry Andric continue; 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andric auto offset = clang::CharUnits::fromQuantity(base->getOffset()); 14050b57cec5SDimitry Andric layout_info.base_offsets.insert(std::make_pair(decl, offset)); 14060b57cec5SDimitry Andric } 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(), 14090b57cec5SDimitry Andric std::move(base_classes)); 14100b57cec5SDimitry Andric } 14110b57cec5SDimitry Andric 14120b57cec5SDimitry Andric void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file, 14130b57cec5SDimitry Andric lldb_private::CompilerType &record_type, 14140b57cec5SDimitry Andric PDBFuncSymbolEnumerator &methods_enum) { 14150b57cec5SDimitry Andric while (std::unique_ptr<PDBSymbolFunc> method = methods_enum.getNext()) 14160b57cec5SDimitry Andric if (clang::CXXMethodDecl *decl = 14170b57cec5SDimitry Andric AddRecordMethod(symbol_file, record_type, *method)) 14180b57cec5SDimitry Andric m_uid_to_decl[method->getSymIndexId()] = decl; 14190b57cec5SDimitry Andric } 14200b57cec5SDimitry Andric 14210b57cec5SDimitry Andric clang::CXXMethodDecl * 14220b57cec5SDimitry Andric PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file, 14230b57cec5SDimitry Andric lldb_private::CompilerType &record_type, 14240b57cec5SDimitry Andric const llvm::pdb::PDBSymbolFunc &method) const { 14255ffd83dbSDimitry Andric std::string name = 14265ffd83dbSDimitry Andric std::string(MSVCUndecoratedNameParser::DropScope(method.getName())); 14270b57cec5SDimitry Andric 14280b57cec5SDimitry Andric Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId()); 14290b57cec5SDimitry Andric // MSVC specific __vecDelDtor. 14300b57cec5SDimitry Andric if (!method_type) 14310b57cec5SDimitry Andric return nullptr; 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andric CompilerType method_comp_type = method_type->GetFullCompilerType(); 14340b57cec5SDimitry Andric if (!method_comp_type.GetCompleteType()) { 14350b57cec5SDimitry Andric symbol_file.GetObjectFile()->GetModule()->ReportError( 1436bdd1243dSDimitry Andric ":: Class '{0}' has a method '{1}' whose type cannot be completed.", 14370b57cec5SDimitry Andric record_type.GetTypeName().GetCString(), 14380b57cec5SDimitry Andric method_comp_type.GetTypeName().GetCString()); 14395ffd83dbSDimitry Andric if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type)) 14405ffd83dbSDimitry Andric TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type); 14410b57cec5SDimitry Andric } 14420b57cec5SDimitry Andric 14430b57cec5SDimitry Andric AccessType access = TranslateMemberAccess(method.getAccess()); 14440b57cec5SDimitry Andric if (access == eAccessNone) 14450b57cec5SDimitry Andric access = eAccessPublic; 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andric // TODO: get mangled name for the method. 14480b57cec5SDimitry Andric return m_ast.AddMethodToCXXRecordType( 14490b57cec5SDimitry Andric record_type.GetOpaqueQualType(), name.c_str(), 14500b57cec5SDimitry Andric /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(), 14510b57cec5SDimitry Andric method.isStatic(), method.hasInlineAttribute(), 14520b57cec5SDimitry Andric /*is_explicit*/ false, // FIXME: Need this field in CodeView. 14530b57cec5SDimitry Andric /*is_attr_used*/ false, 14540b57cec5SDimitry Andric /*is_artificial*/ method.isCompilerGenerated()); 14550b57cec5SDimitry Andric } 1456