@@ -1423,3 +1423,197 @@ TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ParameterCreation) {
14231423 EXPECT_EQ (func->getParamDecl (1 )->getDeclContext (), func);
14241424 EXPECT_EQ (func->getParamDecl (1 )->getName (), " namedParam" );
14251425}
1426+
1427+ TEST_F (DWARFASTParserClangTests, TestObjectPointer_IndexEncoding) {
1428+ // This tests the behaviour of DWARFASTParserClang
1429+ // for DW_TAG_subprogram definitions which have a DW_AT_object_pointer
1430+ // that encodes a constant index (instead of a DIE reference).
1431+
1432+ const char *yamldata = R"(
1433+ --- !ELF
1434+ FileHeader:
1435+ Class: ELFCLASS64
1436+ Data: ELFDATA2LSB
1437+ Type: ET_EXEC
1438+ Machine: EM_AARCH64
1439+ DWARF:
1440+ debug_str:
1441+ - Context
1442+ - func
1443+ - this
1444+ - self
1445+ - arg
1446+ debug_abbrev:
1447+ - ID: 0
1448+ Table:
1449+ - Code: 0x1
1450+ Tag: DW_TAG_compile_unit
1451+ Children: DW_CHILDREN_yes
1452+ Attributes:
1453+ - Attribute: DW_AT_language
1454+ Form: DW_FORM_data2
1455+ - Code: 0x2
1456+ Tag: DW_TAG_structure_type
1457+ Children: DW_CHILDREN_yes
1458+ Attributes:
1459+ - Attribute: DW_AT_name
1460+ Form: DW_FORM_strp
1461+ - Code: 0x3
1462+ Tag: DW_TAG_subprogram
1463+ Children: DW_CHILDREN_yes
1464+ Attributes:
1465+ - Attribute: DW_AT_name
1466+ Form: DW_FORM_strp
1467+ - Attribute: DW_AT_declaration
1468+ Form: DW_FORM_flag_present
1469+ - Attribute: DW_AT_object_pointer
1470+ Form: DW_FORM_implicit_const
1471+ Value: 1
1472+ - Attribute: DW_AT_external
1473+ Form: DW_FORM_flag_present
1474+ - Code: 0x4
1475+ Tag: DW_TAG_subprogram
1476+ Children: DW_CHILDREN_yes
1477+ Attributes:
1478+ - Attribute: DW_AT_name
1479+ Form: DW_FORM_strp
1480+ - Attribute: DW_AT_declaration
1481+ Form: DW_FORM_flag_present
1482+ - Attribute: DW_AT_object_pointer
1483+ Form: DW_FORM_implicit_const
1484+ Value: 0
1485+ - Attribute: DW_AT_external
1486+ Form: DW_FORM_flag_present
1487+
1488+ - Code: 0x5
1489+ Tag: DW_TAG_formal_parameter
1490+ Children: DW_CHILDREN_no
1491+ Attributes:
1492+ - Attribute: DW_AT_name
1493+ Form: DW_FORM_strp
1494+
1495+ - Code: 0x6
1496+ Tag: DW_TAG_formal_parameter
1497+ Children: DW_CHILDREN_no
1498+ Attributes:
1499+ - Attribute: DW_AT_name
1500+ Form: DW_FORM_strp
1501+ - Attribute: DW_AT_artificial
1502+ Form: DW_FORM_flag_present
1503+
1504+ debug_info:
1505+ - Version: 5
1506+ UnitType: DW_UT_compile
1507+ AddrSize: 8
1508+ Entries:
1509+
1510+ # DW_TAG_compile_unit
1511+ # DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)
1512+
1513+ - AbbrCode: 0x1
1514+ Values:
1515+ - Value: 0x04
1516+
1517+ # DW_TAG_structure_type
1518+ # DW_AT_name [DW_FORM_strp] ("Context")
1519+
1520+ - AbbrCode: 0x2
1521+ Values:
1522+ - Value: 0x0
1523+
1524+ # DW_TAG_subprogram
1525+ # DW_AT_name [DW_FORM_strp] ("func")
1526+ # DW_AT_object_pointer [DW_FORM_implicit_const] (1)
1527+ - AbbrCode: 0x3
1528+ Values:
1529+ - Value: 0x8
1530+ - Value: 0x1
1531+ - Value: 0x1
1532+ - Value: 0x1
1533+
1534+ # DW_TAG_formal_parameter
1535+ # DW_AT_name [DW_FORM_strp] ("arg")
1536+ - AbbrCode: 0x5
1537+ Values:
1538+ - Value: 0x17
1539+
1540+ # DW_TAG_formal_parameter
1541+ # DW_AT_name [DW_FORM_strp] ("self")
1542+ # DW_AT_artificial
1543+ - AbbrCode: 0x6
1544+ Values:
1545+ - Value: 0x12
1546+ - Value: 0x1
1547+
1548+ - AbbrCode: 0x0
1549+
1550+ # DW_TAG_subprogram
1551+ # DW_AT_object_pointer [DW_FORM_implicit_const] (0)
1552+ # DW_AT_name [DW_FORM_strp] ("func")
1553+ - AbbrCode: 0x4
1554+ Values:
1555+ - Value: 0x8
1556+ - Value: 0x1
1557+ - Value: 0x1
1558+ - Value: 0x1
1559+
1560+ # DW_TAG_formal_parameter
1561+ # DW_AT_name [DW_FORM_strp] ("this")
1562+ # DW_AT_artificial
1563+ - AbbrCode: 0x6
1564+ Values:
1565+ - Value: 0xd
1566+ - Value: 0x1
1567+
1568+ # DW_TAG_formal_parameter
1569+ # DW_AT_name [DW_FORM_strp] ("arg")
1570+ - AbbrCode: 0x5
1571+ Values:
1572+ - Value: 0x17
1573+
1574+ - AbbrCode: 0x0
1575+ - AbbrCode: 0x0
1576+ ...
1577+ )" ;
1578+
1579+ YAMLModuleTester t (yamldata);
1580+
1581+ DWARFUnit *unit = t.GetDwarfUnit ();
1582+ ASSERT_NE (unit, nullptr );
1583+ const DWARFDebugInfoEntry *cu_entry = unit->DIE ().GetDIE ();
1584+ ASSERT_EQ (cu_entry->Tag (), DW_TAG_compile_unit);
1585+ ASSERT_EQ (unit->GetDWARFLanguageType (), DW_LANG_C_plus_plus);
1586+ DWARFDIE cu_die (unit, cu_entry);
1587+
1588+ auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>(" ast" );
1589+ auto &ast_ctx = *holder->GetAST ();
1590+ DWARFASTParserClangStub ast_parser (ast_ctx);
1591+
1592+ auto context_die = cu_die.GetFirstChild ();
1593+ ASSERT_TRUE (context_die.IsValid ());
1594+ ASSERT_EQ (context_die.Tag (), DW_TAG_structure_type);
1595+
1596+ auto sub1 = context_die.GetFirstChild ();
1597+ ASSERT_TRUE (sub1.IsValid ());
1598+ ASSERT_EQ (sub1.Tag (), DW_TAG_subprogram);
1599+
1600+ auto sub2 = sub1.GetSibling ();
1601+ ASSERT_TRUE (sub2.IsValid ());
1602+ ASSERT_EQ (sub2.Tag (), DW_TAG_subprogram);
1603+
1604+ // Object parameter is at constant index 1
1605+ {
1606+ auto param_die = sub1.GetFirstChild ().GetSibling ();
1607+ ASSERT_TRUE (param_die.IsValid ());
1608+
1609+ EXPECT_EQ (param_die, ast_parser.GetObjectParameter (sub1, context_die));
1610+ }
1611+
1612+ // Object parameter is at constant index 0
1613+ {
1614+ auto param_die = sub2.GetFirstChild ();
1615+ ASSERT_TRUE (param_die.IsValid ());
1616+
1617+ EXPECT_EQ (param_die, ast_parser.GetObjectParameter (sub2, context_die));
1618+ }
1619+ }
0 commit comments