Skip to content

Commit 38f0b9e

Browse files
authored
Fix scope of typedefs present inside a template class (#146729)
When a typedef is declared within a templated class, clang incorrectly assigns the typedef to the compilation unit (CU) scope rather than the intended scope of the templated class. This issue arises because, during the creation of the typedef, the context lookup in the RegionMap fails to locate the templated class, despite its prior creation. The problem stems from the way the context is stored in the RegionMap. When handling templated types, the current implementation stores the class specialization rather than the templated declaration itself. This leads to a mismatch when attempting to retrieve the context for the typedef. To address this issue, the solution involves modifying the CreatedLimitedType() function. Specifically, when a struct or class is a templated type, we should store the actual templated declaration in the RegionMap instead of the class specialization. This ensures that subsequent lookups for context, such as those needed for typedef declarations, correctly identify the templated class scope. Fixes #91451
1 parent 9b24ccc commit 38f0b9e

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ Bug Fixes in This Version
229229
cast chain. (#GH149967).
230230
- Fixed a crash with incompatible pointer to integer conversions in designated
231231
initializers involving string literals. (#GH154046)
232+
- Fixed scope of typedefs present inside a template class. (#GH91451)
232233

233234
Bug Fixes to Compiler Builtins
234235
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4184,7 +4184,14 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
41844184
break;
41854185
}
41864186

4187-
RegionMap[RD].reset(RealDecl);
4187+
if (auto *CTSD =
4188+
dyn_cast<ClassTemplateSpecializationDecl>(Ty->getOriginalDecl())) {
4189+
CXXRecordDecl *TemplateDecl =
4190+
CTSD->getSpecializedTemplate()->getTemplatedDecl();
4191+
RegionMap[TemplateDecl].reset(RealDecl);
4192+
} else {
4193+
RegionMap[RD].reset(RealDecl);
4194+
}
41884195
TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
41894196

41904197
if (const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=standalone -o - %s | FileCheck %s
2+
3+
template <typename T = int>
4+
struct Y {
5+
typedef int outside;
6+
outside o;
7+
};
8+
9+
Y<> y;
10+
11+
// CHECK: ![[Y:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Y<int>", {{.*}}identifier: "_ZTS1YIiE")
12+
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "outside", scope: ![[Y]],

0 commit comments

Comments
 (0)