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

    <tr>
        <th>Summary</th>
        <td>
            [Clang][DebugInfo] typedef in template class given wrong scope
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

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

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

<pre>
    Clang trunk built at d4cf20ca37160cb062a9db773d0e6255d6bbc31a (19.0)

Godbolt version of example below https://godbolt.org/z/7esxK8dbY


$ cat test.cpp
```
struct X {
  typedef int inside;
  inside i;
};

template <typename T = int>
struct Y {
  typedef int outside;
  outside o;
};

X x;
Y<> y;
```

The DIE for `outside` is scoped to `DW_TAG_compile_unit (0x0000000b)` while the DIE for `inside` is scoped to its enclosing `DW_TAG_structure_type (0x00000033)`. `outside` should be scoped to the `DW_TAG_structure_type` DIE for `Y<int>` (`0x00000070`).

$ clang -O0 -g test.cpp -o - | llvm-dwarfdump -
```
0x00000000: Compile Unit: length = 0x00000097, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000009b)

0x0000000b: DW_TAG_compile_unit
 DW_AT_producer ("clang version 19.0.0git (https://github.com/llvm/llvm-project.git d4cf20ca37160cb062a9db773d0e6255d6bbc31a)")
 DW_AT_language (DW_LANG_C_plus_plus_14)
 DW_AT_name     ("test.cpp")
              DW_AT_stmt_list   (0x00000000)
 DW_AT_comp_dir ("/")

0x0000001e:   DW_TAG_variable
 DW_AT_name     ("x")
                DW_AT_type      (0x00000033 "X")
                DW_AT_external  (true)
 DW_AT_decl_file        ("test.cpp")
                DW_AT_decl_line (12)
 DW_AT_location (DW_OP_addr 0x0)

0x00000033: DW_TAG_structure_type
 DW_AT_calling_convention       (DW_CC_pass_by_value)
 DW_AT_name     ("X")
                DW_AT_byte_size (0x04)
 DW_AT_decl_file        ("test.cpp")
 DW_AT_decl_line        (1)

0x0000003c:     DW_TAG_member
 DW_AT_name     ("i")
                  DW_AT_type    (0x00000048 "inside")
                  DW_AT_decl_file       ("test.cpp")
 DW_AT_decl_line        (3)
 DW_AT_data_member_location     (0x00)

0x00000048:     DW_TAG_typedef
 DW_AT_type     (0x00000054 "int")
 DW_AT_name     ("inside")
 DW_AT_decl_file        ("test.cpp")
 DW_AT_decl_line        (2)

0x00000053:     NULL

0x00000054: DW_TAG_base_type
                DW_AT_name      ("int")
 DW_AT_encoding (DW_ATE_signed)
 DW_AT_byte_size        (0x04)

0x0000005b:   DW_TAG_variable
 DW_AT_name     ("y")
                DW_AT_type      (0x00000070 "Y<int>")
                DW_AT_external  (true)
 DW_AT_decl_file        ("test.cpp")
                DW_AT_decl_line (13)
 DW_AT_location (DW_OP_addr 0x0)

0x00000070: DW_TAG_structure_type
 DW_AT_calling_convention       (DW_CC_pass_by_value)
 DW_AT_name     ("Y<int>")
                DW_AT_byte_size (0x04)
 DW_AT_decl_file        ("test.cpp")
 DW_AT_decl_line        (7)

0x00000079: DW_TAG_template_type_parameter
                  DW_AT_type    (0x00000054 "int")
                  DW_AT_name    ("T")
 DW_AT_default_value    (true)

0x00000082:     DW_TAG_member
 DW_AT_name     ("o")
                  DW_AT_type    (0x0000008f "outside")
                  DW_AT_decl_file       ("test.cpp")
 DW_AT_decl_line        (9)
 DW_AT_data_member_location     (0x00)

0x0000008e: NULL

0x0000008f:   DW_TAG_typedef
 DW_AT_type     (0x00000054 "int")
 DW_AT_name     ("outside")
 DW_AT_decl_file        ("test.cpp")
 DW_AT_decl_line        (8)

0x0000009a:   NULL
```


Looking at the IR produced by Clang:

$ clang -O0 -g test.cpp -emit-llvm -S -o -
```
source_filename = "test.cpp"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.X = type { i32 }
%struct.Y = type { i32 }

@x = dso_local global %struct.X zeroinitializer, align 4, !dbg !0
@y = dso_local global %struct.Y zeroinitializer, align 4, !dbg !5

!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!19, !20, !21, !22, !23, !24, !25}
!llvm.ident = !{!26}

!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "x", scope: !2, file: !7, line: 12, type: !15, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 19.0.0git (https://github.com/llvm/llvm-project.git d4cf20ca37160cb062a9db773d0e6255d6bbc31a)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
!3 = !DIFile(filename: "test.cpp")
!4 = !{!0, !5}
!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
!6 = distinct !DIGlobalVariable(name: "y", scope: !2, file: !7, line: 13, type: !8, isLocal: false, isDefinition: true)
!7 = !DIFile(filename: "example.cpp"test.cpp)
!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Y<int>", file: !7, line: 7, size: 32, flags: DIFlagTypePassByValue, elements: !9, templateParams: !13, identifier: "_ZTS1YIiE")
!9 = !{!10}
!10 = !DIDerivedType(tag: DW_TAG_member, name: "o", scope: !8, file: !7, line: 9, baseType: !11, size: 32)
!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "outside", file: !7, line: 8, baseType: !12)
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !{!14}
!14 = !DITemplateTypeParameter(name: "T", type: !12, defaulted: true)
!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "X", file: !7, line: 1, size: 32, flags: DIFlagTypePassByValue, elements: !16, identifier: "_ZTS1X")
!16 = !{!17}
!17 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !15, file: !7, line: 3, baseType: !18, size: 32)
!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "inside", scope: !15, file: !7, line: 2, baseType: !12)
!19 = !{i32 7, !"Dwarf Version", i32 4}
!20 = !{i32 2, !"Debug Info Version", i32 3}
!21 = !{i32 1, !"wchar_size", i32 4}
!22 = !{i32 8, !"PIC Level", i32 2}
!23 = !{i32 7, !"PIE Level", i32 2}
!24 = !{i32 7, !"uwtable", i32 2}
!25 = !{i32 7, !"frame-pointer", i32 2}
!26 = !{!"clang version 19.0.0git (https://github.com/llvm/llvm-project.git d4cf20ca37160cb062a9db773d0e6255d6bbc31a)"}
```

`inside` has a `scope` field pointing to `X`.
```
!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "X", ...)
!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "inside", scope: !15, file: !7, line: 2, baseType: !12)
```

`outside` has no scope field.
```
!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "outside", file: !7, line: 8, baseType: !12)
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWllzo7j2_zTkRWUXiMX4IQ-OHfc_NanprhlPd_J_oQQIrNuyRCGR2P3pb0kCDBiy9HKnUykMQjrL7yw6RzYSguQM42vLv7H8zRWq5J6X1x_X_3dCB3EV8_R0vaaI5UCWFfsK4opQCZAEqZdk0E6Qu3ACO4ntAKJlGi8WbmrjAPp-GsRx4joIWDB0lnPbgkvL3lj2ylw_8DTmVIInXArCGeAZwEd0KCgGMab8GeylLITlriy4teA2N9PnvMwtuP1mwe0Ci-MfYRo_dqnWV-iBBEkgsZDzpCjq0cCu__WjkGWVSPAArMWNGQFAngqc4gwQJgFhgqTYctuXZgCQdshabM73-irxoaBIYmC5a0WLoQMGO2C5G0XScm97rB-nWPNKDnjXI4C_wPwBHNuRR8tdW-4tOJ3n9LU3190eg83dLch4CazAbvgGNiACiIQXOAWSq1ebL9Fu9SFK-KEgFEcVI1IZ1j7a5i9W5g1s8LwnFAPZp1tDOSRLpACYJZQLwvIOEwNPVeJIgdJl47qGzXwgrdjziqYgxh3qSoYpmmpNRz6FVm2fwFb8rMBuWC40ZnA5v3AwHRSzjzaY5a2ngRkHM2At1oDSp8MsfUZlllaHAsxGrdDCZ1vuCqwNuOAfRqR6ppjlcq-9p5m4XFhwrcQ-IKlfbL6s_tq6UI02kdTO99QoiuMy4lkmsOxQ0m_StIwE-Yab8VCpzvBRAm1eJM9s40H0duzursCIc9SOu_kSrXZRUfK0SnBp2UsFLoQGu0ZglR3mdm48ahD2RO6reJ7wgwW3CtL6Y1aU_D84kXO16q2ZSOkAYatJLZwSpUI5NsJtvkT3qz8_ROuooJUwF8cbrlFx3SrTZpku7d6fWSTkQUaUCGlWdmw_oK5wjFJyhktjASdM4GBlAtAY4QmVBMUUT8t7nBa0EVXHSE9K1wUWhA-vL8VHiUuGqFkuywoP1UtxQqOM0PcgCLprKWH1WufSmjxBknDWWvPjp0g5unLlCQBdt-PDgzzRMwuilLA8Sjh7wqzHZL2OCiREFJ-iJ0QvVe7h_wYQ45PEOjRbI1y44BtRHIdtConEuFLrTAd8iFXYTqlCXlJl2pk8lWlgvSu8gcKP6OpevEcS1YoNvEWJN4GMFw6QqbfrHuVLRX3PKCpH5OwDeYnFj6s-lTF8t1Hmz3_u70dneJ2QiJHoRcOoiQbajCmMWcJTwvI2ala720gXn-lw6kv-P5A0fmf2O31P9luoqgB2yoTfLA1eOPl3pMGF_b9Ng-9B8xfnw8UUJMsOJE1trxGJClSiA5Ztcnxz7htPCRPLe4DtRhXJUEVlDfelr_X1CeE78zv_vvweZkrHpj7_xQl--VMSfKirqKl8GGa9LPOTk_8YUD-OSzih6RIZXTq6jrWG5nrP-VfVnKlmeo_B3V-gruVTEJ-APhdQtfrbWiN8IHKmqncw-1s3SuN9Oa_KBGutdfusmpOB4qbXRmWOJVDWpujEK9nMxLOD5a7wrIA6pblQX9Sj039Ud4GnLzPS3jhQ7fUODGdZaNd3TA8FzfLAm_3tmMq8K4osSUFbgY9hEAXerGJfGX9mM0pYdZzlrGpXNXj5JtnOH_RK0_IubgBxIVBN_mDW40uzzNWzj3pSKrgOAApyymNEQZfXN1xywogkiJJvuNQNISU5A7prtKCTxrn6sFuip9eIPr6ZqN9HwFFOMU_jfJ5UNXyOtbixoAM7CJhZB55WFM8zinLRn-ssaybQbm6c5gY2N25z00gE_QsWJMVMDuQIhiBDx26mbO4-aCg-18XH7bEosVCtrQXDJ1SqeFPyKY74WDTPm7veRN2dLlvqjkGbCElYIsfYqGZdpRFNre7q1uYApOagB3T6MM_68EBnCHcFzFudtmr5fDVAxL2yrhrLEBXYjG1wpu3KmXrR32KgA0dkrQ8z9FkGDNsm2-ynoy12T1Rtp_bcwKj4754aKBg-FpIcyDec9uApKybJAX82gqlX2gHxgWjb_kGYnr-tKN3guMrVSxM8otZWay8KSqSecMcoYUSn1jMXZeudsntD70_OelZwz_64Jdo9mhxa4ze2dyjmfVdvgqcXF_47fT14l68H7_T107t93R34evi9rr54DeT6ELvG-Qz5mUQ4ES1cEIl3SkYYSpRPV-O1M9QMB3X0NAj6QRfR7gqYI0OdRTWjuy1FuWL-CQlxc_psyvc1wBQfMJONo-oU21TCn1QN3LwxEOvUSTLSxmz0_7u_ncc7cjtwuuUgd9tdb-um1g0uyRNOR3Gpy9c-HnzEOcKXcNE6qSZ318mFzhCsTmZ23iZdUyUOxOsUe9MyhWMy9aWAZylukCBJLUOHVVN6Dq3eNuJuXTpetOHangMLeT0LeWfuu9odjPc0bVFPkl0th-xrswZ1_2IS6jDW6qzz0yLl4RXQL2z-HQFiMt94GDwMYqDOe2eIFz2IFz8QBGQkCMz-PqW8O-Zx4QtREP5IFHTOu94jJHw9LLqJRRXHi3o7syDcPKMyA802Xe_pLgQ9z4b2gADsEFCbM7hjGR-h4vaoOAMqzpnKc7JH5ouXSRngYHV4Xv3pbg3u8ROmncW9Khm60wh8urt9ZbE3vbh6lmYrnljqTy_NVFaYFZwwnRomCAzC4d-u-FrRRtvj7reaeyQAAlZgG08ObJARTFOgFVbts_kO9cEK7Pk4zV-X7Obz-W8fthMAd77gVQgzblgacKeB_A2250aoq_TaTZfuEl3ha2fh-E7g-K57tb-GWRb4tuMlNrZTP_A8H2I39j3PW0CIbXxFrqENPdu3Q3vp-S6cOy5eOiFybAeHMEwTy7PxARE61y0rL_MrIkSFr5eO5ztXFMWYCv2bjjqKlEb-5qq81mERV7mwPJsSIcWZgiSS6h-CmIMdf2P5N3VDknHL33R-pNAWgSChSAiQkyfMwHPJWW6sdFWV9Pp9QWrBrdZBWHCr1fhvAAAA__9XZ3ui">