diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 123 |
1 files changed, 42 insertions, 81 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 188a667ca564..46015f7b43b1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> +#include <cstdlib> #include "DWARFASTParserClang.h" #include "DWARFDebugInfo.h" @@ -49,7 +49,7 @@ //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN #ifdef ENABLE_DEBUG_PRINTF -#include <stdio.h> +#include <cstdio> #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) #else #define DEBUG_PRINTF(fmt, ...) @@ -60,7 +60,7 @@ using namespace lldb_private; DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast) : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} -DWARFASTParserClang::~DWARFASTParserClang() {} +DWARFASTParserClang::~DWARFASTParserClang() = default; static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) { switch (dwarf_accessibility) { @@ -157,7 +157,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, // The type in the Clang module must have the same language as the current CU. LanguageSet languages; - languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU())); + languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU())); llvm::DenseSet<SymbolFile *> searched_symbol_files; clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, searched_symbol_files, pcm_types); @@ -666,8 +666,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, // Blocks have a __FuncPtr inside them which is a pointer to a // function of the proper type. - for (DWARFDIE child_die = target_die.GetFirstChild(); - child_die.IsValid(); child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : target_die.children()) { if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), "__FuncPtr")) { DWARFDIE function_pointer_type = @@ -1226,6 +1225,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, } if (!function_decl) { + char *name_buf = nullptr; llvm::StringRef name = attrs.name.GetStringRef(); // We currently generate function templates with template parameters in @@ -1233,8 +1233,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, // we want to strip these from the name when creating the AST. if (attrs.mangled_name) { llvm::ItaniumPartialDemangler D; - if (!D.partialDemangle(attrs.mangled_name)) - name = D.getFunctionBaseName(nullptr, nullptr); + if (!D.partialDemangle(attrs.mangled_name)) { + name_buf = D.getFunctionBaseName(nullptr, nullptr); + name = name_buf; + } } // We just have a function that isn't part of a class @@ -1243,6 +1245,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, : containing_decl_ctx, GetOwningClangModule(die), name, clang_type, attrs.storage, attrs.is_inline); + std::free(name_buf); if (has_template_params) { TypeSystemClang::TemplateParameterInfos template_param_infos; @@ -1266,13 +1269,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, LinkDeclContextToDIE(function_decl, die); if (!function_param_decls.empty()) { - m_ast.SetFunctionParameters(function_decl, - &function_param_decls.front(), - function_param_decls.size()); + m_ast.SetFunctionParameters(function_decl, function_param_decls); if (template_function_decl) m_ast.SetFunctionParameters(template_function_decl, - &function_param_decls.front(), - function_param_decls.size()); + function_param_decls); } ClangASTMetadata metadata; @@ -1357,7 +1357,7 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true); CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType(); - CompilerType class_clang_type = class_type->GetLayoutCompilerType(); + CompilerType class_clang_type = class_type->GetForwardCompilerType(); CompilerType clang_type = TypeSystemClang::CreateMemberPointerType( class_clang_type, pointee_clang_type); @@ -1684,14 +1684,18 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, die.GetOffset(), attrs.name.GetCString()); } - if (tag == DW_TAG_structure_type) // this only applies in C - { + // If the byte size of the record is specified then overwrite the size + // that would be computed by Clang. This is only needed as LLDB's + // TypeSystemClang is always in C++ mode, but some compilers such as + // GCC and Clang give empty structs a size of 0 in C mode (in contrast to + // the size of 1 for empty structs that would be computed in C++ mode). + if (attrs.byte_size) { clang::RecordDecl *record_decl = TypeSystemClang::GetAsRecordDecl(clang_type); - if (record_decl) { - GetClangASTImporter().SetRecordLayout( - record_decl, ClangASTImporter::LayoutInfo()); + ClangASTImporter::LayoutInfo layout; + layout.bit_size = *attrs.byte_size * 8; + GetClangASTImporter().SetRecordLayout(record_decl, layout); } } } else if (clang_type_was_created) { @@ -1822,8 +1826,7 @@ bool DWARFASTParserClang::ParseTemplateDIE( case DW_TAG_GNU_template_parameter_pack: { template_param_infos.packed_args = std::make_unique<TypeSystemClang::TemplateParameterInfos>(); - for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); - child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : die.children()) { if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args)) return false; } @@ -1928,8 +1931,7 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos( if (!parent_die) return false; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); switch (tag) { @@ -1978,15 +1980,12 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, } std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; - std::vector<int> member_accessibilities; - bool is_a_class = false; // Parse members and base classes first std::vector<DWARFDIE> member_function_dies; DelayedPropertyList delayed_properties; - ParseChildMembers(die, clang_type, bases, member_accessibilities, - member_function_dies, delayed_properties, - default_accessibility, is_a_class, layout_info); + ParseChildMembers(die, clang_type, bases, member_function_dies, + delayed_properties, default_accessibility, layout_info); // Now parse any methods if there were any... for (const DWARFDIE &die : member_function_dies) @@ -2007,31 +2006,6 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, } } - // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we - // need to tell the clang type it is actually a class. - if (!type_is_objc_object_or_interface) { - if (is_a_class && tag_decl_kind != clang::TTK_Class) - m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), - clang::TTK_Class); - } - - // Since DW_TAG_structure_type gets used for both classes and - // structures, we may need to set any DW_TAG_member fields to have a - // "private" access if none was specified. When we parsed the child - // members we tracked that actual accessibility value for each - // DW_TAG_member in the "member_accessibilities" array. If the value - // for the member is zero, then it was set to the - // "default_accessibility" which for structs was "public". Below we - // correct this by setting any fields to "private" that weren't - // correctly set. - if (is_a_class && !member_accessibilities.empty()) { - // This is a class and all members that didn't have their access - // specified are private. - m_ast.SetDefaultAccessForRecordFields( - m_ast.GetAsRecordDecl(clang_type), eAccessPrivate, - &member_accessibilities.front(), member_accessibilities.size()); - } - 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 @@ -2131,8 +2105,7 @@ void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed( for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx); it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx; it = m_decl_ctx_to_die.erase(it)) - for (DWARFDIE decl = it->second.GetFirstChild(); decl; - decl = decl.GetSibling()) + for (DWARFDIE decl : it->second.children()) GetClangDeclForDIE(decl); } @@ -2168,8 +2141,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators( size_t enumerators_added = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); if (tag == DW_TAG_enumerator) { DWARFAttributes attributes; @@ -2201,7 +2173,8 @@ size_t DWARFASTParserClang::ParseChildEnumerators( case DW_AT_description: default: case DW_AT_decl_file: - decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned())); + decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile( + form_value.Unsigned())); break; case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); @@ -2343,7 +2316,6 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, void DWARFASTParserClang::ParseSingleMember( const DWARFDIE &die, const DWARFDIE &parent_die, const lldb_private::CompilerType &class_clang_type, - std::vector<int> &member_accessibilities, lldb::AccessType default_accessibility, DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, @@ -2533,7 +2505,7 @@ void DWARFASTParserClang::ParseSingleMember( if (accessibility == eAccessNone) accessibility = eAccessPublic; TypeSystemClang::AddVariableToRecordType( - class_clang_type, name, var_type->GetLayoutCompilerType(), + class_clang_type, name, var_type->GetForwardCompilerType(), accessibility); } return; @@ -2551,7 +2523,6 @@ void DWARFASTParserClang::ParseSingleMember( if (accessibility == eAccessNone) accessibility = default_accessibility; - member_accessibilities.push_back(accessibility); uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); @@ -2666,7 +2637,7 @@ void DWARFASTParserClang::ParseSingleMember( last_field_info.bit_offset = field_bit_offset; if (llvm::Optional<uint64_t> clang_type_size = - member_clang_type.GetByteSize(nullptr)) { + member_type->GetByteSize(nullptr)) { last_field_info.bit_size = *clang_type_size * character_width; } @@ -2761,10 +2732,9 @@ void DWARFASTParserClang::ParseSingleMember( bool DWARFASTParserClang::ParseChildMembers( const DWARFDIE &parent_die, CompilerType &class_clang_type, std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, - std::vector<int> &member_accessibilities, std::vector<DWARFDIE> &member_function_dies, DelayedPropertyList &delayed_properties, AccessType &default_accessibility, - bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) { + ClangASTImporter::LayoutInfo &layout_info) { if (!parent_die) return false; @@ -2776,16 +2746,15 @@ bool DWARFASTParserClang::ParseChildMembers( if (ast == nullptr) return false; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_member: case DW_TAG_APPLE_property: ParseSingleMember(die, parent_die, class_clang_type, - member_accessibilities, default_accessibility, - delayed_properties, layout_info, last_field_info); + default_accessibility, delayed_properties, layout_info, + last_field_info); break; case DW_TAG_subprogram: @@ -2794,9 +2763,6 @@ bool DWARFASTParserClang::ParseChildMembers( break; case DW_TAG_inheritance: { - is_a_class = true; - if (default_accessibility == eAccessNone) - default_accessibility = eAccessPrivate; // TODO: implement DW_TAG_inheritance type parsing DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); @@ -2926,8 +2892,7 @@ size_t DWARFASTParserClang::ParseChildParameters( return 0; size_t arg_idx = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_formal_parameter: { @@ -3046,8 +3011,7 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, if (!parent_die) return llvm::None; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { + for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); if (tag != DW_TAG_subrange_type) continue; @@ -3349,8 +3313,7 @@ static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) { } static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) { - for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid(); - candidate = candidate.GetSibling()) { + for (DWARFDIE candidate : context.children()) { if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) { return candidate; } @@ -3514,8 +3477,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( UniqueCStringMap<DWARFDIE> dst_name_to_die; UniqueCStringMap<DWARFDIE> src_name_to_die_artificial; UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial; - for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); - src_die = src_die.GetSibling()) { + for (DWARFDIE src_die : src_class_die.children()) { if (src_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances @@ -3533,8 +3495,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } } } - for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); - dst_die = dst_die.GetSibling()) { + for (DWARFDIE dst_die : dst_class_die.children()) { if (dst_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances |