@@ -902,3 +902,183 @@ TEST_F(DWARFASTParserClangTests, TestParseDWARFAttributes_ObjectPointer) {
902
902
EXPECT_TRUE (attrs.object_pointer .IsValid ());
903
903
EXPECT_EQ (attrs.object_pointer , param_die);
904
904
}
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