Skip to content

[clang][DebugInfo] DW_AT_name of inheriting constructor is the base class name #115247

@Michael137

Description

@Michael137

Given:

struct Foo {
  Foo(int) {}
};

struct Bar : public Foo {
  using Foo::Foo;
};

int main() {
  Bar b(5);
}

Clang produces following DWARF:

0x0000002a:   DW_TAG_structure_type
                DW_AT_calling_convention        (DW_CC_pass_by_value)
                DW_AT_name      ("Bar")
                DW_AT_byte_size (0x01)
                DW_AT_decl_file ("inherit.cpp")
                DW_AT_decl_line (5)

0x00000033:     DW_TAG_inheritance
                  DW_AT_type    (0x0000004a "Foo")
                  DW_AT_data_member_location    (0x00)

0x00000039:     DW_TAG_subprogram
                  DW_AT_name    ("Foo")
                  DW_AT_declaration     (true)
                  DW_AT_artificial      (true)
                  DW_AT_external        (true)

0x0000003e:       DW_TAG_formal_parameter
                    DW_AT_type  (0x0000009a "Bar *")
                    DW_AT_artificial    (true)

0x00000043:       DW_TAG_formal_parameter
                    DW_AT_type  (0x0000006b "int")

Note how the constructor DW_AT_name is Foo (despite the implicit this parameter being Bar).

GCC produces:

0x00000061:   DW_TAG_structure_type                                                                       
                DW_AT_name      ("Bar")                                                                   
                DW_AT_byte_size (1)                 
                DW_AT_decl_file ("inherit.cpp")                                         
                DW_AT_decl_line (5)                 
                DW_AT_decl_column       (8)                                                               
                DW_AT_sibling   (0x0000008a)      
                                                     
0x0000006b:     DW_TAG_inheritance                                                                        
                  DW_AT_type    (0x0000002a "Foo")                                                        
                  DW_AT_data_member_location    (0x00)       

0x00000071:     DW_TAG_subprogram        
                  DW_AT_external        (true)    
                  DW_AT_name    ("Bar")              
                  DW_AT_linkage_name    ("_ZN3BarCI43FooEi")                                              
                  DW_AT_artificial      (true)       
                  DW_AT_declaration     (true)
                  DW_AT_object_pointer  (0x0000007e) 
                                                                                                          
0x0000007e:       DW_TAG_formal_parameter                                                                 
                    DW_AT_type  (0x000000ba "Bar *")
                    DW_AT_artificial    (true)       
                                                     
0x00000083:       DW_TAG_formal_parameter                                                                 
                    DW_AT_type  (0x0000005a "int")                                                        

I'm not certain which of these is technically the correct representation here. Though for LLDB, GCC's DWARF is easier to handle because to know whether we're dealing with a constructor DIE we can just check function name == enclosing class name (came up in https://discourse.llvm.org/t/rfc-lldb-handling-abi-tagged-constructors-destructors-in-expression-evaluator/82816).

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:codegenIR generation bugs: mangling, exceptions, etc.debuginfo

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions