diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp')
| -rw-r--r-- | source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 308 | 
1 files changed, 110 insertions, 198 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index fe6f1be3ca48a..70d48e5f1dfa1 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -125,7 +125,7 @@ ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {  }  /// Detect a forward declaration that is nested in a DW_TAG_module. -static bool isClangModuleFwdDecl(const DWARFDIE &Die) { +static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {    if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))      return false;    auto Parent = Die.GetParent(); @@ -142,30 +142,31 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {    if (!dwo_module_sp)      return TypeSP(); -  // This type comes from an external DWO module. -  std::vector<CompilerContext> dwo_context; -  die.GetDWOContext(dwo_context); +  // If this type comes from a Clang module, look in the DWARF section +  // of the pcm file in the module cache. Clang generates DWO skeleton +  // units as breadcrumbs to find them. +  std::vector<CompilerContext> decl_context; +  die.GetDeclContext(decl_context);    TypeMap dwo_types; -  if (!dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, +  if (!dwo_module_sp->GetSymbolVendor()->FindTypes(decl_context, true,                                                     dwo_types)) { -    if (!isClangModuleFwdDecl(die)) +    if (!IsClangModuleFwdDecl(die))        return TypeSP();      // Since this this type is defined in one of the Clang modules imported by      // this symbol file, search all of them. -    auto *SymFile = die.GetCU()->GetSymbolFileDWARF(); -    for (const auto &NameModule : SymFile->getExternalTypeModules()) { -      if (!NameModule.second) +    auto *sym_file = die.GetCU()->GetSymbolFileDWARF(); +    for (const auto &name_module : sym_file->getExternalTypeModules()) { +      if (!name_module.second)          continue; -      SymbolVendor *SymVendor = NameModule.second->GetSymbolVendor(); -      if (SymVendor->FindTypes(dwo_context, true, dwo_types)) +      SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor(); +      if (sym_vendor->FindTypes(decl_context, true, dwo_types))          break;      }    } -  const size_t num_dwo_types = dwo_types.GetSize(); -  if (num_dwo_types != 1) +  if (dwo_types.GetSize() != 1)      return TypeSP();    // We found a real definition for this type in the Clang module, so lets use @@ -307,14 +308,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,                  decl.SetColumn(form_value.Unsigned());                  break;                case DW_AT_name: -                  type_name_cstr = form_value.AsCString(); -                // Work around a bug in llvm-gcc where they give a name to a -                // reference type which doesn't include the "&"... -                if (tag == DW_TAG_reference_type) { -                  if (strchr(type_name_cstr, '&') == NULL) -                    type_name_cstr = NULL; -                }                  if (type_name_cstr)                    type_name_const_str.SetCString(type_name_cstr);                  break; @@ -421,8 +415,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,          if (!clang_type &&              (encoding_data_type == Type::eEncodingIsPointerUID || -             encoding_data_type == Type::eEncodingIsTypedefUID) && -            sc.comp_unit != NULL) { +             encoding_data_type == Type::eEncodingIsTypedefUID)) {            if (tag == DW_TAG_pointer_type) {              DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type); @@ -558,16 +551,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,              if (attributes.ExtractFormValueAtIndex(i, form_value)) {                switch (attr) {                case DW_AT_decl_file: -                if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) { -                  // llvm-gcc outputs invalid DW_AT_decl_file attributes that -                  // always point to the compile unit file, so we clear this -                  // invalid value so that we can still unique types -                  // efficiently. -                  decl.SetFile(FileSpec("<invalid>", false)); -                } else -                  decl.SetFile( -                      sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( -                          form_value.Unsigned())); +                decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( +                    form_value.Unsigned()));                  break;                case DW_AT_decl_line: @@ -671,7 +656,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,          }          if (byte_size_valid && byte_size == 0 && type_name_cstr && -            die.HasChildren() == false && +            !die.HasChildren() &&              sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {            // Work around an issue with clang at the moment where forward            // declarations for objective C classes are emitted as: @@ -909,7 +894,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,            // has child classes or types that require the class to be created            // for use as their decl contexts the class will be ready to accept            // these child definitions. -          if (die.HasChildren() == false) { +          if (!die.HasChildren()) {              // No children for this struct/union/class, lets finish it              if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {                ClangASTContext::CompleteTagDeclarationDefinition(clang_type); @@ -1308,10 +1293,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,          if (die.HasChildren()) {            bool skip_artificial = true; -          ParseChildParameters(sc, containing_decl_ctx, die, skip_artificial, -                               is_static, is_variadic, has_template_params, -                               function_param_types, function_param_decls, -                               type_quals); +          ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die, +                               skip_artificial, is_static, is_variadic, +                               has_template_params, function_param_types, +                               function_param_decls, type_quals);          }          bool ignore_containing_context = false; @@ -1748,16 +1733,19 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,            Type *element_type = dwarf->ResolveTypeUID(type_die_ref);            if (element_type) { -            std::vector<uint64_t> element_orders; -            ParseChildArrayInfo(sc, die, first_index, element_orders, -                                byte_stride, bit_stride); +            auto array_info = ParseChildArrayInfo(die); +            if (array_info) { +              first_index = array_info->first_index; +              byte_stride = array_info->byte_stride; +              bit_stride = array_info->bit_stride; +            }              if (byte_stride == 0 && bit_stride == 0)                byte_stride = element_type->GetByteSize();              CompilerType array_element_type =                  element_type->GetForwardCompilerType();              if (ClangASTContext::IsCXXClassType(array_element_type) && -                array_element_type.GetCompleteType() == false) { +                !array_element_type.GetCompleteType()) {                ModuleSP module_sp = die.GetModule();                if (module_sp) {                  if (die.GetCU()->GetProducer() == eProducerClang) @@ -1800,12 +1788,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,              }              uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; -            if (element_orders.size() > 0) { +            if (array_info && array_info->element_orders.size() > 0) {                uint64_t num_elements = 0; -              std::vector<uint64_t>::const_reverse_iterator pos; -              std::vector<uint64_t>::const_reverse_iterator end = -                  element_orders.rend(); -              for (pos = element_orders.rbegin(); pos != end; ++pos) { +              auto end = array_info->element_orders.rend(); +              for (auto pos = array_info->element_orders.rbegin(); pos != end; +                   ++pos) {                  num_elements = *pos;                  clang_type = m_ast.CreateArrayType(array_element_type,                                                     num_elements, is_vector); @@ -1824,6 +1811,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,                  NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID,                  &decl, clang_type, Type::eResolveStateFull));              type_sp->SetEncodingType(element_type); +            m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), +                                      die.GetID());            }          }        } break; @@ -1861,12 +1850,14 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,            clang_type = ClangASTContext::CreateMemberPointerType(                class_clang_type, pointee_clang_type); -          byte_size = clang_type.GetByteSize(nullptr); - -          type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, -                                 byte_size, NULL, LLDB_INVALID_UID, -                                 Type::eEncodingIsUID, NULL, clang_type, -                                 Type::eResolveStateForward)); +          if (llvm::Optional<uint64_t> clang_type_size = +                  clang_type.GetByteSize(nullptr)) { +            byte_size = *clang_type_size; +            type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, +                                   byte_size, NULL, LLDB_INVALID_UID, +                                   Type::eEncodingIsUID, NULL, clang_type, +                                   Type::eResolveStateForward)); +          }          }          break; @@ -2056,7 +2047,10 @@ bool DWARFASTParserClang::ParseTemplateDIE(          clang_type.IsIntegerOrEnumerationType(is_signed);          if (tag == DW_TAG_template_value_parameter && uval64_valid) { -          llvm::APInt apint(clang_type.GetBitSize(nullptr), uval64, is_signed); +          llvm::Optional<uint64_t> size = clang_type.GetBitSize(nullptr); +          if (!size) +            return false; +          llvm::APInt apint(*size, uval64, is_signed);            template_param_infos.args.push_back(                clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed),                                        ClangUtil::GetQualType(clang_type))); @@ -2108,95 +2102,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(    return template_param_infos.args.size() == template_param_infos.names.size();  } -// Checks whether m1 is an overload of m2 (as opposed to an override). This is -// called by addOverridesForMethod to distinguish overrides (which share a -// vtable entry) from overloads (which require distinct entries). -static bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) { -  // FIXME: This should detect covariant return types, but currently doesn't. -  lldbassert(&m1->getASTContext() == &m2->getASTContext() && -             "Methods should have the same AST context"); -  clang::ASTContext &context = m1->getASTContext(); - -  const auto *m1Type = -    llvm::cast<clang::FunctionProtoType>( -      context.getCanonicalType(m1->getType())); - -  const auto *m2Type = -    llvm::cast<clang::FunctionProtoType>( -      context.getCanonicalType(m2->getType())); - -  auto compareArgTypes = -    [&context](const clang::QualType &m1p, const clang::QualType &m2p) { -      return context.hasSameType(m1p.getUnqualifiedType(), -                                 m2p.getUnqualifiedType()); -    }; - -  // FIXME: In C++14 and later, we can just pass m2Type->param_type_end() -  //        as a fourth parameter to std::equal(). -  return (m1->getNumParams() != m2->getNumParams()) || -         !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(), -                     m2Type->param_type_begin(), compareArgTypes); -} - -// If decl is a virtual method, walk the base classes looking for methods that -// decl overrides. This table of overridden methods is used by IRGen to -// determine the vtable layout for decl's parent class. -static void addOverridesForMethod(clang::CXXMethodDecl *decl) { -  if (!decl->isVirtual()) -    return; - -  clang::CXXBasePaths paths; - -  auto find_overridden_methods = -    [decl](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) { -      if (auto *base_record = -          llvm::dyn_cast<clang::CXXRecordDecl>( -            specifier->getType()->getAs<clang::RecordType>()->getDecl())) { - -        clang::DeclarationName name = decl->getDeclName(); - -        // If this is a destructor, check whether the base class destructor is -        // virtual. -        if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) -          if (auto *baseDtorDecl = base_record->getDestructor()) { -            if (baseDtorDecl->isVirtual()) { -              path.Decls = baseDtorDecl; -              return true; -            } else -              return false; -          } - -        // Otherwise, search for name in the base class. -        for (path.Decls = base_record->lookup(name); !path.Decls.empty(); -             path.Decls = path.Decls.slice(1)) { -          if (auto *method_decl = -                llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front())) -            if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { -              path.Decls = method_decl; -              return true; -            } -        } -      } - -      return false; -    }; - -  if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) { -    for (auto *overridden_decl : paths.found_decls()) -      decl->addOverriddenMethod( -        llvm::cast<clang::CXXMethodDecl>(overridden_decl)); -  } -} - -// If clang_type is a CXXRecordDecl, builds the method override list for each -// of its virtual methods. -static void addMethodOverrides(ClangASTContext &ast, CompilerType &clang_type) { -  if (auto *record = -      ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType())) -    for (auto *method : record->methods()) -      addOverridesForMethod(method); -} -  bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,                                                  lldb_private::Type *type,                                                  CompilerType &clang_type) { @@ -2287,14 +2192,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,          }          SymbolContext sc(die.GetLLDBCompileUnit()); -        std::vector<clang::CXXBaseSpecifier *> base_classes; +        std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;          std::vector<int> member_accessibilities;          bool is_a_class = false;          // Parse members and base classes first          DWARFDIECollection member_function_dies;          DelayedPropertyList delayed_properties; -        ParseChildMembers(sc, die, clang_type, class_language, base_classes, +        ParseChildMembers(sc, die, clang_type, class_language, bases,                            member_accessibilities, member_function_dies,                            delayed_properties, default_accessibility, is_a_class,                            layout_info); @@ -2358,17 +2263,17 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,                &member_accessibilities.front(), member_accessibilities.size());          } -        if (!base_classes.empty()) { +        if (!bases.empty()) {            // Make sure all base classes refer to complete types and not forward            // declarations. If we don't do this, clang will crash with an -          // assertion in the call to clang_type.SetBaseClassesForClassType() -          for (auto &base_class : base_classes) { +          // assertion in the call to clang_type.TransferBaseClasses() +          for (const auto &base_class : bases) {              clang::TypeSourceInfo *type_source_info =                  base_class->getTypeSourceInfo();              if (type_source_info) {                CompilerType base_class_type(                    &m_ast, type_source_info->getType().getAsOpaquePtr()); -              if (base_class_type.GetCompleteType() == false) { +              if (!base_class_type.GetCompleteType()) {                  auto module = dwarf->GetObjectFile()->GetModule();                  module->ReportError(":: Class '%s' has a base class '%s' which "                                      "does not have a complete definition.", @@ -2381,7 +2286,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,                  // We have no choice other than to pretend that the base class                  // is complete. If we don't do this, clang will crash when we                  // call setBases() inside of -                // "clang_type.SetBaseClassesForClassType()" below. Since we +                // "clang_type.TransferBaseClasses()" below. Since we                  // provide layout assistance, all ivars in this class and other                  // classes will be fine, this is the best we can do short of                  // crashing. @@ -2393,19 +2298,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,                }              }            } -          m_ast.SetBaseClassesForClassType(clang_type.GetOpaqueQualType(), -                                           &base_classes.front(), -                                           base_classes.size()); - -          // Clang will copy each CXXBaseSpecifier in "base_classes" so we have -          // to free them all. -          ClangASTContext::DeleteBaseClassSpecifiers(&base_classes.front(), -                                                     base_classes.size()); + +          m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), +                                    std::move(bases));          }        }      } -    addMethodOverrides(m_ast, clang_type); +    m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType());      ClangASTContext::BuildIndirectFields(clang_type);      ClangASTContext::CompleteTagDeclarationDefinition(clang_type); @@ -2604,9 +2504,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators(          if (name && name[0] && got_value) {            m_ast.AddEnumerationValueToEnumerationType( -              clang_type.GetOpaqueQualType(), -              m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()), -              decl, name, enum_value, enumerator_byte_size * 8); +              clang_type, decl, name, enum_value, enumerator_byte_size * 8);            ++enumerators_added;          }        } @@ -2663,7 +2561,7 @@ protected:  };  #endif -Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, +Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,                                                        const DWARFDIE &die) {    DWARFRangeList func_ranges;    const char *name = NULL; @@ -2724,9 +2622,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,          clang::DeclContext *containing_decl_ctx =              GetClangDeclContextContainingDIE(die, nullptr); -        ParseChildParameters(sc, containing_decl_ctx, die, true, is_static, -                             is_variadic, has_template_params, param_types, -                             param_decls, type_quals); +        ParseChildParameters(comp_unit, containing_decl_ctx, die, true, +                             is_static, is_variadic, has_template_params, +                             param_types, param_decls, type_quals);          sstr << "(";          for (size_t i = 0; i < param_types.size(); i++) {            if (i > 0) @@ -2747,7 +2645,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,        std::unique_ptr<Declaration> decl_ap;        if (decl_file != 0 || decl_line != 0 || decl_column != 0)          decl_ap.reset(new Declaration( -            sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), +            comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),              decl_line, decl_column));        SymbolFileDWARF *dwarf = die.GetDWARF(); @@ -2758,7 +2656,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,        if (dwarf->FixupAddress(func_range.GetBaseAddress())) {          const user_id_t func_user_id = die.GetID(); -        func_sp.reset(new Function(sc.comp_unit, +        func_sp.reset(new Function(&comp_unit,                                     func_user_id, // UserID is the DIE offset                                     func_user_id, func_name, func_type,                                     func_range)); // first address range @@ -2766,7 +2664,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,          if (func_sp.get() != NULL) {            if (frame_base.IsValid())              func_sp->GetFrameBaseExpression() = frame_base; -          sc.comp_unit->AddFunction(func_sp); +          comp_unit.AddFunction(func_sp);            return func_sp.get();          }        } @@ -2778,7 +2676,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,  bool DWARFASTParserClang::ParseChildMembers(      const SymbolContext &sc, const DWARFDIE &parent_die,      CompilerType &class_clang_type, const LanguageType class_language, -    std::vector<clang::CXXBaseSpecifier *> &base_classes, +    std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,      std::vector<int> &member_accessibilities,      DWARFDIECollection &member_function_dies,      DelayedPropertyList &delayed_properties, AccessType &default_accessibility, @@ -2977,15 +2875,6 @@ bool DWARFASTParserClang::ParseChildMembers(              class_language == eLanguageTypeObjC_plus_plus)            accessibility = eAccessNone; -        if (member_idx == 0 && !is_artificial && name && -            (strstr(name, "_vptr$") == name)) { -          // Not all compilers will mark the vtable pointer member as -          // artificial (llvm-gcc). We can't have the virtual members in our -          // classes otherwise it throws off all child offsets since we end up -          // having and extra pointer sized member in our class layouts. -          is_artificial = true; -        } -          // Handle static members          if (is_external && member_byte_offset == UINT32_MAX) {            Type *var_type = die.ResolveTypeUID(DIERef(encoding_form)); @@ -3000,7 +2889,7 @@ bool DWARFASTParserClang::ParseChildMembers(            break;          } -        if (is_artificial == false) { +        if (!is_artificial) {            Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));            clang::FieldDecl *field_decl = NULL; @@ -3141,7 +3030,7 @@ bool DWARFASTParserClang::ParseChildMembers(                    if (anon_field_info.IsValid()) {                      clang::FieldDecl *unnamed_bitfield_decl =                          ClangASTContext::AddFieldToRecordType( -                            class_clang_type, NULL, +                            class_clang_type, llvm::StringRef(),                              m_ast.GetBuiltinTypeForEncodingAndBitSize(                                  eEncodingSint, word_width),                              accessibility, anon_field_info.bit_size); @@ -3198,7 +3087,7 @@ bool DWARFASTParserClang::ParseChildMembers(                }                if (ClangASTContext::IsCXXClassType(member_clang_type) && -                  member_clang_type.GetCompleteType() == false) { +                  !member_clang_type.GetCompleteType()) {                  if (die.GetCU()->GetProducer() == eProducerClang)                    module_sp->ReportError(                        "DWARF DIE at 0x%8.8x (class %s) has a member variable " @@ -3383,9 +3272,14 @@ bool DWARFASTParserClang::ParseChildMembers(          if (class_language == eLanguageTypeObjC) {            ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);          } else { -          base_classes.push_back(ast->CreateBaseClassSpecifier( -              base_class_clang_type.GetOpaqueQualType(), accessibility, -              is_virtual, is_base_of_class)); +          std::unique_ptr<clang::CXXBaseSpecifier> result = +              ast->CreateBaseClassSpecifier( +                  base_class_clang_type.GetOpaqueQualType(), accessibility, +                  is_virtual, is_base_of_class); +          if (!result) +            break; + +          base_classes.push_back(std::move(result));            if (is_virtual) {              // Do not specify any offset for virtual inheritance. The DWARF @@ -3419,7 +3313,7 @@ bool DWARFASTParserClang::ParseChildMembers(  }  size_t DWARFASTParserClang::ParseChildParameters( -    const SymbolContext &sc, clang::DeclContext *containing_decl_ctx, +    CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx,      const DWARFDIE &parent_die, bool skip_artificial, bool &is_static,      bool &is_variadic, bool &has_template_params,      std::vector<CompilerType> &function_param_types, @@ -3451,7 +3345,7 @@ size_t DWARFASTParserClang::ParseChildParameters(            if (attributes.ExtractFormValueAtIndex(i, form_value)) {              switch (attr) {              case DW_AT_decl_file: -              decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( +              decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex(                    form_value.Unsigned()));                break;              case DW_AT_decl_line: @@ -3517,8 +3411,9 @@ size_t DWARFASTParserClang::ParseChildParameters(              function_param_types.push_back(type->GetForwardCompilerType());              clang::ParmVarDecl *param_var_decl = -                m_ast.CreateParameterDeclaration( -                    name, type->GetForwardCompilerType(), storage); +                m_ast.CreateParameterDeclaration(containing_decl_ctx, name, +                                                 type->GetForwardCompilerType(), +                                                 storage);              assert(param_var_decl);              function_param_decls.push_back(param_var_decl); @@ -3551,12 +3446,12 @@ size_t DWARFASTParserClang::ParseChildParameters(    return arg_idx;  } -void DWARFASTParserClang::ParseChildArrayInfo( -    const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, -    std::vector<uint64_t> &element_orders, uint32_t &byte_stride, -    uint32_t &bit_stride) { +llvm::Optional<SymbolFile::ArrayInfo> +DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, +                                    const ExecutionContext *exe_ctx) { +  SymbolFile::ArrayInfo array_info;    if (!parent_die) -    return; +    return llvm::None;    for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();         die = die.GetSibling()) { @@ -3580,15 +3475,31 @@ void DWARFASTParserClang::ParseChildArrayInfo(                break;              case DW_AT_count: -              num_elements = form_value.Unsigned(); +              if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { +                if (var_die.Tag() == DW_TAG_variable) +                  if (exe_ctx) { +                    if (auto frame = exe_ctx->GetFrameSP()) { +                      Status error; +                      lldb::VariableSP var_sp; +                      auto valobj_sp = frame->GetValueForVariableExpressionPath( +                          var_die.GetName(), eNoDynamicValues, 0, var_sp, +                          error); +                      if (valobj_sp) { +                        num_elements = valobj_sp->GetValueAsUnsigned(0); +                        break; +                      } +                    } +                  } +              } else +                num_elements = form_value.Unsigned();                break;              case DW_AT_bit_stride: -              bit_stride = form_value.Unsigned(); +              array_info.bit_stride = form_value.Unsigned();                break;              case DW_AT_byte_stride: -              byte_stride = form_value.Unsigned(); +              array_info.byte_stride = form_value.Unsigned();                break;              case DW_AT_lower_bound: @@ -3622,11 +3533,12 @@ void DWARFASTParserClang::ParseChildArrayInfo(              num_elements = upper_bound - lower_bound + 1;          } -        element_orders.push_back(num_elements); +        array_info.element_orders.push_back(num_elements);        }      } break;      }    } +  return array_info;  }  Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {  | 
