Author: Zequan Wu Date: 2024-11-20T17:19:35-05:00 New Revision: f06c187799d910fd3ac3e9106397e5eecff9f265
URL: https://github.com/llvm/llvm-project/commit/f06c187799d910fd3ac3e9106397e5eecff9f265 DIFF: https://github.com/llvm/llvm-project/commit/f06c187799d910fd3ac3e9106397e5eecff9f265.diff LOG: [lldb][dwarf] Compute fully qualified names on simplified template names with DWARFTypePrinter (#117071) This is a reland of https://github.com/llvm/llvm-project/pull/112811. Fixed the bot breakage by running ld.lld explicitly. Added: lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h llvm/lib/DebugInfo/DWARF/DWARFDie.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index d9bdeb560e1220..37c1132c1c9f9a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -45,6 +45,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h" #include "llvm/Demangle/Demangle.h" #include <map> @@ -826,11 +827,11 @@ std::string DWARFASTParserClang::GetDIEClassTemplateParams(DWARFDIE die) { if (llvm::StringRef(die.GetName()).contains("<")) return {}; - TypeSystemClang::TemplateParameterInfos template_param_infos; - if (ParseTemplateParameterInfos(die, template_param_infos)) - return m_ast.PrintTemplateParams(template_param_infos); - - return {}; + std::string name; + llvm::raw_string_ostream os(name); + llvm::DWARFTypePrinter<DWARFDIE> type_printer(os); + type_printer.appendAndTerminateTemplateParameters(die); + return name; } void DWARFASTParserClang::MapDeclDIEToDefDIE( @@ -1618,9 +1619,9 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration( case DW_TAG_structure_type: case DW_TAG_union_type: { if (const char *class_union_struct_name = parent_decl_ctx_die.GetName()) { - qualified_name.insert( - 0, GetDIEClassTemplateParams(parent_decl_ctx_die)); qualified_name.insert(0, "::"); + qualified_name.insert(0, + GetDIEClassTemplateParams(parent_decl_ctx_die)); qualified_name.insert(0, class_union_struct_name); } parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); @@ -1673,6 +1674,12 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (attrs.name) { GetUniqueTypeNameAndDeclaration(die, cu_language, unique_typename, unique_decl); + if (log) { + dwarf->GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF({0:p}) - {1:x16}: {2} has unique name: {3} ", + static_cast<void *>(this), die.GetID(), DW_TAG_value_to_name(tag), + unique_typename.AsCString()); + } if (UniqueDWARFASTType *unique_ast_entry_type = dwarf->GetUniqueDWARFASTTypeMap().Find( unique_typename, die, unique_decl, byte_size, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h index 235343d2271223..d92de658a49e89 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h @@ -24,9 +24,11 @@ class DWARFUnit; class DWARFDebugInfoEntry; class DWARFDeclContext; class SymbolFileDWARF; +class DWARFFormValue; class DWARFBaseDIE { public: + using DWARFFormValue = dwarf::DWARFFormValue; DWARFBaseDIE() = default; DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die) @@ -117,6 +119,12 @@ class DWARFBaseDIE { enum class Recurse : bool { no, yes }; DWARFAttributes GetAttributes(Recurse recurse = Recurse::yes) const; + // The following methods use LLVM naming convension in order to be are used by + // LLVM libraries. + dw_tag_t getTag() const { return Tag(); } + + const char *getShortName() const { return GetName(); } + protected: DWARFUnit *m_cu = nullptr; DWARFDebugInfoEntry *m_die = nullptr; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 4c9f1d8505f6e6..362f4c44240c76 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -572,6 +572,43 @@ bool DWARFDIE::GetDIENamesAndRanges( return false; } +// The following methods use LLVM naming convension in order to be are used by +// LLVM libraries. llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const { return llvm::make_range(child_iterator(*this), child_iterator()); } + +DWARFDIE::child_iterator DWARFDIE::begin() const { + return child_iterator(*this); +} + +DWARFDIE::child_iterator DWARFDIE::end() const { return child_iterator(); } + +std::optional<DWARFFormValue> DWARFDIE::find(const dw_attr_t attr) const { + DWARFFormValue form_value; + if (m_die->GetAttributeValue(m_cu, attr, form_value, nullptr, false)) + return form_value; + return std::nullopt; +} + +std::optional<uint64_t> DWARFDIE::getLanguage() const { + if (IsValid()) + return m_cu->GetDWARFLanguageType(); + return std::nullopt; +} + +DWARFDIE DWARFDIE::resolveReferencedType(dw_attr_t attr) const { + return GetReferencedDIE(attr); +} + +DWARFDIE DWARFDIE::resolveReferencedType(DWARFFormValue v) const { + if (IsValid()) + return v.Reference(); + return {}; +} + +DWARFDIE DWARFDIE::resolveTypeUnitReference() const { + if (DWARFDIE reference = GetReferencedDIE(DW_AT_signature)) + return reference; + return *this; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 077b78eb26d0c3..5c1d381930c4ed 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -103,8 +103,25 @@ class DWARFDIE : public DWARFBaseDIE { std::optional<int> &call_line, std::optional<int> &call_column, DWARFExpressionList *frame_base) const; + // The following methods use LLVM naming convension in order to be are used by + // LLVM libraries. + std::optional<uint64_t> getLanguage() const; + + DWARFDIE getParent() const { return GetParent(); } + + DWARFDIE resolveReferencedType(dw_attr_t attr) const; + + DWARFDIE resolveReferencedType(DWARFFormValue v) const; + + DWARFDIE resolveTypeUnitReference() const; + + std::optional<DWARFFormValue> find(const dw_attr_t attr) const; + /// The range of all the children of this DIE. llvm::iterator_range<child_iterator> children() const; + + child_iterator begin() const; + child_iterator end() const; }; class DWARFDIE::child_iterator diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index 404e50d57a9251..fd3d45cef4c5e4 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -574,6 +574,31 @@ uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { } } +std::optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { + if ((!IsDataForm(m_form)) || m_form == lldb_private::dwarf::DW_FORM_sdata) + return std::nullopt; + return m_value.uval; +} + +std::optional<int64_t> DWARFFormValue::getAsSignedConstant() const { + if ((!IsDataForm(m_form)) || + (m_form == lldb_private::dwarf::DW_FORM_udata && + uint64_t(std::numeric_limits<int64_t>::max()) < m_value.uval)) + return std::nullopt; + switch (m_form) { + case lldb_private::dwarf::DW_FORM_data4: + return int32_t(m_value.uval); + case lldb_private::dwarf::DW_FORM_data2: + return int16_t(m_value.uval); + case lldb_private::dwarf::DW_FORM_data1: + return int8_t(m_value.uval); + case lldb_private::dwarf::DW_FORM_sdata: + case lldb_private::dwarf::DW_FORM_data8: + default: + return m_value.sval; + } +} + const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } bool DWARFFormValue::IsBlockForm(const dw_form_t form) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index 8ab9163e645fea..613948f2f3c9b7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -76,6 +76,12 @@ class DWARFFormValue { void Clear(); static bool FormIsSupported(dw_form_t form); + // The following methods use LLVM naming convension in order to be are used by + // LLVM libraries. + std::optional<uint64_t> getAsUnsignedConstant() const; + std::optional<int64_t> getAsSignedConstant() const; + const char *getAsCString() const { return AsCString(); } + protected: // Compile unit where m_value was located. // It may be diff erent from compile unit where m_value refers to. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 8ce0db4588a46a..47050d86409a60 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -9,6 +9,7 @@ #include "SymbolFileDWARF.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" +#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h" #include "llvm/Support/Casting.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/Format.h" @@ -2810,33 +2811,14 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) { return true; // Keep iterating over index types, language mismatch. } - // Check the context matches - std::vector<lldb_private::CompilerContext> die_context; - if (query.GetModuleSearch()) - die_context = die.GetDeclContext(); - else - die_context = die.GetTypeLookupContext(); - assert(!die_context.empty()); - if (!query_simple.ContextMatches(die_context)) - return true; // Keep iterating over index types, context mismatch. - - // Try to resolve the type. - if (Type *matching_type = ResolveType(die, true, true)) { - ConstString name = matching_type->GetQualifiedName(); - // We have found a type that still might not match due to template - // parameters. If we create a new TypeQuery that uses the new type's - // fully qualified name, we can find out if this type matches at all - // context levels. We can't use just the "match_simple" context - // because all template parameters were stripped off. The fully - // qualified name of the type will have the template parameters and - // will allow us to make sure it matches correctly. - TypeQuery die_query(name.GetStringRef(), - TypeQueryOptions::e_exact_match); - if (!query.ContextMatches(die_query.GetContextRef())) - return true; // Keep iterating over index types, context mismatch. - - results.InsertUnique(matching_type->shared_from_this()); - } + std::string qualified_name; + llvm::raw_string_ostream os(qualified_name); + llvm::DWARFTypePrinter<DWARFDIE> type_printer(os); + type_printer.appendQualifiedName(die); + TypeQuery die_query(qualified_name, e_exact_match); + if (query.ContextMatches(die_query.GetContextRef())) + if (Type *matching_type = ResolveType(die, true, true)) + results.InsertUnique(matching_type->shared_from_this()); return !results.Done(query); // Keep iterating if we aren't done. }); if (results.Done(query)) { diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 1a77c7cf9161a0..5f8163211857c3 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1403,26 +1403,6 @@ static TemplateParameterList *CreateTemplateParameterList( return template_param_list; } -std::string TypeSystemClang::PrintTemplateParams( - const TemplateParameterInfos &template_param_infos) { - llvm::SmallVector<NamedDecl *, 8> ignore; - clang::TemplateParameterList *template_param_list = - CreateTemplateParameterList(getASTContext(), template_param_infos, - ignore); - llvm::SmallVector<clang::TemplateArgument, 2> args( - template_param_infos.GetArgs()); - if (template_param_infos.hasParameterPack()) { - llvm::ArrayRef<TemplateArgument> pack_args = - template_param_infos.GetParameterPackArgs(); - args.append(pack_args.begin(), pack_args.end()); - } - std::string str; - llvm::raw_string_ostream os(str); - clang::printTemplateArgumentList(os, args, GetTypePrintingPolicy(), - template_param_list); - return str; -} - clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, clang::FunctionDecl *func_decl, diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index e39aedec7e3902..678eaed381fd49 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -1148,10 +1148,6 @@ class TypeSystemClang : public TypeSystem { bool SetDeclIsForcefullyCompleted(const clang::TagDecl *td); - /// Return the template parameters (including surrounding <>) in string form. - std::string - PrintTemplateParams(const TemplateParameterInfos &template_param_infos); - private: /// Returns the PrintingPolicy used when generating the internal type names. /// These type names are mostly used for the formatter selection. diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp new file mode 100644 index 00000000000000..328d6d2e16d595 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp @@ -0,0 +1,36 @@ +// Test lldb is able to compute the fully qualified names on templates with +// -gsimple-template-names and -fdebug-types-section. + +// REQUIRES: lld + +// Test against logging to see if we print the fully qualified names correctly. +// RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names %s -c -o %t1.o +// RUN: ld.lld %t1.o -o %t1 +// RUN: %lldb %t1 -o "log enable dwarf comp" -o "target variable v3" -o exit | FileCheck %s --check-prefix=LOG + +// Test that we following DW_AT_signature correctly. If not, lldb might confuse the types of v1 and v2. +// RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names -fdebug-types-section %s -c -o %t2.o +// RUN: ld.lld %t2.o -o %t2 +// RUN: %lldb %t2 -o "target variable v1 v2" -o exit | FileCheck %s --check-prefix=TYPE + +// LOG: unique name: t3<t2<int> >::t4 + +// TYPE: (t2<outer_struct1::t1<int> >) v1 = {} +// TYPE-NEXT: (t2<outer_struct2::t1<int> >) v2 = {} + +struct outer_struct1 { + template <typename> struct t1 {}; +}; + +struct outer_struct2 { + template <typename> struct t1 {}; +}; + +template <typename> struct t2 {}; +t2<outer_struct1::t1<int>> v1; +t2<outer_struct2::t1<int>> v2; + +template <typename> struct t3 { + struct t4 {}; +}; +t3<t2<int>>::t4 v3; diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp index 1e4c8f3ba07787..ae63e286cc1551 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp @@ -14,6 +14,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/lldb-private-enumerations.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -394,3 +395,127 @@ TEST(DWARFDIETest, GetContextInFunction) { EXPECT_THAT(foo_struct_die.GetTypeLookupContext(), testing::ElementsAre(make_struct("struct_t"))); } + +TEST(DWARFDIETest, TestDWARFTypePrinter) { + // Make sure we can get template parameters and qualified names correctly with + // DWARFTypePrinter when using -gsimple-template-names. + + // 0x0000000b: DW_TAG_compile_unit + // 0x0000000c: DW_TAG_base_type + // DW_AT_name ("int") + // 0x00000011: DW_TAG_structure_type + // DW_AT_name ("t1") + // 0x00000015: DW_TAG_template_type_parameter + // DW_AT_type (0x0000001f "t3<int>") + // 0x0000001a: DW_TAG_structure_type + // DW_AT_name ("t2") + // 0x0000001e: NULL + // 0x0000001f: DW_TAG_structure_type + // DW_AT_name ("t3") + // 0x00000023: DW_TAG_template_type_parameter + // DW_AT_type (0x0000000c "int") + // 0x00000028: NULL + // 0x00000029: NULL + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_386 +DWARF: + debug_abbrev: + - ID: 0 + Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + - Code: 0x2 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Code: 0x3 + Tag: DW_TAG_structure_type + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Code: 0x4 + Tag: DW_TAG_template_type_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Code: 0x5 + Tag: DW_TAG_structure_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Code: 0x6 + Tag: DW_TAG_structure_type + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Code: 0x7 + Tag: DW_TAG_template_type_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + debug_info: + - Version: 4 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + - AbbrCode: 0x2 + Values: + - Value: 0xDEADBEEFDEADBEEF + CStr: int + - AbbrCode: 0x3 + Values: + - Value: 0xDEADBEEFDEADBEEF + CStr: t1 + - AbbrCode: 0x4 + Values: + - Value: 0x0000001f # update + - AbbrCode: 0x5 + Values: + - Value: 0xDEADBEEFDEADBEEF + CStr: t2 + - AbbrCode: 0x0 + - AbbrCode: 0x6 + Values: + - Value: 0xDEADBEEFDEADBEEF + CStr: t3 + - AbbrCode: 0x7 + Values: + - Value: 0x0000000c # update + - AbbrCode: 0x0 + - AbbrCode: 0x0)"; + YAMLModuleTester t(yamldata); + auto *symbol_file = + llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile()); + DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0); + std::string debug_str; + StreamString debug_os; + unit->Dump(&debug_os); + ASSERT_TRUE(unit); + + DWARFDIE t1_die = unit->GetDIE(0x11); + std::string template_name; + llvm::raw_string_ostream template_name_os(template_name); + llvm::DWARFTypePrinter<DWARFDIE> template_name_printer(template_name_os); + template_name_printer.appendAndTerminateTemplateParameters(t1_die); + EXPECT_THAT(template_name, "<t3<int> >"); + + DWARFDIE t2_die = unit->GetDIE(0x1a); + std::string qualified_name; + llvm::raw_string_ostream qualified_name_os(qualified_name); + llvm::DWARFTypePrinter<DWARFDIE> qualified_name_printer(qualified_name_os); + qualified_name_printer.appendQualifiedName(t2_die); + EXPECT_THAT(qualified_name, "t1<t3<int> >::t2"); +} diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h index 69c91835a4d9a1..2e98a4a397147b 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -226,6 +226,8 @@ class DWARFDie { bool addressRangeContainsAddress(const uint64_t Address) const; + std::optional<uint64_t> getLanguage() const; + Expected<DWARFLocationExpressionsVector> getLocations(dwarf::Attribute Attr) const; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h index 87e876273c4b97..962462b8278259 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h @@ -11,6 +11,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/Support/Error.h" #include <string> @@ -107,13 +108,11 @@ void DWARFTypePrinter<DieType>::appendArrayType(const DieType &D) { if (std::optional<typename DieType::DWARFFormValue> UpperV = C.find(dwarf::DW_AT_upper_bound)) UB = UpperV->getAsUnsignedConstant(); - if (std::optional<typename DieType::DWARFFormValue> LV = - D.getDwarfUnit()->getUnitDIE().find(dwarf::DW_AT_language)) - if (std::optional<uint64_t> LC = LV->getAsUnsignedConstant()) - if ((DefaultLB = - LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC)))) - if (LB && *LB == *DefaultLB) - LB = std::nullopt; + if (std::optional<uint64_t> LV = D.getLanguage()) + if ((DefaultLB = + LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LV)))) + if (LB && *LB == *DefaultLB) + LB = std::nullopt; if (!LB && !Count && !UB) OS << "[]"; else if (!LB && (Count || UB) && DefaultLB) @@ -150,6 +149,16 @@ template <typename DieType> DieType resolveReferencedType(DieType D, typename DieType::DWARFFormValue F) { return D.resolveReferencedType(F); } +template <typename DWARFFormValueType> +const char *toString(std::optional<DWARFFormValueType> F) { + if (F) { + llvm::Expected<const char *> E = F->getAsCString(); + if (E) + return *E; + llvm::consumeError(E.takeError()); + } + return nullptr; +} } // namespace detail template <typename DieType> @@ -239,7 +248,7 @@ DieType DWARFTypePrinter<DieType>::appendUnqualifiedNameBefore( appendConstVolatileQualifierBefore(D); break; case dwarf::DW_TAG_namespace: { - if (const char *Name = dwarf::toString(D.find(dwarf::DW_AT_name), nullptr)) + if (const char *Name = detail::toString(D.find(dwarf::DW_AT_name))) OS << Name; else OS << "(anonymous namespace)"; @@ -261,7 +270,7 @@ DieType DWARFTypePrinter<DieType>::appendUnqualifiedNameBefore( case DW_TAG_base_type: */ default: { - const char *NamePtr = dwarf::toString(D.find(dwarf::DW_AT_name), nullptr); + const char *NamePtr = detail::toString(D.find(dwarf::DW_AT_name)); if (!NamePtr) { appendTypeTagName(D.getTag()); return DieType(); @@ -440,7 +449,7 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D, if (T.getTag() == dwarf::DW_TAG_pointer_type || T.getTag() == dwarf::DW_TAG_reference_type) continue; - const char *RawName = dwarf::toString(T.find(dwarf::DW_AT_name), nullptr); + const char *RawName = detail::toString(T.find(dwarf::DW_AT_name)); assert(RawName); StringRef Name = RawName; auto V = C.find(dwarf::DW_AT_const_value); @@ -533,7 +542,7 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D, } if (C.getTag() == dwarf::DW_TAG_GNU_template_template_param) { const char *RawName = - dwarf::toString(C.find(dwarf::DW_AT_GNU_template_name), nullptr); + detail::toString(C.find(dwarf::DW_AT_GNU_template_name)); assert(RawName); StringRef Name = RawName; Sep(); @@ -593,7 +602,7 @@ void DWARFTypePrinter<DieType>::appendConstVolatileQualifierAfter(DieType N) { decomposeConstVolatile(N, T, C, V); if (T && T.getTag() == dwarf::DW_TAG_subroutine_type) appendSubroutineNameAfter(T, detail::resolveReferencedType(T), false, - C.isValid(), V.isValid()); + static_cast<bool>(C), static_cast<bool>(V)); else appendUnqualifiedNameAfter(T, detail::resolveReferencedType(T)); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index dcce484a7a37ea..a0ce7810f91b04 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -413,6 +413,15 @@ bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const { return false; } +std::optional<uint64_t> DWARFDie::getLanguage() const { + if (isValid()) { + if (std::optional<DWARFFormValue> LV = + U->getUnitDIE().find(dwarf::DW_AT_language)) + return LV->getAsUnsignedConstant(); + } + return std::nullopt; +} + Expected<DWARFLocationExpressionsVector> DWARFDie::getLocations(dwarf::Attribute Attr) const { std::optional<DWARFFormValue> Location = find(Attr); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits