Skip to content

Commit 636bc72

Browse files
committed
Reland "[lldb][DWARFASTParserClang] Make C++ method parsing aware of explicit object parameters" (#124100)"
This reverts commit a802093. Relands original commit but fixing the unit-test to consume the `llvm::Expected` error object.
1 parent 1311b36 commit 636bc72

File tree

2 files changed

+183
-6
lines changed

2 files changed

+183
-6
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ GetCXXObjectParameter(const DWARFDIE &subprogram,
173173
if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
174174
return {};
175175

176-
// FIXME: if subprogram has a explicit DW_AT_object_pointer, use it.
176+
if (DWARFDIE object_parameter =
177+
subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
178+
return object_parameter;
177179

178180
// If no DW_AT_object_pointer was specified, assume the implicit object
179181
// parameter is the first parameter to the function, is called "this" and is
@@ -215,11 +217,6 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram,
215217
return 0;
216218

217219
uint32_t encoding_mask = this_type->GetEncodingMask();
218-
219-
// FIXME: explicit object parameters need not to be pointers
220-
if (!(encoding_mask & (1u << Type::eEncodingIsPointerUID)))
221-
return 0;
222-
223220
unsigned cv_quals = 0;
224221
if (encoding_mask & (1u << Type::eEncodingIsConstUID))
225222
cv_quals |= clang::Qualifiers::Const;

lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,3 +902,183 @@ TEST_F(DWARFASTParserClangTests, TestParseDWARFAttributes_ObjectPointer) {
902902
EXPECT_TRUE(attrs.object_pointer.IsValid());
903903
EXPECT_EQ(attrs.object_pointer, param_die);
904904
}
905+
906+
TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ExplicitObjectParameter) {
907+
// Tests parsing of a C++ non-static member function with an explicit object
908+
// parameter that isn't called "this" and is not a pointer (but a CV-qualified
909+
// rvalue reference instead).
910+
911+
const char *yamldata = R"(
912+
--- !ELF
913+
FileHeader:
914+
Class: ELFCLASS64
915+
Data: ELFDATA2LSB
916+
Type: ET_EXEC
917+
Machine: EM_AARCH64
918+
DWARF:
919+
debug_str:
920+
- Context
921+
- func
922+
- mySelf
923+
debug_abbrev:
924+
- ID: 0
925+
Table:
926+
- Code: 0x1
927+
Tag: DW_TAG_compile_unit
928+
Children: DW_CHILDREN_yes
929+
Attributes:
930+
- Attribute: DW_AT_language
931+
Form: DW_FORM_data2
932+
- Code: 0x2
933+
Tag: DW_TAG_structure_type
934+
Children: DW_CHILDREN_yes
935+
Attributes:
936+
- Attribute: DW_AT_name
937+
Form: DW_FORM_strp
938+
- Code: 0x3
939+
Tag: DW_TAG_subprogram
940+
Children: DW_CHILDREN_yes
941+
Attributes:
942+
- Attribute: DW_AT_name
943+
Form: DW_FORM_strp
944+
- Attribute: DW_AT_declaration
945+
Form: DW_FORM_flag_present
946+
- Attribute: DW_AT_object_pointer
947+
Form: DW_FORM_ref4
948+
- Attribute: DW_AT_external
949+
Form: DW_FORM_flag_present
950+
- Code: 0x4
951+
Tag: DW_TAG_formal_parameter
952+
Children: DW_CHILDREN_no
953+
Attributes:
954+
- Attribute: DW_AT_name
955+
Form: DW_FORM_strp
956+
- Attribute: DW_AT_type
957+
Form: DW_FORM_ref4
958+
- Code: 0x5
959+
Tag: DW_TAG_rvalue_reference_type
960+
Children: DW_CHILDREN_no
961+
Attributes:
962+
- Attribute: DW_AT_type
963+
Form: DW_FORM_ref4
964+
- Code: 0x6
965+
Tag: DW_TAG_const_type
966+
Children: DW_CHILDREN_no
967+
Attributes:
968+
- Attribute: DW_AT_type
969+
Form: DW_FORM_ref4
970+
- Code: 0x7
971+
Tag: DW_TAG_volatile_type
972+
Children: DW_CHILDREN_no
973+
Attributes:
974+
- Attribute: DW_AT_type
975+
Form: DW_FORM_ref4
976+
debug_info:
977+
- Version: 5
978+
UnitType: DW_UT_compile
979+
AddrSize: 8
980+
Entries:
981+
982+
# DW_TAG_compile_unit
983+
# DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)
984+
985+
- AbbrCode: 0x1
986+
Values:
987+
- Value: 0x04
988+
989+
# DW_TAG_structure_type
990+
# DW_AT_name [DW_FORM_strp] ("Context")
991+
992+
- AbbrCode: 0x2
993+
Values:
994+
- Value: 0x0
995+
996+
# DW_TAG_subprogram
997+
# DW_AT_name [DW_FORM_strp] ("func")
998+
# DW_AT_object_pointer [DW_FORM_ref4]
999+
- AbbrCode: 0x3
1000+
Values:
1001+
- Value: 0x8
1002+
- Value: 0x1
1003+
- Value: 0x1d
1004+
- Value: 0x1
1005+
1006+
# DW_TAG_formal_parameter
1007+
# DW_AT_name [DW_FORM_strp] ("mySelf")
1008+
# DW_AT_type [DW_FORM_ref4] (const volatile Context &&)
1009+
- AbbrCode: 0x4
1010+
Values:
1011+
- Value: 0xd
1012+
- Value: 0x28
1013+
1014+
- AbbrCode: 0x0
1015+
- AbbrCode: 0x0
1016+
1017+
# DW_TAG_rvalue_reference_type
1018+
# DW_AT_type [DW_FORM_ref4] ("const volatile Context")
1019+
1020+
- AbbrCode: 0x5
1021+
Values:
1022+
- Value: 0x2d
1023+
1024+
# DW_TAG_const_type
1025+
# DW_AT_type [DW_FORM_ref4] ("volatile Context")
1026+
1027+
- AbbrCode: 0x6
1028+
Values:
1029+
- Value: 0x32
1030+
1031+
# DW_TAG_volatile_type
1032+
# DW_AT_type [DW_FORM_ref4] ("Context")
1033+
1034+
- AbbrCode: 0x7
1035+
Values:
1036+
- Value: 0xf
1037+
1038+
- AbbrCode: 0x0
1039+
...
1040+
)";
1041+
YAMLModuleTester t(yamldata);
1042+
1043+
DWARFUnit *unit = t.GetDwarfUnit();
1044+
ASSERT_NE(unit, nullptr);
1045+
const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
1046+
ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
1047+
ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
1048+
DWARFDIE cu_die(unit, cu_entry);
1049+
1050+
auto ts_or_err =
1051+
cu_die.GetDWARF()->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
1052+
ASSERT_TRUE(static_cast<bool>(ts_or_err));
1053+
llvm::consumeError(ts_or_err.takeError());
1054+
auto *parser =
1055+
static_cast<DWARFASTParserClang *>((*ts_or_err)->GetDWARFParser());
1056+
1057+
auto context_die = cu_die.GetFirstChild();
1058+
ASSERT_TRUE(context_die.IsValid());
1059+
ASSERT_EQ(context_die.Tag(), DW_TAG_structure_type);
1060+
1061+
SymbolContext sc;
1062+
bool new_type;
1063+
auto context_type_sp = parser->ParseTypeFromDWARF(sc, context_die, &new_type);
1064+
ASSERT_NE(context_type_sp, nullptr);
1065+
1066+
ASSERT_TRUE(
1067+
parser->CompleteTypeFromDWARF(context_die, context_type_sp.get(),
1068+
context_type_sp->GetForwardCompilerType()));
1069+
1070+
auto *record_decl = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
1071+
ClangUtil::GetAsTagDecl(context_type_sp->GetForwardCompilerType()));
1072+
ASSERT_NE(record_decl, nullptr);
1073+
1074+
auto method_it = record_decl->method_begin();
1075+
ASSERT_NE(method_it, record_decl->method_end());
1076+
1077+
// Check that we didn't parse the function as static.
1078+
EXPECT_FALSE(method_it->isStatic());
1079+
1080+
// Check that method qualifiers were correctly set.
1081+
EXPECT_EQ(method_it->getMethodQualifiers(),
1082+
clang::Qualifiers::fromCVRMask(clang::Qualifiers::Const |
1083+
clang::Qualifiers::Volatile));
1084+
}

0 commit comments

Comments
 (0)