3931 lines · cpp
1//===-- DWARFASTParserClang.cpp -------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <cstdlib>10 11#include "DWARFASTParser.h"12#include "DWARFASTParserClang.h"13#include "DWARFDebugInfo.h"14#include "DWARFDeclContext.h"15#include "DWARFDefines.h"16#include "SymbolFileDWARF.h"17#include "SymbolFileDWARFDebugMap.h"18#include "SymbolFileDWARFDwo.h"19#include "UniqueDWARFASTType.h"20 21#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"22#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"23#include "Plugins/ExpressionParser/Clang/ClangUtil.h"24#include "Plugins/Language/ObjC/ObjCLanguage.h"25#include "lldb/Core/Module.h"26#include "lldb/Core/Value.h"27#include "lldb/Expression/Expression.h"28#include "lldb/Host/Host.h"29#include "lldb/Symbol/CompileUnit.h"30#include "lldb/Symbol/Function.h"31#include "lldb/Symbol/ObjectFile.h"32#include "lldb/Symbol/SymbolFile.h"33#include "lldb/Symbol/TypeList.h"34#include "lldb/Symbol/TypeMap.h"35#include "lldb/Symbol/VariableList.h"36#include "lldb/Target/Language.h"37#include "lldb/Utility/LLDBAssert.h"38#include "lldb/Utility/Log.h"39#include "lldb/Utility/StreamString.h"40#include "lldb/lldb-private-enumerations.h"41 42#include "clang/AST/CXXInheritance.h"43#include "clang/AST/DeclBase.h"44#include "clang/AST/DeclCXX.h"45#include "clang/AST/DeclObjC.h"46#include "clang/AST/DeclTemplate.h"47#include "clang/AST/Type.h"48#include "clang/Basic/Specifiers.h"49#include "llvm/ADT/StringExtras.h"50#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"51#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"52#include "llvm/Demangle/Demangle.h"53 54#include <map>55#include <memory>56#include <optional>57#include <vector>58 59//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN60 61#ifdef ENABLE_DEBUG_PRINTF62#include <cstdio>63#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)64#else65#define DEBUG_PRINTF(fmt, ...)66#endif67 68using namespace lldb;69using namespace lldb_private;70using namespace lldb_private::plugin::dwarf;71using namespace llvm::dwarf;72 73DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast)74 : DWARFASTParser(Kind::DWARFASTParserClang), m_ast(ast),75 m_die_to_decl_ctx(), m_decl_ctx_to_die() {}76 77DWARFASTParserClang::~DWARFASTParserClang() = default;78 79static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) {80 switch (decl_kind) {81 case clang::Decl::CXXRecord:82 case clang::Decl::ClassTemplateSpecialization:83 return true;84 default:85 break;86 }87 return false;88}89 90 91ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {92 if (!m_clang_ast_importer_up) {93 m_clang_ast_importer_up = std::make_unique<ClangASTImporter>();94 }95 return *m_clang_ast_importer_up;96}97 98/// Detect a forward declaration that is nested in a DW_TAG_module.99static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {100 if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))101 return false;102 auto Parent = Die.GetParent();103 while (Parent.IsValid()) {104 if (Parent.Tag() == DW_TAG_module)105 return true;106 Parent = Parent.GetParent();107 }108 return false;109}110 111static DWARFDIE GetContainingClangModuleDIE(const DWARFDIE &die) {112 if (die.IsValid()) {113 DWARFDIE top_module_die;114 // Now make sure this DIE is scoped in a DW_TAG_module tag and return true115 // if so116 for (DWARFDIE parent = die.GetParent(); parent.IsValid();117 parent = parent.GetParent()) {118 const dw_tag_t tag = parent.Tag();119 if (tag == DW_TAG_module)120 top_module_die = parent;121 else if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)122 break;123 }124 125 return top_module_die;126 }127 return DWARFDIE();128}129 130static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) {131 if (die.IsValid()) {132 DWARFDIE clang_module_die = GetContainingClangModuleDIE(die);133 134 if (clang_module_die) {135 const char *module_name = clang_module_die.GetName();136 if (module_name)137 return die.GetDWARF()->GetExternalModule(138 lldb_private::ConstString(module_name));139 }140 }141 return lldb::ModuleSP();142}143 144// Returns true if the given artificial field name should be ignored when145// parsing the DWARF.146static bool ShouldIgnoreArtificialField(llvm::StringRef FieldName) {147 return FieldName.starts_with("_vptr$")148 // gdb emit vtable pointer as "_vptr.classname"149 || FieldName.starts_with("_vptr.");150}151 152/// Returns true for C++ constructs represented by clang::CXXRecordDecl153static bool TagIsRecordType(dw_tag_t tag) {154 switch (tag) {155 case DW_TAG_class_type:156 case DW_TAG_structure_type:157 case DW_TAG_union_type:158 return true;159 default:160 return false;161 }162}163 164DWARFDIE165DWARFASTParserClang::GetObjectParameter(const DWARFDIE &subprogram,166 const DWARFDIE &decl_ctx_die) {167 assert(subprogram);168 assert(subprogram.Tag() == DW_TAG_subprogram ||169 subprogram.Tag() == DW_TAG_inlined_subroutine ||170 subprogram.Tag() == DW_TAG_subroutine_type);171 172 // The DW_AT_object_pointer may be either encoded as a reference to a DIE,173 // in which case that's the object parameter we want. Or it can be a constant174 // index of the parameter.175 std::optional<size_t> object_pointer_index;176 DWARFFormValue form_value;177 if (subprogram.GetDIE()->GetAttributeValue(178 subprogram.GetCU(), DW_AT_object_pointer, form_value,179 /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {180 if (auto ref = form_value.Reference())181 return ref;182 183 object_pointer_index = form_value.Unsigned();184 }185 186 // Try to find the DW_TAG_formal_parameter via object_pointer_index.187 DWARFDIE object_pointer;188 size_t param_index = 0;189 for (const auto &child : subprogram.children()) {190 if (child.Tag() != DW_TAG_formal_parameter)191 continue;192 193 if (param_index == object_pointer_index.value_or(0)) {194 object_pointer = child;195 break;196 }197 198 ++param_index;199 }200 201 // No formal parameter found for object pointer index.202 // Nothing to be done.203 if (!object_pointer)204 return {};205 206 // We found the object pointer encoded via DW_AT_object_pointer.207 // No need for the remaining heuristics.208 if (object_pointer_index)209 return object_pointer;210 211 // If no DW_AT_object_pointer was specified, assume the implicit object212 // parameter is the first parameter to the function, is called "this" and is213 // artificial (which is what most compilers would generate).214 215 if (!decl_ctx_die.IsStructUnionOrClass())216 return {};217 218 if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))219 return {};220 221 // Often times compilers omit the "this" name for the222 // specification DIEs, so we can't rely upon the name being in223 // the formal parameter DIE...224 if (const char *name = object_pointer.GetName();225 name && ::strcmp(name, "this") != 0)226 return {};227 228 return object_pointer;229}230 231/// In order to determine the CV-qualifiers for a C++ class232/// method in DWARF, we have to look at the CV-qualifiers of233/// the object parameter's type.234static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram,235 const DWARFDIE &object_parameter) {236 if (!subprogram || !object_parameter)237 return 0;238 239 Type *this_type = subprogram.ResolveTypeUID(240 object_parameter.GetAttributeValueAsReferenceDIE(DW_AT_type));241 if (!this_type)242 return 0;243 244 uint32_t encoding_mask = this_type->GetEncodingMask();245 unsigned cv_quals = 0;246 if (encoding_mask & (1u << Type::eEncodingIsConstUID))247 cv_quals |= clang::Qualifiers::Const;248 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))249 cv_quals |= clang::Qualifiers::Volatile;250 251 return cv_quals;252}253 254static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {255 const char *name = die.GetMangledName(/*substitute_name_allowed*/ false);256 if (!name)257 return {};258 259 SymbolFileDWARF *dwarf = die.GetDWARF();260 if (!dwarf)261 return {};262 263 auto get_module_id = [&](SymbolFile *sym) {264 if (!sym)265 return LLDB_INVALID_UID;266 267 auto *obj = sym->GetMainObjectFile();268 if (!obj)269 return LLDB_INVALID_UID;270 271 auto module_sp = obj->GetModule();272 if (!module_sp)273 return LLDB_INVALID_UID;274 275 return module_sp->GetID();276 };277 278 lldb::user_id_t module_id = get_module_id(dwarf->GetDebugMapSymfile());279 if (module_id == LLDB_INVALID_UID)280 module_id = get_module_id(dwarf);281 282 if (module_id == LLDB_INVALID_UID)283 return {};284 285 const auto die_id = die.GetID();286 if (die_id == LLDB_INVALID_UID)287 return {};288 289 // Note, discriminator is added by Clang during mangling.290 return FunctionCallLabel{/*discriminator=*/{},291 /*module_id=*/module_id,292 /*symbol_id=*/die_id,293 /*.lookup_name=*/name}294 .toString();295}296 297TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,298 const DWARFDIE &die,299 Log *log) {300 ModuleSP clang_module_sp = GetContainingClangModule(die);301 if (!clang_module_sp)302 return TypeSP();303 304 // If this type comes from a Clang module, recursively look in the305 // DWARF section of the .pcm file in the module cache. Clang306 // generates DWO skeleton units as breadcrumbs to find them.307 std::vector<lldb_private::CompilerContext> die_context = die.GetDeclContext();308 TypeQuery query(die_context, TypeQueryOptions::e_module_search |309 TypeQueryOptions::e_find_one);310 TypeResults results;311 312 // The type in the Clang module must have the same language as the current CU.313 query.AddLanguage(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));314 clang_module_sp->FindTypes(query, results);315 TypeSP pcm_type_sp = results.GetTypeMap().FirstType();316 if (!pcm_type_sp) {317 // Since this type is defined in one of the Clang modules imported318 // by this symbol file, search all of them. Instead of calling319 // sym_file->FindTypes(), which would return this again, go straight320 // to the imported modules.321 auto &sym_file = die.GetCU()->GetSymbolFileDWARF();322 323 // Well-formed clang modules never form cycles; guard against corrupted324 // ones by inserting the current file.325 results.AlreadySearched(&sym_file);326 sym_file.ForEachExternalModule(327 *sc.comp_unit, results.GetSearchedSymbolFiles(), [&](Module &module) {328 module.FindTypes(query, results);329 pcm_type_sp = results.GetTypeMap().FirstType();330 return (bool)pcm_type_sp;331 });332 }333 334 if (!pcm_type_sp)335 return TypeSP();336 337 // We found a real definition for this type in the Clang module, so lets use338 // it and cache the fact that we found a complete type for this die.339 lldb_private::CompilerType pcm_type = pcm_type_sp->GetForwardCompilerType();340 lldb_private::CompilerType type =341 GetClangASTImporter().CopyType(m_ast, pcm_type);342 343 if (!type)344 return TypeSP();345 346 // Under normal operation pcm_type is a shallow forward declaration347 // that gets completed later. This is necessary to support cyclic348 // data structures. If, however, pcm_type is already complete (for349 // example, because it was loaded for a different target before),350 // the definition needs to be imported right away, too.351 // Type::ResolveClangType() effectively ignores the ResolveState352 // inside type_sp and only looks at IsDefined(), so it never calls353 // ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(),354 // which does extra work for Objective-C classes. This would result355 // in only the forward declaration to be visible.356 if (pcm_type.IsDefined())357 GetClangASTImporter().RequireCompleteType(ClangUtil::GetQualType(type));358 359 SymbolFileDWARF *dwarf = die.GetDWARF();360 auto type_sp = dwarf->MakeType(361 die.GetID(), pcm_type_sp->GetName(),362 llvm::expectedToOptional(pcm_type_sp->GetByteSize(nullptr)), nullptr,363 LLDB_INVALID_UID, Type::eEncodingInvalid, &pcm_type_sp->GetDeclaration(),364 type, Type::ResolveState::Forward,365 TypePayloadClang(GetOwningClangModule(die)));366 clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);367 if (tag_decl) {368 LinkDeclContextToDIE(tag_decl, die);369 } else {370 clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);371 if (defn_decl_ctx)372 LinkDeclContextToDIE(defn_decl_ctx, die);373 }374 375 return type_sp;376}377 378/// This function ensures we are able to add members (nested types, functions,379/// etc.) to this type. It does so by starting its definition even if one cannot380/// be found in the debug info. This means the type may need to be "forcibly381/// completed" later -- see CompleteTypeFromDWARF).382static void PrepareContextToReceiveMembers(TypeSystemClang &ast,383 ClangASTImporter &ast_importer,384 clang::DeclContext *decl_ctx,385 DWARFDIE die,386 const char *type_name_cstr) {387 auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);388 if (!tag_decl_ctx)389 return; // Non-tag context are always ready.390 391 // We have already completed the type or it is already prepared.392 if (tag_decl_ctx->isCompleteDefinition() || tag_decl_ctx->isBeingDefined())393 return;394 395 // If this tag was imported from another AST context (in the gmodules case),396 // we can complete the type by doing a full import.397 398 // If this type was not imported from an external AST, there's nothing to do.399 CompilerType type = ast.GetTypeForDecl(tag_decl_ctx);400 if (type && ast_importer.CanImport(type)) {401 auto qual_type = ClangUtil::GetQualType(type);402 if (ast_importer.RequireCompleteType(qual_type))403 return;404 die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(405 "Unable to complete the Decl context for DIE {0} at offset "406 "{1:x16}.\nPlease file a bug report.",407 type_name_cstr ? type_name_cstr : "", die.GetOffset());408 }409 410 // We don't have a type definition and/or the import failed, but we need to411 // add members to it. Start the definition to make that possible. If the type412 // has no external storage we also have to complete the definition. Otherwise,413 // that will happen when we are asked to complete the type414 // (CompleteTypeFromDWARF).415 ast.StartTagDeclarationDefinition(type);416 if (!tag_decl_ctx->hasExternalLexicalStorage()) {417 ast.SetDeclIsForcefullyCompleted(tag_decl_ctx);418 ast.CompleteTagDeclarationDefinition(type);419 }420}421 422ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {423 DWARFAttributes attributes = die.GetAttributes();424 for (size_t i = 0; i < attributes.Size(); ++i) {425 dw_attr_t attr = attributes.AttributeAtIndex(i);426 DWARFFormValue form_value;427 if (!attributes.ExtractFormValueAtIndex(i, form_value))428 continue;429 switch (attr) {430 default:431 break;432 case DW_AT_abstract_origin:433 abstract_origin = form_value;434 break;435 436 case DW_AT_accessibility:437 accessibility =438 DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned());439 break;440 441 case DW_AT_artificial:442 is_artificial = form_value.Boolean();443 break;444 445 case DW_AT_bit_stride:446 bit_stride = form_value.Unsigned();447 break;448 449 case DW_AT_byte_size:450 byte_size = form_value.Unsigned();451 break;452 453 case DW_AT_bit_size:454 data_bit_size = form_value.Unsigned();455 break;456 457 case DW_AT_alignment:458 alignment = form_value.Unsigned();459 break;460 461 case DW_AT_byte_stride:462 byte_stride = form_value.Unsigned();463 break;464 465 case DW_AT_calling_convention:466 calling_convention = form_value.Unsigned();467 break;468 469 case DW_AT_containing_type:470 containing_type = form_value;471 break;472 473 case DW_AT_decl_file:474 // die.GetCU() can differ if DW_AT_specification uses DW_FORM_ref_addr.475 decl.SetFile(476 attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));477 break;478 case DW_AT_decl_line:479 decl.SetLine(form_value.Unsigned());480 break;481 case DW_AT_decl_column:482 decl.SetColumn(form_value.Unsigned());483 break;484 485 case DW_AT_declaration:486 is_forward_declaration = form_value.Boolean();487 break;488 489 case DW_AT_encoding:490 encoding = form_value.Unsigned();491 break;492 493 case DW_AT_enum_class:494 is_scoped_enum = form_value.Boolean();495 break;496 497 case DW_AT_explicit:498 is_explicit = form_value.Boolean();499 break;500 501 case DW_AT_external:502 if (form_value.Unsigned())503 storage = clang::SC_Extern;504 break;505 506 case DW_AT_inline:507 is_inline = form_value.Boolean();508 break;509 510 case DW_AT_linkage_name:511 case DW_AT_MIPS_linkage_name:512 mangled_name = form_value.AsCString();513 break;514 515 case DW_AT_name:516 name.SetCString(form_value.AsCString());517 break;518 519 case DW_AT_signature:520 signature = form_value;521 break;522 523 case DW_AT_specification:524 specification = form_value;525 break;526 527 case DW_AT_type:528 type = form_value;529 break;530 531 case DW_AT_virtuality:532 is_virtual = form_value.Boolean();533 break;534 535 case DW_AT_APPLE_objc_complete_type:536 is_complete_objc_class = form_value.Signed();537 break;538 539 case DW_AT_APPLE_objc_direct:540 is_objc_direct_call = true;541 break;542 543 case DW_AT_APPLE_runtime_class:544 class_language = (LanguageType)form_value.Signed();545 break;546 547 case DW_AT_GNU_vector:548 is_vector = form_value.Boolean();549 break;550 case DW_AT_export_symbols:551 exports_symbols = form_value.Boolean();552 break;553 case DW_AT_rvalue_reference:554 ref_qual = clang::RQ_RValue;555 break;556 case DW_AT_reference:557 ref_qual = clang::RQ_LValue;558 break;559 case DW_AT_APPLE_enum_kind:560 enum_kind = static_cast<clang::EnumExtensibilityAttr::Kind>(561 form_value.Unsigned());562 break;563 }564 }565}566 567static std::string GetUnitName(const DWARFDIE &die) {568 if (DWARFUnit *unit = die.GetCU())569 return unit->GetAbsolutePath().GetPath();570 return "<missing DWARF unit path>";571}572 573TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,574 const DWARFDIE &die,575 bool *type_is_new_ptr) {576 if (type_is_new_ptr)577 *type_is_new_ptr = false;578 579 if (!die)580 return nullptr;581 582 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);583 584 SymbolFileDWARF *dwarf = die.GetDWARF();585 if (log) {586 DWARFDIE context_die;587 clang::DeclContext *context =588 GetClangDeclContextContainingDIE(die, &context_die);589 590 dwarf->GetObjectFile()->GetModule()->LogMessage(591 log,592 "DWARFASTParserClang::ParseTypeFromDWARF "593 "(die = {0:x16}, decl_ctx = {1:p} (die "594 "{2:x16})) {3} ({4}) name = '{5}')",595 die.GetOffset(), static_cast<void *>(context), context_die.GetOffset(),596 DW_TAG_value_to_name(die.Tag()), die.Tag(), die.GetName());597 }598 599 // Set a bit that lets us know that we are currently parsing this600 if (auto [it, inserted] =601 dwarf->GetDIEToType().try_emplace(die.GetDIE(), DIE_IS_BEING_PARSED);602 !inserted) {603 if (it->getSecond() == nullptr || it->getSecond() == DIE_IS_BEING_PARSED)604 return nullptr;605 return it->getSecond()->shared_from_this();606 }607 608 ParsedDWARFTypeAttributes attrs(die);609 610 TypeSP type_sp;611 if (DWARFDIE signature_die = attrs.signature.Reference()) {612 type_sp = ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr);613 if (type_sp) {614 if (clang::DeclContext *decl_ctx =615 GetCachedClangDeclContextForDIE(signature_die))616 LinkDeclContextToDIE(decl_ctx, die);617 }618 } else {619 if (type_is_new_ptr)620 *type_is_new_ptr = true;621 622 const dw_tag_t tag = die.Tag();623 624 switch (tag) {625 case DW_TAG_typedef:626 case DW_TAG_base_type:627 case DW_TAG_pointer_type:628 case DW_TAG_reference_type:629 case DW_TAG_rvalue_reference_type:630 case DW_TAG_const_type:631 case DW_TAG_restrict_type:632 case DW_TAG_volatile_type:633 case DW_TAG_LLVM_ptrauth_type:634 case DW_TAG_atomic_type:635 case DW_TAG_unspecified_type:636 type_sp = ParseTypeModifier(sc, die, attrs);637 break;638 case DW_TAG_structure_type:639 case DW_TAG_union_type:640 case DW_TAG_class_type:641 type_sp = ParseStructureLikeDIE(sc, die, attrs);642 break;643 case DW_TAG_enumeration_type:644 type_sp = ParseEnum(sc, die, attrs);645 break;646 case DW_TAG_inlined_subroutine:647 case DW_TAG_subprogram:648 case DW_TAG_subroutine_type:649 type_sp = ParseSubroutine(die, attrs);650 break;651 case DW_TAG_array_type:652 type_sp = ParseArrayType(die, attrs);653 break;654 case DW_TAG_ptr_to_member_type:655 type_sp = ParsePointerToMemberType(die, attrs);656 break;657 default:658 dwarf->GetObjectFile()->GetModule()->ReportError(659 "[{0:x16}]: unhandled type tag {1:x4} ({2}), "660 "please file a bug and "661 "attach the file at the start of this error message",662 die.GetOffset(), tag, DW_TAG_value_to_name(tag));663 break;664 }665 UpdateSymbolContextScopeForType(sc, die, type_sp);666 }667 if (type_sp) {668 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();669 }670 return type_sp;671}672 673static std::optional<uint32_t>674ExtractDataMemberLocation(DWARFDIE const &die, DWARFFormValue const &form_value,675 ModuleSP module_sp) {676 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);677 678 // With DWARF 3 and later, if the value is an integer constant,679 // this form value is the offset in bytes from the beginning of680 // the containing entity.681 if (!form_value.BlockData())682 return form_value.Unsigned();683 684 Value initialValue(0);685 const DWARFDataExtractor &debug_info_data = die.GetData();686 uint32_t block_length = form_value.Unsigned();687 uint32_t block_offset =688 form_value.BlockData() - debug_info_data.GetDataStart();689 690 llvm::Expected<Value> memberOffset = DWARFExpression::Evaluate(691 /*ExecutionContext=*/nullptr,692 /*RegisterContext=*/nullptr, module_sp,693 DataExtractor(debug_info_data, block_offset, block_length), die.GetCU(),694 eRegisterKindDWARF, &initialValue, nullptr);695 if (!memberOffset) {696 LLDB_LOG_ERROR(log, memberOffset.takeError(),697 "ExtractDataMemberLocation failed: {0}");698 return {};699 }700 701 return memberOffset->ResolveValue(nullptr).UInt();702}703 704static TypePayloadClang GetPtrAuthMofidierPayload(const DWARFDIE &die) {705 auto getAttr = [&](llvm::dwarf::Attribute Attr, unsigned defaultValue = 0) {706 return die.GetAttributeValueAsUnsigned(Attr, defaultValue);707 };708 const unsigned key = getAttr(DW_AT_LLVM_ptrauth_key);709 const bool addr_disc = getAttr(DW_AT_LLVM_ptrauth_address_discriminated);710 const unsigned extra = getAttr(DW_AT_LLVM_ptrauth_extra_discriminator);711 const bool isapointer = getAttr(DW_AT_LLVM_ptrauth_isa_pointer);712 const bool authenticates_null_values =713 getAttr(DW_AT_LLVM_ptrauth_authenticates_null_values);714 const unsigned authentication_mode_int = getAttr(715 DW_AT_LLVM_ptrauth_authentication_mode,716 static_cast<unsigned>(clang::PointerAuthenticationMode::SignAndAuth));717 clang::PointerAuthenticationMode authentication_mode =718 clang::PointerAuthenticationMode::SignAndAuth;719 if (authentication_mode_int >=720 static_cast<unsigned>(clang::PointerAuthenticationMode::None) &&721 authentication_mode_int <=722 static_cast<unsigned>(723 clang::PointerAuthenticationMode::SignAndAuth)) {724 authentication_mode =725 static_cast<clang::PointerAuthenticationMode>(authentication_mode_int);726 } else {727 die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(728 "[{0:x16}]: invalid pointer authentication mode method {1:x4}",729 die.GetOffset(), authentication_mode_int);730 }731 auto ptr_auth = clang::PointerAuthQualifier::Create(732 key, addr_disc, extra, authentication_mode, isapointer,733 authenticates_null_values);734 return TypePayloadClang(ptr_auth.getAsOpaqueValue());735}736 737lldb::TypeSP738DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,739 const DWARFDIE &die,740 ParsedDWARFTypeAttributes &attrs) {741 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);742 SymbolFileDWARF *dwarf = die.GetDWARF();743 const dw_tag_t tag = die.Tag();744 LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());745 Type::ResolveState resolve_state = Type::ResolveState::Unresolved;746 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;747 TypePayloadClang payload(GetOwningClangModule(die));748 TypeSP type_sp;749 CompilerType clang_type;750 751 if (tag == DW_TAG_typedef) {752 // DeclContext will be populated when the clang type is materialized in753 // Type::ResolveCompilerType.754 PrepareContextToReceiveMembers(755 m_ast, GetClangASTImporter(),756 GetClangDeclContextContainingDIE(die, nullptr), die,757 attrs.name.GetCString());758 759 if (attrs.type.IsValid()) {760 // Try to parse a typedef from the (DWARF embedded in the) Clang761 // module file first as modules can contain typedef'ed762 // structures that have no names like:763 //764 // typedef struct { int a; } Foo;765 //766 // In this case we will have a structure with no name and a767 // typedef named "Foo" that points to this unnamed768 // structure. The name in the typedef is the only identifier for769 // the struct, so always try to get typedefs from Clang modules770 // if possible.771 //772 // The type_sp returned will be empty if the typedef doesn't773 // exist in a module file, so it is cheap to call this function774 // just to check.775 //776 // If we don't do this we end up creating a TypeSP that says777 // this is a typedef to type 0x123 (the DW_AT_type value would778 // be 0x123 in the DW_TAG_typedef), and this is the unnamed779 // structure type. We will have a hard time tracking down an780 // unnammed structure type in the module debug info, so we make781 // sure we don't get into this situation by always resolving782 // typedefs from the module.783 const DWARFDIE encoding_die = attrs.type.Reference();784 785 // First make sure that the die that this is typedef'ed to _is_786 // just a declaration (DW_AT_declaration == 1), not a full787 // definition since template types can't be represented in788 // modules since only concrete instances of templates are ever789 // emitted and modules won't contain those790 if (encoding_die &&791 encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {792 type_sp = ParseTypeFromClangModule(sc, die, log);793 if (type_sp)794 return type_sp;795 }796 }797 }798 799 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(),800 DW_TAG_value_to_name(tag), type_name_cstr,801 encoding_uid.Reference());802 803 switch (tag) {804 default:805 break;806 807 case DW_TAG_unspecified_type:808 if (attrs.name == "nullptr_t" || attrs.name == "decltype(nullptr)") {809 resolve_state = Type::ResolveState::Full;810 clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);811 break;812 }813 // Fall through to base type below in case we can handle the type814 // there...815 [[fallthrough]];816 817 case DW_TAG_base_type: {818 resolve_state = Type::ResolveState::Full;819 // If a builtin type's size isn't a multiple of a byte, DWARF producers may820 // add a precise bit-size to the type. Use the most precise bit-size821 // possible.822 const uint64_t bit_size = attrs.data_bit_size823 ? *attrs.data_bit_size824 : attrs.byte_size.value_or(0) * 8;825 clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(826 attrs.name.GetStringRef(), attrs.encoding, bit_size);827 break;828 }829 case DW_TAG_pointer_type:830 encoding_data_type = Type::eEncodingIsPointerUID;831 break;832 case DW_TAG_reference_type:833 encoding_data_type = Type::eEncodingIsLValueReferenceUID;834 break;835 case DW_TAG_rvalue_reference_type:836 encoding_data_type = Type::eEncodingIsRValueReferenceUID;837 break;838 case DW_TAG_typedef:839 encoding_data_type = Type::eEncodingIsTypedefUID;840 break;841 case DW_TAG_const_type:842 encoding_data_type = Type::eEncodingIsConstUID;843 break;844 case DW_TAG_restrict_type:845 encoding_data_type = Type::eEncodingIsRestrictUID;846 break;847 case DW_TAG_volatile_type:848 encoding_data_type = Type::eEncodingIsVolatileUID;849 break;850 case DW_TAG_LLVM_ptrauth_type:851 encoding_data_type = Type::eEncodingIsLLVMPtrAuthUID;852 payload = GetPtrAuthMofidierPayload(die);853 break;854 case DW_TAG_atomic_type:855 encoding_data_type = Type::eEncodingIsAtomicUID;856 break;857 }858 859 if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID ||860 encoding_data_type == Type::eEncodingIsTypedefUID)) {861 if (tag == DW_TAG_pointer_type) {862 DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);863 864 if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {865 // Blocks have a __FuncPtr inside them which is a pointer to a866 // function of the proper type.867 868 for (DWARFDIE child_die : target_die.children()) {869 if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),870 "__FuncPtr")) {871 DWARFDIE function_pointer_type =872 child_die.GetReferencedDIE(DW_AT_type);873 874 if (function_pointer_type) {875 DWARFDIE function_type =876 function_pointer_type.GetReferencedDIE(DW_AT_type);877 878 bool function_type_is_new_pointer;879 TypeSP lldb_function_type_sp = ParseTypeFromDWARF(880 sc, function_type, &function_type_is_new_pointer);881 882 if (lldb_function_type_sp) {883 clang_type = m_ast.CreateBlockPointerType(884 lldb_function_type_sp->GetForwardCompilerType());885 encoding_data_type = Type::eEncodingIsUID;886 attrs.type.Clear();887 resolve_state = Type::ResolveState::Full;888 }889 }890 891 break;892 }893 }894 }895 }896 897 if (cu_language == eLanguageTypeObjC ||898 cu_language == eLanguageTypeObjC_plus_plus) {899 if (attrs.name) {900 if (attrs.name == "id") {901 if (log)902 dwarf->GetObjectFile()->GetModule()->LogMessage(903 log,904 "SymbolFileDWARF::ParseType (die = {0:x16}) {1} ({2}) '{3}' "905 "is Objective-C 'id' built-in type.",906 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),907 die.GetName());908 clang_type = m_ast.GetBasicType(eBasicTypeObjCID);909 encoding_data_type = Type::eEncodingIsUID;910 attrs.type.Clear();911 resolve_state = Type::ResolveState::Full;912 } else if (attrs.name == "Class") {913 if (log)914 dwarf->GetObjectFile()->GetModule()->LogMessage(915 log,916 "SymbolFileDWARF::ParseType (die = {0:x16}) {1} ({2}) '{3}' "917 "is Objective-C 'Class' built-in type.",918 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),919 die.GetName());920 clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);921 encoding_data_type = Type::eEncodingIsUID;922 attrs.type.Clear();923 resolve_state = Type::ResolveState::Full;924 } else if (attrs.name == "SEL") {925 if (log)926 dwarf->GetObjectFile()->GetModule()->LogMessage(927 log,928 "SymbolFileDWARF::ParseType (die = {0:x16}) {1} ({2}) '{3}' "929 "is Objective-C 'selector' built-in type.",930 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),931 die.GetName());932 clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);933 encoding_data_type = Type::eEncodingIsUID;934 attrs.type.Clear();935 resolve_state = Type::ResolveState::Full;936 }937 } else if (encoding_data_type == Type::eEncodingIsPointerUID &&938 attrs.type.IsValid()) {939 // Clang sometimes erroneously emits id as objc_object*. In that940 // case we fix up the type to "id".941 942 const DWARFDIE encoding_die = attrs.type.Reference();943 944 if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {945 llvm::StringRef struct_name = encoding_die.GetName();946 if (struct_name == "objc_object") {947 if (log)948 dwarf->GetObjectFile()->GetModule()->LogMessage(949 log,950 "SymbolFileDWARF::ParseType (die = {0:x16}) {1} ({2}) '{3}' "951 "is 'objc_object*', which we overrode to 'id'.",952 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),953 die.GetName());954 clang_type = m_ast.GetBasicType(eBasicTypeObjCID);955 encoding_data_type = Type::eEncodingIsUID;956 attrs.type.Clear();957 resolve_state = Type::ResolveState::Full;958 }959 }960 }961 }962 }963 964 return dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,965 attrs.type.Reference().GetID(), encoding_data_type,966 &attrs.decl, clang_type, resolve_state, payload);967}968 969std::string DWARFASTParserClang::GetDIEClassTemplateParams(DWARFDIE die) {970 if (DWARFDIE signature_die = die.GetReferencedDIE(DW_AT_signature))971 die = signature_die;972 973 if (llvm::StringRef(die.GetName()).contains("<"))974 return {};975 976 std::string name;977 llvm::raw_string_ostream os(name);978 llvm::DWARFTypePrinter<DWARFDIE> type_printer(os);979 type_printer.appendAndTerminateTemplateParameters(die);980 return name;981}982 983void DWARFASTParserClang::MapDeclDIEToDefDIE(984 const lldb_private::plugin::dwarf::DWARFDIE &decl_die,985 const lldb_private::plugin::dwarf::DWARFDIE &def_die) {986 LinkDeclContextToDIE(GetCachedClangDeclContextForDIE(decl_die), def_die);987 SymbolFileDWARF *dwarf = def_die.GetDWARF();988 ParsedDWARFTypeAttributes decl_attrs(decl_die);989 ParsedDWARFTypeAttributes def_attrs(def_die);990 ConstString unique_typename(decl_attrs.name);991 Declaration decl_declaration(decl_attrs.decl);992 GetUniqueTypeNameAndDeclaration(993 decl_die, SymbolFileDWARF::GetLanguage(*decl_die.GetCU()),994 unique_typename, decl_declaration);995 if (UniqueDWARFASTType *unique_ast_entry_type =996 dwarf->GetUniqueDWARFASTTypeMap().Find(997 unique_typename, decl_die, decl_declaration,998 decl_attrs.byte_size.value_or(0),999 decl_attrs.is_forward_declaration)) {1000 unique_ast_entry_type->UpdateToDefDIE(def_die, def_attrs.decl,1001 def_attrs.byte_size.value_or(0));1002 } else if (Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups)) {1003 const dw_tag_t tag = decl_die.Tag();1004 LLDB_LOG(log,1005 "Failed to find {0:x16} {1} ({2}) type \"{3}\" in "1006 "UniqueDWARFASTTypeMap",1007 decl_die.GetID(), DW_TAG_value_to_name(tag), tag, unique_typename);1008 }1009}1010 1011TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,1012 const DWARFDIE &decl_die,1013 ParsedDWARFTypeAttributes &attrs) {1014 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);1015 SymbolFileDWARF *dwarf = decl_die.GetDWARF();1016 const dw_tag_t tag = decl_die.Tag();1017 1018 DWARFDIE def_die;1019 if (attrs.is_forward_declaration) {1020 if (TypeSP type_sp = ParseTypeFromClangModule(sc, decl_die, log))1021 return type_sp;1022 1023 def_die = dwarf->FindDefinitionDIE(decl_die);1024 1025 if (!def_die) {1026 SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();1027 if (debug_map_symfile) {1028 // We weren't able to find a full declaration in this DWARF,1029 // see if we have a declaration anywhere else...1030 def_die = debug_map_symfile->FindDefinitionDIE(decl_die);1031 }1032 }1033 1034 if (log) {1035 dwarf->GetObjectFile()->GetModule()->LogMessage(1036 log,1037 "SymbolFileDWARF({0:p}) - {1:x16}}: {2} ({3}) type \"{4}\" is a "1038 "forward declaration, complete DIE is {5}",1039 static_cast<void *>(this), decl_die.GetID(), DW_TAG_value_to_name(tag),1040 tag, attrs.name.GetCString(),1041 def_die ? llvm::utohexstr(def_die.GetID()) : "not found");1042 }1043 }1044 if (def_die) {1045 if (auto [it, inserted] = dwarf->GetDIEToType().try_emplace(1046 def_die.GetDIE(), DIE_IS_BEING_PARSED);1047 !inserted) {1048 if (it->getSecond() == nullptr || it->getSecond() == DIE_IS_BEING_PARSED)1049 return nullptr;1050 return it->getSecond()->shared_from_this();1051 }1052 attrs = ParsedDWARFTypeAttributes(def_die);1053 } else {1054 // No definition found. Proceed with the declaration die. We can use it to1055 // create a forward-declared type.1056 def_die = decl_die;1057 }1058 1059 CompilerType enumerator_clang_type;1060 if (attrs.type.IsValid()) {1061 Type *enumerator_type =1062 dwarf->ResolveTypeUID(attrs.type.Reference(), true);1063 if (enumerator_type)1064 enumerator_clang_type = enumerator_type->GetFullCompilerType();1065 }1066 1067 if (!enumerator_clang_type) {1068 if (attrs.byte_size) {1069 enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(1070 "", DW_ATE_signed, *attrs.byte_size * 8);1071 } else {1072 enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);1073 }1074 }1075 1076 CompilerType clang_type = m_ast.CreateEnumerationType(1077 attrs.name.GetStringRef(),1078 GetClangDeclContextContainingDIE(def_die, nullptr),1079 GetOwningClangModule(def_die), attrs.decl, enumerator_clang_type,1080 attrs.is_scoped_enum, attrs.enum_kind);1081 TypeSP type_sp =1082 dwarf->MakeType(def_die.GetID(), attrs.name, attrs.byte_size, nullptr,1083 attrs.type.Reference().GetID(), Type::eEncodingIsUID,1084 &attrs.decl, clang_type, Type::ResolveState::Forward,1085 TypePayloadClang(GetOwningClangModule(def_die)));1086 1087 clang::DeclContext *type_decl_ctx =1088 TypeSystemClang::GetDeclContextForType(clang_type);1089 LinkDeclContextToDIE(type_decl_ctx, decl_die);1090 if (decl_die != def_die) {1091 LinkDeclContextToDIE(type_decl_ctx, def_die);1092 dwarf->GetDIEToType()[def_die.GetDIE()] = type_sp.get();1093 // Declaration DIE is inserted into the type map in ParseTypeFromDWARF1094 }1095 1096 if (!CompleteEnumType(def_die, type_sp.get(), clang_type)) {1097 dwarf->GetObjectFile()->GetModule()->ReportError(1098 "DWARF DIE at {0:x16} named \"{1}\" was not able to start its "1099 "definition.\nPlease file a bug and attach the file at the "1100 "start of this error message",1101 def_die.GetOffset(), attrs.name.GetCString());1102 }1103 return type_sp;1104}1105 1106static clang::CallingConv1107ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes &attrs) {1108 switch (attrs.calling_convention) {1109 case llvm::dwarf::DW_CC_normal:1110 return clang::CC_C;1111 case llvm::dwarf::DW_CC_BORLAND_stdcall:1112 return clang::CC_X86StdCall;1113 case llvm::dwarf::DW_CC_BORLAND_msfastcall:1114 return clang::CC_X86FastCall;1115 case llvm::dwarf::DW_CC_LLVM_vectorcall:1116 return clang::CC_X86VectorCall;1117 case llvm::dwarf::DW_CC_BORLAND_pascal:1118 return clang::CC_X86Pascal;1119 case llvm::dwarf::DW_CC_LLVM_Win64:1120 return clang::CC_Win64;1121 case llvm::dwarf::DW_CC_LLVM_X86_64SysV:1122 return clang::CC_X86_64SysV;1123 case llvm::dwarf::DW_CC_LLVM_X86RegCall:1124 return clang::CC_X86RegCall;1125 default:1126 break;1127 }1128 1129 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);1130 LLDB_LOG(log, "Unsupported DW_AT_calling_convention value: {0}",1131 attrs.calling_convention);1132 // Use the default calling convention as a fallback.1133 return clang::CC_C;1134}1135 1136bool DWARFASTParserClang::ParseObjCMethod(1137 const ObjCLanguage::ObjCMethodName &objc_method, const DWARFDIE &die,1138 CompilerType clang_type, const ParsedDWARFTypeAttributes &attrs,1139 bool is_variadic) {1140 SymbolFileDWARF *dwarf = die.GetDWARF();1141 assert(dwarf);1142 1143 const auto tag = die.Tag();1144 ConstString class_name(objc_method.GetClassName());1145 if (!class_name)1146 return false;1147 1148 TypeSP complete_objc_class_type_sp =1149 dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name,1150 false);1151 1152 if (!complete_objc_class_type_sp)1153 return false;1154 1155 CompilerType type_clang_forward_type =1156 complete_objc_class_type_sp->GetForwardCompilerType();1157 1158 if (!type_clang_forward_type)1159 return false;1160 1161 if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type))1162 return false;1163 1164 clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType(1165 type_clang_forward_type, attrs.name.GetCString(), clang_type,1166 attrs.is_artificial, is_variadic, attrs.is_objc_direct_call);1167 1168 if (!objc_method_decl) {1169 dwarf->GetObjectFile()->GetModule()->ReportError(1170 "[{0:x16}]: invalid Objective-C method {1:x4} ({2}), "1171 "please file a bug and attach the file at the start of "1172 "this error message",1173 die.GetOffset(), tag, DW_TAG_value_to_name(tag));1174 return false;1175 }1176 1177 LinkDeclContextToDIE(objc_method_decl, die);1178 m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());1179 1180 return true;1181}1182 1183std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod(1184 const DWARFDIE &die, CompilerType clang_type,1185 const ParsedDWARFTypeAttributes &attrs, const DWARFDIE &decl_ctx_die,1186 const DWARFDIE &object_parameter, bool &ignore_containing_context) {1187 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);1188 SymbolFileDWARF *dwarf = die.GetDWARF();1189 assert(dwarf);1190 1191 Type *class_type = dwarf->ResolveType(decl_ctx_die);1192 if (!class_type)1193 return {};1194 1195 if (class_type->GetID() != decl_ctx_die.GetID() ||1196 IsClangModuleFwdDecl(decl_ctx_die)) {1197 1198 // We uniqued the parent class of this function to another1199 // class so we now need to associate all dies under1200 // "decl_ctx_die" to DIEs in the DIE for "class_type"...1201 if (DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID())) {1202 std::vector<DWARFDIE> failures;1203 1204 CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type,1205 failures);1206 1207 // FIXME do something with these failures that's1208 // smarter than just dropping them on the ground.1209 // Unfortunately classes don't like having stuff added1210 // to them after their definitions are complete...1211 1212 Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());1213 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)1214 return {true, type_ptr->shared_from_this()};1215 }1216 }1217 1218 if (attrs.specification.IsValid()) {1219 // We have a specification which we are going to base our1220 // function prototype off of, so we need this type to be1221 // completed so that the m_die_to_decl_ctx for the method in1222 // the specification has a valid clang decl context.1223 class_type->GetForwardCompilerType();1224 // If we have a specification, then the function type should1225 // have been made with the specification and not with this1226 // die.1227 DWARFDIE spec_die = attrs.specification.Reference();1228 clang::DeclContext *spec_clang_decl_ctx =1229 GetClangDeclContextForDIE(spec_die);1230 if (spec_clang_decl_ctx)1231 LinkDeclContextToDIE(spec_clang_decl_ctx, die);1232 else1233 dwarf->GetObjectFile()->GetModule()->ReportWarning(1234 "{0:x8}: DW_AT_specification({1:x16}"1235 ") has no decl\n",1236 die.GetID(), spec_die.GetOffset());1237 1238 return {true, nullptr};1239 }1240 1241 if (attrs.abstract_origin.IsValid()) {1242 // We have a specification which we are going to base our1243 // function prototype off of, so we need this type to be1244 // completed so that the m_die_to_decl_ctx for the method in1245 // the abstract origin has a valid clang decl context.1246 class_type->GetForwardCompilerType();1247 1248 DWARFDIE abs_die = attrs.abstract_origin.Reference();1249 clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE(abs_die);1250 if (abs_clang_decl_ctx)1251 LinkDeclContextToDIE(abs_clang_decl_ctx, die);1252 else1253 dwarf->GetObjectFile()->GetModule()->ReportWarning(1254 "{0:x8}: DW_AT_abstract_origin({1:x16}"1255 ") has no decl\n",1256 die.GetID(), abs_die.GetOffset());1257 1258 return {true, nullptr};1259 }1260 1261 CompilerType class_opaque_type = class_type->GetForwardCompilerType();1262 if (!TypeSystemClang::IsCXXClassType(class_opaque_type))1263 return {};1264 1265 PrepareContextToReceiveMembers(1266 m_ast, GetClangASTImporter(),1267 TypeSystemClang::GetDeclContextForType(class_opaque_type), die,1268 attrs.name.GetCString());1269 1270 // In DWARF, a C++ method is static if it has no object parameter child.1271 const bool is_static = !object_parameter.IsValid();1272 1273 // We have a C++ member function with no children (this pointer!) and clang1274 // will get mad if we try and make a function that isn't well formed in the1275 // DWARF, so we will just skip it...1276 if (!is_static && !die.HasChildren())1277 return {true, nullptr};1278 1279 const bool is_attr_used = false;1280 // Neither GCC 4.2 nor clang++ currently set a valid1281 // accessibility in the DWARF for C++ methods...1282 // Default to public for now...1283 const auto accessibility =1284 attrs.accessibility == eAccessNone ? eAccessPublic : attrs.accessibility;1285 1286 clang::CXXMethodDecl *cxx_method_decl = m_ast.AddMethodToCXXRecordType(1287 class_opaque_type.GetOpaqueQualType(), attrs.name.GetCString(),1288 MakeLLDBFuncAsmLabel(die), clang_type, accessibility, attrs.is_virtual,1289 is_static, attrs.is_inline, attrs.is_explicit, is_attr_used,1290 attrs.is_artificial);1291 1292 if (cxx_method_decl) {1293 LinkDeclContextToDIE(cxx_method_decl, die);1294 1295 ClangASTMetadata metadata;1296 metadata.SetUserID(die.GetID());1297 1298 if (char const *object_pointer_name = object_parameter.GetName()) {1299 metadata.SetObjectPtrName(object_pointer_name);1300 LLDB_LOGF(log, "Setting object pointer name: %s on method object %p.\n",1301 object_pointer_name, static_cast<void *>(cxx_method_decl));1302 }1303 m_ast.SetMetadata(cxx_method_decl, metadata);1304 } else {1305 ignore_containing_context = true;1306 }1307 1308 // Artificial methods are always handled even when we1309 // don't create a new declaration for them.1310 const bool type_handled = cxx_method_decl != nullptr || attrs.is_artificial;1311 1312 return {type_handled, nullptr};1313}1314 1315TypeSP1316DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,1317 const ParsedDWARFTypeAttributes &attrs) {1318 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);1319 1320 SymbolFileDWARF *dwarf = die.GetDWARF();1321 const dw_tag_t tag = die.Tag();1322 1323 bool is_variadic = false;1324 bool has_template_params = false;1325 1326 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),1327 DW_TAG_value_to_name(tag), type_name_cstr);1328 1329 CompilerType return_clang_type;1330 Type *func_type = nullptr;1331 1332 if (attrs.type.IsValid())1333 func_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);1334 1335 if (func_type)1336 return_clang_type = func_type->GetForwardCompilerType();1337 else1338 return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);1339 1340 std::vector<CompilerType> function_param_types;1341 llvm::SmallVector<llvm::StringRef> function_param_names;1342 1343 // Parse the function children for the parameters1344 1345 DWARFDIE decl_ctx_die;1346 clang::DeclContext *containing_decl_ctx =1347 GetClangDeclContextContainingDIE(die, &decl_ctx_die);1348 assert(containing_decl_ctx);1349 1350 if (die.HasChildren()) {1351 ParseChildParameters(containing_decl_ctx, die, is_variadic,1352 has_template_params, function_param_types,1353 function_param_names);1354 }1355 1356 bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());1357 bool ignore_containing_context = false;1358 // Check for templatized class member functions. If we had any1359 // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter1360 // the DW_TAG_subprogram DIE, then we can't let this become a method in1361 // a class. Why? Because templatized functions are only emitted if one1362 // of the templatized methods is used in the current compile unit and1363 // we will end up with classes that may or may not include these member1364 // functions and this means one class won't match another class1365 // definition and it affects our ability to use a class in the clang1366 // expression parser. So for the greater good, we currently must not1367 // allow any template member functions in a class definition.1368 if (is_cxx_method && has_template_params) {1369 ignore_containing_context = true;1370 is_cxx_method = false;1371 }1372 1373 clang::CallingConv calling_convention =1374 ConvertDWARFCallingConventionToClang(attrs);1375 1376 const DWARFDIE object_parameter = GetObjectParameter(die, decl_ctx_die);1377 1378 // clang_type will get the function prototype clang type after this1379 // call1380 CompilerType clang_type = m_ast.CreateFunctionType(1381 return_clang_type, function_param_types, is_variadic,1382 GetCXXMethodCVQuals(die, object_parameter), calling_convention,1383 attrs.ref_qual);1384 1385 if (attrs.name) {1386 bool type_handled = false;1387 if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {1388 if (std::optional<const ObjCLanguage::ObjCMethodName> objc_method =1389 ObjCLanguage::ObjCMethodName::Create(attrs.name.GetStringRef(),1390 true)) {1391 type_handled =1392 ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic);1393 } else if (is_cxx_method) {1394 auto [handled, type_sp] =1395 ParseCXXMethod(die, clang_type, attrs, decl_ctx_die,1396 object_parameter, ignore_containing_context);1397 if (type_sp)1398 return type_sp;1399 1400 type_handled = handled;1401 }1402 }1403 1404 if (!type_handled) {1405 clang::FunctionDecl *function_decl = nullptr;1406 clang::FunctionDecl *template_function_decl = nullptr;1407 1408 if (attrs.abstract_origin.IsValid()) {1409 DWARFDIE abs_die = attrs.abstract_origin.Reference();1410 1411 if (dwarf->ResolveType(abs_die)) {1412 function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(1413 GetCachedClangDeclContextForDIE(abs_die));1414 1415 if (function_decl) {1416 LinkDeclContextToDIE(function_decl, die);1417 }1418 }1419 }1420 1421 if (!function_decl) {1422 char *name_buf = nullptr;1423 llvm::StringRef name = attrs.name.GetStringRef();1424 1425 // We currently generate function templates with template parameters in1426 // their name. In order to get closer to the AST that clang generates1427 // we want to strip these from the name when creating the AST.1428 if (attrs.mangled_name) {1429 llvm::ItaniumPartialDemangler D;1430 if (!D.partialDemangle(attrs.mangled_name)) {1431 name_buf = D.getFunctionBaseName(nullptr, nullptr);1432 name = name_buf;1433 }1434 }1435 1436 // We just have a function that isn't part of a class1437 function_decl = m_ast.CreateFunctionDeclaration(1438 ignore_containing_context ? m_ast.GetTranslationUnitDecl()1439 : containing_decl_ctx,1440 GetOwningClangModule(die), name, clang_type, attrs.storage,1441 attrs.is_inline, MakeLLDBFuncAsmLabel(die));1442 std::free(name_buf);1443 1444 if (has_template_params) {1445 TypeSystemClang::TemplateParameterInfos template_param_infos;1446 ParseTemplateParameterInfos(die, template_param_infos);1447 template_function_decl = m_ast.CreateFunctionDeclaration(1448 ignore_containing_context ? m_ast.GetTranslationUnitDecl()1449 : containing_decl_ctx,1450 GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type,1451 attrs.storage, attrs.is_inline, /*asm_label=*/{});1452 clang::FunctionTemplateDecl *func_template_decl =1453 m_ast.CreateFunctionTemplateDecl(1454 containing_decl_ctx, GetOwningClangModule(die),1455 template_function_decl, template_param_infos);1456 m_ast.CreateFunctionTemplateSpecializationInfo(1457 template_function_decl, func_template_decl, template_param_infos);1458 }1459 1460 lldbassert(function_decl);1461 1462 if (function_decl) {1463 LinkDeclContextToDIE(function_decl, die);1464 1465 const clang::FunctionProtoType *function_prototype(1466 llvm::cast<clang::FunctionProtoType>(1467 ClangUtil::GetQualType(clang_type).getTypePtr()));1468 const auto params = m_ast.CreateParameterDeclarations(1469 function_decl, *function_prototype, function_param_names);1470 function_decl->setParams(params);1471 if (template_function_decl)1472 template_function_decl->setParams(params);1473 1474 ClangASTMetadata metadata;1475 metadata.SetUserID(die.GetID());1476 1477 if (char const *object_pointer_name = object_parameter.GetName()) {1478 metadata.SetObjectPtrName(object_pointer_name);1479 LLDB_LOGF(log,1480 "Setting object pointer name: %s on function "1481 "object %p.",1482 object_pointer_name, static_cast<void *>(function_decl));1483 }1484 m_ast.SetMetadata(function_decl, metadata);1485 }1486 }1487 }1488 }1489 return dwarf->MakeType(1490 die.GetID(), attrs.name, std::nullopt, nullptr, LLDB_INVALID_UID,1491 Type::eEncodingIsUID, &attrs.decl, clang_type, Type::ResolveState::Full);1492}1493 1494TypeSP1495DWARFASTParserClang::ParseArrayType(const DWARFDIE &die,1496 const ParsedDWARFTypeAttributes &attrs) {1497 SymbolFileDWARF *dwarf = die.GetDWARF();1498 1499 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),1500 DW_TAG_value_to_name(tag), type_name_cstr);1501 1502 DWARFDIE type_die = attrs.type.Reference();1503 Type *element_type = dwarf->ResolveTypeUID(type_die, true);1504 1505 if (!element_type)1506 return nullptr;1507 1508 std::optional<SymbolFile::ArrayInfo> array_info = ParseChildArrayInfo(die);1509 uint32_t byte_stride = attrs.byte_stride;1510 uint32_t bit_stride = attrs.bit_stride;1511 if (array_info) {1512 byte_stride = array_info->byte_stride;1513 bit_stride = array_info->bit_stride;1514 }1515 if (byte_stride == 0 && bit_stride == 0)1516 byte_stride = llvm::expectedToOptional(element_type->GetByteSize(nullptr))1517 .value_or(0);1518 CompilerType array_element_type = element_type->GetForwardCompilerType();1519 TypeSystemClang::RequireCompleteType(array_element_type);1520 1521 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;1522 CompilerType clang_type;1523 if (array_info && array_info->element_orders.size() > 0) {1524 auto end = array_info->element_orders.rend();1525 for (auto pos = array_info->element_orders.rbegin(); pos != end; ++pos) {1526 clang_type = m_ast.CreateArrayType(1527 array_element_type, /*element_count=*/*pos, attrs.is_vector);1528 1529 uint64_t num_elements = pos->value_or(0);1530 array_element_type = clang_type;1531 array_element_bit_stride = num_elements1532 ? array_element_bit_stride * num_elements1533 : array_element_bit_stride;1534 }1535 } else {1536 clang_type = m_ast.CreateArrayType(1537 array_element_type, /*element_count=*/std::nullopt, attrs.is_vector);1538 }1539 ConstString empty_name;1540 TypeSP type_sp =1541 dwarf->MakeType(die.GetID(), empty_name, array_element_bit_stride / 8,1542 nullptr, type_die.GetID(), Type::eEncodingIsUID,1543 &attrs.decl, clang_type, Type::ResolveState::Full);1544 type_sp->SetEncodingType(element_type);1545 const clang::Type *type = ClangUtil::GetQualType(clang_type).getTypePtr();1546 m_ast.SetMetadataAsUserID(type, die.GetID());1547 return type_sp;1548}1549 1550TypeSP DWARFASTParserClang::ParsePointerToMemberType(1551 const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs) {1552 SymbolFileDWARF *dwarf = die.GetDWARF();1553 Type *pointee_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);1554 Type *class_type =1555 dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true);1556 1557 // Check to make sure pointers are not NULL before attempting to1558 // dereference them.1559 if ((class_type == nullptr) || (pointee_type == nullptr))1560 return nullptr;1561 1562 CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();1563 CompilerType class_clang_type = class_type->GetForwardCompilerType();1564 1565 CompilerType clang_type = TypeSystemClang::CreateMemberPointerType(1566 class_clang_type, pointee_clang_type);1567 1568 if (std::optional<uint64_t> clang_type_size =1569 llvm::expectedToOptional(clang_type.GetByteSize(nullptr))) {1570 return dwarf->MakeType(die.GetID(), attrs.name, *clang_type_size, nullptr,1571 LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr,1572 clang_type, Type::ResolveState::Forward);1573 }1574 return nullptr;1575}1576 1577void DWARFASTParserClang::ParseInheritance(1578 const DWARFDIE &die, const DWARFDIE &parent_die,1579 const CompilerType class_clang_type, const AccessType default_accessibility,1580 const lldb::ModuleSP &module_sp,1581 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,1582 ClangASTImporter::LayoutInfo &layout_info) {1583 auto ast = class_clang_type.GetTypeSystem<TypeSystemClang>();1584 if (ast == nullptr)1585 return;1586 1587 // TODO: implement DW_TAG_inheritance type parsing.1588 DWARFAttributes attributes = die.GetAttributes();1589 if (attributes.Size() == 0)1590 return;1591 1592 DWARFFormValue encoding_form;1593 AccessType accessibility = default_accessibility;1594 bool is_virtual = false;1595 bool is_base_of_class = true;1596 off_t member_byte_offset = 0;1597 1598 for (uint32_t i = 0; i < attributes.Size(); ++i) {1599 const dw_attr_t attr = attributes.AttributeAtIndex(i);1600 DWARFFormValue form_value;1601 if (attributes.ExtractFormValueAtIndex(i, form_value)) {1602 switch (attr) {1603 case DW_AT_type:1604 encoding_form = form_value;1605 break;1606 case DW_AT_data_member_location:1607 if (auto maybe_offset =1608 ExtractDataMemberLocation(die, form_value, module_sp))1609 member_byte_offset = *maybe_offset;1610 break;1611 1612 case DW_AT_accessibility:1613 accessibility =1614 DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned());1615 break;1616 1617 case DW_AT_virtuality:1618 is_virtual = form_value.Boolean();1619 break;1620 1621 default:1622 break;1623 }1624 }1625 }1626 1627 Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference());1628 if (base_class_type == nullptr) {1629 module_sp->ReportError("{0:x16}: DW_TAG_inheritance failed to "1630 "resolve the base class at {1:x16}"1631 " from enclosing type {2:x16}. \nPlease file "1632 "a bug and attach the file at the start of "1633 "this error message",1634 die.GetOffset(),1635 encoding_form.Reference().GetOffset(),1636 parent_die.GetOffset());1637 return;1638 }1639 1640 CompilerType base_class_clang_type = base_class_type->GetFullCompilerType();1641 assert(base_class_clang_type);1642 if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) {1643 ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);1644 return;1645 }1646 std::unique_ptr<clang::CXXBaseSpecifier> result =1647 ast->CreateBaseClassSpecifier(base_class_clang_type.GetOpaqueQualType(),1648 accessibility, is_virtual,1649 is_base_of_class);1650 if (!result)1651 return;1652 1653 base_classes.push_back(std::move(result));1654 1655 if (is_virtual) {1656 // Do not specify any offset for virtual inheritance. The DWARF1657 // produced by clang doesn't give us a constant offset, but gives1658 // us a DWARF expressions that requires an actual object in memory.1659 // the DW_AT_data_member_location for a virtual base class looks1660 // like:1661 // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref,1662 // DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref,1663 // DW_OP_plus )1664 // Given this, there is really no valid response we can give to1665 // clang for virtual base class offsets, and this should eventually1666 // be removed from LayoutRecordType() in the external1667 // AST source in clang.1668 } else {1669 layout_info.base_offsets.insert(std::make_pair(1670 ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()),1671 clang::CharUnits::fromQuantity(member_byte_offset)));1672 }1673}1674 1675TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(1676 const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {1677 if (!type_sp)1678 return type_sp;1679 1680 DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);1681 dw_tag_t sc_parent_tag = sc_parent_die.Tag();1682 1683 SymbolContextScope *symbol_context_scope = nullptr;1684 if (sc_parent_tag == DW_TAG_compile_unit ||1685 sc_parent_tag == DW_TAG_partial_unit) {1686 symbol_context_scope = sc.comp_unit;1687 } else if (sc.function != nullptr && sc_parent_die) {1688 symbol_context_scope =1689 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());1690 if (symbol_context_scope == nullptr)1691 symbol_context_scope = sc.function;1692 } else {1693 symbol_context_scope = sc.module_sp.get();1694 }1695 1696 if (symbol_context_scope != nullptr)1697 type_sp->SetSymbolContextScope(symbol_context_scope);1698 return type_sp;1699}1700 1701void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration(1702 const lldb_private::plugin::dwarf::DWARFDIE &die,1703 lldb::LanguageType language, lldb_private::ConstString &unique_typename,1704 lldb_private::Declaration &decl_declaration) {1705 // For C++, we rely solely upon the one definition rule that says1706 // only one thing can exist at a given decl context. We ignore the1707 // file and line that things are declared on.1708 // FIXME: Rust pretends to be C++ for now, so use C++ name qualification rules1709 if (!Language::LanguageIsCPlusPlus(language) &&1710 language != lldb::eLanguageTypeRust)1711 return;1712 if (!die.IsValid() || unique_typename.IsEmpty())1713 return;1714 decl_declaration.Clear();1715 std::string qualified_name;1716 DWARFDIE parent_decl_ctx_die = die.GetParentDeclContextDIE();1717 // TODO: change this to get the correct decl context parent....1718 while (parent_decl_ctx_die) {1719 // The name may not contain template parameters due to1720 // -gsimple-template-names; we must reconstruct the full name from child1721 // template parameter dies via GetDIEClassTemplateParams().1722 const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();1723 switch (parent_tag) {1724 case DW_TAG_namespace: {1725 if (const char *namespace_name = parent_decl_ctx_die.GetName()) {1726 qualified_name.insert(0, "::");1727 qualified_name.insert(0, namespace_name);1728 } else {1729 qualified_name.insert(0, "(anonymous namespace)::");1730 }1731 parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();1732 break;1733 }1734 1735 case DW_TAG_class_type:1736 case DW_TAG_structure_type:1737 case DW_TAG_union_type: {1738 if (const char *class_union_struct_name = parent_decl_ctx_die.GetName()) {1739 qualified_name.insert(0, "::");1740 qualified_name.insert(0,1741 GetDIEClassTemplateParams(parent_decl_ctx_die));1742 qualified_name.insert(0, class_union_struct_name);1743 }1744 parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();1745 break;1746 }1747 1748 default:1749 parent_decl_ctx_die.Clear();1750 break;1751 }1752 }1753 1754 if (qualified_name.empty())1755 qualified_name.append("::");1756 1757 qualified_name.append(unique_typename.GetCString());1758 qualified_name.append(GetDIEClassTemplateParams(die));1759 1760 unique_typename = ConstString(qualified_name);1761}1762 1763TypeSP1764DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,1765 const DWARFDIE &die,1766 ParsedDWARFTypeAttributes &attrs) {1767 CompilerType clang_type;1768 const dw_tag_t tag = die.Tag();1769 SymbolFileDWARF *dwarf = die.GetDWARF();1770 LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());1771 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);1772 1773 ConstString unique_typename(attrs.name);1774 Declaration unique_decl(attrs.decl);1775 uint64_t byte_size = attrs.byte_size.value_or(0);1776 1777 if (attrs.name) {1778 GetUniqueTypeNameAndDeclaration(die, cu_language, unique_typename,1779 unique_decl);1780 if (log) {1781 dwarf->GetObjectFile()->GetModule()->LogMessage(1782 log, "SymbolFileDWARF({0:p}) - {1:x16}: {2} has unique name: {3} ",1783 static_cast<void *>(this), die.GetID(), DW_TAG_value_to_name(tag),1784 unique_typename.AsCString());1785 }1786 if (UniqueDWARFASTType *unique_ast_entry_type =1787 dwarf->GetUniqueDWARFASTTypeMap().Find(1788 unique_typename, die, unique_decl, byte_size,1789 attrs.is_forward_declaration)) {1790 if (TypeSP type_sp = unique_ast_entry_type->m_type_sp) {1791 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();1792 LinkDeclContextToDIE(1793 GetCachedClangDeclContextForDIE(unique_ast_entry_type->m_die), die);1794 // If the DIE being parsed in this function is a definition and the1795 // entry in the map is a declaration, then we need to update the entry1796 // to point to the definition DIE.1797 if (!attrs.is_forward_declaration &&1798 unique_ast_entry_type->m_is_forward_declaration) {1799 unique_ast_entry_type->UpdateToDefDIE(die, unique_decl, byte_size);1800 clang_type = type_sp->GetForwardCompilerType();1801 1802 CompilerType compiler_type_no_qualifiers =1803 ClangUtil::RemoveFastQualifiers(clang_type);1804 dwarf->GetForwardDeclCompilerTypeToDIE().insert_or_assign(1805 compiler_type_no_qualifiers.GetOpaqueQualType(),1806 *die.GetDIERef());1807 }1808 return type_sp;1809 }1810 }1811 }1812 1813 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),1814 DW_TAG_value_to_name(tag), type_name_cstr);1815 1816 int tag_decl_kind = -1;1817 AccessType default_accessibility = eAccessNone;1818 if (tag == DW_TAG_structure_type) {1819 tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Struct);1820 default_accessibility = eAccessPublic;1821 } else if (tag == DW_TAG_union_type) {1822 tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Union);1823 default_accessibility = eAccessPublic;1824 } else if (tag == DW_TAG_class_type) {1825 tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Class);1826 default_accessibility = eAccessPrivate;1827 }1828 1829 if ((attrs.class_language == eLanguageTypeObjC ||1830 attrs.class_language == eLanguageTypeObjC_plus_plus) &&1831 !attrs.is_complete_objc_class) {1832 // We have a valid eSymbolTypeObjCClass class symbol whose name1833 // matches the current objective C class that we are trying to find1834 // and this DIE isn't the complete definition (we checked1835 // is_complete_objc_class above and know it is false), so the real1836 // definition is in here somewhere1837 TypeSP type_sp =1838 dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);1839 1840 if (!type_sp) {1841 SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();1842 if (debug_map_symfile) {1843 // We weren't able to find a full declaration in this DWARF,1844 // see if we have a declaration anywhere else...1845 type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(1846 die, attrs.name, true);1847 }1848 }1849 1850 if (type_sp) {1851 if (log) {1852 dwarf->GetObjectFile()->GetModule()->LogMessage(1853 log,1854 "SymbolFileDWARF({0:p}) - {1:x16}: {2} ({3}) type \"{4}\" is an "1855 "incomplete objc type, complete type is {5:x8}",1856 static_cast<void *>(this), die.GetID(), DW_TAG_value_to_name(tag),1857 tag, attrs.name.GetCString(), type_sp->GetID());1858 }1859 return type_sp;1860 }1861 }1862 1863 if (attrs.is_forward_declaration) {1864 // See if the type comes from a Clang module and if so, track down1865 // that type.1866 TypeSP type_sp = ParseTypeFromClangModule(sc, die, log);1867 if (type_sp)1868 return type_sp;1869 }1870 1871 assert(tag_decl_kind != -1);1872 UNUSED_IF_ASSERT_DISABLED(tag_decl_kind);1873 clang::DeclContext *containing_decl_ctx =1874 GetClangDeclContextContainingDIE(die, nullptr);1875 1876 PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(),1877 containing_decl_ctx, die,1878 attrs.name.GetCString());1879 1880 if (attrs.accessibility == eAccessNone && containing_decl_ctx) {1881 // Check the decl context that contains this class/struct/union. If1882 // it is a class we must give it an accessibility.1883 const clang::Decl::Kind containing_decl_kind =1884 containing_decl_ctx->getDeclKind();1885 if (DeclKindIsCXXClass(containing_decl_kind))1886 attrs.accessibility = default_accessibility;1887 }1888 1889 ClangASTMetadata metadata;1890 metadata.SetUserID(die.GetID());1891 if (!attrs.is_forward_declaration)1892 metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));1893 1894 TypeSystemClang::TemplateParameterInfos template_param_infos;1895 if (ParseTemplateParameterInfos(die, template_param_infos)) {1896 clang::ClassTemplateDecl *class_template_decl =1897 m_ast.ParseClassTemplateDecl(1898 containing_decl_ctx, GetOwningClangModule(die), attrs.accessibility,1899 attrs.name.GetCString(), tag_decl_kind, template_param_infos);1900 if (!class_template_decl) {1901 if (log) {1902 dwarf->GetObjectFile()->GetModule()->LogMessage(1903 log,1904 "SymbolFileDWARF({0:p}) - {1:x16}: {2} ({3}) type \"{4}\" "1905 "clang::ClassTemplateDecl failed to return a decl.",1906 static_cast<void *>(this), die.GetID(), DW_TAG_value_to_name(tag),1907 tag, attrs.name.GetCString());1908 }1909 return TypeSP();1910 }1911 1912 clang::ClassTemplateSpecializationDecl *class_specialization_decl =1913 m_ast.CreateClassTemplateSpecializationDecl(1914 containing_decl_ctx, GetOwningClangModule(die), class_template_decl,1915 tag_decl_kind, template_param_infos);1916 if (!class_specialization_decl) {1917 if (log) {1918 dwarf->GetObjectFile()->GetModule()->LogMessage(1919 log,1920 "SymbolFileDWARF({0:p}) - Failed to create specialization for "1921 "clang::ClassTemplateDecl({1}, {2:p}).",1922 this, llvm::StringRef(attrs.name), class_template_decl);1923 }1924 return TypeSP();1925 }1926 1927 clang_type =1928 m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);1929 1930 m_ast.SetMetadata(class_template_decl, metadata);1931 m_ast.SetMetadata(class_specialization_decl, metadata);1932 }1933 1934 if (!clang_type) {1935 clang_type = m_ast.CreateRecordType(1936 containing_decl_ctx, GetOwningClangModule(die), attrs.accessibility,1937 attrs.name.GetCString(), tag_decl_kind, attrs.class_language, metadata,1938 attrs.exports_symbols);1939 }1940 1941 TypeSP type_sp = dwarf->MakeType(1942 die.GetID(), attrs.name, attrs.byte_size, nullptr, LLDB_INVALID_UID,1943 Type::eEncodingIsUID, &attrs.decl, clang_type,1944 Type::ResolveState::Forward,1945 TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class));1946 1947 // Store a forward declaration to this class type in case any1948 // parameters in any class methods need it for the clang types for1949 // function prototypes.1950 clang::DeclContext *type_decl_ctx =1951 TypeSystemClang::GetDeclContextForType(clang_type);1952 LinkDeclContextToDIE(type_decl_ctx, die);1953 1954 // UniqueDWARFASTType is large, so don't create a local variables on the1955 // stack, put it on the heap. This function is often called recursively and1956 // clang isn't good at sharing the stack space for variables in different1957 // blocks.1958 auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();1959 // Add our type to the unique type map so we don't end up creating many1960 // copies of the same type over and over in the ASTContext for our1961 // module1962 unique_ast_entry_up->m_type_sp = type_sp;1963 unique_ast_entry_up->m_die = die;1964 unique_ast_entry_up->m_declaration = unique_decl;1965 unique_ast_entry_up->m_byte_size = byte_size;1966 unique_ast_entry_up->m_is_forward_declaration = attrs.is_forward_declaration;1967 dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,1968 *unique_ast_entry_up);1969 1970 // Leave this as a forward declaration until we need to know the1971 // details of the type. lldb_private::Type will automatically call1972 // the SymbolFile virtual function1973 // "SymbolFileDWARF::CompleteType(Type *)" When the definition1974 // needs to be defined.1975 bool inserted =1976 dwarf->GetForwardDeclCompilerTypeToDIE()1977 .try_emplace(1978 ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(),1979 *die.GetDIERef())1980 .second;1981 assert(inserted && "Type already in the forward declaration map!");1982 (void)inserted;1983 m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);1984 1985 // If we made a clang type, set the trivial abi if applicable: We only1986 // do this for pass by value - which implies the Trivial ABI. There1987 // isn't a way to assert that something that would normally be pass by1988 // value is pass by reference, so we ignore that attribute if set.1989 if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {1990 clang::CXXRecordDecl *record_decl =1991 m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());1992 if (record_decl && record_decl->getDefinition()) {1993 record_decl->setHasTrivialSpecialMemberForCall();1994 }1995 }1996 1997 if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {1998 clang::CXXRecordDecl *record_decl =1999 m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());2000 if (record_decl)2001 record_decl->setArgPassingRestrictions(2002 clang::RecordArgPassingKind::CannotPassInRegs);2003 }2004 return type_sp;2005}2006 2007// DWARF parsing functions2008 2009class DWARFASTParserClang::DelayedAddObjCClassProperty {2010public:2011 DelayedAddObjCClassProperty(2012 const CompilerType &class_opaque_type, const char *property_name,2013 const CompilerType &property_opaque_type, // The property type is only2014 // required if you don't have an2015 // ivar decl2016 const char *property_setter_name, const char *property_getter_name,2017 uint32_t property_attributes, ClangASTMetadata metadata)2018 : m_class_opaque_type(class_opaque_type), m_property_name(property_name),2019 m_property_opaque_type(property_opaque_type),2020 m_property_setter_name(property_setter_name),2021 m_property_getter_name(property_getter_name),2022 m_property_attributes(property_attributes), m_metadata(metadata) {}2023 2024 bool Finalize() {2025 return TypeSystemClang::AddObjCClassProperty(2026 m_class_opaque_type, m_property_name, m_property_opaque_type,2027 /*ivar_decl=*/nullptr, m_property_setter_name, m_property_getter_name,2028 m_property_attributes, m_metadata);2029 }2030 2031private:2032 CompilerType m_class_opaque_type;2033 const char *m_property_name;2034 CompilerType m_property_opaque_type;2035 const char *m_property_setter_name;2036 const char *m_property_getter_name;2037 uint32_t m_property_attributes;2038 ClangASTMetadata m_metadata;2039};2040 2041static std::optional<clang::APValue> MakeAPValue(const clang::ASTContext &ast,2042 CompilerType clang_type,2043 uint64_t value) {2044 std::optional<uint64_t> bit_width =2045 llvm::expectedToOptional(clang_type.GetBitSize(nullptr));2046 if (!bit_width)2047 return std::nullopt;2048 2049 bool is_signed = false;2050 const bool is_integral = clang_type.IsIntegerOrEnumerationType(is_signed);2051 2052 llvm::APSInt apint(*bit_width, !is_signed);2053 apint = value;2054 2055 if (is_integral)2056 return clang::APValue(apint);2057 2058 bool is_complex;2059 // FIXME: we currently support a limited set of floating point types.2060 // E.g., 16-bit floats are not supported.2061 if (!clang_type.IsFloatingPointType(is_complex))2062 return std::nullopt;2063 2064 return clang::APValue(llvm::APFloat(2065 ast.getFloatTypeSemantics(ClangUtil::GetQualType(clang_type)), apint));2066}2067 2068bool DWARFASTParserClang::ParseTemplateDIE(2069 const DWARFDIE &die,2070 TypeSystemClang::TemplateParameterInfos &template_param_infos) {2071 const dw_tag_t tag = die.Tag();2072 bool is_template_template_argument = false;2073 2074 switch (tag) {2075 case DW_TAG_GNU_template_parameter_pack: {2076 template_param_infos.SetParameterPack(2077 std::make_unique<TypeSystemClang::TemplateParameterInfos>());2078 for (DWARFDIE child_die : die.children()) {2079 if (!ParseTemplateDIE(child_die, template_param_infos.GetParameterPack()))2080 return false;2081 }2082 if (const char *name = die.GetName()) {2083 template_param_infos.SetPackName(name);2084 }2085 return true;2086 }2087 case DW_TAG_GNU_template_template_param:2088 is_template_template_argument = true;2089 [[fallthrough]];2090 case DW_TAG_template_type_parameter:2091 case DW_TAG_template_value_parameter: {2092 DWARFAttributes attributes = die.GetAttributes();2093 if (attributes.Size() == 0)2094 return true;2095 2096 const char *name = nullptr;2097 const char *template_name = nullptr;2098 CompilerType clang_type;2099 uint64_t uval64 = 0;2100 bool uval64_valid = false;2101 bool is_default_template_arg = false;2102 DWARFFormValue form_value;2103 for (size_t i = 0; i < attributes.Size(); ++i) {2104 const dw_attr_t attr = attributes.AttributeAtIndex(i);2105 2106 switch (attr) {2107 case DW_AT_name:2108 if (attributes.ExtractFormValueAtIndex(i, form_value))2109 name = form_value.AsCString();2110 break;2111 2112 case DW_AT_GNU_template_name:2113 if (attributes.ExtractFormValueAtIndex(i, form_value))2114 template_name = form_value.AsCString();2115 break;2116 2117 case DW_AT_type:2118 if (attributes.ExtractFormValueAtIndex(i, form_value)) {2119 Type *lldb_type = die.ResolveTypeUID(form_value.Reference());2120 if (lldb_type)2121 clang_type = lldb_type->GetForwardCompilerType();2122 }2123 break;2124 2125 case DW_AT_const_value:2126 if (attributes.ExtractFormValueAtIndex(i, form_value)) {2127 uval64_valid = true;2128 uval64 = form_value.Unsigned();2129 }2130 break;2131 case DW_AT_default_value:2132 if (attributes.ExtractFormValueAtIndex(i, form_value))2133 is_default_template_arg = form_value.Boolean();2134 break;2135 default:2136 break;2137 }2138 }2139 2140 clang::ASTContext &ast = m_ast.getASTContext();2141 if (!clang_type)2142 clang_type = m_ast.GetBasicType(eBasicTypeVoid);2143 2144 if (!is_template_template_argument) {2145 2146 if (name && !name[0])2147 name = nullptr;2148 2149 if (tag == DW_TAG_template_value_parameter && uval64_valid) {2150 if (auto value = MakeAPValue(ast, clang_type, uval64)) {2151 template_param_infos.InsertArg(2152 name, clang::TemplateArgument(2153 ast, ClangUtil::GetQualType(clang_type),2154 std::move(*value), is_default_template_arg));2155 return true;2156 }2157 }2158 2159 // We get here if this is a type-template parameter or we couldn't create2160 // a non-type template parameter.2161 template_param_infos.InsertArg(2162 name, clang::TemplateArgument(ClangUtil::GetQualType(clang_type),2163 /*isNullPtr*/ false,2164 is_default_template_arg));2165 } else {2166 auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name);2167 template_param_infos.InsertArg(2168 name, clang::TemplateArgument(clang::TemplateName(tplt_type),2169 is_default_template_arg));2170 }2171 }2172 return true;2173 2174 default:2175 break;2176 }2177 return false;2178}2179 2180bool DWARFASTParserClang::ParseTemplateParameterInfos(2181 const DWARFDIE &parent_die,2182 TypeSystemClang::TemplateParameterInfos &template_param_infos) {2183 2184 if (!parent_die)2185 return false;2186 2187 for (DWARFDIE die : parent_die.children()) {2188 const dw_tag_t tag = die.Tag();2189 2190 switch (tag) {2191 case DW_TAG_template_type_parameter:2192 case DW_TAG_template_value_parameter:2193 case DW_TAG_GNU_template_parameter_pack:2194 case DW_TAG_GNU_template_template_param:2195 ParseTemplateDIE(die, template_param_infos);2196 break;2197 2198 default:2199 break;2200 }2201 }2202 2203 return !template_param_infos.IsEmpty() ||2204 template_param_infos.hasParameterPack();2205}2206 2207bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,2208 const CompilerType &clang_type) {2209 const dw_tag_t tag = die.Tag();2210 SymbolFileDWARF *dwarf = die.GetDWARF();2211 2212 ClangASTImporter::LayoutInfo layout_info;2213 std::vector<DWARFDIE> contained_type_dies;2214 2215 if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))2216 return false; // No definition, cannot complete.2217 2218 // Start the definition if the type is not being defined already. This can2219 // happen (e.g.) when adding nested types to a class type -- see2220 // PrepareContextToReceiveMembers.2221 if (!clang_type.IsBeingDefined())2222 TypeSystemClang::StartTagDeclarationDefinition(clang_type);2223 2224 AccessType default_accessibility = eAccessNone;2225 if (tag == DW_TAG_structure_type) {2226 default_accessibility = eAccessPublic;2227 } else if (tag == DW_TAG_union_type) {2228 default_accessibility = eAccessPublic;2229 } else if (tag == DW_TAG_class_type) {2230 default_accessibility = eAccessPrivate;2231 }2232 2233 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;2234 // Parse members and base classes first2235 std::vector<DWARFDIE> member_function_dies;2236 2237 DelayedPropertyList delayed_properties;2238 ParseChildMembers(die, clang_type, bases, member_function_dies,2239 contained_type_dies, delayed_properties,2240 default_accessibility, layout_info);2241 2242 // Now parse any methods if there were any...2243 for (const DWARFDIE &die : member_function_dies)2244 dwarf->ResolveType(die);2245 2246 if (TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type)) {2247 ConstString class_name(clang_type.GetTypeName());2248 if (class_name) {2249 dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) {2250 method_die.ResolveType();2251 return IterationAction::Continue;2252 });2253 2254 for (DelayedAddObjCClassProperty &property : delayed_properties)2255 property.Finalize();2256 }2257 } else if (Language::LanguageIsObjC(2258 static_cast<LanguageType>(die.GetAttributeValueAsUnsigned(2259 DW_AT_APPLE_runtime_class, eLanguageTypeUnknown)))) {2260 /// The forward declaration was C++ but the definition is Objective-C.2261 /// We currently don't handle such situations. In such cases, keep the2262 /// forward declaration without a definition to avoid violating Clang AST2263 /// invariants.2264 LLDB_LOG(GetLog(LLDBLog::Expressions),2265 "WARNING: Type completion aborted because forward declaration for "2266 "'{0}' is C++ while definition is Objective-C.",2267 llvm::StringRef(die.GetName()));2268 return {};2269 }2270 2271 if (!bases.empty()) {2272 // Make sure all base classes refer to complete types and not forward2273 // declarations. If we don't do this, clang will crash with an2274 // assertion in the call to clang_type.TransferBaseClasses()2275 for (const auto &base_class : bases) {2276 clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo();2277 if (type_source_info)2278 TypeSystemClang::RequireCompleteType(2279 m_ast.GetType(type_source_info->getType()));2280 }2281 2282 m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), std::move(bases));2283 }2284 2285 m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType());2286 TypeSystemClang::BuildIndirectFields(clang_type);2287 TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);2288 2289 layout_info.bit_size =2290 die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;2291 layout_info.alignment =2292 die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_alignment, 0) * 8;2293 2294 clang::CXXRecordDecl *record_decl =2295 m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());2296 if (record_decl)2297 GetClangASTImporter().SetRecordLayout(record_decl, layout_info);2298 2299 // DWARF doesn't have the attribute, but we can infer the value the same way2300 // as Clang Sema does. It's required to calculate the size of pointers to2301 // member functions of this type.2302 if (m_ast.getASTContext().getTargetInfo().getCXXABI().isMicrosoft()) {2303 auto IM = record_decl->calculateInheritanceModel();2304 record_decl->addAttr(clang::MSInheritanceAttr::CreateImplicit(2305 m_ast.getASTContext(), true, {},2306 clang::MSInheritanceAttr::Spelling(IM)));2307 }2308 2309 // Now parse all contained types inside of the class. We make forward2310 // declarations to all classes, but we need the CXXRecordDecl to have decls2311 // for all contained types because we don't get asked for them via the2312 // external AST support.2313 for (const DWARFDIE &die : contained_type_dies)2314 dwarf->ResolveType(die);2315 2316 return (bool)clang_type;2317}2318 2319bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die,2320 lldb_private::Type *type,2321 const CompilerType &clang_type) {2322 assert(clang_type.IsEnumerationType());2323 2324 if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {2325 if (die.HasChildren())2326 ParseChildEnumerators(2327 clang_type, clang_type.IsEnumerationIntegerTypeSigned(),2328 llvm::expectedToOptional(type->GetByteSize(nullptr)).value_or(0),2329 die);2330 2331 TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);2332 }2333 return (bool)clang_type;2334}2335 2336bool DWARFASTParserClang::CompleteTypeFromDWARF(2337 const DWARFDIE &die, lldb_private::Type *type,2338 const CompilerType &clang_type) {2339 SymbolFileDWARF *dwarf = die.GetDWARF();2340 2341 std::lock_guard<std::recursive_mutex> guard(2342 dwarf->GetObjectFile()->GetModule()->GetMutex());2343 2344 // Disable external storage for this type so we don't get anymore2345 // clang::ExternalASTSource queries for this type.2346 m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), false);2347 2348 if (!die)2349 return false;2350 2351 const dw_tag_t tag = die.Tag();2352 2353 assert(clang_type);2354 switch (tag) {2355 case DW_TAG_structure_type:2356 case DW_TAG_union_type:2357 case DW_TAG_class_type:2358 CompleteRecordType(die, clang_type);2359 break;2360 case DW_TAG_enumeration_type:2361 CompleteEnumType(die, type, clang_type);2362 break;2363 default:2364 assert(false && "not a forward clang type decl!");2365 break;2366 }2367 2368 // If the type is still not fully defined at this point, it means we weren't2369 // able to find its definition. We must forcefully complete it to preserve2370 // clang AST invariants.2371 if (clang_type.IsBeingDefined()) {2372 TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);2373 m_ast.SetDeclIsForcefullyCompleted(ClangUtil::GetAsTagDecl(clang_type));2374 }2375 2376 return true;2377}2378 2379void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(2380 lldb_private::CompilerDeclContext decl_context) {2381 auto opaque_decl_ctx =2382 (clang::DeclContext *)decl_context.GetOpaqueDeclContext();2383 for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);2384 it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;2385 it = m_decl_ctx_to_die.erase(it))2386 for (DWARFDIE decl : it->second.children())2387 GetClangDeclForDIE(decl);2388}2389 2390CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {2391 clang::Decl *clang_decl = GetClangDeclForDIE(die);2392 if (clang_decl != nullptr)2393 return m_ast.GetCompilerDecl(clang_decl);2394 return {};2395}2396 2397CompilerDeclContext2398DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {2399 clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die);2400 if (clang_decl_ctx)2401 return m_ast.CreateDeclContext(clang_decl_ctx);2402 return {};2403}2404 2405CompilerDeclContext2406DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {2407 clang::DeclContext *clang_decl_ctx =2408 GetClangDeclContextContainingDIE(die, nullptr);2409 if (clang_decl_ctx)2410 return m_ast.CreateDeclContext(clang_decl_ctx);2411 return {};2412}2413 2414size_t DWARFASTParserClang::ParseChildEnumerators(2415 const lldb_private::CompilerType &clang_type, bool is_signed,2416 uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {2417 if (!parent_die)2418 return 0;2419 2420 size_t enumerators_added = 0;2421 2422 for (DWARFDIE die : parent_die.children()) {2423 const dw_tag_t tag = die.Tag();2424 if (tag != DW_TAG_enumerator)2425 continue;2426 2427 DWARFAttributes attributes = die.GetAttributes();2428 if (attributes.Size() == 0)2429 continue;2430 2431 const char *name = nullptr;2432 std::optional<uint64_t> enum_value;2433 Declaration decl;2434 2435 for (size_t i = 0; i < attributes.Size(); ++i) {2436 const dw_attr_t attr = attributes.AttributeAtIndex(i);2437 DWARFFormValue form_value;2438 if (attributes.ExtractFormValueAtIndex(i, form_value)) {2439 switch (attr) {2440 case DW_AT_const_value:2441 if (is_signed)2442 enum_value = form_value.Signed();2443 else2444 enum_value = form_value.Unsigned();2445 break;2446 2447 case DW_AT_name:2448 name = form_value.AsCString();2449 break;2450 2451 case DW_AT_description:2452 default:2453 case DW_AT_decl_file:2454 decl.SetFile(2455 attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));2456 break;2457 case DW_AT_decl_line:2458 decl.SetLine(form_value.Unsigned());2459 break;2460 case DW_AT_decl_column:2461 decl.SetColumn(form_value.Unsigned());2462 break;2463 case DW_AT_sibling:2464 break;2465 }2466 }2467 }2468 2469 if (name && name[0] && enum_value) {2470 m_ast.AddEnumerationValueToEnumerationType(2471 clang_type, decl, name, *enum_value, enumerator_byte_size * 8);2472 ++enumerators_added;2473 }2474 }2475 return enumerators_added;2476}2477 2478ConstString2479DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {2480 bool is_variadic = false;2481 bool has_template_params = false;2482 std::vector<CompilerType> param_types;2483 llvm::SmallVector<llvm::StringRef> param_names;2484 StreamString sstr;2485 2486 DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();2487 sstr << decl_ctx.GetQualifiedName();2488 2489 DWARFDIE decl_ctx_die;2490 clang::DeclContext *containing_decl_ctx =2491 GetClangDeclContextContainingDIE(die, &decl_ctx_die);2492 assert(containing_decl_ctx);2493 2494 const unsigned cv_quals =2495 GetCXXMethodCVQuals(die, GetObjectParameter(die, decl_ctx_die));2496 2497 ParseChildParameters(containing_decl_ctx, die, is_variadic,2498 has_template_params, param_types, param_names);2499 sstr << "(";2500 for (size_t i = 0; i < param_types.size(); i++) {2501 if (i > 0)2502 sstr << ", ";2503 sstr << param_types[i].GetTypeName();2504 }2505 if (is_variadic)2506 sstr << ", ...";2507 sstr << ")";2508 if (cv_quals & clang::Qualifiers::Const)2509 sstr << " const";2510 2511 return ConstString(sstr.GetString());2512}2513 2514Function *DWARFASTParserClang::ParseFunctionFromDWARF(2515 CompileUnit &comp_unit, const DWARFDIE &die, AddressRanges func_ranges) {2516 llvm::DWARFAddressRangesVector unused_func_ranges;2517 const char *name = nullptr;2518 const char *mangled = nullptr;2519 std::optional<int> decl_file;2520 std::optional<int> decl_line;2521 std::optional<int> decl_column;2522 std::optional<int> call_file;2523 std::optional<int> call_line;2524 std::optional<int> call_column;2525 DWARFExpressionList frame_base;2526 2527 const dw_tag_t tag = die.Tag();2528 2529 if (tag != DW_TAG_subprogram)2530 return nullptr;2531 2532 if (die.GetDIENamesAndRanges(name, mangled, unused_func_ranges, decl_file,2533 decl_line, decl_column, call_file, call_line,2534 call_column, &frame_base)) {2535 Mangled func_name;2536 if (mangled)2537 func_name.SetValue(ConstString(mangled));2538 else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||2539 die.GetParent().Tag() == DW_TAG_partial_unit) &&2540 Language::LanguageIsCPlusPlus(2541 SymbolFileDWARF::GetLanguage(*die.GetCU())) &&2542 !Language::LanguageIsObjC(2543 SymbolFileDWARF::GetLanguage(*die.GetCU())) &&2544 name && strcmp(name, "main") != 0) {2545 // If the mangled name is not present in the DWARF, generate the2546 // demangled name using the decl context. We skip if the function is2547 // "main" as its name is never mangled.2548 func_name.SetDemangledName(ConstructDemangledNameFromDWARF(die));2549 // Ensure symbol is preserved (as the mangled name).2550 func_name.SetMangledName(ConstString(name));2551 } else2552 func_name.SetValue(ConstString(name));2553 2554 FunctionSP func_sp;2555 std::unique_ptr<Declaration> decl_up;2556 if (decl_file || decl_line || decl_column)2557 decl_up = std::make_unique<Declaration>(2558 die.GetCU()->GetFile(decl_file.value_or(0)), decl_line.value_or(0),2559 decl_column.value_or(0));2560 2561 SymbolFileDWARF *dwarf = die.GetDWARF();2562 // Supply the type _only_ if it has already been parsed2563 Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE());2564 2565 assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);2566 2567 const user_id_t func_user_id = die.GetID();2568 2569 // The base address of the scope for any of the debugging information2570 // entries listed above is given by either the DW_AT_low_pc attribute or the2571 // first address in the first range entry in the list of ranges given by the2572 // DW_AT_ranges attribute.2573 // -- DWARFv5, Section 2.17 Code Addresses, Ranges and Base Addresses2574 //2575 // If no DW_AT_entry_pc attribute is present, then the entry address is2576 // assumed to be the same as the base address of the containing scope.2577 // -- DWARFv5, Section 2.18 Entry Address2578 //2579 // We currently don't support Debug Info Entries with2580 // DW_AT_low_pc/DW_AT_entry_pc and DW_AT_ranges attributes (the latter2581 // attributes are ignored even though they should be used for the address of2582 // the function), but compilers also don't emit that kind of information. If2583 // this becomes a problem we need to plumb these attributes separately.2584 Address func_addr = func_ranges[0].GetBaseAddress();2585 2586 func_sp = std::make_shared<Function>(2587 &comp_unit,2588 func_user_id, // UserID is the DIE offset2589 func_user_id, func_name, func_type, std::move(func_addr),2590 std::move(func_ranges));2591 2592 if (func_sp.get() != nullptr) {2593 if (frame_base.IsValid())2594 func_sp->GetFrameBaseExpression() = frame_base;2595 comp_unit.AddFunction(func_sp);2596 return func_sp.get();2597 }2598 }2599 return nullptr;2600}2601 2602namespace {2603/// Parsed form of all attributes that are relevant for parsing Objective-C2604/// properties.2605struct PropertyAttributes {2606 explicit PropertyAttributes(const DWARFDIE &die);2607 const char *prop_name = nullptr;2608 const char *prop_getter_name = nullptr;2609 const char *prop_setter_name = nullptr;2610 /// \see clang::ObjCPropertyAttribute2611 uint32_t prop_attributes = 0;2612};2613 2614struct DiscriminantValue {2615 explicit DiscriminantValue(const DWARFDIE &die, ModuleSP module_sp);2616 2617 uint32_t byte_offset;2618 uint32_t byte_size;2619 DWARFFormValue type_ref;2620};2621 2622struct VariantMember {2623 explicit VariantMember(DWARFDIE &die, ModuleSP module_sp);2624 bool IsDefault() const;2625 2626 std::optional<uint32_t> discr_value;2627 DWARFFormValue type_ref;2628 ConstString variant_name;2629 uint32_t byte_offset;2630 ConstString GetName() const;2631};2632 2633struct VariantPart {2634 explicit VariantPart(const DWARFDIE &die, const DWARFDIE &parent_die,2635 ModuleSP module_sp);2636 2637 std::vector<VariantMember> &members();2638 2639 DiscriminantValue &discriminant();2640 2641private:2642 std::vector<VariantMember> _members;2643 DiscriminantValue _discriminant;2644};2645 2646} // namespace2647 2648ConstString VariantMember::GetName() const { return this->variant_name; }2649 2650bool VariantMember::IsDefault() const { return !discr_value; }2651 2652VariantMember::VariantMember(DWARFDIE &die, lldb::ModuleSP module_sp) {2653 assert(die.Tag() == llvm::dwarf::DW_TAG_variant);2654 this->discr_value =2655 die.GetAttributeValueAsOptionalUnsigned(DW_AT_discr_value);2656 2657 for (auto child_die : die.children()) {2658 switch (child_die.Tag()) {2659 case llvm::dwarf::DW_TAG_member: {2660 DWARFAttributes attributes = child_die.GetAttributes();2661 for (std::size_t i = 0; i < attributes.Size(); ++i) {2662 DWARFFormValue form_value;2663 const dw_attr_t attr = attributes.AttributeAtIndex(i);2664 if (attributes.ExtractFormValueAtIndex(i, form_value)) {2665 switch (attr) {2666 case DW_AT_name:2667 variant_name = ConstString(form_value.AsCString());2668 break;2669 case DW_AT_type:2670 type_ref = form_value;2671 break;2672 2673 case DW_AT_data_member_location:2674 if (auto maybe_offset =2675 ExtractDataMemberLocation(die, form_value, module_sp))2676 byte_offset = *maybe_offset;2677 break;2678 2679 default:2680 break;2681 }2682 }2683 }2684 break;2685 }2686 default:2687 break;2688 }2689 break;2690 }2691}2692 2693DiscriminantValue::DiscriminantValue(const DWARFDIE &die, ModuleSP module_sp) {2694 auto referenced_die = die.GetReferencedDIE(DW_AT_discr);2695 DWARFAttributes attributes = referenced_die.GetAttributes();2696 for (std::size_t i = 0; i < attributes.Size(); ++i) {2697 const dw_attr_t attr = attributes.AttributeAtIndex(i);2698 DWARFFormValue form_value;2699 if (attributes.ExtractFormValueAtIndex(i, form_value)) {2700 switch (attr) {2701 case DW_AT_type:2702 type_ref = form_value;2703 break;2704 case DW_AT_data_member_location:2705 if (auto maybe_offset =2706 ExtractDataMemberLocation(die, form_value, module_sp))2707 byte_offset = *maybe_offset;2708 break;2709 default:2710 break;2711 }2712 }2713 }2714}2715 2716VariantPart::VariantPart(const DWARFDIE &die, const DWARFDIE &parent_die,2717 lldb::ModuleSP module_sp)2718 : _members(), _discriminant(die, module_sp) {2719 2720 for (auto child : die.children()) {2721 if (child.Tag() == llvm::dwarf::DW_TAG_variant) {2722 _members.push_back(VariantMember(child, module_sp));2723 }2724 }2725}2726 2727std::vector<VariantMember> &VariantPart::members() { return this->_members; }2728 2729DiscriminantValue &VariantPart::discriminant() { return this->_discriminant; }2730 2731DWARFASTParserClang::MemberAttributes::MemberAttributes(2732 const DWARFDIE &die, const DWARFDIE &parent_die, ModuleSP module_sp) {2733 DWARFAttributes attributes = die.GetAttributes();2734 for (size_t i = 0; i < attributes.Size(); ++i) {2735 const dw_attr_t attr = attributes.AttributeAtIndex(i);2736 DWARFFormValue form_value;2737 if (attributes.ExtractFormValueAtIndex(i, form_value)) {2738 switch (attr) {2739 case DW_AT_name:2740 name = form_value.AsCString();2741 break;2742 case DW_AT_type:2743 encoding_form = form_value;2744 break;2745 case DW_AT_bit_offset:2746 bit_offset = form_value.Signed();2747 break;2748 case DW_AT_bit_size:2749 bit_size = form_value.Unsigned();2750 break;2751 case DW_AT_byte_size:2752 byte_size = form_value.Unsigned();2753 break;2754 case DW_AT_const_value:2755 const_value_form = form_value;2756 break;2757 case DW_AT_data_bit_offset:2758 data_bit_offset = form_value.Unsigned();2759 break;2760 case DW_AT_data_member_location:2761 if (auto maybe_offset =2762 ExtractDataMemberLocation(die, form_value, module_sp))2763 member_byte_offset = *maybe_offset;2764 break;2765 2766 case DW_AT_accessibility:2767 accessibility =2768 DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned());2769 break;2770 case DW_AT_artificial:2771 is_artificial = form_value.Boolean();2772 break;2773 case DW_AT_declaration:2774 is_declaration = form_value.Boolean();2775 break;2776 default:2777 break;2778 }2779 }2780 }2781 2782 // Clang has a DWARF generation bug where sometimes it represents2783 // fields that are references with bad byte size and bit size/offset2784 // information such as:2785 //2786 // DW_AT_byte_size( 0x00 )2787 // DW_AT_bit_size( 0x40 )2788 // DW_AT_bit_offset( 0xffffffffffffffc0 )2789 //2790 // So check the bit offset to make sure it is sane, and if the values2791 // are not sane, remove them. If we don't do this then we will end up2792 // with a crash if we try to use this type in an expression when clang2793 // becomes unhappy with its recycled debug info.2794 if (byte_size.value_or(0) == 0 && bit_offset < 0) {2795 bit_size = 0;2796 bit_offset = 0;2797 }2798}2799 2800PropertyAttributes::PropertyAttributes(const DWARFDIE &die) {2801 2802 DWARFAttributes attributes = die.GetAttributes();2803 for (size_t i = 0; i < attributes.Size(); ++i) {2804 const dw_attr_t attr = attributes.AttributeAtIndex(i);2805 DWARFFormValue form_value;2806 if (attributes.ExtractFormValueAtIndex(i, form_value)) {2807 switch (attr) {2808 case DW_AT_APPLE_property_name:2809 prop_name = form_value.AsCString();2810 break;2811 case DW_AT_APPLE_property_getter:2812 prop_getter_name = form_value.AsCString();2813 break;2814 case DW_AT_APPLE_property_setter:2815 prop_setter_name = form_value.AsCString();2816 break;2817 case DW_AT_APPLE_property_attribute:2818 prop_attributes = form_value.Unsigned();2819 break;2820 default:2821 break;2822 }2823 }2824 }2825 2826 if (!prop_name)2827 return;2828 ConstString fixed_setter;2829 2830 // Check if the property getter/setter were provided as full names.2831 // We want basenames, so we extract them.2832 if (prop_getter_name && prop_getter_name[0] == '-') {2833 std::optional<const ObjCLanguage::ObjCMethodName> prop_getter_method =2834 ObjCLanguage::ObjCMethodName::Create(prop_getter_name, true);2835 if (prop_getter_method)2836 prop_getter_name =2837 ConstString(prop_getter_method->GetSelector()).GetCString();2838 }2839 2840 if (prop_setter_name && prop_setter_name[0] == '-') {2841 std::optional<const ObjCLanguage::ObjCMethodName> prop_setter_method =2842 ObjCLanguage::ObjCMethodName::Create(prop_setter_name, true);2843 if (prop_setter_method)2844 prop_setter_name =2845 ConstString(prop_setter_method->GetSelector()).GetCString();2846 }2847 2848 // If the names haven't been provided, they need to be filled in.2849 if (!prop_getter_name)2850 prop_getter_name = prop_name;2851 if (!prop_setter_name && prop_name[0] &&2852 !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {2853 StreamString ss;2854 2855 ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);2856 2857 fixed_setter.SetString(ss.GetString());2858 prop_setter_name = fixed_setter.GetCString();2859 }2860}2861 2862void DWARFASTParserClang::ParseObjCProperty(2863 const DWARFDIE &die, const DWARFDIE &parent_die,2864 const lldb_private::CompilerType &class_clang_type,2865 DelayedPropertyList &delayed_properties) {2866 // This function can only parse DW_TAG_APPLE_property.2867 assert(die.Tag() == DW_TAG_APPLE_property);2868 2869 ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();2870 2871 const MemberAttributes attrs(die, parent_die, module_sp);2872 const PropertyAttributes propAttrs(die);2873 2874 if (!propAttrs.prop_name) {2875 module_sp->ReportError("{0:x8}: DW_TAG_APPLE_property has no name.",2876 die.GetID());2877 return;2878 }2879 2880 Type *member_type = die.ResolveTypeUID(attrs.encoding_form.Reference());2881 if (!member_type) {2882 module_sp->ReportError(2883 "{0:x8}: DW_TAG_APPLE_property '{1}' refers to type {2:x16}"2884 " which was unable to be parsed",2885 die.GetID(), propAttrs.prop_name,2886 attrs.encoding_form.Reference().GetOffset());2887 return;2888 }2889 2890 ClangASTMetadata metadata;2891 metadata.SetUserID(die.GetID());2892 delayed_properties.emplace_back(2893 class_clang_type, propAttrs.prop_name,2894 member_type->GetLayoutCompilerType(), propAttrs.prop_setter_name,2895 propAttrs.prop_getter_name, propAttrs.prop_attributes, metadata);2896}2897 2898llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue(2899 const CompilerType &int_type, const DWARFFormValue &form_value) const {2900 clang::QualType qt = ClangUtil::GetQualType(int_type);2901 assert(qt->isIntegralOrEnumerationType());2902 auto ts_ptr = int_type.GetTypeSystem<TypeSystemClang>();2903 if (!ts_ptr)2904 return llvm::createStringError(llvm::inconvertibleErrorCode(),2905 "TypeSystem not clang");2906 TypeSystemClang &ts = *ts_ptr;2907 clang::ASTContext &ast = ts.getASTContext();2908 2909 const unsigned type_bits = ast.getIntWidth(qt);2910 const bool is_unsigned = qt->isUnsignedIntegerType();2911 2912 // The maximum int size supported at the moment by this function. Limited2913 // by the uint64_t return type of DWARFFormValue::Signed/Unsigned.2914 constexpr std::size_t max_bit_size = 64;2915 2916 // For values bigger than 64 bit (e.g. __int128_t values),2917 // DWARFFormValue's Signed/Unsigned functions will return wrong results so2918 // emit an error for now.2919 if (type_bits > max_bit_size) {2920 auto msg = llvm::formatv("Can only parse integers with up to {0} bits, but "2921 "given integer has {1} bits.",2922 max_bit_size, type_bits);2923 return llvm::createStringError(llvm::inconvertibleErrorCode(), msg.str());2924 }2925 2926 // Construct an APInt with the maximum bit size and the given integer.2927 llvm::APInt result(max_bit_size, form_value.Unsigned(), !is_unsigned);2928 2929 // Calculate how many bits are required to represent the input value.2930 // For unsigned types, take the number of active bits in the APInt.2931 // For signed types, ask APInt how many bits are required to represent the2932 // signed integer.2933 const unsigned required_bits =2934 is_unsigned ? result.getActiveBits() : result.getSignificantBits();2935 2936 // If the input value doesn't fit into the integer type, return an error.2937 if (required_bits > type_bits) {2938 std::string value_as_str = is_unsigned2939 ? std::to_string(form_value.Unsigned())2940 : std::to_string(form_value.Signed());2941 auto msg = llvm::formatv("Can't store {0} value {1} in integer with {2} "2942 "bits.",2943 (is_unsigned ? "unsigned" : "signed"),2944 value_as_str, type_bits);2945 return llvm::createStringError(llvm::inconvertibleErrorCode(), msg.str());2946 }2947 2948 // Trim the result to the bit width our the int type.2949 if (result.getBitWidth() > type_bits)2950 result = result.trunc(type_bits);2951 return result;2952}2953 2954void DWARFASTParserClang::CreateStaticMemberVariable(2955 const DWARFDIE &die, const MemberAttributes &attrs,2956 const lldb_private::CompilerType &class_clang_type) {2957 Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);2958 assert(die.Tag() == DW_TAG_member || die.Tag() == DW_TAG_variable);2959 2960 Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference());2961 2962 if (!var_type)2963 return;2964 2965 auto accessibility =2966 attrs.accessibility == eAccessNone ? eAccessPublic : attrs.accessibility;2967 2968 CompilerType ct = var_type->GetForwardCompilerType();2969 clang::VarDecl *v = TypeSystemClang::AddVariableToRecordType(2970 class_clang_type, attrs.name, ct, accessibility);2971 if (!v) {2972 LLDB_LOG(log, "Failed to add variable to the record type");2973 return;2974 }2975 2976 bool unused;2977 // TODO: Support float/double static members as well.2978 if (!ct.IsIntegerOrEnumerationType(unused) || !attrs.const_value_form)2979 return;2980 2981 llvm::Expected<llvm::APInt> const_value_or_err =2982 ExtractIntFromFormValue(ct, *attrs.const_value_form);2983 if (!const_value_or_err) {2984 LLDB_LOG_ERROR(log, const_value_or_err.takeError(),2985 "Failed to add const value to variable {1}: {0}",2986 v->getQualifiedNameAsString());2987 return;2988 }2989 2990 TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);2991}2992 2993void DWARFASTParserClang::ParseSingleMember(2994 const DWARFDIE &die, const DWARFDIE &parent_die,2995 const lldb_private::CompilerType &class_clang_type,2996 lldb::AccessType default_accessibility,2997 lldb_private::ClangASTImporter::LayoutInfo &layout_info,2998 FieldInfo &last_field_info) {2999 // This function can only parse DW_TAG_member.3000 assert(die.Tag() == DW_TAG_member);3001 3002 ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();3003 const dw_tag_t tag = die.Tag();3004 // Get the parent byte size so we can verify any members will fit3005 const uint64_t parent_byte_size =3006 parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);3007 const uint64_t parent_bit_size =3008 parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;3009 3010 const MemberAttributes attrs(die, parent_die, module_sp);3011 3012 // Handle static members, which are typically members without3013 // locations. However, GCC doesn't emit DW_AT_data_member_location3014 // for any union members (regardless of linkage).3015 // Non-normative text pre-DWARFv5 recommends marking static3016 // data members with an DW_AT_external flag. Clang emits this consistently3017 // whereas GCC emits it only for static data members if not part of an3018 // anonymous namespace. The flag that is consistently emitted for static3019 // data members is DW_AT_declaration, so we check it instead.3020 // The following block is only necessary to support DWARFv4 and earlier.3021 // Starting with DWARFv5, static data members are marked DW_AT_variable so we3022 // can consistently detect them on both GCC and Clang without below heuristic.3023 if (attrs.member_byte_offset == UINT32_MAX &&3024 attrs.data_bit_offset == UINT64_MAX && attrs.is_declaration) {3025 CreateStaticMemberVariable(die, attrs, class_clang_type);3026 return;3027 }3028 3029 Type *member_type = die.ResolveTypeUID(attrs.encoding_form.Reference());3030 if (!member_type) {3031 if (attrs.name)3032 module_sp->ReportError(3033 "{0:x8}: DW_TAG_member '{1}' refers to type {2:x16}"3034 " which was unable to be parsed",3035 die.GetID(), attrs.name, attrs.encoding_form.Reference().GetOffset());3036 else3037 module_sp->ReportError("{0:x8}: DW_TAG_member refers to type {1:x16}"3038 " which was unable to be parsed",3039 die.GetID(),3040 attrs.encoding_form.Reference().GetOffset());3041 return;3042 }3043 3044 const uint64_t character_width = 8;3045 CompilerType member_clang_type = member_type->GetLayoutCompilerType();3046 3047 const auto accessibility = attrs.accessibility == eAccessNone3048 ? default_accessibility3049 : attrs.accessibility;3050 3051 uint64_t field_bit_offset = (attrs.member_byte_offset == UINT32_MAX3052 ? 03053 : (attrs.member_byte_offset * 8ULL));3054 3055 if (attrs.bit_size > 0) {3056 FieldInfo this_field_info;3057 this_field_info.bit_offset = field_bit_offset;3058 this_field_info.bit_size = attrs.bit_size;3059 3060 if (attrs.data_bit_offset != UINT64_MAX) {3061 this_field_info.bit_offset = attrs.data_bit_offset;3062 } else {3063 auto byte_size = attrs.byte_size;3064 if (!byte_size)3065 byte_size = llvm::expectedToOptional(member_type->GetByteSize(nullptr));3066 3067 ObjectFile *objfile = die.GetDWARF()->GetObjectFile();3068 if (objfile->GetByteOrder() == eByteOrderLittle) {3069 this_field_info.bit_offset += byte_size.value_or(0) * 8;3070 this_field_info.bit_offset -= (attrs.bit_offset + attrs.bit_size);3071 } else {3072 this_field_info.bit_offset += attrs.bit_offset;3073 }3074 }3075 3076 // The ObjC runtime knows the byte offset but we still need to provide3077 // the bit-offset in the layout. It just means something different then3078 // what it does in C and C++. So we skip this check for ObjC types.3079 //3080 // We also skip this for fields of a union since they will all have a3081 // zero offset.3082 if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) &&3083 !(parent_die.Tag() == DW_TAG_union_type &&3084 this_field_info.bit_offset == 0) &&3085 ((this_field_info.bit_offset >= parent_bit_size) ||3086 (last_field_info.IsBitfield() &&3087 !last_field_info.NextBitfieldOffsetIsValid(3088 this_field_info.bit_offset)))) {3089 ObjectFile *objfile = die.GetDWARF()->GetObjectFile();3090 objfile->GetModule()->ReportWarning(3091 "{0:x16}: {1} ({2}) bitfield named \"{3}\" has invalid "3092 "bit offset ({4:x8}) member will be ignored. Please file a bug "3093 "against the "3094 "compiler and include the preprocessed output for {5}\n",3095 die.GetID(), DW_TAG_value_to_name(tag), tag, attrs.name,3096 this_field_info.bit_offset, GetUnitName(parent_die).c_str());3097 return;3098 }3099 3100 // Update the field bit offset we will report for layout3101 field_bit_offset = this_field_info.bit_offset;3102 3103 // Objective-C has invalid DW_AT_bit_offset values in older3104 // versions of clang, so we have to be careful and only insert3105 // unnamed bitfields if we have a new enough clang.3106 bool detect_unnamed_bitfields = true;3107 3108 if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type))3109 detect_unnamed_bitfields =3110 die.GetCU()->Supports_unnamed_objc_bitfields();3111 3112 if (detect_unnamed_bitfields)3113 AddUnnamedBitfieldToRecordTypeIfNeeded(layout_info, class_clang_type,3114 last_field_info, this_field_info);3115 3116 last_field_info = this_field_info;3117 last_field_info.SetIsBitfield(true);3118 } else {3119 FieldInfo this_field_info;3120 this_field_info.is_bitfield = false;3121 this_field_info.bit_offset = field_bit_offset;3122 3123 // TODO: we shouldn't silently ignore the bit_size if we fail3124 // to GetByteSize.3125 if (std::optional<uint64_t> clang_type_size =3126 llvm::expectedToOptional(member_type->GetByteSize(nullptr))) {3127 this_field_info.bit_size = *clang_type_size * character_width;3128 }3129 3130 if (this_field_info.GetFieldEnd() <= last_field_info.GetEffectiveFieldEnd())3131 this_field_info.SetEffectiveFieldEnd(3132 last_field_info.GetEffectiveFieldEnd());3133 3134 last_field_info = this_field_info;3135 }3136 3137 // Don't turn artificial members such as vtable pointers into real FieldDecls3138 // in our AST. Clang will re-create those articial members and they would3139 // otherwise just overlap in the layout with the FieldDecls we add here.3140 // This needs to be done after updating FieldInfo which keeps track of where3141 // field start/end so we don't later try to fill the space of this3142 // artificial member with (unnamed bitfield) padding.3143 if (attrs.is_artificial && ShouldIgnoreArtificialField(attrs.name)) {3144 last_field_info.SetIsArtificial(true);3145 return;3146 }3147 3148 if (!member_clang_type.IsCompleteType())3149 member_clang_type.GetCompleteType();3150 3151 TypeSystemClang::RequireCompleteType(member_clang_type);3152 3153 clang::FieldDecl *field_decl = TypeSystemClang::AddFieldToRecordType(3154 class_clang_type, attrs.name, member_clang_type, accessibility,3155 attrs.bit_size);3156 3157 m_ast.SetMetadataAsUserID(field_decl, die.GetID());3158 3159 layout_info.field_offsets.insert(3160 std::make_pair(field_decl, field_bit_offset));3161}3162 3163bool DWARFASTParserClang::ParseChildMembers(3164 const DWARFDIE &parent_die, const CompilerType &class_clang_type,3165 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,3166 std::vector<DWARFDIE> &member_function_dies,3167 std::vector<DWARFDIE> &contained_type_dies,3168 DelayedPropertyList &delayed_properties,3169 const AccessType default_accessibility,3170 ClangASTImporter::LayoutInfo &layout_info) {3171 if (!parent_die)3172 return false;3173 3174 FieldInfo last_field_info;3175 3176 ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();3177 auto ast = class_clang_type.GetTypeSystem<TypeSystemClang>();3178 if (ast == nullptr)3179 return false;3180 3181 for (DWARFDIE die : parent_die.children()) {3182 dw_tag_t tag = die.Tag();3183 3184 switch (tag) {3185 case DW_TAG_APPLE_property:3186 ParseObjCProperty(die, parent_die, class_clang_type, delayed_properties);3187 break;3188 3189 case DW_TAG_variant_part:3190 if (die.GetCU()->GetDWARFLanguageType() == eLanguageTypeRust) {3191 ParseRustVariantPart(die, parent_die, class_clang_type,3192 default_accessibility, layout_info);3193 }3194 break;3195 3196 case DW_TAG_variable: {3197 const MemberAttributes attrs(die, parent_die, module_sp);3198 CreateStaticMemberVariable(die, attrs, class_clang_type);3199 } break;3200 case DW_TAG_member:3201 ParseSingleMember(die, parent_die, class_clang_type,3202 default_accessibility, layout_info, last_field_info);3203 break;3204 3205 case DW_TAG_subprogram:3206 // Let the type parsing code handle this one for us.3207 member_function_dies.push_back(die);3208 break;3209 3210 case DW_TAG_inheritance:3211 ParseInheritance(die, parent_die, class_clang_type, default_accessibility,3212 module_sp, base_classes, layout_info);3213 break;3214 3215 default:3216 if (llvm::dwarf::isType(tag))3217 contained_type_dies.push_back(die);3218 break;3219 }3220 }3221 3222 return true;3223}3224 3225void DWARFASTParserClang::ParseChildParameters(3226 clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die,3227 bool &is_variadic, bool &has_template_params,3228 std::vector<CompilerType> &function_param_types,3229 llvm::SmallVectorImpl<llvm::StringRef> &function_param_names) {3230 if (!parent_die)3231 return;3232 3233 for (DWARFDIE die : parent_die.children()) {3234 const dw_tag_t tag = die.Tag();3235 switch (tag) {3236 case DW_TAG_formal_parameter: {3237 if (die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))3238 continue;3239 3240 DWARFDIE param_type_die = die.GetAttributeValueAsReferenceDIE(DW_AT_type);3241 3242 Type *type = die.ResolveTypeUID(param_type_die);3243 if (!type)3244 break;3245 3246 function_param_names.emplace_back(die.GetName());3247 function_param_types.push_back(type->GetForwardCompilerType());3248 } break;3249 3250 case DW_TAG_unspecified_parameters:3251 is_variadic = true;3252 break;3253 3254 case DW_TAG_template_type_parameter:3255 case DW_TAG_template_value_parameter:3256 case DW_TAG_GNU_template_parameter_pack:3257 // The one caller of this was never using the template_param_infos, and3258 // the local variable was taking up a large amount of stack space in3259 // SymbolFileDWARF::ParseType() so this was removed. If we ever need the3260 // template params back, we can add them back.3261 // ParseTemplateDIE (dwarf_cu, die, template_param_infos);3262 has_template_params = true;3263 break;3264 3265 default:3266 break;3267 }3268 }3269 3270 assert(function_param_names.size() == function_param_types.size());3271}3272 3273clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {3274 if (!die)3275 return nullptr;3276 3277 switch (die.Tag()) {3278 case DW_TAG_constant:3279 case DW_TAG_formal_parameter:3280 case DW_TAG_imported_declaration:3281 case DW_TAG_imported_module:3282 break;3283 case DW_TAG_variable:3284 // This means 'die' is a C++ static data member.3285 // We don't want to create decls for such members3286 // here.3287 if (auto parent = die.GetParent();3288 parent.IsValid() && TagIsRecordType(parent.Tag()))3289 return nullptr;3290 break;3291 default:3292 return nullptr;3293 }3294 3295 DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE());3296 if (cache_pos != m_die_to_decl.end())3297 return cache_pos->second;3298 3299 if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) {3300 clang::Decl *decl = GetClangDeclForDIE(spec_die);3301 m_die_to_decl[die.GetDIE()] = decl;3302 return decl;3303 }3304 3305 if (DWARFDIE abstract_origin_die =3306 die.GetReferencedDIE(DW_AT_abstract_origin)) {3307 clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);3308 m_die_to_decl[die.GetDIE()] = decl;3309 return decl;3310 }3311 3312 clang::Decl *decl = nullptr;3313 switch (die.Tag()) {3314 case DW_TAG_variable:3315 case DW_TAG_constant:3316 case DW_TAG_formal_parameter: {3317 SymbolFileDWARF *dwarf = die.GetDWARF();3318 Type *type = GetTypeForDIE(die);3319 if (dwarf && type) {3320 const char *name = die.GetName();3321 clang::DeclContext *decl_context =3322 TypeSystemClang::DeclContextGetAsDeclContext(3323 dwarf->GetDeclContextContainingUID(die.GetID()));3324 decl = m_ast.CreateVariableDeclaration(3325 decl_context, GetOwningClangModule(die), name,3326 ClangUtil::GetQualType(type->GetForwardCompilerType()));3327 }3328 break;3329 }3330 case DW_TAG_imported_declaration: {3331 SymbolFileDWARF *dwarf = die.GetDWARF();3332 DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);3333 if (imported_uid) {3334 CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid);3335 if (imported_decl) {3336 clang::DeclContext *decl_context =3337 TypeSystemClang::DeclContextGetAsDeclContext(3338 dwarf->GetDeclContextContainingUID(die.GetID()));3339 if (clang::NamedDecl *clang_imported_decl =3340 llvm::dyn_cast<clang::NamedDecl>(3341 (clang::Decl *)imported_decl.GetOpaqueDecl()))3342 decl = m_ast.CreateUsingDeclaration(3343 decl_context, OptionalClangModuleID(), clang_imported_decl);3344 }3345 }3346 break;3347 }3348 case DW_TAG_imported_module: {3349 SymbolFileDWARF *dwarf = die.GetDWARF();3350 DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);3351 3352 if (imported_uid) {3353 CompilerDeclContext imported_decl_ctx =3354 SymbolFileDWARF::GetDeclContext(imported_uid);3355 if (imported_decl_ctx) {3356 clang::DeclContext *decl_context =3357 TypeSystemClang::DeclContextGetAsDeclContext(3358 dwarf->GetDeclContextContainingUID(die.GetID()));3359 if (clang::NamespaceDecl *ns_decl =3360 TypeSystemClang::DeclContextGetAsNamespaceDecl(3361 imported_decl_ctx))3362 decl = m_ast.CreateUsingDirectiveDeclaration(3363 decl_context, OptionalClangModuleID(), ns_decl);3364 }3365 }3366 break;3367 }3368 default:3369 break;3370 }3371 3372 m_die_to_decl[die.GetDIE()] = decl;3373 3374 return decl;3375}3376 3377clang::DeclContext *3378DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {3379 if (die) {3380 clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die);3381 if (decl_ctx)3382 return decl_ctx;3383 3384 bool try_parsing_type = true;3385 switch (die.Tag()) {3386 case DW_TAG_compile_unit:3387 case DW_TAG_partial_unit:3388 decl_ctx = m_ast.GetTranslationUnitDecl();3389 try_parsing_type = false;3390 break;3391 3392 case DW_TAG_namespace:3393 decl_ctx = ResolveNamespaceDIE(die);3394 try_parsing_type = false;3395 break;3396 3397 case DW_TAG_imported_declaration:3398 decl_ctx = ResolveImportedDeclarationDIE(die);3399 try_parsing_type = false;3400 break;3401 3402 case DW_TAG_lexical_block:3403 decl_ctx = GetDeclContextForBlock(die);3404 try_parsing_type = false;3405 break;3406 3407 default:3408 break;3409 }3410 3411 if (decl_ctx == nullptr && try_parsing_type) {3412 Type *type = die.GetDWARF()->ResolveType(die);3413 if (type)3414 decl_ctx = GetCachedClangDeclContextForDIE(die);3415 }3416 3417 if (decl_ctx) {3418 LinkDeclContextToDIE(decl_ctx, die);3419 return decl_ctx;3420 }3421 }3422 return nullptr;3423}3424 3425OptionalClangModuleID3426DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) {3427 if (!die.IsValid())3428 return {};3429 3430 for (DWARFDIE parent = die.GetParent(); parent.IsValid();3431 parent = parent.GetParent()) {3432 const dw_tag_t tag = parent.Tag();3433 if (tag == DW_TAG_module) {3434 DWARFDIE module_die = parent;3435 auto it = m_die_to_module.find(module_die.GetDIE());3436 if (it != m_die_to_module.end())3437 return it->second;3438 const char *name =3439 module_die.GetAttributeValueAsString(DW_AT_name, nullptr);3440 if (!name)3441 return {};3442 3443 OptionalClangModuleID id =3444 m_ast.GetOrCreateClangModule(name, GetOwningClangModule(module_die));3445 m_die_to_module.insert({module_die.GetDIE(), id});3446 return id;3447 }3448 }3449 return {};3450}3451 3452static bool IsSubroutine(const DWARFDIE &die) {3453 switch (die.Tag()) {3454 case DW_TAG_subprogram:3455 case DW_TAG_inlined_subroutine:3456 return true;3457 default:3458 return false;3459 }3460}3461 3462static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) {3463 for (DWARFDIE candidate = die; candidate; candidate = candidate.GetParent()) {3464 if (IsSubroutine(candidate)) {3465 if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {3466 return candidate;3467 } else {3468 return DWARFDIE();3469 }3470 }3471 }3472 assert(0 && "Shouldn't call GetContainingFunctionWithAbstractOrigin on "3473 "something not in a function");3474 return DWARFDIE();3475}3476 3477static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) {3478 for (DWARFDIE candidate : context.children()) {3479 if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {3480 return candidate;3481 }3482 }3483 return DWARFDIE();3484}3485 3486static DWARFDIE FindFirstChildWithAbstractOrigin(const DWARFDIE &block,3487 const DWARFDIE &function) {3488 assert(IsSubroutine(function));3489 for (DWARFDIE context = block; context != function.GetParent();3490 context = context.GetParent()) {3491 assert(!IsSubroutine(context) || context == function);3492 if (DWARFDIE child = FindAnyChildWithAbstractOrigin(context)) {3493 return child;3494 }3495 }3496 return DWARFDIE();3497}3498 3499clang::DeclContext *3500DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) {3501 assert(die.Tag() == DW_TAG_lexical_block);3502 DWARFDIE containing_function_with_abstract_origin =3503 GetContainingFunctionWithAbstractOrigin(die);3504 if (!containing_function_with_abstract_origin) {3505 return (clang::DeclContext *)ResolveBlockDIE(die);3506 }3507 DWARFDIE child = FindFirstChildWithAbstractOrigin(3508 die, containing_function_with_abstract_origin);3509 CompilerDeclContext decl_context =3510 GetDeclContextContainingUIDFromDWARF(child);3511 return (clang::DeclContext *)decl_context.GetOpaqueDeclContext();3512}3513 3514clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {3515 if (die && die.Tag() == DW_TAG_lexical_block) {3516 clang::BlockDecl *decl =3517 llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);3518 3519 if (!decl) {3520 DWARFDIE decl_context_die;3521 clang::DeclContext *decl_context =3522 GetClangDeclContextContainingDIE(die, &decl_context_die);3523 decl =3524 m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die));3525 3526 if (decl)3527 LinkDeclContextToDIE((clang::DeclContext *)decl, die);3528 }3529 3530 return decl;3531 }3532 return nullptr;3533}3534 3535clang::NamespaceDecl *3536DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {3537 if (die && die.Tag() == DW_TAG_namespace) {3538 // See if we already parsed this namespace DIE and associated it with a3539 // uniqued namespace declaration3540 clang::NamespaceDecl *namespace_decl =3541 static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);3542 if (namespace_decl)3543 return namespace_decl;3544 else {3545 const char *namespace_name = die.GetName();3546 clang::DeclContext *containing_decl_ctx =3547 GetClangDeclContextContainingDIE(die, nullptr);3548 bool is_inline =3549 die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;3550 3551 namespace_decl = m_ast.GetUniqueNamespaceDeclaration(3552 namespace_name, containing_decl_ctx, GetOwningClangModule(die),3553 is_inline);3554 3555 if (namespace_decl)3556 LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die);3557 return namespace_decl;3558 }3559 }3560 return nullptr;3561}3562 3563clang::NamespaceDecl *3564DWARFASTParserClang::ResolveImportedDeclarationDIE(const DWARFDIE &die) {3565 assert(die && die.Tag() == DW_TAG_imported_declaration);3566 3567 // See if we cached a NamespaceDecl for this imported declaration3568 // already3569 auto it = m_die_to_decl_ctx.find(die.GetDIE());3570 if (it != m_die_to_decl_ctx.end())3571 return static_cast<clang::NamespaceDecl *>(it->getSecond());3572 3573 clang::NamespaceDecl *namespace_decl = nullptr;3574 3575 const DWARFDIE imported_uid =3576 die.GetAttributeValueAsReferenceDIE(DW_AT_import);3577 if (!imported_uid)3578 return nullptr;3579 3580 switch (imported_uid.Tag()) {3581 case DW_TAG_imported_declaration:3582 namespace_decl = ResolveImportedDeclarationDIE(imported_uid);3583 break;3584 case DW_TAG_namespace:3585 namespace_decl = ResolveNamespaceDIE(imported_uid);3586 break;3587 default:3588 return nullptr;3589 }3590 3591 if (!namespace_decl)3592 return nullptr;3593 3594 LinkDeclContextToDIE(namespace_decl, die);3595 3596 return namespace_decl;3597}3598 3599clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE(3600 const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) {3601 SymbolFileDWARF *dwarf = die.GetDWARF();3602 3603 DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die);3604 3605 if (decl_ctx_die_copy)3606 *decl_ctx_die_copy = decl_ctx_die;3607 3608 if (decl_ctx_die) {3609 clang::DeclContext *clang_decl_ctx =3610 GetClangDeclContextForDIE(decl_ctx_die);3611 if (clang_decl_ctx)3612 return clang_decl_ctx;3613 }3614 return m_ast.GetTranslationUnitDecl();3615}3616 3617clang::DeclContext *3618DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) {3619 if (die) {3620 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());3621 if (pos != m_die_to_decl_ctx.end())3622 return pos->second;3623 }3624 return nullptr;3625}3626 3627void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx,3628 const DWARFDIE &die) {3629 m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;3630 // There can be many DIEs for a single decl context3631 // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());3632 m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));3633}3634 3635bool DWARFASTParserClang::CopyUniqueClassMethodTypes(3636 const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die,3637 lldb_private::Type *class_type, std::vector<DWARFDIE> &failures) {3638 if (!class_type || !src_class_die || !dst_class_die)3639 return false;3640 if (src_class_die.Tag() != dst_class_die.Tag())3641 return false;3642 3643 // We need to complete the class type so we can get all of the method types3644 // parsed so we can then unique those types to their equivalent counterparts3645 // in "dst_cu" and "dst_class_die"3646 class_type->GetFullCompilerType();3647 3648 auto gather = [](DWARFDIE die, UniqueCStringMap<DWARFDIE> &map,3649 UniqueCStringMap<DWARFDIE> &map_artificial) {3650 if (die.Tag() != DW_TAG_subprogram)3651 return;3652 // Make sure this is a declaration and not a concrete instance by looking3653 // for DW_AT_declaration set to 1. Sometimes concrete function instances are3654 // placed inside the class definitions and shouldn't be included in the list3655 // of things that are tracking here.3656 if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) != 1)3657 return;3658 3659 if (const char *name = die.GetMangledName()) {3660 ConstString const_name(name);3661 if (die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))3662 map_artificial.Append(const_name, die);3663 else3664 map.Append(const_name, die);3665 }3666 };3667 3668 UniqueCStringMap<DWARFDIE> src_name_to_die;3669 UniqueCStringMap<DWARFDIE> dst_name_to_die;3670 UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;3671 UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;3672 for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die.IsValid();3673 src_die = src_die.GetSibling()) {3674 gather(src_die, src_name_to_die, src_name_to_die_artificial);3675 }3676 for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();3677 dst_die = dst_die.GetSibling()) {3678 gather(dst_die, dst_name_to_die, dst_name_to_die_artificial);3679 }3680 const uint32_t src_size = src_name_to_die.GetSize();3681 const uint32_t dst_size = dst_name_to_die.GetSize();3682 3683 // Is everything kosher so we can go through the members at top speed?3684 bool fast_path = true;3685 3686 if (src_size != dst_size)3687 fast_path = false;3688 3689 uint32_t idx;3690 3691 if (fast_path) {3692 for (idx = 0; idx < src_size; ++idx) {3693 DWARFDIE src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);3694 DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);3695 3696 if (src_die.Tag() != dst_die.Tag())3697 fast_path = false;3698 3699 const char *src_name = src_die.GetMangledName();3700 const char *dst_name = dst_die.GetMangledName();3701 3702 // Make sure the names match3703 if (src_name == dst_name || (strcmp(src_name, dst_name) == 0))3704 continue;3705 3706 fast_path = false;3707 }3708 }3709 3710 DWARFASTParserClang *src_dwarf_ast_parser =3711 static_cast<DWARFASTParserClang *>(3712 SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU()));3713 DWARFASTParserClang *dst_dwarf_ast_parser =3714 static_cast<DWARFASTParserClang *>(3715 SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU()));3716 auto link = [&](DWARFDIE src, DWARFDIE dst) {3717 auto &die_to_type = dst_class_die.GetDWARF()->GetDIEToType();3718 clang::DeclContext *dst_decl_ctx =3719 dst_dwarf_ast_parser->m_die_to_decl_ctx[dst.GetDIE()];3720 if (dst_decl_ctx)3721 src_dwarf_ast_parser->LinkDeclContextToDIE(dst_decl_ctx, src);3722 3723 if (Type *src_child_type = die_to_type.lookup(src.GetDIE()))3724 die_to_type[dst.GetDIE()] = src_child_type;3725 };3726 3727 // Now do the work of linking the DeclContexts and Types.3728 if (fast_path) {3729 // We can do this quickly. Just run across the tables index-for-index3730 // since we know each node has matching names and tags.3731 for (idx = 0; idx < src_size; ++idx) {3732 link(src_name_to_die.GetValueAtIndexUnchecked(idx),3733 dst_name_to_die.GetValueAtIndexUnchecked(idx));3734 }3735 } else {3736 // We must do this slowly. For each member of the destination, look up a3737 // member in the source with the same name, check its tag, and unique them3738 // if everything matches up. Report failures.3739 3740 if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) {3741 src_name_to_die.Sort();3742 3743 for (idx = 0; idx < dst_size; ++idx) {3744 ConstString dst_name = dst_name_to_die.GetCStringAtIndex(idx);3745 DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);3746 DWARFDIE src_die = src_name_to_die.Find(dst_name, DWARFDIE());3747 3748 if (src_die && (src_die.Tag() == dst_die.Tag()))3749 link(src_die, dst_die);3750 else3751 failures.push_back(dst_die);3752 }3753 }3754 }3755 3756 const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize();3757 const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize();3758 3759 if (src_size_artificial && dst_size_artificial) {3760 dst_name_to_die_artificial.Sort();3761 3762 for (idx = 0; idx < src_size_artificial; ++idx) {3763 ConstString src_name_artificial =3764 src_name_to_die_artificial.GetCStringAtIndex(idx);3765 DWARFDIE src_die =3766 src_name_to_die_artificial.GetValueAtIndexUnchecked(idx);3767 DWARFDIE dst_die =3768 dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE());3769 3770 // Both classes have the artificial types, link them3771 if (dst_die)3772 link(src_die, dst_die);3773 }3774 }3775 3776 if (dst_size_artificial) {3777 for (idx = 0; idx < dst_size_artificial; ++idx) {3778 failures.push_back(3779 dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx));3780 }3781 }3782 3783 return !failures.empty();3784}3785 3786bool DWARFASTParserClang::ShouldCreateUnnamedBitfield(3787 FieldInfo const &last_field_info, uint64_t last_field_end,3788 FieldInfo const &this_field_info,3789 lldb_private::ClangASTImporter::LayoutInfo const &layout_info) const {3790 // If we have a gap between the last_field_end and the current3791 // field we have an unnamed bit-field.3792 if (this_field_info.bit_offset <= last_field_end)3793 return false;3794 3795 // If we have a base class, we assume there is no unnamed3796 // bit-field if either of the following is true:3797 // (a) this is the first field since the gap can be3798 // attributed to the members from the base class.3799 // FIXME: This assumption is not correct if the first field of3800 // the derived class is indeed an unnamed bit-field. We currently3801 // do not have the machinary to track the offset of the last field3802 // of classes we have seen before, so we are not handling this case.3803 // (b) Or, the first member of the derived class was a vtable pointer.3804 // In this case we don't want to create an unnamed bitfield either3805 // since those will be inserted by clang later.3806 const bool have_base = layout_info.base_offsets.size() != 0;3807 const bool this_is_first_field =3808 last_field_info.bit_offset == 0 && last_field_info.bit_size == 0;3809 const bool first_field_is_vptr =3810 last_field_info.bit_offset == 0 && last_field_info.IsArtificial();3811 3812 if (have_base && (this_is_first_field || first_field_is_vptr))3813 return false;3814 3815 return true;3816}3817 3818void DWARFASTParserClang::AddUnnamedBitfieldToRecordTypeIfNeeded(3819 ClangASTImporter::LayoutInfo &class_layout_info,3820 const CompilerType &class_clang_type, const FieldInfo &previous_field,3821 const FieldInfo ¤t_field) {3822 // TODO: get this value from target3823 const uint64_t word_width = 32;3824 uint64_t last_field_end = previous_field.GetEffectiveFieldEnd();3825 3826 if (!previous_field.IsBitfield()) {3827 // The last field was not a bit-field...3828 // but if it did take up the entire word then we need to extend3829 // last_field_end so the bit-field does not step into the last3830 // fields padding.3831 if (last_field_end != 0 && ((last_field_end % word_width) != 0))3832 last_field_end += word_width - (last_field_end % word_width);3833 }3834 3835 // Nothing to be done.3836 if (!ShouldCreateUnnamedBitfield(previous_field, last_field_end,3837 current_field, class_layout_info))3838 return;3839 3840 // Place the unnamed bitfield into the gap between the previous field's end3841 // and the current field's start.3842 const uint64_t unnamed_bit_size = current_field.bit_offset - last_field_end;3843 const uint64_t unnamed_bit_offset = last_field_end;3844 3845 clang::FieldDecl *unnamed_bitfield_decl =3846 TypeSystemClang::AddFieldToRecordType(3847 class_clang_type, llvm::StringRef(),3848 m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),3849 lldb::AccessType::eAccessPublic, unnamed_bit_size);3850 3851 class_layout_info.field_offsets.insert(3852 std::make_pair(unnamed_bitfield_decl, unnamed_bit_offset));3853}3854 3855void DWARFASTParserClang::ParseRustVariantPart(3856 DWARFDIE &die, const DWARFDIE &parent_die,3857 const CompilerType &class_clang_type,3858 const lldb::AccessType default_accesibility,3859 ClangASTImporter::LayoutInfo &layout_info) {3860 assert(die.Tag() == llvm::dwarf::DW_TAG_variant_part);3861 assert(SymbolFileDWARF::GetLanguage(*die.GetCU()) ==3862 LanguageType::eLanguageTypeRust);3863 3864 ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();3865 3866 VariantPart variants(die, parent_die, module_sp);3867 3868 auto discriminant_type =3869 die.ResolveTypeUID(variants.discriminant().type_ref.Reference());3870 3871 auto decl_context = m_ast.GetDeclContextForType(class_clang_type);3872 3873 auto inner_holder = m_ast.CreateRecordType(3874 decl_context, OptionalClangModuleID(), lldb::eAccessPublic,3875 std::string(3876 llvm::formatv("{0}$Inner", class_clang_type.GetTypeName(false))),3877 llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeRust);3878 m_ast.StartTagDeclarationDefinition(inner_holder);3879 m_ast.SetIsPacked(inner_holder);3880 3881 for (auto member : variants.members()) {3882 3883 auto has_discriminant = !member.IsDefault();3884 3885 auto member_type = die.ResolveTypeUID(member.type_ref.Reference());3886 3887 auto field_type = m_ast.CreateRecordType(3888 m_ast.GetDeclContextForType(inner_holder), OptionalClangModuleID(),3889 lldb::eAccessPublic,3890 std::string(llvm::formatv("{0}$Variant", member.GetName())),3891 llvm::to_underlying(clang::TagTypeKind::Struct),3892 lldb::eLanguageTypeRust);3893 3894 m_ast.StartTagDeclarationDefinition(field_type);3895 auto offset = member.byte_offset;3896 3897 if (has_discriminant) {3898 m_ast.AddFieldToRecordType(3899 field_type, "$discr$", discriminant_type->GetFullCompilerType(),3900 lldb::eAccessPublic, variants.discriminant().byte_offset);3901 offset +=3902 llvm::expectedToOptional(discriminant_type->GetByteSize(nullptr))3903 .value_or(0);3904 }3905 3906 m_ast.AddFieldToRecordType(field_type, "value",3907 member_type->GetFullCompilerType(),3908 lldb::eAccessPublic, offset * 8);3909 3910 m_ast.CompleteTagDeclarationDefinition(field_type);3911 3912 auto name = has_discriminant3913 ? llvm::formatv("$variant${0}", member.discr_value.value())3914 : std::string("$variant$");3915 3916 auto variant_decl =3917 m_ast.AddFieldToRecordType(inner_holder, llvm::StringRef(name),3918 field_type, default_accesibility, 0);3919 3920 layout_info.field_offsets.insert({variant_decl, 0});3921 }3922 3923 auto inner_field = m_ast.AddFieldToRecordType(class_clang_type,3924 llvm::StringRef("$variants$"),3925 inner_holder, eAccessPublic, 0);3926 3927 m_ast.CompleteTagDeclarationDefinition(inner_holder);3928 3929 layout_info.field_offsets.insert({inner_field, 0});3930}3931