-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer #144998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) ChangesStarting with #124790, Clang emits Full diff: https://github.com/llvm/llvm-project/pull/144998.diff 3 Files Affected:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4f79c8aa3f811..7d699434ca3c8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -174,23 +174,46 @@ DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
if (!decl_ctx_die.IsStructUnionOrClass())
return {};
- if (DWARFDIE object_parameter =
- subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
- return object_parameter;
+ // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+ // in which case that's the object parameter we want. Or it can be a constant
+ // index of the parameter.
+ std::optional<size_t> object_pointer_index;
+ DWARFFormValue form_value;
+ if (subprogram.GetDIE()->GetAttributeValue(
+ subprogram.GetCU(), DW_AT_object_pointer, form_value,
+ /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+ if (auto ref = form_value.Reference())
+ return ref;
+
+ object_pointer_index = form_value.Unsigned();
+ }
+
+ // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+ DWARFDIE object_pointer;
+ size_t param_index = 0;
+ for (const auto &child : subprogram.children()) {
+ if (child.Tag() != DW_TAG_formal_parameter)
+ continue;
- // If no DW_AT_object_pointer was specified, assume the implicit object
- // parameter is the first parameter to the function, is called "this" and is
- // artificial (which is what most compilers would generate).
- auto children = subprogram.children();
- auto it = llvm::find_if(children, [](const DWARFDIE &child) {
- return child.Tag() == DW_TAG_formal_parameter;
- });
+ if (param_index == object_pointer_index.value_or(0))
+ object_pointer = child;
+
+ ++param_index;
+ }
- if (it == children.end())
+ // No formal parameter found for object pointer index.
+ // Nothing to be done.
+ if (!object_pointer)
return {};
- DWARFDIE object_pointer = *it;
+ // We found the object pointer encoded via DW_AT_object_pointer.
+ // No need for the remaining heuristics.
+ if (object_pointer_index)
+ return object_pointer;
+ // If no DW_AT_object_pointer was specified, assume the implicit object
+ // parameter is the first parameter to the function, is called "this" and is
+ // artificial (which is what most compilers would generate).
if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
return {};
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
// XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
// Tests that we correctly deduce the CV-quals and storage
// class of explicit object member functions.
@@ -8,15 +13,15 @@
//
// CHECK: (lldb) type lookup Foo
// CHECK-NEXT: struct Foo {
-// CHECK-NEXT: void Method(Foo);
-// CHECK-NEXT: void cMethod(const Foo &) const;
-// CHECK-NEXT: void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT: void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT: void Method(this Foo);
+// CHECK-NEXT: void cMethod(this const Foo &) const;
+// CHECK-NEXT: void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT: void cvMethod(this const volatile Foo &) const volatile;
// CHECK-NEXT: }
struct Foo {
- void Method(this Foo) {}
- void cMethod(this Foo const &) {}
- void vMethod(this Foo volatile &) {}
- void cvMethod(this Foo const volatile &) {}
+ [[gnu::always_inline]] void Method(this Foo) {}
+ [[gnu::always_inline]] void cMethod(this Foo const &) {}
+ [[gnu::always_inline]] void vMethod(this Foo volatile &) {}
+ [[gnu::always_inline]] void cvMethod(this Foo const volatile &) {}
} f;
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index 2d4b79fed4a55..3de73a64f2758 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -1266,3 +1266,199 @@ TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ParameterCreation) {
EXPECT_EQ(func->getParamDecl(1)->getDeclContext(), func);
EXPECT_EQ(func->getParamDecl(1)->getName(), "namedParam");
}
+
+TEST_F(DWARFASTParserClangTests, TestParseDWARFAttributes_ObjectPointerIndex) {
+ // This tests the behaviour of ParsedDWARFTypeAttributes
+ // for DW_TAG_subprogram definitions which have a DW_AT_object_pointer
+ // that encodes a constant index (instead of a DIE reference).
+
+ const char *yamldata = R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_AARCH64
+DWARF:
+ debug_str:
+ - Context
+ - func
+ - this
+ - self
+ - arg
+ debug_abbrev:
+ - ID: 0
+ Table:
+ - Code: 0x1
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_language
+ Form: DW_FORM_data2
+ - Code: 0x2
+ Tag: DW_TAG_structure_type
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Code: 0x3
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_declaration
+ Form: DW_FORM_flag_present
+ - Attribute: DW_AT_object_pointer
+ Form: DW_FORM_implicit_const
+ Value: 1
+ - Attribute: DW_AT_external
+ Form: DW_FORM_flag_present
+ - Code: 0x4
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_declaration
+ Form: DW_FORM_flag_present
+ - Attribute: DW_AT_object_pointer
+ Form: DW_FORM_implicit_const
+ Value: 0
+ - Attribute: DW_AT_external
+ Form: DW_FORM_flag_present
+
+ - Code: 0x5
+ Tag: DW_TAG_formal_parameter
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+
+ - Code: 0x6
+ Tag: DW_TAG_formal_parameter
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_artificial
+ Form: DW_FORM_flag_present
+
+ debug_info:
+ - Version: 5
+ UnitType: DW_UT_compile
+ AddrSize: 8
+ Entries:
+
+# DW_TAG_compile_unit
+# DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)
+
+ - AbbrCode: 0x1
+ Values:
+ - Value: 0x04
+
+# DW_TAG_structure_type
+# DW_AT_name [DW_FORM_strp] ("Context")
+
+ - AbbrCode: 0x2
+ Values:
+ - Value: 0x0
+
+# DW_TAG_subprogram
+# DW_AT_name [DW_FORM_strp] ("func")
+# DW_AT_object_pointer [DW_FORM_implicit_const] (1)
+ - AbbrCode: 0x3
+ Values:
+ - Value: 0x8
+ - Value: 0x1
+ - Value: 0x1
+ - Value: 0x1
+
+# DW_TAG_formal_parameter
+# DW_AT_name [DW_FORM_strp] ("arg")
+ - AbbrCode: 0x5
+ Values:
+ - Value: 0x17
+
+# DW_TAG_formal_parameter
+# DW_AT_name [DW_FORM_strp] ("self")
+# DW_AT_artificial
+ - AbbrCode: 0x6
+ Values:
+ - Value: 0x12
+ - Value: 0x1
+
+ - AbbrCode: 0x0
+ - AbbrCode: 0x0
+
+# DW_TAG_subprogram
+# DW_AT_object_pointer [DW_FORM_implicit_const] (0)
+# DW_AT_name [DW_FORM_strp] ("func")
+ - AbbrCode: 0x4
+ Values:
+ - Value: 0x8
+ - Value: 0x1
+ - Value: 0x1
+ - Value: 0x1
+
+# DW_TAG_formal_parameter
+# DW_AT_name [DW_FORM_strp] ("this")
+# DW_AT_artificial
+ - AbbrCode: 0x6
+ Values:
+ - Value: 0xd
+ - Value: 0x1
+
+# DW_TAG_formal_parameter
+# DW_AT_name [DW_FORM_strp] ("arg")
+ - AbbrCode: 0x5
+ Values:
+ - Value: 0x17
+
+ - AbbrCode: 0x0
+ - AbbrCode: 0x0
+...
+)";
+
+ YAMLModuleTester t(yamldata);
+
+ DWARFUnit *unit = t.GetDwarfUnit();
+ ASSERT_NE(unit, nullptr);
+ const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
+ ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
+ ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
+ DWARFDIE cu_die(unit, cu_entry);
+
+ auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
+ auto &ast_ctx = *holder->GetAST();
+ DWARFASTParserClangStub ast_parser(ast_ctx);
+
+ auto context_die = cu_die.GetFirstChild();
+ ASSERT_TRUE(context_die.IsValid());
+ ASSERT_EQ(context_die.Tag(), DW_TAG_structure_type);
+
+ auto sub1 = context_die.GetFirstChild();
+ ASSERT_TRUE(sub1.IsValid());
+ ASSERT_EQ(sub1.Tag(), DW_TAG_subprogram);
+
+ auto sub2 = sub1.GetSibling();
+ ASSERT_TRUE(sub2.IsValid());
+ ASSERT_EQ(sub2.Tag(), DW_TAG_subprogram);
+
+ // Object parameter is at constant index 1
+ {
+ auto param_die = sub1.GetFirstChild().GetSibling();
+ ASSERT_TRUE(param_die.IsValid());
+
+ EXPECT_EQ(param_die, ast_parser.GetCXXObjectParameter(sub1, context_die));
+ }
+
+ // Object parameter is at constant index 0
+ {
+ auto param_die = sub2.GetFirstChild();
+ ASSERT_TRUE(param_die.IsValid());
+
+ EXPECT_EQ(param_die,
+ ast_parser.GetCXXObjectParameter(param_die, context_die));
+ }
+}
|
0fd5f5a
to
e7594af
Compare
…object_pointer Starting with llvm#124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this.
e7594af
to
3df8d0a
Compare
It seems the buildbot lldb-remote-linux-ubuntu is broken after this patch.
|
…object_pointer (llvm#144998) Starting with llvm#124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this. Depends on llvm#145328 and llvm#145126
Looks like it got resolved? Possibly a different root cause? I think I saw some Modules related changes flying around that could've caused this |
Yes, sorry for the inconvenience. |
…object_pointer (llvm#144998) Starting with llvm#124790, Clang emits `DW_AT_object_pointer` encoded as integer constants rather than DIE references. This patch accounts for this. Depends on llvm#145328 and llvm#145126
Starting with #124790, Clang emits
DW_AT_object_pointer
encoded as integer constants rather than DIE references. This patch accounts for this.Depends on #145328 and #145126