brintos

brintos / llvm-project-archived public Read only

0
0
Text · 139.2 KiB · 36aa49a Raw
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 &current_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