1493 lines · cpp
1#include "PdbAstBuilder.h"2 3#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"4#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"5#include "llvm/DebugInfo/CodeView/RecordName.h"6#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"7#include "llvm/DebugInfo/CodeView/SymbolRecord.h"8#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"9#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"10#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"11#include "llvm/DebugInfo/PDB/Native/DbiStream.h"12#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"13#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"14#include "llvm/DebugInfo/PDB/Native/TpiStream.h"15#include "llvm/Demangle/MicrosoftDemangle.h"16 17#include "PdbUtil.h"18#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"19#include "Plugins/ExpressionParser/Clang/ClangUtil.h"20#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"21#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"22#include "SymbolFileNativePDB.h"23#include "UdtRecordCompleter.h"24#include "lldb/Core/Module.h"25#include "lldb/Symbol/ObjectFile.h"26#include "lldb/Utility/LLDBAssert.h"27#include <optional>28#include <string_view>29 30using namespace lldb_private;31using namespace lldb_private::npdb;32using namespace llvm::codeview;33using namespace llvm::pdb;34 35namespace {36struct CreateMethodDecl : public TypeVisitorCallbacks {37 CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang,38 TypeIndex func_type_index,39 clang::FunctionDecl *&function_decl,40 lldb::opaque_compiler_type_t parent_ty,41 llvm::StringRef proc_name, ConstString mangled_name,42 CompilerType func_ct)43 : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),44 function_decl(function_decl), parent_ty(parent_ty),45 proc_name(proc_name), mangled_name(mangled_name), func_ct(func_ct) {}46 PdbIndex &m_index;47 TypeSystemClang &m_clang;48 TypeIndex func_type_index;49 clang::FunctionDecl *&function_decl;50 lldb::opaque_compiler_type_t parent_ty;51 llvm::StringRef proc_name;52 ConstString mangled_name;53 CompilerType func_ct;54 55 llvm::Error visitKnownMember(CVMemberRecord &cvr,56 OverloadedMethodRecord &overloaded) override {57 TypeIndex method_list_idx = overloaded.MethodList;58 59 CVType method_list_type = m_index.tpi().getType(method_list_idx);60 assert(method_list_type.kind() == LF_METHODLIST);61 62 MethodOverloadListRecord method_list;63 llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(64 method_list_type, method_list));65 66 for (const OneMethodRecord &method : method_list.Methods) {67 if (method.getType().getIndex() == func_type_index.getIndex())68 AddMethod(overloaded.Name, method.getAccess(), method.getOptions(),69 method.Attrs);70 }71 72 return llvm::Error::success();73 }74 75 llvm::Error visitKnownMember(CVMemberRecord &cvr,76 OneMethodRecord &record) override {77 AddMethod(record.getName(), record.getAccess(), record.getOptions(),78 record.Attrs);79 return llvm::Error::success();80 }81 82 void AddMethod(llvm::StringRef name, MemberAccess access,83 MethodOptions options, MemberAttributes attrs) {84 if (name != proc_name || function_decl)85 return;86 lldb::AccessType access_type = TranslateMemberAccess(access);87 bool is_virtual = attrs.isVirtual();88 bool is_static = attrs.isStatic();89 bool is_artificial = (options & MethodOptions::CompilerGenerated) ==90 MethodOptions::CompilerGenerated;91 function_decl = m_clang.AddMethodToCXXRecordType(92 parent_ty, proc_name, mangled_name, func_ct, /*access=*/access_type,93 /*is_virtual=*/is_virtual, /*is_static=*/is_static,94 /*is_inline=*/false, /*is_explicit=*/false,95 /*is_attr_used=*/false, /*is_artificial=*/is_artificial);96 }97};98} // namespace99 100static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {101 switch (cr.Kind) {102 case TypeRecordKind::Class:103 return clang::TagTypeKind::Class;104 case TypeRecordKind::Struct:105 return clang::TagTypeKind::Struct;106 case TypeRecordKind::Union:107 return clang::TagTypeKind::Union;108 case TypeRecordKind::Interface:109 return clang::TagTypeKind::Interface;110 case TypeRecordKind::Enum:111 return clang::TagTypeKind::Enum;112 default:113 lldbassert(false && "Invalid tag record kind!");114 return clang::TagTypeKind::Struct;115 }116}117 118static bool IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args) {119 if (args.empty())120 return false;121 return args.back() == TypeIndex::None();122}123 124static bool125AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {126 for (llvm::ms_demangle::Node *n : scopes) {127 auto *idn = static_cast<llvm::ms_demangle::IdentifierNode *>(n);128 if (idn->TemplateParams)129 return true;130 }131 return false;132}133 134static std::optional<clang::CallingConv>135TranslateCallingConvention(llvm::codeview::CallingConvention conv) {136 using CC = llvm::codeview::CallingConvention;137 switch (conv) {138 139 case CC::NearC:140 case CC::FarC:141 return clang::CallingConv::CC_C;142 case CC::NearPascal:143 case CC::FarPascal:144 return clang::CallingConv::CC_X86Pascal;145 case CC::NearFast:146 case CC::FarFast:147 return clang::CallingConv::CC_X86FastCall;148 case CC::NearStdCall:149 case CC::FarStdCall:150 return clang::CallingConv::CC_X86StdCall;151 case CC::ThisCall:152 return clang::CallingConv::CC_X86ThisCall;153 case CC::NearVector:154 return clang::CallingConv::CC_X86VectorCall;155 default:156 return std::nullopt;157 }158}159 160static bool IsAnonymousNamespaceName(llvm::StringRef name) {161 return name == "`anonymous namespace'" || name == "`anonymous-namespace'";162}163 164PdbAstBuilder::PdbAstBuilder(TypeSystemClang &clang) : m_clang(clang) {}165 166lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() {167 return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl());168}169 170std::pair<clang::DeclContext *, std::string>171PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {172 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(173 m_clang.GetSymbolFile()->GetBackingSymbolFile());174 // FIXME: Move this to GetDeclContextContainingUID.175 if (!record.hasUniqueName())176 return CreateDeclInfoForUndecoratedName(record.Name);177 178 llvm::ms_demangle::Demangler demangler;179 std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());180 llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);181 if (demangler.Error)182 return CreateDeclInfoForUndecoratedName(record.Name);183 184 llvm::ms_demangle::IdentifierNode *idn =185 ttn->QualifiedName->getUnqualifiedIdentifier();186 std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier);187 188 llvm::ms_demangle::NodeArrayNode *name_components =189 ttn->QualifiedName->Components;190 llvm::ArrayRef<llvm::ms_demangle::Node *> scopes(name_components->Nodes,191 name_components->Count - 1);192 193 clang::DeclContext *context = m_clang.GetTranslationUnitDecl();194 195 // If this type doesn't have a parent type in the debug info, then the best we196 // can do is to say that it's either a series of namespaces (if the scope is197 // non-empty), or the translation unit (if the scope is empty).198 std::optional<TypeIndex> parent_index = pdb->GetParentType(ti);199 if (!parent_index) {200 if (scopes.empty())201 return {context, uname};202 203 // If there is no parent in the debug info, but some of the scopes have204 // template params, then this is a case of bad debug info. See, for205 // example, llvm.org/pr39607. We don't want to create an ambiguity between206 // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at207 // global scope with the fully qualified name.208 if (AnyScopesHaveTemplateParams(scopes))209 return {context, std::string(record.Name)};210 211 for (llvm::ms_demangle::Node *scope : scopes) {212 auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);213 std::string str = nii->toString();214 context = GetOrCreateNamespaceDecl(str.c_str(), *context);215 }216 return {context, uname};217 }218 219 // Otherwise, all we need to do is get the parent type of this type and220 // recurse into our lazy type creation / AST reconstruction logic to get an221 // LLDB TypeSP for the parent. This will cause the AST to automatically get222 // the right DeclContext created for any parent.223 clang::QualType parent_qt = GetOrCreateType(*parent_index);224 if (parent_qt.isNull())225 return {nullptr, ""};226 227 context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl());228 return {context, uname};229}230 231static bool isLocalVariableType(SymbolKind K) {232 switch (K) {233 case S_REGISTER:234 case S_REGREL32:235 case S_LOCAL:236 return true;237 default:238 break;239 }240 return false;241}242 243clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {244 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(245 m_clang.GetSymbolFile()->GetBackingSymbolFile());246 PdbIndex &index = pdb->GetIndex();247 CVSymbol cvs = index.ReadSymbolRecord(id);248 249 if (isLocalVariableType(cvs.kind())) {250 clang::DeclContext *scope = GetParentDeclContext(id);251 if (!scope)252 return nullptr;253 clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope);254 PdbCompilandSymId scope_id =255 PdbSymUid(m_decl_to_status[scope_decl].uid).asCompilandSym();256 return GetOrCreateVariableDecl(scope_id, id);257 }258 259 switch (cvs.kind()) {260 case S_GPROC32:261 case S_LPROC32:262 return GetOrCreateFunctionDecl(id);263 case S_GDATA32:264 case S_LDATA32:265 case S_GTHREAD32:266 case S_CONSTANT:267 // global variable268 return nullptr;269 case S_BLOCK32:270 return GetOrCreateBlockDecl(id);271 case S_INLINESITE:272 return GetOrCreateInlinedFunctionDecl(id);273 default:274 return nullptr;275 }276}277 278std::optional<CompilerDecl>279PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {280 if (clang::Decl *result = TryGetDecl(uid))281 return ToCompilerDecl(*result);282 283 clang::Decl *result = nullptr;284 switch (uid.kind()) {285 case PdbSymUidKind::CompilandSym:286 result = GetOrCreateSymbolForId(uid.asCompilandSym());287 break;288 case PdbSymUidKind::Type: {289 clang::QualType qt = GetOrCreateType(uid.asTypeSym());290 if (qt.isNull())291 return std::nullopt;292 if (auto *tag = qt->getAsTagDecl()) {293 result = tag;294 break;295 }296 return std::nullopt;297 }298 default:299 return std::nullopt;300 }301 302 if (!result)303 return std::nullopt;304 m_uid_to_decl[toOpaqueUid(uid)] = result;305 return ToCompilerDecl(*result);306}307 308clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {309 if (uid.kind() == PdbSymUidKind::CompilandSym) {310 if (uid.asCompilandSym().offset == 0)311 return FromCompilerDeclContext(GetTranslationUnitDecl());312 }313 auto option = GetOrCreateDeclForUid(uid);314 if (!option)315 return nullptr;316 clang::Decl *decl = FromCompilerDecl(*option);317 if (!decl)318 return nullptr;319 320 return clang::Decl::castToDeclContext(decl);321}322 323std::pair<clang::DeclContext *, std::string>324PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {325 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(326 m_clang.GetSymbolFile()->GetBackingSymbolFile());327 PdbIndex &index = pdb->GetIndex();328 MSVCUndecoratedNameParser parser(name);329 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();330 331 auto *context = FromCompilerDeclContext(GetTranslationUnitDecl());332 333 llvm::StringRef uname = specs.back().GetBaseName();334 specs = specs.drop_back();335 if (specs.empty())336 return {context, std::string(name)};337 338 llvm::StringRef scope_name = specs.back().GetFullName();339 340 // It might be a class name, try that first.341 std::vector<TypeIndex> types = index.tpi().findRecordsByName(scope_name);342 while (!types.empty()) {343 clang::QualType qt = GetOrCreateType(types.back());344 if (qt.isNull())345 continue;346 clang::TagDecl *tag = qt->getAsTagDecl();347 if (tag)348 return {clang::TagDecl::castToDeclContext(tag), std::string(uname)};349 types.pop_back();350 }351 352 // If that fails, treat it as a series of namespaces.353 for (const MSVCUndecoratedNameSpecifier &spec : specs) {354 std::string ns_name = spec.GetBaseName().str();355 context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);356 }357 return {context, std::string(uname)};358}359 360clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {361 // We must do this *without* calling GetOrCreate on the current uid, as362 // that would be an infinite recursion.363 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(364 m_clang.GetSymbolFile()->GetBackingSymbolFile());365 PdbIndex& index = pdb->GetIndex();366 switch (uid.kind()) {367 case PdbSymUidKind::CompilandSym: {368 std::optional<PdbCompilandSymId> scope =369 pdb->FindSymbolScope(uid.asCompilandSym());370 if (scope)371 return GetOrCreateDeclContextForUid(*scope);372 373 CVSymbol sym = index.ReadSymbolRecord(uid.asCompilandSym());374 return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;375 }376 case PdbSymUidKind::Type: {377 // It could be a namespace, class, or global. We don't support nested378 // functions yet. Anyway, we just need to consult the parent type map.379 PdbTypeSymId type_id = uid.asTypeSym();380 std::optional<TypeIndex> parent_index = pdb->GetParentType(type_id.index);381 if (!parent_index)382 return FromCompilerDeclContext(GetTranslationUnitDecl());383 return GetOrCreateDeclContextForUid(PdbTypeSymId(*parent_index));384 }385 case PdbSymUidKind::FieldListMember:386 // In this case the parent DeclContext is the one for the class that this387 // member is inside of.388 break;389 case PdbSymUidKind::GlobalSym: {390 // If this refers to a compiland symbol, just recurse in with that symbol.391 // The only other possibilities are S_CONSTANT and S_UDT, in which case we392 // need to parse the undecorated name to figure out the scope, then look393 // that up in the TPI stream. If it's found, it's a type, othewrise it's394 // a series of namespaces.395 // FIXME: do this.396 CVSymbol global = index.ReadSymbolRecord(uid.asGlobalSym());397 switch (global.kind()) {398 case SymbolKind::S_GDATA32:399 case SymbolKind::S_LDATA32:400 return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;;401 case SymbolKind::S_PROCREF:402 case SymbolKind::S_LPROCREF: {403 ProcRefSym ref{global.kind()};404 llvm::cantFail(405 SymbolDeserializer::deserializeAs<ProcRefSym>(global, ref));406 PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset};407 return GetParentDeclContext(cu_sym_id);408 }409 case SymbolKind::S_CONSTANT:410 case SymbolKind::S_UDT:411 return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;412 default:413 break;414 }415 break;416 }417 default:418 break;419 }420 return FromCompilerDeclContext(GetTranslationUnitDecl());421}422 423bool PdbAstBuilder::CompleteType(clang::QualType qt) {424 if (qt.isNull())425 return false;426 clang::TagDecl *tag = qt->getAsTagDecl();427 if (qt->isArrayType()) {428 const clang::Type *element_type = qt->getArrayElementTypeNoTypeQual();429 tag = element_type->getAsTagDecl();430 }431 if (!tag)432 return false;433 434 return CompleteTagDecl(*tag);435}436 437bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {438 // If this is not in our map, it's an error.439 auto status_iter = m_decl_to_status.find(&tag);440 lldbassert(status_iter != m_decl_to_status.end());441 442 // If it's already complete, just return.443 DeclStatus &status = status_iter->second;444 if (status.resolved)445 return true;446 447 PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym();448 PdbIndex &index = static_cast<SymbolFileNativePDB *>(449 m_clang.GetSymbolFile()->GetBackingSymbolFile())450 ->GetIndex();451 lldbassert(IsTagRecord(type_id, index.tpi()));452 453 clang::QualType tag_qt = m_clang.getASTContext().getCanonicalTagType(&tag);454 TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);455 456 TypeIndex tag_ti = type_id.index;457 CVType cvt = index.tpi().getType(tag_ti);458 if (cvt.kind() == LF_MODIFIER)459 tag_ti = LookThroughModifierRecord(cvt);460 461 PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, index.tpi());462 cvt = index.tpi().getType(best_ti.index);463 lldbassert(IsTagRecord(cvt));464 465 if (IsForwardRefUdt(cvt)) {466 // If we can't find a full decl for this forward ref anywhere in the debug467 // info, then we have no way to complete it.468 return false;469 }470 471 TypeIndex field_list_ti = GetFieldListIndex(cvt);472 CVType field_list_cvt = index.tpi().getType(field_list_ti);473 if (field_list_cvt.kind() != LF_FIELDLIST)474 return false;475 FieldListRecord field_list;476 if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(477 field_list_cvt, field_list))478 llvm::consumeError(std::move(error));479 480 // Visit all members of this class, then perform any finalization necessary481 // to complete the class.482 CompilerType ct = ToCompilerType(tag_qt);483 UdtRecordCompleter completer(best_ti, ct, tag, *this, index, m_decl_to_status,484 m_cxx_record_map);485 llvm::Error error =486 llvm::codeview::visitMemberRecordStream(field_list.Data, completer);487 completer.complete();488 489 m_decl_to_status[&tag].resolved = true;490 if (error) {491 llvm::consumeError(std::move(error));492 return false;493 }494 return true;495}496 497clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) {498 if (ti == TypeIndex::NullptrT())499 return GetBasicType(lldb::eBasicTypeNullPtr);500 501 if (ti.getSimpleMode() != SimpleTypeMode::Direct) {502 clang::QualType direct_type = GetOrCreateType(ti.makeDirect());503 if (direct_type.isNull())504 return {};505 return m_clang.getASTContext().getPointerType(direct_type);506 }507 508 if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)509 return {};510 511 lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind());512 if (bt == lldb::eBasicTypeInvalid)513 return {};514 515 return GetBasicType(bt);516}517 518clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) {519 clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType);520 521 // This can happen for pointers to LF_VTSHAPE records, which we shouldn't522 // create in the AST.523 if (pointee_type.isNull())524 return {};525 526 if (pointer.isPointerToMember()) {527 MemberPointerInfo mpi = pointer.getMemberInfo();528 clang::QualType class_type = GetOrCreateType(mpi.ContainingType);529 if (class_type.isNull())530 return {};531 if (clang::TagDecl *tag = class_type->getAsTagDecl()) {532 clang::MSInheritanceAttr::Spelling spelling;533 switch (mpi.Representation) {534 case llvm::codeview::PointerToMemberRepresentation::SingleInheritanceData:535 case llvm::codeview::PointerToMemberRepresentation::536 SingleInheritanceFunction:537 spelling =538 clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance;539 break;540 case llvm::codeview::PointerToMemberRepresentation::541 MultipleInheritanceData:542 case llvm::codeview::PointerToMemberRepresentation::543 MultipleInheritanceFunction:544 spelling =545 clang::MSInheritanceAttr::Spelling::Keyword_multiple_inheritance;546 break;547 case llvm::codeview::PointerToMemberRepresentation::548 VirtualInheritanceData:549 case llvm::codeview::PointerToMemberRepresentation::550 VirtualInheritanceFunction:551 spelling =552 clang::MSInheritanceAttr::Spelling::Keyword_virtual_inheritance;553 break;554 case llvm::codeview::PointerToMemberRepresentation::Unknown:555 spelling =556 clang::MSInheritanceAttr::Spelling::Keyword_unspecified_inheritance;557 break;558 default:559 spelling = clang::MSInheritanceAttr::Spelling::SpellingNotCalculated;560 break;561 }562 tag->addAttr(clang::MSInheritanceAttr::CreateImplicit(563 m_clang.getASTContext(), spelling));564 }565 return m_clang.getASTContext().getMemberPointerType(566 pointee_type, /*Qualifier=*/std::nullopt,567 class_type->getAsCXXRecordDecl());568 }569 570 clang::QualType pointer_type;571 if (pointer.getMode() == PointerMode::LValueReference)572 pointer_type = m_clang.getASTContext().getLValueReferenceType(pointee_type);573 else if (pointer.getMode() == PointerMode::RValueReference)574 pointer_type = m_clang.getASTContext().getRValueReferenceType(pointee_type);575 else576 pointer_type = m_clang.getASTContext().getPointerType(pointee_type);577 578 if ((pointer.getOptions() & PointerOptions::Const) != PointerOptions::None)579 pointer_type.addConst();580 581 if ((pointer.getOptions() & PointerOptions::Volatile) != PointerOptions::None)582 pointer_type.addVolatile();583 584 if ((pointer.getOptions() & PointerOptions::Restrict) != PointerOptions::None)585 pointer_type.addRestrict();586 587 return pointer_type;588}589 590clang::QualType591PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) {592 clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType);593 if (unmodified_type.isNull())594 return {};595 596 if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None)597 unmodified_type.addConst();598 if ((modifier.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)599 unmodified_type.addVolatile();600 601 return unmodified_type;602}603 604clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,605 const TagRecord &record) {606 clang::DeclContext *context = nullptr;607 std::string uname;608 std::tie(context, uname) = CreateDeclInfoForType(record, id.index);609 if (!context)610 return {};611 612 clang::TagTypeKind ttk = TranslateUdtKind(record);613 lldb::AccessType access = (ttk == clang::TagTypeKind::Class)614 ? lldb::eAccessPrivate615 : lldb::eAccessPublic;616 617 ClangASTMetadata metadata;618 metadata.SetUserID(toOpaqueUid(id));619 metadata.SetIsDynamicCXXType(false);620 621 CompilerType ct = m_clang.CreateRecordType(622 context, OptionalClangModuleID(), access, uname, llvm::to_underlying(ttk),623 lldb::eLanguageTypeC_plus_plus, metadata);624 625 lldbassert(ct.IsValid());626 627 TypeSystemClang::StartTagDeclarationDefinition(ct);628 629 // Even if it's possible, don't complete it at this point. Just mark it630 // forward resolved, and if/when LLDB needs the full definition, it can631 // ask us.632 clang::QualType result =633 clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());634 635 TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true);636 return result;637}638 639clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {640 auto iter = m_uid_to_decl.find(toOpaqueUid(uid));641 if (iter != m_uid_to_decl.end())642 return iter->second;643 return nullptr;644}645 646clang::NamespaceDecl *647PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,648 clang::DeclContext &context) {649 clang::NamespaceDecl *ns = m_clang.GetUniqueNamespaceDeclaration(650 IsAnonymousNamespaceName(name) ? nullptr : name, &context,651 OptionalClangModuleID());652 m_known_namespaces.insert(ns);653 m_parent_to_namespaces[&context].insert(ns);654 return ns;655}656 657clang::BlockDecl *658PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {659 if (clang::Decl *decl = TryGetDecl(block_id))660 return llvm::dyn_cast<clang::BlockDecl>(decl);661 662 clang::DeclContext *scope = GetParentDeclContext(block_id);663 664 clang::BlockDecl *block_decl =665 m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID());666 m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});667 668 DeclStatus status;669 status.resolved = true;670 status.uid = toOpaqueUid(block_id);671 m_decl_to_status.insert({block_decl, status});672 673 return block_decl;674}675 676clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,677 clang::DeclContext &scope) {678 VariableInfo var_info = GetVariableNameInfo(sym);679 clang::QualType qt = GetOrCreateType(var_info.type);680 if (qt.isNull())681 return nullptr;682 683 clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(684 &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt);685 686 m_uid_to_decl[toOpaqueUid(uid)] = var_decl;687 DeclStatus status;688 status.resolved = true;689 status.uid = toOpaqueUid(uid);690 m_decl_to_status.insert({var_decl, status});691 return var_decl;692}693 694clang::VarDecl *695PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id,696 PdbCompilandSymId var_id) {697 if (clang::Decl *decl = TryGetDecl(var_id))698 return llvm::dyn_cast<clang::VarDecl>(decl);699 700 clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id);701 if (!scope)702 return nullptr;703 704 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(705 m_clang.GetSymbolFile()->GetBackingSymbolFile());706 PdbIndex &index = pdb->GetIndex();707 CVSymbol sym = index.ReadSymbolRecord(var_id);708 return CreateVariableDecl(PdbSymUid(var_id), sym, *scope);709}710 711clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) {712 if (clang::Decl *decl = TryGetDecl(var_id))713 return llvm::dyn_cast<clang::VarDecl>(decl);714 715 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(716 m_clang.GetSymbolFile()->GetBackingSymbolFile());717 PdbIndex &index = pdb->GetIndex();718 CVSymbol sym = index.ReadSymbolRecord(var_id);719 auto context = FromCompilerDeclContext(GetTranslationUnitDecl());720 return CreateVariableDecl(PdbSymUid(var_id), sym, *context);721}722 723clang::TypedefNameDecl *724PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {725 if (clang::Decl *decl = TryGetDecl(id))726 return llvm::dyn_cast<clang::TypedefNameDecl>(decl);727 728 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(729 m_clang.GetSymbolFile()->GetBackingSymbolFile());730 PdbIndex &index = pdb->GetIndex();731 CVSymbol sym = index.ReadSymbolRecord(id);732 lldbassert(sym.kind() == S_UDT);733 UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));734 735 clang::DeclContext *scope = GetParentDeclContext(id);736 737 PdbTypeSymId real_type_id{udt.Type, false};738 clang::QualType qt = GetOrCreateType(real_type_id);739 if (qt.isNull() || !scope)740 return nullptr;741 742 std::string uname = std::string(DropNameScope(udt.Name));743 744 CompilerType ct = ToCompilerType(qt).CreateTypedef(745 uname.c_str(), ToCompilerDeclContext(*scope), 0);746 clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);747 DeclStatus status;748 status.resolved = true;749 status.uid = toOpaqueUid(id);750 m_decl_to_status.insert({tnd, status});751 return tnd;752}753 754clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) {755 CompilerType ct = m_clang.GetBasicType(type);756 return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());757}758 759clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) {760 if (type.index.isSimple())761 return CreateSimpleType(type.index);762 763 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(764 m_clang.GetSymbolFile()->GetBackingSymbolFile());765 PdbIndex &index = pdb->GetIndex();766 CVType cvt = index.tpi().getType(type.index);767 768 if (cvt.kind() == LF_MODIFIER) {769 ModifierRecord modifier;770 llvm::cantFail(771 TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));772 return CreateModifierType(modifier);773 }774 775 if (cvt.kind() == LF_POINTER) {776 PointerRecord pointer;777 llvm::cantFail(778 TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));779 return CreatePointerType(pointer);780 }781 782 if (IsTagRecord(cvt)) {783 CVTagRecord tag = CVTagRecord::create(cvt);784 if (tag.kind() == CVTagRecord::Union)785 return CreateRecordType(type.index, tag.asUnion());786 if (tag.kind() == CVTagRecord::Enum)787 return CreateEnumType(type.index, tag.asEnum());788 return CreateRecordType(type.index, tag.asClass());789 }790 791 if (cvt.kind() == LF_ARRAY) {792 ArrayRecord ar;793 llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));794 return CreateArrayType(ar);795 }796 797 if (cvt.kind() == LF_PROCEDURE) {798 ProcedureRecord pr;799 llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));800 return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv);801 }802 803 if (cvt.kind() == LF_MFUNCTION) {804 MemberFunctionRecord mfr;805 llvm::cantFail(806 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));807 return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv);808 }809 810 return {};811}812 813clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) {814 if (type.index.isNoneType())815 return {};816 817 lldb::user_id_t uid = toOpaqueUid(type);818 auto iter = m_uid_to_type.find(uid);819 if (iter != m_uid_to_type.end())820 return iter->second;821 822 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(823 m_clang.GetSymbolFile()->GetBackingSymbolFile());824 PdbIndex &index = pdb->GetIndex();825 PdbTypeSymId best_type = GetBestPossibleDecl(type, index.tpi());826 827 clang::QualType qt;828 if (best_type.index != type.index) {829 // This is a forward decl. Call GetOrCreate on the full decl, then map the830 // forward decl id to the full decl QualType.831 clang::QualType qt = GetOrCreateType(best_type);832 if (qt.isNull())833 return {};834 m_uid_to_type[toOpaqueUid(type)] = qt;835 return qt;836 }837 838 // This is either a full decl, or a forward decl with no matching full decl839 // in the debug info.840 qt = CreateType(type);841 if (qt.isNull())842 return {};843 844 m_uid_to_type[toOpaqueUid(type)] = qt;845 if (IsTagRecord(type, index.tpi())) {846 clang::TagDecl *tag = qt->getAsTagDecl();847 lldbassert(m_decl_to_status.count(tag) == 0);848 849 DeclStatus &status = m_decl_to_status[tag];850 status.uid = uid;851 status.resolved = false;852 }853 return qt;854}855 856clang::FunctionDecl *857PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,858 llvm::StringRef func_name, TypeIndex func_ti,859 CompilerType func_ct, uint32_t param_count,860 clang::StorageClass func_storage,861 bool is_inline, clang::DeclContext *parent) {862 clang::FunctionDecl *function_decl = nullptr;863 if (parent->isRecord()) {864 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(865 m_clang.GetSymbolFile()->GetBackingSymbolFile());866 PdbIndex &index = pdb->GetIndex();867 clang::CanQualType parent_qt =868 m_clang.getASTContext().getCanonicalTypeDeclType(869 llvm::cast<clang::TypeDecl>(parent));870 lldb::opaque_compiler_type_t parent_opaque_ty =871 ToCompilerType(parent_qt).GetOpaqueQualType();872 // FIXME: Remove this workaround.873 auto iter = m_cxx_record_map.find(parent_opaque_ty);874 if (iter != m_cxx_record_map.end()) {875 if (iter->getSecond().contains({func_name, func_ct})) {876 return nullptr;877 }878 }879 880 CVType cvt = index.tpi().getType(func_ti);881 MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));882 llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(883 cvt, func_record));884 TypeIndex class_index = func_record.getClassType();885 886 CVType parent_cvt = index.tpi().getType(class_index);887 TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag();888 // If it's a forward reference, try to get the real TypeIndex.889 if (tag_record.isForwardRef()) {890 llvm::Expected<TypeIndex> eti =891 index.tpi().findFullDeclForForwardRef(class_index);892 if (eti) {893 tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag();894 }895 }896 897 ConstString mangled_name(898 pdb->FindMangledFunctionName(func_id).value_or(llvm::StringRef()));899 900 if (!tag_record.FieldList.isSimple()) {901 CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);902 FieldListRecord field_list;903 if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(904 field_list_cvt, field_list))905 llvm::consumeError(std::move(error));906 CreateMethodDecl process(index, m_clang, func_ti, function_decl,907 parent_opaque_ty, func_name, mangled_name,908 func_ct);909 if (llvm::Error err = visitMemberRecordStream(field_list.Data, process))910 llvm::consumeError(std::move(err));911 }912 913 if (!function_decl) {914 function_decl = m_clang.AddMethodToCXXRecordType(915 parent_opaque_ty, func_name, mangled_name, func_ct,916 /*access=*/lldb::AccessType::eAccessPublic,917 /*is_virtual=*/false, /*is_static=*/false,918 /*is_inline=*/false, /*is_explicit=*/false,919 /*is_attr_used=*/false, /*is_artificial=*/false);920 }921 m_cxx_record_map[parent_opaque_ty].insert({func_name, func_ct});922 } else {923 function_decl = m_clang.CreateFunctionDeclaration(924 parent, OptionalClangModuleID(), func_name, func_ct, func_storage,925 is_inline, /*asm_label=*/{});926 CreateFunctionParameters(func_id, *function_decl, param_count);927 }928 return function_decl;929}930 931clang::FunctionDecl *932PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) {933 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(934 m_clang.GetSymbolFile()->GetBackingSymbolFile());935 PdbIndex &index = pdb->GetIndex();936 CompilandIndexItem *cii =937 index.compilands().GetCompiland(inlinesite_id.modi);938 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset);939 InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));940 cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));941 942 // Inlinee is the id index to the function id record that is inlined.943 PdbTypeSymId func_id(inline_site.Inlinee, true);944 // Look up the function decl by the id index to see if we have created a945 // function decl for a different inlinesite that refers the same function.946 if (clang::Decl *decl = TryGetDecl(func_id))947 return llvm::dyn_cast<clang::FunctionDecl>(decl);948 clang::FunctionDecl *function_decl =949 CreateFunctionDeclFromId(func_id, inlinesite_id);950 if (function_decl == nullptr)951 return nullptr;952 953 // Use inline site id in m_decl_to_status because it's expected to be a954 // PdbCompilandSymId so that we can parse local variables info after it.955 uint64_t inlinesite_uid = toOpaqueUid(inlinesite_id);956 DeclStatus status;957 status.resolved = true;958 status.uid = inlinesite_uid;959 m_decl_to_status.insert({function_decl, status});960 // Use the index in IPI stream as uid in m_uid_to_decl, because index in IPI961 // stream are unique and there could be multiple inline sites (different ids)962 // referring the same inline function. This avoid creating multiple same963 // inline function delcs.964 uint64_t func_uid = toOpaqueUid(func_id);965 lldbassert(m_uid_to_decl.count(func_uid) == 0);966 m_uid_to_decl[func_uid] = function_decl;967 return function_decl;968}969 970clang::FunctionDecl *971PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid,972 PdbCompilandSymId func_sid) {973 lldbassert(func_tid.is_ipi);974 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(975 m_clang.GetSymbolFile()->GetBackingSymbolFile());976 PdbIndex &index = pdb->GetIndex();977 CVType func_cvt = index.ipi().getType(func_tid.index);978 llvm::StringRef func_name;979 TypeIndex func_ti;980 clang::DeclContext *parent = nullptr;981 switch (func_cvt.kind()) {982 case LF_MFUNC_ID: {983 MemberFuncIdRecord mfr;984 cantFail(985 TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr));986 func_name = mfr.getName();987 func_ti = mfr.getFunctionType();988 PdbTypeSymId class_type_id(mfr.ClassType, false);989 parent = GetOrCreateDeclContextForUid(class_type_id);990 break;991 }992 case LF_FUNC_ID: {993 FuncIdRecord fir;994 cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir));995 func_name = fir.getName();996 func_ti = fir.getFunctionType();997 parent = FromCompilerDeclContext(GetTranslationUnitDecl());998 if (!fir.ParentScope.isNoneType()) {999 CVType parent_cvt = index.ipi().getType(fir.ParentScope);1000 if (parent_cvt.kind() == LF_STRING_ID) {1001 StringIdRecord sir;1002 cantFail(1003 TypeDeserializer::deserializeAs<StringIdRecord>(parent_cvt, sir));1004 parent = GetOrCreateNamespaceDecl(sir.String.data(), *parent);1005 }1006 }1007 break;1008 }1009 default:1010 lldbassert(false && "Invalid function id type!");1011 }1012 clang::QualType func_qt = GetOrCreateType(func_ti);1013 if (func_qt.isNull() || !parent)1014 return nullptr;1015 CompilerType func_ct = ToCompilerType(func_qt);1016 uint32_t param_count =1017 llvm::cast<clang::FunctionProtoType>(func_qt)->getNumParams();1018 return CreateFunctionDecl(func_sid, func_name, func_ti, func_ct, param_count,1019 clang::SC_None, true, parent);1020}1021 1022clang::FunctionDecl *1023PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {1024 if (clang::Decl *decl = TryGetDecl(func_id))1025 return llvm::dyn_cast<clang::FunctionDecl>(decl);1026 1027 clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id));1028 if (!parent)1029 return nullptr;1030 std::string context_name;1031 if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) {1032 context_name = ns->getQualifiedNameAsString();1033 } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) {1034 context_name = tag->getQualifiedNameAsString();1035 }1036 1037 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1038 m_clang.GetSymbolFile()->GetBackingSymbolFile());1039 PdbIndex &index = pdb->GetIndex();1040 CVSymbol cvs = index.ReadSymbolRecord(func_id);1041 ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind()));1042 llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc));1043 1044 PdbTypeSymId type_id(proc.FunctionType);1045 clang::QualType qt = GetOrCreateType(type_id);1046 if (qt.isNull())1047 return nullptr;1048 1049 clang::StorageClass storage = clang::SC_None;1050 if (proc.Kind == SymbolRecordKind::ProcSym)1051 storage = clang::SC_Static;1052 1053 const clang::FunctionProtoType *func_type =1054 llvm::dyn_cast<clang::FunctionProtoType>(qt);1055 1056 CompilerType func_ct = ToCompilerType(qt);1057 1058 llvm::StringRef proc_name = proc.Name;1059 proc_name.consume_front(context_name);1060 proc_name.consume_front("::");1061 clang::FunctionDecl *function_decl =1062 CreateFunctionDecl(func_id, proc_name, proc.FunctionType, func_ct,1063 func_type->getNumParams(), storage, false, parent);1064 if (function_decl == nullptr)1065 return nullptr;1066 1067 lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);1068 m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;1069 DeclStatus status;1070 status.resolved = true;1071 status.uid = toOpaqueUid(func_id);1072 m_decl_to_status.insert({function_decl, status});1073 1074 return function_decl;1075}1076 1077void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,1078 clang::FunctionDecl &function_decl,1079 uint32_t param_count) {1080 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1081 m_clang.GetSymbolFile()->GetBackingSymbolFile());1082 PdbIndex &index = pdb->GetIndex();1083 CompilandIndexItem *cii = index.compilands().GetCompiland(func_id.modi);1084 CVSymbolArray scope =1085 cii->m_debug_stream.getSymbolArrayForScope(func_id.offset);1086 1087 scope.drop_front();1088 auto begin = scope.begin();1089 auto end = scope.end();1090 std::vector<clang::ParmVarDecl *> params;1091 for (uint32_t i = 0; i < param_count && begin != end;) {1092 uint32_t record_offset = begin.offset();1093 CVSymbol sym = *begin++;1094 1095 TypeIndex param_type;1096 llvm::StringRef param_name;1097 switch (sym.kind()) {1098 case S_REGREL32: {1099 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);1100 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));1101 param_type = reg.Type;1102 param_name = reg.Name;1103 break;1104 }1105 case S_REGISTER: {1106 RegisterSym reg(SymbolRecordKind::RegisterSym);1107 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));1108 param_type = reg.Index;1109 param_name = reg.Name;1110 break;1111 }1112 case S_LOCAL: {1113 LocalSym local(SymbolRecordKind::LocalSym);1114 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));1115 if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None)1116 continue;1117 param_type = local.Type;1118 param_name = local.Name;1119 break;1120 }1121 case S_BLOCK32:1122 case S_INLINESITE:1123 case S_INLINESITE2:1124 // All parameters should come before the first block/inlinesite. If that1125 // isn't the case, then perhaps this is bad debug info that doesn't1126 // contain information about all parameters.1127 return;1128 default:1129 continue;1130 }1131 1132 PdbCompilandSymId param_uid(func_id.modi, record_offset);1133 clang::QualType qt = GetOrCreateType(param_type);1134 if (qt.isNull())1135 return;1136 1137 CompilerType param_type_ct = m_clang.GetType(qt);1138 clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(1139 &function_decl, OptionalClangModuleID(), param_name.str().c_str(),1140 param_type_ct, clang::SC_None, true);1141 lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);1142 1143 m_uid_to_decl[toOpaqueUid(param_uid)] = param;1144 params.push_back(param);1145 ++i;1146 }1147 1148 if (!params.empty() && params.size() == param_count)1149 function_decl.setParams(params);1150}1151 1152clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,1153 const EnumRecord &er) {1154 clang::DeclContext *decl_context = nullptr;1155 std::string uname;1156 std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index);1157 if (!decl_context)1158 return {};1159 1160 clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType);1161 if (underlying_type.isNull())1162 return {};1163 1164 Declaration declaration;1165 CompilerType enum_ct = m_clang.CreateEnumerationType(1166 uname, decl_context, OptionalClangModuleID(), declaration,1167 ToCompilerType(underlying_type), er.isScoped());1168 1169 TypeSystemClang::StartTagDeclarationDefinition(enum_ct);1170 TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);1171 1172 return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType());1173}1174 1175clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {1176 clang::QualType element_type = GetOrCreateType(ar.ElementType);1177 TypeSystemClang::RequireCompleteType(ToCompilerType(element_type));1178 1179 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1180 m_clang.GetSymbolFile()->GetBackingSymbolFile());1181 PdbIndex &index = pdb->GetIndex();1182 uint64_t element_size = GetSizeOfType({ar.ElementType}, index.tpi());1183 if (element_type.isNull() || element_size == 0)1184 return {};1185 uint64_t element_count = ar.Size / element_size;1186 1187 CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type),1188 element_count, false);1189 return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType());1190}1191 1192clang::QualType PdbAstBuilder::CreateFunctionType(1193 TypeIndex args_type_idx, TypeIndex return_type_idx,1194 llvm::codeview::CallingConvention calling_convention) {1195 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1196 m_clang.GetSymbolFile()->GetBackingSymbolFile());1197 PdbIndex &index = pdb->GetIndex();1198 TpiStream &stream = index.tpi();1199 CVType args_cvt = stream.getType(args_type_idx);1200 ArgListRecord args;1201 llvm::cantFail(1202 TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args));1203 1204 llvm::ArrayRef<TypeIndex> arg_indices = llvm::ArrayRef(args.ArgIndices);1205 bool is_variadic = IsCVarArgsFunction(arg_indices);1206 if (is_variadic)1207 arg_indices = arg_indices.drop_back();1208 1209 std::vector<CompilerType> arg_types;1210 arg_types.reserve(arg_indices.size());1211 1212 for (TypeIndex arg_index : arg_indices) {1213 clang::QualType arg_type = GetOrCreateType(arg_index);1214 if (arg_type.isNull())1215 continue;1216 arg_types.push_back(ToCompilerType(arg_type));1217 }1218 1219 clang::QualType return_type = GetOrCreateType(return_type_idx);1220 if (return_type.isNull())1221 return {};1222 1223 std::optional<clang::CallingConv> cc =1224 TranslateCallingConvention(calling_convention);1225 if (!cc)1226 return {};1227 1228 CompilerType return_ct = ToCompilerType(return_type);1229 CompilerType func_sig_ast_type =1230 m_clang.CreateFunctionType(return_ct, arg_types, is_variadic, 0, *cc);1231 1232 return clang::QualType::getFromOpaquePtr(1233 func_sig_ast_type.GetOpaqueQualType());1234}1235 1236static bool isTagDecl(clang::DeclContext &context) {1237 return llvm::isa<clang::TagDecl>(&context);1238}1239 1240static bool isFunctionDecl(clang::DeclContext &context) {1241 return llvm::isa<clang::FunctionDecl>(&context);1242}1243 1244static bool isBlockDecl(clang::DeclContext &context) {1245 return llvm::isa<clang::BlockDecl>(&context);1246}1247 1248void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) {1249 clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(&context);1250 if (m_parsed_namespaces.contains(ns))1251 return;1252 std::string qname = ns->getQualifiedNameAsString();1253 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1254 m_clang.GetSymbolFile()->GetBackingSymbolFile());1255 PdbIndex &index = pdb->GetIndex();1256 TypeIndex ti{index.tpi().TypeIndexBegin()};1257 for (const CVType &cvt : index.tpi().typeArray()) {1258 PdbTypeSymId tid{ti};1259 ++ti;1260 1261 if (!IsTagRecord(cvt))1262 continue;1263 1264 CVTagRecord tag = CVTagRecord::create(cvt);1265 1266 // Call CreateDeclInfoForType unconditionally so that the namespace info1267 // gets created. But only call CreateRecordType if the namespace name1268 // matches.1269 clang::DeclContext *context = nullptr;1270 std::string uname;1271 std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index);1272 if (!context || !context->isNamespace())1273 continue;1274 1275 clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);1276 llvm::StringRef ns_name = ns->getName();1277 if (ns_name.starts_with(qname)) {1278 ns_name = ns_name.drop_front(qname.size());1279 if (ns_name.starts_with("::"))1280 GetOrCreateType(tid);1281 }1282 }1283 ParseAllFunctionsAndNonLocalVars();1284 m_parsed_namespaces.insert(ns);1285}1286 1287void PdbAstBuilder::ParseAllTypes() {1288 llvm::call_once(m_parse_all_types, [this]() {1289 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1290 m_clang.GetSymbolFile()->GetBackingSymbolFile());1291 PdbIndex &index = pdb->GetIndex();1292 TypeIndex ti{index.tpi().TypeIndexBegin()};1293 for (const CVType &cvt : index.tpi().typeArray()) {1294 PdbTypeSymId tid{ti};1295 ++ti;1296 1297 if (!IsTagRecord(cvt))1298 continue;1299 1300 GetOrCreateType(tid);1301 }1302 });1303}1304 1305void PdbAstBuilder::ParseAllFunctionsAndNonLocalVars() {1306 llvm::call_once(m_parse_functions_and_non_local_vars, [this]() {1307 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1308 m_clang.GetSymbolFile()->GetBackingSymbolFile());1309 PdbIndex &index = pdb->GetIndex();1310 uint32_t module_count = index.dbi().modules().getModuleCount();1311 for (uint16_t modi = 0; modi < module_count; ++modi) {1312 CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);1313 const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();1314 auto iter = symbols.begin();1315 while (iter != symbols.end()) {1316 PdbCompilandSymId sym_id{modi, iter.offset()};1317 1318 switch (iter->kind()) {1319 case S_GPROC32:1320 case S_LPROC32:1321 GetOrCreateFunctionDecl(sym_id);1322 iter = symbols.at(getScopeEndOffset(*iter));1323 break;1324 case S_GDATA32:1325 case S_GTHREAD32:1326 case S_LDATA32:1327 case S_LTHREAD32:1328 GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);1329 ++iter;1330 break;1331 default:1332 ++iter;1333 continue;1334 }1335 }1336 }1337 });1338}1339 1340static CVSymbolArray skipFunctionParameters(clang::Decl &decl,1341 const CVSymbolArray &symbols) {1342 clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>(&decl);1343 if (!func_decl)1344 return symbols;1345 unsigned int params = func_decl->getNumParams();1346 if (params == 0)1347 return symbols;1348 1349 CVSymbolArray result = symbols;1350 1351 while (!result.empty()) {1352 if (params == 0)1353 return result;1354 1355 CVSymbol sym = *result.begin();1356 result.drop_front();1357 1358 if (!isLocalVariableType(sym.kind()))1359 continue;1360 1361 --params;1362 }1363 return result;1364}1365 1366void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) {1367 SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1368 m_clang.GetSymbolFile()->GetBackingSymbolFile());1369 PdbIndex &index = pdb->GetIndex();1370 CVSymbol sym = index.ReadSymbolRecord(block_id);1371 lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 ||1372 sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE);1373 CompilandIndexItem &cii =1374 index.compilands().GetOrCreateCompiland(block_id.modi);1375 CVSymbolArray symbols =1376 cii.m_debug_stream.getSymbolArrayForScope(block_id.offset);1377 1378 // Function parameters should already have been created when the function was1379 // parsed.1380 if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32)1381 symbols =1382 skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols);1383 1384 symbols.drop_front();1385 auto begin = symbols.begin();1386 while (begin != symbols.end()) {1387 PdbCompilandSymId child_sym_id(block_id.modi, begin.offset());1388 GetOrCreateSymbolForId(child_sym_id);1389 if (begin->kind() == S_BLOCK32 || begin->kind() == S_INLINESITE) {1390 ParseBlockChildren(child_sym_id);1391 begin = symbols.at(getScopeEndOffset(*begin));1392 }1393 ++begin;1394 }1395}1396 1397void PdbAstBuilder::ParseDeclsForSimpleContext(clang::DeclContext &context) {1398 1399 clang::Decl *decl = clang::Decl::castFromDeclContext(&context);1400 lldbassert(decl);1401 1402 auto iter = m_decl_to_status.find(decl);1403 lldbassert(iter != m_decl_to_status.end());1404 1405 if (auto *tag = llvm::dyn_cast<clang::TagDecl>(&context)) {1406 CompleteTagDecl(*tag);1407 return;1408 }1409 1410 if (isFunctionDecl(context) || isBlockDecl(context)) {1411 PdbCompilandSymId block_id = PdbSymUid(iter->second.uid).asCompilandSym();1412 ParseBlockChildren(block_id);1413 }1414}1415 1416void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) {1417 // Namespaces aren't explicitly represented in the debug info, and the only1418 // way to parse them is to parse all type info, demangling every single type1419 // and trying to reconstruct the DeclContext hierarchy this way. Since this1420 // is an expensive operation, we have to special case it so that we do other1421 // work (such as parsing the items that appear within the namespaces) at the1422 // same time.1423 if (context.isTranslationUnit()) {1424 ParseAllTypes();1425 ParseAllFunctionsAndNonLocalVars();1426 return;1427 }1428 1429 if (context.isNamespace()) {1430 ParseNamespace(context);1431 return;1432 }1433 1434 if (isTagDecl(context) || isFunctionDecl(context) || isBlockDecl(context)) {1435 ParseDeclsForSimpleContext(context);1436 return;1437 }1438}1439 1440CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) {1441 return m_clang.GetCompilerDecl(&decl);1442}1443 1444CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) {1445 return {m_clang.weak_from_this(), qt.getAsOpaquePtr()};1446}1447 1448CompilerDeclContext1449PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {1450 return m_clang.CreateDeclContext(&context);1451}1452 1453clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) {1454 return ClangUtil::GetDecl(decl);1455}1456 1457clang::DeclContext *1458PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {1459 return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());1460}1461 1462void PdbAstBuilder::Dump(Stream &stream, llvm::StringRef filter,1463 bool show_color) {1464 m_clang.Dump(stream.AsRawOstream(), filter, show_color);1465}1466 1467clang::NamespaceDecl *1468PdbAstBuilder::FindNamespaceDecl(const clang::DeclContext *parent,1469 llvm::StringRef name) {1470 NamespaceSet *set;1471 if (parent) {1472 auto it = m_parent_to_namespaces.find(parent);1473 if (it == m_parent_to_namespaces.end())1474 return nullptr;1475 1476 set = &it->second;1477 } else {1478 // In this case, search through all known namespaces1479 set = &m_known_namespaces;1480 }1481 assert(set);1482 1483 for (clang::NamespaceDecl *namespace_decl : *set)1484 if (namespace_decl->getName() == name)1485 return namespace_decl;1486 1487 for (clang::NamespaceDecl *namespace_decl : *set)1488 if (namespace_decl->isAnonymousNamespace())1489 return FindNamespaceDecl(namespace_decl, name);1490 1491 return nullptr;1492}1493