<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/55680>55680</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [DWARF][DebugInfo] Function-local types may have concrete out-of-line parent subprogram instead of abstract one
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            debuginfo
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          chbessonova
      </td>
    </tr>
</table>

<pre>
    Consider the following example:

```
template<typename T>
struct A { 
  A(T &in) : a(in) {}
  T a;
};

__attribute__((always_inline))
void foo() {
  struct B { int i; };
  B objB;
  A<B> objA(objB);
}

int main() {
  foo();
}
```

Here the function `foo()` should have 3 subprogram instances emitted: abstract, inlined and out-of-line.
The definition of `struct B` is expected to be a child of abstract instance of `foo()`.

But actually, it is emitted as a child of out-of-line instance of `foo()`:

```
$ clang -g -c -o - test.cpp | llvm-dwarfdump - --name=foo --show-children 

0x0000002a: DW_TAG_subprogram
              DW_AT_low_pc      (0x0000000000000000)
              DW_AT_high_pc     (0x000000000000001b)
              DW_AT_frame_base  (DW_OP_reg6 RBP)
              DW_AT_abstract_origin     (0x000000dc "_Z3foov")
              ...

0x0000004d:   DW_TAG_structure_type
                DW_AT_calling_convention        (DW_CC_pass_by_value)
                DW_AT_name      ("B")
                DW_AT_byte_size (0x04)
                DW_AT_decl_file ("test.cpp")
                DW_AT_decl_line (9)
                ...
0x00000062:     NULL

0x00000063:   NULL

0x000000dc: DW_TAG_subprogram
              DW_AT_linkage_name        ("_Z3foov")
              DW_AT_name        ("foo")
              DW_AT_decl_file   ("test.cpp")
              DW_AT_decl_line   (8)
              DW_AT_external    (true)
              DW_AT_inline      (DW_INL_inlined)
              ...
0x000000fe:   NULL

0x00000118: DW_TAG_inlined_subroutine
              DW_AT_abstract_origin     (0x000000dc "_Z3foov")
              DW_AT_low_pc      (0x0000000000000048)
              DW_AT_high_pc     (0x0000000000000055)
              DW_AT_call_file   ("test.cpp")
              DW_AT_call_line   (15)
              DW_AT_call_column (0x03)
              ...
0x0000013c:   NULL
```

While looking for a context subprogram DIE for `foo()::B` we are considering to get or create only a concrete subprogram DIE, never accounting an abstract one.

This makes impossible to directly inspect the type in debugger:

```
Breakpoint 1, foo () at test.cpp:11
11        A<B> objA(objB);
(gdb) ptype B
No symbol "B" in current context.
(gdb) ptype objB
type = struct B {
    int i;
}
```

while gcc-compiled example (where `struct B` gets placed correctly) allows this:

```
Breakpoint 1, foo () at test.cpp:11
11        A<B> objA(objB);
(gdb) ptype B
type = struct B {
    int i;
}
(gdb) ptype objB
type = struct B {
    int i;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNV1tv6jgQ_jXhZQTKhVB44IFLu1upOnt01FWlfYkcx0l86sRR7EDZX79jJ4HQBdqtdKRFEcT23Gc88xHL5LDcyFLxhNWgcwapFELueZkBeyNFJZgTrBx367j998ztHrvUDGmIRqqNPlSsJAWDZye4b0-VrhuqYQXO3RraLYCV48-fwfFnvHT8BaB8ILjVre7Wzt22J33Gk2DdKcbt47v9jiKidc3jRrMoQgn4ELEnBxXxUvCSoTzzWNqd5An6Ji1Zq6bT0dm4tjbyUgNHNTDUBngo45_rwcYK_cX1vdk3_thj1DU0dmCpEVsQ4-F77UeTLrCeR7r9_p3VrM1TU1LNZQlIcBIyc0HlshEJ5GTHIADVxFUts5oU6JvSpKRMASu41iyxkY_Rf0K142-gjVoCpExANnos07HZmLSan1FpwlJecqtWpkZzHzyjmKPgt4pRlAxaQsyAAM052oK0vZ6jFZ2AoemToaPrRgPSN0SIgzVOWwWt5UDUUPjA2Fvyb1ey40-BCoKFP8aHwljCGDRTekKrClO2ASF2xTjZkzpNmqLC0_HY1LsTbFELLjDy-7E1qmYlDFW5b679-MTEfPsSPa9-i06p6Yth-EGi1XOEVzGqqONiIc97IafPsbovseY8y6_yevFN3hSNYlFMFGvZcfeP71HNshn8WH-_ydonOpI1z7Diz9QnFO-9H_0VYMB2-HZF0mQyuRS9qa1YOMbP1l5Ts8h0nktyepsoFhF2tIjKcsdKU75HtzabqCJKRfEh2hHRsCsW9ZJsvi0vWr--7kFPHx-wNyn-NzvGYfoBR8KoiFIuTmr6GvxYm-W1nc_yLq6SHwPch3bmt6EF-Pbn09Ol4M-CluLaeUL_a2nz8pVk7DykH5bGhTTYK36b_itBvRjS-U1i9qZZXRLR0mJ5XiunlrybUn0pPn576raSj-5FH_SU3UyK580HSelkm-TU2DGt6l95iz_uYNPb4bzZwcLwJq-58l_LuOU8Jcb7hB4qRVOcghR8Mn1eQP-Vvksz_wVHCgMh5auBZamszeyTpcZyG8737eO9PTybejjygpUdz3ucx4gdaAf2jCic0hnTgDy0ZgjiQJbi0ArHDVyfSzdjuGQ7BIqEUtlgI0UZpDzNdnkECz1kwJFdkFeEHLyopFI8RkdQa8JrxAmoC6e1QQwW0ZgujhsIMuImy1h9e1yv0eLXShpk5RnDzAju4BXRx7mNMjyvZTC_i08gN3-eJWY6QmUN6ra_SVCHIpYCusZvLKVNjZNe98mYXJZgNbRg2SwRLpxhzlOl9ODzMzhwb2sio3RMZVHhe9LjdROFfW5g4jt8hqlWgGCdIi2VdZsBGy-D-BXmgKv_Vcy_GK5fFf5RsgySRbAgI821YEsnXG9fVj8enHBrXk3VPpapxCU8dOB8LCQ2CFvZ5iIcWlR-vF5D3FoRW0rv8Doj5-gZb9ioqcUy17qyyfIf8Mm4zpt4gpWAC4NSu58xivrJDLh_4Eo1TOFLGM7m7ihf-qHr0buYhYnvJenMX6TJ3I2DxJ37_vQujUeCxEwo4yVWu72T3HiH3TPcjvjSd33fDf2phx0y9Ccz4gUh8RaxGyxiRkNn6jL8xyMmxo6JrLNRvbQmoRyFh4IrrU6HCMF4VjIbVCOfNDqX9ZLmMVNKlnJHRtaDpTX_H8SyEC8">