@@ -741,3 +741,164 @@ TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) {
741741
742742 ASSERT_EQ (type_sp, reparsed_type_sp);
743743}
744+
745+ TEST_F (DWARFASTParserClangTests, TestParseDWARFAttributes_ObjectPointer) {
746+ // This tests the behaviour of ParsedDWARFTypeAttributes
747+ // for DW_TAG_subprogram definitions which have a DW_AT_object_pointer
748+ // *and* a DW_AT_specification that also has a DW_AT_object_pointer.
749+ // We don't want the declaration DW_AT_object_pointer to overwrite the
750+ // one from the more specific definition's.
751+
752+ const char *yamldata = R"(
753+ --- !ELF
754+ FileHeader:
755+ Class: ELFCLASS64
756+ Data: ELFDATA2LSB
757+ Type: ET_EXEC
758+ Machine: EM_AARCH64
759+ DWARF:
760+ debug_str:
761+ - Context
762+ - func
763+ - this
764+ debug_abbrev:
765+ - ID: 0
766+ Table:
767+ - Code: 0x1
768+ Tag: DW_TAG_compile_unit
769+ Children: DW_CHILDREN_yes
770+ Attributes:
771+ - Attribute: DW_AT_language
772+ Form: DW_FORM_data2
773+ - Code: 0x2
774+ Tag: DW_TAG_structure_type
775+ Children: DW_CHILDREN_yes
776+ Attributes:
777+ - Attribute: DW_AT_name
778+ Form: DW_FORM_strp
779+ - Code: 0x3
780+ Tag: DW_TAG_subprogram
781+ Children: DW_CHILDREN_yes
782+ Attributes:
783+ - Attribute: DW_AT_name
784+ Form: DW_FORM_strp
785+ - Attribute: DW_AT_declaration
786+ Form: DW_FORM_flag_present
787+ - Attribute: DW_AT_object_pointer
788+ Form: DW_FORM_ref4
789+ - Attribute: DW_AT_artificial
790+ Form: DW_FORM_flag_present
791+ - Attribute: DW_AT_external
792+ Form: DW_FORM_flag_present
793+ - Code: 0x4
794+ Tag: DW_TAG_formal_parameter
795+ Children: DW_CHILDREN_no
796+ Attributes:
797+ - Attribute: DW_AT_artificial
798+ Form: DW_FORM_flag_present
799+ - Code: 0x5
800+ Tag: DW_TAG_subprogram
801+ Children: DW_CHILDREN_yes
802+ Attributes:
803+ - Attribute: DW_AT_object_pointer
804+ Form: DW_FORM_ref4
805+ - Attribute: DW_AT_specification
806+ Form: DW_FORM_ref4
807+ - Code: 0x6
808+ Tag: DW_TAG_formal_parameter
809+ Children: DW_CHILDREN_no
810+ Attributes:
811+ - Attribute: DW_AT_name
812+ Form: DW_FORM_strp
813+ - Attribute: DW_AT_artificial
814+ Form: DW_FORM_flag_present
815+ debug_info:
816+ - Version: 5
817+ UnitType: DW_UT_compile
818+ AddrSize: 8
819+ Entries:
820+
821+ # DW_TAG_compile_unit
822+ # DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)
823+
824+ - AbbrCode: 0x1
825+ Values:
826+ - Value: 0x04
827+
828+ # DW_TAG_structure_type
829+ # DW_AT_name [DW_FORM_strp] ("Context")
830+
831+ - AbbrCode: 0x2
832+ Values:
833+ - Value: 0x0
834+
835+ # DW_TAG_subprogram
836+ # DW_AT_name [DW_FORM_strp] ("func")
837+ # DW_AT_object_pointer [DW_FORM_ref4]
838+ - AbbrCode: 0x3
839+ Values:
840+ - Value: 0x8
841+ - Value: 0x1
842+ - Value: 0x1d
843+ - Value: 0x1
844+ - Value: 0x1
845+
846+ # DW_TAG_formal_parameter
847+ # DW_AT_artificial
848+ - AbbrCode: 0x4
849+ Values:
850+ - Value: 0x1
851+
852+ - AbbrCode: 0x0
853+ - AbbrCode: 0x0
854+
855+ # DW_TAG_subprogram
856+ # DW_AT_object_pointer [DW_FORM_ref4] ("this")
857+ # DW_AT_specification [DW_FORM_ref4] ("func")
858+ - AbbrCode: 0x5
859+ Values:
860+ - Value: 0x29
861+ - Value: 0x14
862+
863+ # DW_TAG_formal_parameter
864+ # DW_AT_name [DW_FORM_strp] ("this")
865+ # DW_AT_artificial
866+ - AbbrCode: 0x6
867+ Values:
868+ - Value: 0xd
869+ - Value: 0x1
870+
871+ - AbbrCode: 0x0
872+ - AbbrCode: 0x0
873+ ...
874+ )" ;
875+ YAMLModuleTester t (yamldata);
876+
877+ DWARFUnit *unit = t.GetDwarfUnit ();
878+ ASSERT_NE (unit, nullptr );
879+ const DWARFDebugInfoEntry *cu_entry = unit->DIE ().GetDIE ();
880+ ASSERT_EQ (cu_entry->Tag (), DW_TAG_compile_unit);
881+ ASSERT_EQ (unit->GetDWARFLanguageType (), DW_LANG_C_plus_plus);
882+ DWARFDIE cu_die (unit, cu_entry);
883+
884+ auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>(" ast" );
885+ auto &ast_ctx = *holder->GetAST ();
886+ DWARFASTParserClangStub ast_parser (ast_ctx);
887+
888+ auto context_die = cu_die.GetFirstChild ();
889+ ASSERT_TRUE (context_die.IsValid ());
890+ ASSERT_EQ (context_die.Tag (), DW_TAG_structure_type);
891+
892+ auto subprogram_definition = context_die.GetSibling ();
893+ ASSERT_TRUE (subprogram_definition.IsValid ());
894+ ASSERT_EQ (subprogram_definition.Tag (), DW_TAG_subprogram);
895+ ASSERT_FALSE (subprogram_definition.GetAttributeValueAsOptionalUnsigned (
896+ DW_AT_external));
897+
898+ auto param_die = subprogram_definition.GetFirstChild ();
899+ ASSERT_TRUE (param_die.IsValid ());
900+
901+ ParsedDWARFTypeAttributes attrs (subprogram_definition);
902+ EXPECT_TRUE (attrs.object_pointer .IsValid ());
903+ EXPECT_EQ (attrs.object_pointer , param_die);
904+ }
0 commit comments