@@ -902,3 +902,181 @@ 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+ auto *parser =
1053+ static_cast <DWARFASTParserClang *>((*ts_or_err)->GetDWARFParser ());
1054+
1055+ auto context_die = cu_die.GetFirstChild ();
1056+ ASSERT_TRUE (context_die.IsValid ());
1057+ ASSERT_EQ (context_die.Tag (), DW_TAG_structure_type);
1058+
1059+ SymbolContext sc;
1060+ bool new_type;
1061+ auto context_type_sp = parser->ParseTypeFromDWARF (sc, context_die, &new_type);
1062+ ASSERT_NE (context_type_sp, nullptr );
1063+
1064+ ASSERT_TRUE (
1065+ parser->CompleteTypeFromDWARF (context_die, context_type_sp.get (),
1066+ context_type_sp->GetForwardCompilerType ()));
1067+
1068+ auto *record_decl = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
1069+ ClangUtil::GetAsTagDecl (context_type_sp->GetForwardCompilerType ()));
1070+ ASSERT_NE (record_decl, nullptr );
1071+
1072+ auto method_it = record_decl->method_begin ();
1073+ ASSERT_NE (method_it, record_decl->method_end ());
1074+
1075+ // Check that we didn't parse the function as static.
1076+ EXPECT_FALSE (method_it->isStatic ());
1077+
1078+ // Check that method qualifiers were correctly set.
1079+ EXPECT_EQ (method_it->getMethodQualifiers (),
1080+ clang::Qualifiers::fromCVRMask (clang::Qualifiers::Const |
1081+ clang::Qualifiers::Volatile));
1082+ }
0 commit comments