Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
39644 views
//===-- PDBASTParser.cpp --------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "PDBASTParser.h"910#include "SymbolFilePDB.h"1112#include "clang/AST/CharUnits.h"13#include "clang/AST/Decl.h"14#include "clang/AST/DeclCXX.h"1516#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"17#include "Plugins/ExpressionParser/Clang/ClangUtil.h"18#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"19#include "lldb/Core/Declaration.h"20#include "lldb/Core/Module.h"21#include "lldb/Symbol/SymbolFile.h"22#include "lldb/Symbol/TypeMap.h"23#include "lldb/Symbol/TypeSystem.h"24#include "lldb/Utility/LLDBLog.h"25#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"26#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"27#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"28#include "llvm/DebugInfo/PDB/PDBSymbol.h"29#include "llvm/DebugInfo/PDB/PDBSymbolData.h"30#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"31#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"32#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"33#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"34#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"35#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"36#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"37#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"38#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"39#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"4041#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"42#include <optional>4344using namespace lldb;45using namespace lldb_private;46using namespace llvm::pdb;4748static int TranslateUdtKind(PDB_UdtType pdb_kind) {49switch (pdb_kind) {50case PDB_UdtType::Class:51return llvm::to_underlying(clang::TagTypeKind::Class);52case PDB_UdtType::Struct:53return llvm::to_underlying(clang::TagTypeKind::Struct);54case PDB_UdtType::Union:55return llvm::to_underlying(clang::TagTypeKind::Union);56case PDB_UdtType::Interface:57return llvm::to_underlying(clang::TagTypeKind::Interface);58}59llvm_unreachable("unsuported PDB UDT type");60}6162static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {63switch (type) {64case PDB_BuiltinType::Float:65return lldb::eEncodingIEEE754;66case PDB_BuiltinType::Int:67case PDB_BuiltinType::Long:68case PDB_BuiltinType::Char:69return lldb::eEncodingSint;70case PDB_BuiltinType::Bool:71case PDB_BuiltinType::Char16:72case PDB_BuiltinType::Char32:73case PDB_BuiltinType::UInt:74case PDB_BuiltinType::ULong:75case PDB_BuiltinType::HResult:76case PDB_BuiltinType::WCharT:77return lldb::eEncodingUint;78default:79return lldb::eEncodingInvalid;80}81}8283static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {84switch (type) {85case PDB_VariantType::Int8:86case PDB_VariantType::Int16:87case PDB_VariantType::Int32:88case PDB_VariantType::Int64:89return lldb::eEncodingSint;9091case PDB_VariantType::UInt8:92case PDB_VariantType::UInt16:93case PDB_VariantType::UInt32:94case PDB_VariantType::UInt64:95return lldb::eEncodingUint;9697default:98break;99}100101return lldb::eEncodingSint;102}103104static CompilerType105GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast,106const PDBSymbolTypeBuiltin &pdb_type,107Encoding encoding, uint32_t width) {108clang::ASTContext &ast = clang_ast.getASTContext();109110switch (pdb_type.getBuiltinType()) {111default:112break;113case PDB_BuiltinType::None:114return CompilerType();115case PDB_BuiltinType::Void:116return clang_ast.GetBasicType(eBasicTypeVoid);117case PDB_BuiltinType::Char:118return clang_ast.GetBasicType(eBasicTypeChar);119case PDB_BuiltinType::Bool:120return clang_ast.GetBasicType(eBasicTypeBool);121case PDB_BuiltinType::Long:122if (width == ast.getTypeSize(ast.LongTy))123return CompilerType(clang_ast.weak_from_this(),124ast.LongTy.getAsOpaquePtr());125if (width == ast.getTypeSize(ast.LongLongTy))126return CompilerType(clang_ast.weak_from_this(),127ast.LongLongTy.getAsOpaquePtr());128break;129case PDB_BuiltinType::ULong:130if (width == ast.getTypeSize(ast.UnsignedLongTy))131return CompilerType(clang_ast.weak_from_this(),132ast.UnsignedLongTy.getAsOpaquePtr());133if (width == ast.getTypeSize(ast.UnsignedLongLongTy))134return CompilerType(clang_ast.weak_from_this(),135ast.UnsignedLongLongTy.getAsOpaquePtr());136break;137case PDB_BuiltinType::WCharT:138if (width == ast.getTypeSize(ast.WCharTy))139return CompilerType(clang_ast.weak_from_this(),140ast.WCharTy.getAsOpaquePtr());141break;142case PDB_BuiltinType::Char16:143return CompilerType(clang_ast.weak_from_this(),144ast.Char16Ty.getAsOpaquePtr());145case PDB_BuiltinType::Char32:146return CompilerType(clang_ast.weak_from_this(),147ast.Char32Ty.getAsOpaquePtr());148case PDB_BuiltinType::Float:149// Note: types `long double` and `double` have same bit size in MSVC and150// there is no information in the PDB to distinguish them. So when falling151// back to default search, the compiler type of `long double` will be152// represented by the one generated for `double`.153break;154}155// If there is no match on PDB_BuiltinType, fall back to default search by156// encoding and width only157return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width);158}159160static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,161CompilerType &compiler_type) {162PDB_BuiltinType kind = pdb_type.getBuiltinType();163switch (kind) {164default:165break;166case PDB_BuiltinType::Currency:167return ConstString("CURRENCY");168case PDB_BuiltinType::Date:169return ConstString("DATE");170case PDB_BuiltinType::Variant:171return ConstString("VARIANT");172case PDB_BuiltinType::Complex:173return ConstString("complex");174case PDB_BuiltinType::Bitfield:175return ConstString("bitfield");176case PDB_BuiltinType::BSTR:177return ConstString("BSTR");178case PDB_BuiltinType::HResult:179return ConstString("HRESULT");180case PDB_BuiltinType::BCD:181return ConstString("BCD");182case PDB_BuiltinType::Char16:183return ConstString("char16_t");184case PDB_BuiltinType::Char32:185return ConstString("char32_t");186case PDB_BuiltinType::None:187return ConstString("...");188}189return compiler_type.GetTypeName();190}191192static bool AddSourceInfoToDecl(const PDBSymbol &symbol, Declaration &decl) {193auto &raw_sym = symbol.getRawSymbol();194auto first_line_up = raw_sym.getSrcLineOnTypeDefn();195196if (!first_line_up) {197auto lines_up = symbol.getSession().findLineNumbersByAddress(198raw_sym.getVirtualAddress(), raw_sym.getLength());199if (!lines_up)200return false;201first_line_up = lines_up->getNext();202if (!first_line_up)203return false;204}205uint32_t src_file_id = first_line_up->getSourceFileId();206auto src_file_up = symbol.getSession().getSourceFileById(src_file_id);207if (!src_file_up)208return false;209210FileSpec spec(src_file_up->getFileName());211decl.SetFile(spec);212decl.SetColumn(first_line_up->getColumnNumber());213decl.SetLine(first_line_up->getLineNumber());214return true;215}216217static AccessType TranslateMemberAccess(PDB_MemberAccess access) {218switch (access) {219case PDB_MemberAccess::Private:220return eAccessPrivate;221case PDB_MemberAccess::Protected:222return eAccessProtected;223case PDB_MemberAccess::Public:224return eAccessPublic;225}226return eAccessNone;227}228229static AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) {230switch (udt_kind) {231case PDB_UdtType::Struct:232case PDB_UdtType::Union:233return eAccessPublic;234case PDB_UdtType::Class:235case PDB_UdtType::Interface:236return eAccessPrivate;237}238llvm_unreachable("unsupported PDB UDT type");239}240241static AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) {242AccessType access = TranslateMemberAccess(udt.getAccess());243if (access != lldb::eAccessNone || !udt.isNested())244return access;245246auto parent = udt.getClassParent();247if (!parent)248return lldb::eAccessNone;249250auto parent_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(parent.get());251if (!parent_udt)252return lldb::eAccessNone;253254return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind());255}256257static clang::MSInheritanceAttr::Spelling258GetMSInheritance(const PDBSymbolTypeUDT &udt) {259int base_count = 0;260bool has_virtual = false;261262auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();263if (bases_enum) {264while (auto base = bases_enum->getNext()) {265base_count++;266has_virtual |= base->isVirtualBaseClass();267}268}269270if (has_virtual)271return clang::MSInheritanceAttr::Keyword_virtual_inheritance;272if (base_count > 1)273return clang::MSInheritanceAttr::Keyword_multiple_inheritance;274return clang::MSInheritanceAttr::Keyword_single_inheritance;275}276277static std::unique_ptr<llvm::pdb::PDBSymbol>278GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) {279const IPDBSession &session = symbol.getSession();280const IPDBRawSymbol &raw = symbol.getRawSymbol();281auto tag = symbol.getSymTag();282283// For items that are nested inside of a class, return the class that it is284// nested inside of.285// Note that only certain items can be nested inside of classes.286switch (tag) {287case PDB_SymType::Function:288case PDB_SymType::Data:289case PDB_SymType::UDT:290case PDB_SymType::Enum:291case PDB_SymType::FunctionSig:292case PDB_SymType::Typedef:293case PDB_SymType::BaseClass:294case PDB_SymType::VTable: {295auto class_parent_id = raw.getClassParentId();296if (auto class_parent = session.getSymbolById(class_parent_id))297return class_parent;298break;299}300default:301break;302}303304// Otherwise, if it is nested inside of a function, return the function.305// Note that only certain items can be nested inside of functions.306switch (tag) {307case PDB_SymType::Block:308case PDB_SymType::Data: {309auto lexical_parent_id = raw.getLexicalParentId();310auto lexical_parent = session.getSymbolById(lexical_parent_id);311if (!lexical_parent)312return nullptr;313314auto lexical_parent_tag = lexical_parent->getSymTag();315if (lexical_parent_tag == PDB_SymType::Function)316return lexical_parent;317if (lexical_parent_tag == PDB_SymType::Exe)318return nullptr;319320return GetClassOrFunctionParent(*lexical_parent);321}322default:323return nullptr;324}325}326327static clang::NamedDecl *328GetDeclFromContextByName(const clang::ASTContext &ast,329const clang::DeclContext &decl_context,330llvm::StringRef name) {331clang::IdentifierInfo &ident = ast.Idents.get(name);332clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident);333clang::DeclContext::lookup_result result = decl_context.lookup(decl_name);334if (result.empty())335return nullptr;336337return *result.begin();338}339340static bool IsAnonymousNamespaceName(llvm::StringRef name) {341return name == "`anonymous namespace'" || name == "`anonymous-namespace'";342}343344static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {345switch (pdb_cc) {346case llvm::codeview::CallingConvention::NearC:347return clang::CC_C;348case llvm::codeview::CallingConvention::NearStdCall:349return clang::CC_X86StdCall;350case llvm::codeview::CallingConvention::NearFast:351return clang::CC_X86FastCall;352case llvm::codeview::CallingConvention::ThisCall:353return clang::CC_X86ThisCall;354case llvm::codeview::CallingConvention::NearVector:355return clang::CC_X86VectorCall;356case llvm::codeview::CallingConvention::NearPascal:357return clang::CC_X86Pascal;358default:359assert(false && "Unknown calling convention");360return clang::CC_C;361}362}363364PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {}365366PDBASTParser::~PDBASTParser() = default;367368// DebugInfoASTParser interface369370lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {371Declaration decl;372switch (type.getSymTag()) {373case PDB_SymType::BaseClass: {374auto symbol_file = m_ast.GetSymbolFile();375if (!symbol_file)376return nullptr;377378auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId());379return ty ? ty->shared_from_this() : nullptr;380} break;381case PDB_SymType::UDT: {382auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type);383assert(udt);384385// Note that, unnamed UDT being typedef-ed is generated as a UDT symbol386// other than a Typedef symbol in PDB. For example,387// typedef union { short Row; short Col; } Union;388// is generated as a named UDT in PDB:389// union Union { short Row; short Col; }390// Such symbols will be handled here.391392// Some UDT with trival ctor has zero length. Just ignore.393if (udt->getLength() == 0)394return nullptr;395396// Ignore unnamed-tag UDTs.397std::string name =398std::string(MSVCUndecoratedNameParser::DropScope(udt->getName()));399if (name.empty())400return nullptr;401402auto decl_context = GetDeclContextContainingSymbol(type);403404// Check if such an UDT already exists in the current context.405// This may occur with const or volatile types. There are separate type406// symbols in PDB for types with const or volatile modifiers, but we need407// to create only one declaration for them all.408Type::ResolveState type_resolve_state;409CompilerType clang_type =410m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>(name, decl_context);411if (!clang_type.IsValid()) {412auto access = GetAccessibilityForUdt(*udt);413414auto tag_type_kind = TranslateUdtKind(udt->getUdtKind());415416ClangASTMetadata metadata;417metadata.SetUserID(type.getSymIndexId());418metadata.SetIsDynamicCXXType(false);419420clang_type = m_ast.CreateRecordType(421decl_context, OptionalClangModuleID(), access, name, tag_type_kind,422lldb::eLanguageTypeC_plus_plus, &metadata);423assert(clang_type.IsValid());424425auto record_decl =426m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());427assert(record_decl);428m_uid_to_decl[type.getSymIndexId()] = record_decl;429430auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit(431m_ast.getASTContext(), GetMSInheritance(*udt));432record_decl->addAttr(inheritance_attr);433434TypeSystemClang::StartTagDeclarationDefinition(clang_type);435436auto children = udt->findAllChildren();437if (!children || children->getChildCount() == 0) {438// PDB does not have symbol of forwarder. We assume we get an udt w/o439// any fields. Just complete it at this point.440TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);441442TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),443false);444445type_resolve_state = Type::ResolveState::Full;446} else {447// Add the type to the forward declarations. It will help us to avoid448// an endless recursion in CompleteTypeFromUdt function.449m_forward_decl_to_uid[record_decl] = type.getSymIndexId();450451TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),452true);453454type_resolve_state = Type::ResolveState::Forward;455}456} else457type_resolve_state = Type::ResolveState::Forward;458459if (udt->isConstType())460clang_type = clang_type.AddConstModifier();461462if (udt->isVolatileType())463clang_type = clang_type.AddVolatileModifier();464465AddSourceInfoToDecl(type, decl);466return m_ast.GetSymbolFile()->MakeType(467type.getSymIndexId(), ConstString(name), udt->getLength(), nullptr,468LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type,469type_resolve_state);470} break;471case PDB_SymType::Enum: {472auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type);473assert(enum_type);474475std::string name =476std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName()));477auto decl_context = GetDeclContextContainingSymbol(type);478uint64_t bytes = enum_type->getLength();479480// Check if such an enum already exists in the current context481CompilerType ast_enum =482m_ast.GetTypeForIdentifier<clang::EnumDecl>(name, decl_context);483if (!ast_enum.IsValid()) {484auto underlying_type_up = enum_type->getUnderlyingType();485if (!underlying_type_up)486return nullptr;487488lldb::Encoding encoding =489TranslateBuiltinEncoding(underlying_type_up->getBuiltinType());490// FIXME: Type of underlying builtin is always `Int`. We correct it with491// the very first enumerator's encoding if any.492auto first_child = enum_type->findOneChild<PDBSymbolData>();493if (first_child)494encoding = TranslateEnumEncoding(first_child->getValue().Type);495496CompilerType builtin_type;497if (bytes > 0)498builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize(499m_ast, *underlying_type_up, encoding, bytes * 8);500else501builtin_type = m_ast.GetBasicType(eBasicTypeInt);502503// FIXME: PDB does not have information about scoped enumeration (Enum504// Class). Set it false for now.505bool isScoped = false;506507ast_enum = m_ast.CreateEnumerationType(name, decl_context,508OptionalClangModuleID(), decl,509builtin_type, isScoped);510511auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);512assert(enum_decl);513m_uid_to_decl[type.getSymIndexId()] = enum_decl;514515auto enum_values = enum_type->findAllChildren<PDBSymbolData>();516if (enum_values) {517while (auto enum_value = enum_values->getNext()) {518if (enum_value->getDataKind() != PDB_DataKind::Constant)519continue;520AddEnumValue(ast_enum, *enum_value);521}522}523524if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum))525TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum);526}527528if (enum_type->isConstType())529ast_enum = ast_enum.AddConstModifier();530531if (enum_type->isVolatileType())532ast_enum = ast_enum.AddVolatileModifier();533534AddSourceInfoToDecl(type, decl);535return m_ast.GetSymbolFile()->MakeType(536type.getSymIndexId(), ConstString(name), bytes, nullptr,537LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ast_enum,538lldb_private::Type::ResolveState::Full);539} break;540case PDB_SymType::Typedef: {541auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);542assert(type_def);543544SymbolFile *symbol_file = m_ast.GetSymbolFile();545if (!symbol_file)546return nullptr;547548lldb_private::Type *target_type =549symbol_file->ResolveTypeUID(type_def->getTypeId());550if (!target_type)551return nullptr;552553std::string name =554std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName()));555auto decl_ctx = GetDeclContextContainingSymbol(type);556557// Check if such a typedef already exists in the current context558CompilerType ast_typedef =559m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(name, decl_ctx);560if (!ast_typedef.IsValid()) {561CompilerType target_ast_type = target_type->GetFullCompilerType();562563ast_typedef = target_ast_type.CreateTypedef(564name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);565if (!ast_typedef)566return nullptr;567568auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef);569assert(typedef_decl);570m_uid_to_decl[type.getSymIndexId()] = typedef_decl;571}572573if (type_def->isConstType())574ast_typedef = ast_typedef.AddConstModifier();575576if (type_def->isVolatileType())577ast_typedef = ast_typedef.AddVolatileModifier();578579AddSourceInfoToDecl(type, decl);580std::optional<uint64_t> size;581if (type_def->getLength())582size = type_def->getLength();583return m_ast.GetSymbolFile()->MakeType(584type_def->getSymIndexId(), ConstString(name), size, nullptr,585target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, decl,586ast_typedef, lldb_private::Type::ResolveState::Full);587} break;588case PDB_SymType::Function:589case PDB_SymType::FunctionSig: {590std::string name;591PDBSymbolTypeFunctionSig *func_sig = nullptr;592if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) {593if (pdb_func->isCompilerGenerated())594return nullptr;595596auto sig = pdb_func->getSignature();597if (!sig)598return nullptr;599func_sig = sig.release();600// Function type is named.601name = std::string(602MSVCUndecoratedNameParser::DropScope(pdb_func->getName()));603} else if (auto pdb_func_sig =604llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {605func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig);606} else607llvm_unreachable("Unexpected PDB symbol!");608609auto arg_enum = func_sig->getArguments();610uint32_t num_args = arg_enum->getChildCount();611std::vector<CompilerType> arg_list;612613bool is_variadic = func_sig->isCVarArgs();614// Drop last variadic argument.615if (is_variadic)616--num_args;617for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) {618auto arg = arg_enum->getChildAtIndex(arg_idx);619if (!arg)620break;621622SymbolFile *symbol_file = m_ast.GetSymbolFile();623if (!symbol_file)624return nullptr;625626lldb_private::Type *arg_type =627symbol_file->ResolveTypeUID(arg->getSymIndexId());628// If there's some error looking up one of the dependent types of this629// function signature, bail.630if (!arg_type)631return nullptr;632CompilerType arg_ast_type = arg_type->GetFullCompilerType();633arg_list.push_back(arg_ast_type);634}635lldbassert(arg_list.size() <= num_args);636637auto pdb_return_type = func_sig->getReturnType();638SymbolFile *symbol_file = m_ast.GetSymbolFile();639if (!symbol_file)640return nullptr;641642lldb_private::Type *return_type =643symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId());644// If there's some error looking up one of the dependent types of this645// function signature, bail.646if (!return_type)647return nullptr;648CompilerType return_ast_type = return_type->GetFullCompilerType();649uint32_t type_quals = 0;650if (func_sig->isConstType())651type_quals |= clang::Qualifiers::Const;652if (func_sig->isVolatileType())653type_quals |= clang::Qualifiers::Volatile;654auto cc = TranslateCallingConvention(func_sig->getCallingConvention());655CompilerType func_sig_ast_type =656m_ast.CreateFunctionType(return_ast_type, arg_list.data(),657arg_list.size(), is_variadic, type_quals, cc);658659AddSourceInfoToDecl(type, decl);660return m_ast.GetSymbolFile()->MakeType(661type.getSymIndexId(), ConstString(name), std::nullopt, nullptr,662LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,663func_sig_ast_type, lldb_private::Type::ResolveState::Full);664} break;665case PDB_SymType::ArrayType: {666auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);667assert(array_type);668uint32_t num_elements = array_type->getCount();669uint32_t element_uid = array_type->getElementTypeId();670std::optional<uint64_t> bytes;671if (uint64_t size = array_type->getLength())672bytes = size;673674SymbolFile *symbol_file = m_ast.GetSymbolFile();675if (!symbol_file)676return nullptr;677678// If array rank > 0, PDB gives the element type at N=0. So element type679// will parsed in the order N=0, N=1,..., N=rank sequentially.680lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid);681if (!element_type)682return nullptr;683684CompilerType element_ast_type = element_type->GetForwardCompilerType();685// If element type is UDT, it needs to be complete.686if (TypeSystemClang::IsCXXClassType(element_ast_type) &&687!element_ast_type.GetCompleteType()) {688if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) {689TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type);690} else {691// We are not able to start definition.692return nullptr;693}694}695CompilerType array_ast_type = m_ast.CreateArrayType(696element_ast_type, num_elements, /*is_gnu_vector*/ false);697TypeSP type_sp = m_ast.GetSymbolFile()->MakeType(698array_type->getSymIndexId(), ConstString(), bytes, nullptr,699LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,700array_ast_type, lldb_private::Type::ResolveState::Full);701type_sp->SetEncodingType(element_type);702return type_sp;703} break;704case PDB_SymType::BuiltinType: {705auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type);706assert(builtin_type);707PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType();708if (builtin_kind == PDB_BuiltinType::None)709return nullptr;710711std::optional<uint64_t> bytes;712if (uint64_t size = builtin_type->getLength())713bytes = size;714Encoding encoding = TranslateBuiltinEncoding(builtin_kind);715CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize(716m_ast, *builtin_type, encoding, bytes.value_or(0) * 8);717718if (builtin_type->isConstType())719builtin_ast_type = builtin_ast_type.AddConstModifier();720721if (builtin_type->isVolatileType())722builtin_ast_type = builtin_ast_type.AddVolatileModifier();723724auto type_name = GetPDBBuiltinTypeName(*builtin_type, builtin_ast_type);725726return m_ast.GetSymbolFile()->MakeType(727builtin_type->getSymIndexId(), type_name, bytes, nullptr,728LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,729builtin_ast_type, lldb_private::Type::ResolveState::Full);730} break;731case PDB_SymType::PointerType: {732auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);733assert(pointer_type);734735SymbolFile *symbol_file = m_ast.GetSymbolFile();736if (!symbol_file)737return nullptr;738739Type *pointee_type = symbol_file->ResolveTypeUID(740pointer_type->getPointeeType()->getSymIndexId());741if (!pointee_type)742return nullptr;743744if (pointer_type->isPointerToDataMember() ||745pointer_type->isPointerToMemberFunction()) {746auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId();747auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid);748assert(class_parent_type);749750CompilerType pointer_ast_type;751pointer_ast_type = TypeSystemClang::CreateMemberPointerType(752class_parent_type->GetLayoutCompilerType(),753pointee_type->GetForwardCompilerType());754assert(pointer_ast_type);755756return m_ast.GetSymbolFile()->MakeType(757pointer_type->getSymIndexId(), ConstString(),758pointer_type->getLength(), nullptr, LLDB_INVALID_UID,759lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,760lldb_private::Type::ResolveState::Forward);761}762763CompilerType pointer_ast_type;764pointer_ast_type = pointee_type->GetFullCompilerType();765if (pointer_type->isReference())766pointer_ast_type = pointer_ast_type.GetLValueReferenceType();767else if (pointer_type->isRValueReference())768pointer_ast_type = pointer_ast_type.GetRValueReferenceType();769else770pointer_ast_type = pointer_ast_type.GetPointerType();771772if (pointer_type->isConstType())773pointer_ast_type = pointer_ast_type.AddConstModifier();774775if (pointer_type->isVolatileType())776pointer_ast_type = pointer_ast_type.AddVolatileModifier();777778if (pointer_type->isRestrictedType())779pointer_ast_type = pointer_ast_type.AddRestrictModifier();780781return m_ast.GetSymbolFile()->MakeType(782pointer_type->getSymIndexId(), ConstString(), pointer_type->getLength(),783nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,784pointer_ast_type, lldb_private::Type::ResolveState::Full);785} break;786default:787break;788}789return nullptr;790}791792bool PDBASTParser::CompleteTypeFromPDB(793lldb_private::CompilerType &compiler_type) {794if (GetClangASTImporter().CanImport(compiler_type))795return GetClangASTImporter().CompleteType(compiler_type);796797// Remove the type from the forward declarations to avoid798// an endless recursion for types like a linked list.799clang::CXXRecordDecl *record_decl =800m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());801auto uid_it = m_forward_decl_to_uid.find(record_decl);802if (uid_it == m_forward_decl_to_uid.end())803return true;804805auto symbol_file = static_cast<SymbolFilePDB *>(806m_ast.GetSymbolFile()->GetBackingSymbolFile());807if (!symbol_file)808return false;809810std::unique_ptr<PDBSymbol> symbol =811symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond());812if (!symbol)813return false;814815m_forward_decl_to_uid.erase(uid_it);816817TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),818false);819820switch (symbol->getSymTag()) {821case PDB_SymType::UDT: {822auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(symbol.get());823if (!udt)824return false;825826return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt);827}828default:829llvm_unreachable("not a forward clang type decl!");830}831}832833clang::Decl *834PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {835uint32_t sym_id = symbol.getSymIndexId();836auto it = m_uid_to_decl.find(sym_id);837if (it != m_uid_to_decl.end())838return it->second;839840auto symbol_file = static_cast<SymbolFilePDB *>(841m_ast.GetSymbolFile()->GetBackingSymbolFile());842if (!symbol_file)843return nullptr;844845// First of all, check if the symbol is a member of a class. Resolve the full846// class type and return the declaration from the cache if so.847auto tag = symbol.getSymTag();848if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) {849const IPDBSession &session = symbol.getSession();850const IPDBRawSymbol &raw = symbol.getRawSymbol();851852auto class_parent_id = raw.getClassParentId();853if (std::unique_ptr<PDBSymbol> class_parent =854session.getSymbolById(class_parent_id)) {855auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id);856if (!class_parent_type)857return nullptr;858859CompilerType class_parent_ct = class_parent_type->GetFullCompilerType();860861// Look a declaration up in the cache after completing the class862clang::Decl *decl = m_uid_to_decl.lookup(sym_id);863if (decl)864return decl;865866// A declaration was not found in the cache. It means that the symbol867// has the class parent, but the class doesn't have the symbol in its868// children list.869if (auto func = llvm::dyn_cast_or_null<PDBSymbolFunc>(&symbol)) {870// Try to find a class child method with the same RVA and use its871// declaration if found.872if (uint32_t rva = func->getRelativeVirtualAddress()) {873if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolFunc>>874methods_enum =875class_parent->findAllChildren<PDBSymbolFunc>()) {876while (std::unique_ptr<PDBSymbolFunc> method =877methods_enum->getNext()) {878if (method->getRelativeVirtualAddress() == rva) {879decl = m_uid_to_decl.lookup(method->getSymIndexId());880if (decl)881break;882}883}884}885}886887// If no class methods with the same RVA were found, then create a new888// method. It is possible for template methods.889if (!decl)890decl = AddRecordMethod(*symbol_file, class_parent_ct, *func);891}892893if (decl)894m_uid_to_decl[sym_id] = decl;895896return decl;897}898}899900// If we are here, then the symbol is not belonging to a class and is not901// contained in the cache. So create a declaration for it.902switch (symbol.getSymTag()) {903case PDB_SymType::Data: {904auto data = llvm::dyn_cast<PDBSymbolData>(&symbol);905assert(data);906907auto decl_context = GetDeclContextContainingSymbol(symbol);908assert(decl_context);909910// May be the current context is a class really, but we haven't found911// any class parent. This happens e.g. in the case of class static912// variables - they has two symbols, one is a child of the class when913// another is a child of the exe. So always complete the parent and use914// an existing declaration if possible.915if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context))916m_ast.GetCompleteDecl(parent_decl);917918std::string name =919std::string(MSVCUndecoratedNameParser::DropScope(data->getName()));920921// Check if the current context already contains the symbol with the name.922clang::Decl *decl =923GetDeclFromContextByName(m_ast.getASTContext(), *decl_context, name);924if (!decl) {925auto type = symbol_file->ResolveTypeUID(data->getTypeId());926if (!type)927return nullptr;928929decl = m_ast.CreateVariableDeclaration(930decl_context, OptionalClangModuleID(), name.c_str(),931ClangUtil::GetQualType(type->GetLayoutCompilerType()));932}933934m_uid_to_decl[sym_id] = decl;935936return decl;937}938case PDB_SymType::Function: {939auto func = llvm::dyn_cast<PDBSymbolFunc>(&symbol);940assert(func);941942auto decl_context = GetDeclContextContainingSymbol(symbol);943assert(decl_context);944945std::string name =946std::string(MSVCUndecoratedNameParser::DropScope(func->getName()));947948Type *type = symbol_file->ResolveTypeUID(sym_id);949if (!type)950return nullptr;951952auto storage = func->isStatic() ? clang::StorageClass::SC_Static953: clang::StorageClass::SC_None;954955auto decl = m_ast.CreateFunctionDeclaration(956decl_context, OptionalClangModuleID(), name,957type->GetForwardCompilerType(), storage, func->hasInlineAttribute());958959std::vector<clang::ParmVarDecl *> params;960if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {961if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>>962arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) {963while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg =964arg_enum->getNext()) {965Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId());966if (!arg_type)967continue;968969clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(970decl, OptionalClangModuleID(), nullptr,971arg_type->GetForwardCompilerType(), clang::SC_None, true);972if (param)973params.push_back(param);974}975}976}977if (params.size())978m_ast.SetFunctionParameters(decl, params);979980m_uid_to_decl[sym_id] = decl;981982return decl;983}984default: {985// It's not a variable and not a function, check if it's a type986Type *type = symbol_file->ResolveTypeUID(sym_id);987if (!type)988return nullptr;989990return m_uid_to_decl.lookup(sym_id);991}992}993}994995clang::DeclContext *996PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) {997if (symbol.getSymTag() == PDB_SymType::Function) {998clang::DeclContext *result =999llvm::dyn_cast_or_null<clang::FunctionDecl>(GetDeclForSymbol(symbol));10001001if (result)1002m_decl_context_to_uid[result] = symbol.getSymIndexId();10031004return result;1005}10061007auto symbol_file = static_cast<SymbolFilePDB *>(1008m_ast.GetSymbolFile()->GetBackingSymbolFile());1009if (!symbol_file)1010return nullptr;10111012auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId());1013if (!type)1014return nullptr;10151016clang::DeclContext *result =1017m_ast.GetDeclContextForType(type->GetForwardCompilerType());10181019if (result)1020m_decl_context_to_uid[result] = symbol.getSymIndexId();10211022return result;1023}10241025clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(1026const llvm::pdb::PDBSymbol &symbol) {1027auto parent = GetClassOrFunctionParent(symbol);1028while (parent) {1029if (auto parent_context = GetDeclContextForSymbol(*parent))1030return parent_context;10311032parent = GetClassOrFunctionParent(*parent);1033}10341035// We can't find any class or function parent of the symbol. So analyze1036// the full symbol name. The symbol may be belonging to a namespace1037// or function (or even to a class if it's e.g. a static variable symbol).10381039// TODO: Make clang to emit full names for variables in namespaces1040// (as MSVC does)10411042std::string name(symbol.getRawSymbol().getName());1043MSVCUndecoratedNameParser parser(name);1044llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();1045if (specs.empty())1046return m_ast.GetTranslationUnitDecl();10471048auto symbol_file = static_cast<SymbolFilePDB *>(1049m_ast.GetSymbolFile()->GetBackingSymbolFile());1050if (!symbol_file)1051return m_ast.GetTranslationUnitDecl();10521053auto global = symbol_file->GetPDBSession().getGlobalScope();1054if (!global)1055return m_ast.GetTranslationUnitDecl();10561057bool has_type_or_function_parent = false;1058clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl();1059for (std::size_t i = 0; i < specs.size() - 1; i++) {1060// Check if there is a function or a type with the current context's name.1061if (std::unique_ptr<IPDBEnumSymbols> children_enum = global->findChildren(1062PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) {1063while (IPDBEnumChildren<PDBSymbol>::ChildTypePtr child =1064children_enum->getNext()) {1065if (clang::DeclContext *child_context =1066GetDeclContextForSymbol(*child)) {1067// Note that `GetDeclContextForSymbol' retrieves1068// a declaration context for functions and types only,1069// so if we are here then `child_context' is guaranteed1070// a function or a type declaration context.1071has_type_or_function_parent = true;1072curr_context = child_context;1073}1074}1075}10761077// If there were no functions or types above then retrieve a namespace with1078// the current context's name. There can be no namespaces inside a function1079// or a type. We check it to avoid fake namespaces such as `__l2':1080// `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct'1081if (!has_type_or_function_parent) {1082std::string namespace_name = std::string(specs[i].GetBaseName());1083const char *namespace_name_c_str =1084IsAnonymousNamespaceName(namespace_name) ? nullptr1085: namespace_name.data();1086clang::NamespaceDecl *namespace_decl =1087m_ast.GetUniqueNamespaceDeclaration(1088namespace_name_c_str, curr_context, OptionalClangModuleID());10891090m_parent_to_namespaces[curr_context].insert(namespace_decl);1091m_namespaces.insert(namespace_decl);10921093curr_context = namespace_decl;1094}1095}10961097return curr_context;1098}10991100void PDBASTParser::ParseDeclsForDeclContext(1101const clang::DeclContext *decl_context) {1102auto symbol_file = static_cast<SymbolFilePDB *>(1103m_ast.GetSymbolFile()->GetBackingSymbolFile());1104if (!symbol_file)1105return;11061107IPDBSession &session = symbol_file->GetPDBSession();1108auto symbol_up =1109session.getSymbolById(m_decl_context_to_uid.lookup(decl_context));1110auto global_up = session.getGlobalScope();11111112PDBSymbol *symbol;1113if (symbol_up)1114symbol = symbol_up.get();1115else if (global_up)1116symbol = global_up.get();1117else1118return;11191120if (auto children = symbol->findAllChildren())1121while (auto child = children->getNext())1122GetDeclForSymbol(*child);1123}11241125clang::NamespaceDecl *1126PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent,1127llvm::StringRef name) {1128NamespacesSet *set;1129if (parent) {1130auto pit = m_parent_to_namespaces.find(parent);1131if (pit == m_parent_to_namespaces.end())1132return nullptr;11331134set = &pit->second;1135} else {1136set = &m_namespaces;1137}1138assert(set);11391140for (clang::NamespaceDecl *namespace_decl : *set)1141if (namespace_decl->getName() == name)1142return namespace_decl;11431144for (clang::NamespaceDecl *namespace_decl : *set)1145if (namespace_decl->isAnonymousNamespace())1146return FindNamespaceDecl(namespace_decl, name);11471148return nullptr;1149}11501151bool PDBASTParser::AddEnumValue(CompilerType enum_type,1152const PDBSymbolData &enum_value) {1153Declaration decl;1154Variant v = enum_value.getValue();1155std::string name =1156std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName()));1157int64_t raw_value;1158switch (v.Type) {1159case PDB_VariantType::Int8:1160raw_value = v.Value.Int8;1161break;1162case PDB_VariantType::Int16:1163raw_value = v.Value.Int16;1164break;1165case PDB_VariantType::Int32:1166raw_value = v.Value.Int32;1167break;1168case PDB_VariantType::Int64:1169raw_value = v.Value.Int64;1170break;1171case PDB_VariantType::UInt8:1172raw_value = v.Value.UInt8;1173break;1174case PDB_VariantType::UInt16:1175raw_value = v.Value.UInt16;1176break;1177case PDB_VariantType::UInt32:1178raw_value = v.Value.UInt32;1179break;1180case PDB_VariantType::UInt64:1181raw_value = v.Value.UInt64;1182break;1183default:1184return false;1185}1186CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type);1187uint32_t byte_size = m_ast.getASTContext().getTypeSize(1188ClangUtil::GetQualType(underlying_type));1189auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType(1190enum_type, decl, name.c_str(), raw_value, byte_size * 8);1191if (!enum_constant_decl)1192return false;11931194m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl;11951196return true;1197}11981199bool PDBASTParser::CompleteTypeFromUDT(1200lldb_private::SymbolFile &symbol_file,1201lldb_private::CompilerType &compiler_type,1202llvm::pdb::PDBSymbolTypeUDT &udt) {1203ClangASTImporter::LayoutInfo layout_info;1204layout_info.bit_size = udt.getLength() * 8;12051206auto nested_enums = udt.findAllChildren<PDBSymbolTypeUDT>();1207if (nested_enums)1208while (auto nested = nested_enums->getNext())1209symbol_file.ResolveTypeUID(nested->getSymIndexId());12101211auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();1212if (bases_enum)1213AddRecordBases(symbol_file, compiler_type,1214TranslateUdtKind(udt.getUdtKind()), *bases_enum,1215layout_info);12161217auto members_enum = udt.findAllChildren<PDBSymbolData>();1218if (members_enum)1219AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info);12201221auto methods_enum = udt.findAllChildren<PDBSymbolFunc>();1222if (methods_enum)1223AddRecordMethods(symbol_file, compiler_type, *methods_enum);12241225m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType());1226TypeSystemClang::BuildIndirectFields(compiler_type);1227TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);12281229clang::CXXRecordDecl *record_decl =1230m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());1231if (!record_decl)1232return static_cast<bool>(compiler_type);12331234GetClangASTImporter().SetRecordLayout(record_decl, layout_info);12351236return static_cast<bool>(compiler_type);1237}12381239void PDBASTParser::AddRecordMembers(1240lldb_private::SymbolFile &symbol_file,1241lldb_private::CompilerType &record_type,1242PDBDataSymbolEnumerator &members_enum,1243lldb_private::ClangASTImporter::LayoutInfo &layout_info) {1244while (auto member = members_enum.getNext()) {1245if (member->isCompilerGenerated())1246continue;12471248auto member_name = member->getName();12491250auto member_type = symbol_file.ResolveTypeUID(member->getTypeId());1251if (!member_type)1252continue;12531254auto member_comp_type = member_type->GetLayoutCompilerType();1255if (!member_comp_type.GetCompleteType()) {1256symbol_file.GetObjectFile()->GetModule()->ReportError(1257":: Class '{0}' has a member '{1}' of type '{2}' "1258"which does not have a complete definition.",1259record_type.GetTypeName().GetCString(), member_name.c_str(),1260member_comp_type.GetTypeName().GetCString());1261if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type))1262TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type);1263}12641265auto access = TranslateMemberAccess(member->getAccess());12661267switch (member->getDataKind()) {1268case PDB_DataKind::Member: {1269auto location_type = member->getLocationType();12701271auto bit_size = member->getLength();1272if (location_type == PDB_LocType::ThisRel)1273bit_size *= 8;12741275auto decl = TypeSystemClang::AddFieldToRecordType(1276record_type, member_name.c_str(), member_comp_type, access, bit_size);1277if (!decl)1278continue;12791280m_uid_to_decl[member->getSymIndexId()] = decl;12811282auto offset = member->getOffset() * 8;1283if (location_type == PDB_LocType::BitField)1284offset += member->getBitPosition();12851286layout_info.field_offsets.insert(std::make_pair(decl, offset));12871288break;1289}1290case PDB_DataKind::StaticMember: {1291auto decl = TypeSystemClang::AddVariableToRecordType(1292record_type, member_name.c_str(), member_comp_type, access);1293if (!decl)1294continue;12951296// Static constant members may be a const[expr] declaration.1297// Query the symbol's value as the variable initializer if valid.1298if (member_comp_type.IsConst()) {1299auto value = member->getValue();1300if (value.Type == llvm::pdb::Empty) {1301LLDB_LOG(GetLog(LLDBLog::AST),1302"Class '{0}' has member '{1}' of type '{2}' with an unknown "1303"constant size.",1304record_type.GetTypeName(), member_name,1305member_comp_type.GetTypeName());1306continue;1307}13081309clang::QualType qual_type = decl->getType();1310unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type);1311unsigned constant_width = value.getBitWidth();13121313if (qual_type->isIntegralOrEnumerationType()) {1314if (type_width >= constant_width) {1315TypeSystemClang::SetIntegerInitializerForVariable(1316decl, value.toAPSInt().extOrTrunc(type_width));1317} else {1318LLDB_LOG(GetLog(LLDBLog::AST),1319"Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "1320"which resolves to a wider constant value ({4} bits). "1321"Ignoring constant.",1322record_type.GetTypeName(), member_name,1323member_comp_type.GetTypeName(), type_width,1324constant_width);1325}1326} else {1327switch (member_comp_type.GetBasicTypeEnumeration()) {1328case lldb::eBasicTypeFloat:1329case lldb::eBasicTypeDouble:1330case lldb::eBasicTypeLongDouble:1331if (type_width == constant_width) {1332TypeSystemClang::SetFloatingInitializerForVariable(1333decl, value.toAPFloat());1334decl->setConstexpr(true);1335} else {1336LLDB_LOG(GetLog(LLDBLog::AST),1337"Class '{0}' has a member '{1}' of type '{2}' ({3} "1338"bits) which resolves to a constant value of mismatched "1339"width ({4} bits). Ignoring constant.",1340record_type.GetTypeName(), member_name,1341member_comp_type.GetTypeName(), type_width,1342constant_width);1343}1344break;1345default:1346break;1347}1348}1349}13501351m_uid_to_decl[member->getSymIndexId()] = decl;13521353break;1354}1355default:1356llvm_unreachable("unsupported PDB data kind");1357}1358}1359}13601361void PDBASTParser::AddRecordBases(1362lldb_private::SymbolFile &symbol_file,1363lldb_private::CompilerType &record_type, int record_kind,1364PDBBaseClassSymbolEnumerator &bases_enum,1365lldb_private::ClangASTImporter::LayoutInfo &layout_info) const {1366std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> base_classes;13671368while (auto base = bases_enum.getNext()) {1369auto base_type = symbol_file.ResolveTypeUID(base->getTypeId());1370if (!base_type)1371continue;13721373auto base_comp_type = base_type->GetFullCompilerType();1374if (!base_comp_type.GetCompleteType()) {1375symbol_file.GetObjectFile()->GetModule()->ReportError(1376":: Class '{0}' has a base class '{1}' "1377"which does not have a complete definition.",1378record_type.GetTypeName().GetCString(),1379base_comp_type.GetTypeName().GetCString());1380if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type))1381TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type);1382}13831384auto access = TranslateMemberAccess(base->getAccess());13851386auto is_virtual = base->isVirtualBaseClass();13871388std::unique_ptr<clang::CXXBaseSpecifier> base_spec =1389m_ast.CreateBaseClassSpecifier(1390base_comp_type.GetOpaqueQualType(), access, is_virtual,1391record_kind == llvm::to_underlying(clang::TagTypeKind::Class));1392lldbassert(base_spec);13931394base_classes.push_back(std::move(base_spec));13951396if (is_virtual)1397continue;13981399auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType());1400if (!decl)1401continue;14021403auto offset = clang::CharUnits::fromQuantity(base->getOffset());1404layout_info.base_offsets.insert(std::make_pair(decl, offset));1405}14061407m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(),1408std::move(base_classes));1409}14101411void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file,1412lldb_private::CompilerType &record_type,1413PDBFuncSymbolEnumerator &methods_enum) {1414while (std::unique_ptr<PDBSymbolFunc> method = methods_enum.getNext())1415if (clang::CXXMethodDecl *decl =1416AddRecordMethod(symbol_file, record_type, *method))1417m_uid_to_decl[method->getSymIndexId()] = decl;1418}14191420clang::CXXMethodDecl *1421PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,1422lldb_private::CompilerType &record_type,1423const llvm::pdb::PDBSymbolFunc &method) const {1424std::string name =1425std::string(MSVCUndecoratedNameParser::DropScope(method.getName()));14261427Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId());1428// MSVC specific __vecDelDtor.1429if (!method_type)1430return nullptr;14311432CompilerType method_comp_type = method_type->GetFullCompilerType();1433if (!method_comp_type.GetCompleteType()) {1434symbol_file.GetObjectFile()->GetModule()->ReportError(1435":: Class '{0}' has a method '{1}' whose type cannot be completed.",1436record_type.GetTypeName().GetCString(),1437method_comp_type.GetTypeName().GetCString());1438if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type))1439TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type);1440}14411442AccessType access = TranslateMemberAccess(method.getAccess());1443if (access == eAccessNone)1444access = eAccessPublic;14451446// TODO: get mangled name for the method.1447return m_ast.AddMethodToCXXRecordType(1448record_type.GetOpaqueQualType(), name.c_str(),1449/*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(),1450method.isStatic(), method.hasInlineAttribute(),1451/*is_explicit*/ false, // FIXME: Need this field in CodeView.1452/*is_attr_used*/ false,1453/*is_artificial*/ method.isCompilerGenerated());1454}145514561457