https://github.com/mizvekov created https://github.com/llvm/llvm-project/pull/143291
The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in https://github.com/llvm/llvm-project/pull/90032 Fixes https://github.com/llvm/llvm-project/issues/89774 >From 6ef4b071a72e4606a68f6685243d7fe266a0f79e Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Sat, 7 Jun 2025 21:33:07 -0300 Subject: [PATCH] [clang] AST: fix dependency calculation for TypedefTypes The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in https://github.com/llvm/llvm-project/pull/90032 Fixes https://github.com/llvm/llvm-project/issues/89774 --- clang/docs/ReleaseNotes.rst | 3 ++- clang/include/clang/AST/Type.h | 4 ++-- clang/lib/AST/ASTContext.cpp | 4 ++-- clang/lib/AST/Type.cpp | 10 ++++---- clang/lib/CodeGen/CGDebugInfo.cpp | 23 +------------------ .../CodeGenCXX/dependent-template-alias.cpp | 7 ++---- 6 files changed, 14 insertions(+), 37 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1dd8b794c943a..322686fce0b04 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -687,7 +687,7 @@ Bug Fixes in This Version - Fixed an assertion failure in serialization of constexpr structs containing unions. (#GH140130) - Fixed duplicate entries in TableGen that caused the wrong attribute to be selected. (GH#140701) - Fixed type mismatch error when 'builtin-elementwise-math' arguments have different qualifiers, this should be well-formed. (#GH141397) -- Constant evaluation now correctly runs the destructor of a variable declared in +- Constant evaluation now correctly runs the destructor of a variable declared in the second clause of a C-style ``for`` loop. (#GH139818) Bug Fixes to Compiler Builtins @@ -843,6 +843,7 @@ Bug Fixes to AST Handling - Fixed uninitialized use check in a lambda within CXXOperatorCallExpr. (#GH129198) - Fixed a malformed printout of ``CXXParenListInitExpr`` in certain contexts. - Fixed a malformed printout of certain calling convention function attributes. (#GH143160) +- Fixed dependency calculation for TypedefTypes (#GH89774) Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index a6c26a07800c3..040edd392b7aa 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -5821,8 +5821,8 @@ class TypedefType final : public Type, friend class ASTContext; // ASTContext creates these. friend TrailingObjects; - TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying, - QualType can); + TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType UnderlyingType, + bool HasTypeDifferentFromDecl); public: TypedefNameDecl *getDecl() const { return Decl; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 45f9602856840..b51f7622288df 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5216,7 +5216,7 @@ QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl, if (Underlying.isNull()) Underlying = Decl->getUnderlyingType(); auto *NewType = new (*this, alignof(TypedefType)) TypedefType( - Type::Typedef, Decl, QualType(), getCanonicalType(Underlying)); + Type::Typedef, Decl, Underlying, /*HasTypeDifferentFromDecl=*/false); Decl->TypeForDecl = NewType; Types.push_back(NewType); return QualType(NewType, 0); @@ -5238,7 +5238,7 @@ QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl, void *Mem = Allocate(TypedefType::totalSizeToAlloc<QualType>(true), alignof(TypedefType)); auto *NewType = new (Mem) TypedefType(Type::Typedef, Decl, Underlying, - getCanonicalType(Underlying)); + /*HasTypeDifferentFromDecl=*/true); TypedefTypes.InsertNode(NewType, InsertPos); Types.push_back(NewType); return QualType(NewType, 0); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 5bb39b12693fb..49f5e8138834b 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -4013,13 +4013,13 @@ StringRef CountAttributedType::getAttributeName(bool WithMacroPrefix) const { } TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D, - QualType Underlying, QualType can) - : Type(tc, can, toSemanticDependence(can->getDependence())), + QualType UnderlyingType, bool HasTypeDifferentFromDecl) + : Type(tc, UnderlyingType.getCanonicalType(), + toSemanticDependence(UnderlyingType->getDependence())), Decl(const_cast<TypedefNameDecl *>(D)) { - assert(!isa<TypedefType>(can) && "Invalid canonical type"); - TypedefBits.hasTypeDifferentFromDecl = !Underlying.isNull(); + TypedefBits.hasTypeDifferentFromDecl = HasTypeDifferentFromDecl; if (!typeMatchesDecl()) - *getTrailingObjects<QualType>() = Underlying; + *getTrailingObjects<QualType>() = UnderlyingType; } QualType TypedefType::desugar() const { diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 001b208e1c3ff..ee5e3d68a5ffa 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1564,28 +1564,7 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, SourceLocation Loc = AliasDecl->getLocation(); - if (CGM.getCodeGenOpts().DebugTemplateAlias && - // FIXME: This is a workaround for the issue - // https://github.com/llvm/llvm-project/issues/89774 - // The TemplateSpecializationType doesn't contain any instantiation - // information; dependent template arguments can't be resolved. For now, - // fall back to DW_TAG_typedefs for template aliases that are - // instantiation dependent, e.g.: - // ``` - // template <int> - // using A = int; - // - // template<int I> - // struct S { - // using AA = A<I>; // Instantiation dependent. - // AA aa; - // }; - // - // S<0> s; - // ``` - // S::AA's underlying type A<I> is dependent on I so will be emitted as a - // DW_TAG_typedef. - !Ty->isInstantiationDependentType()) { + if (CGM.getCodeGenOpts().DebugTemplateAlias) { auto ArgVector = ::GetTemplateArgs(TD, Ty); TemplateArgs Args = {TD->getTemplateParameters(), ArgVector}; diff --git a/clang/test/CodeGenCXX/dependent-template-alias.cpp b/clang/test/CodeGenCXX/dependent-template-alias.cpp index deb243f9fc88d..324b16f1919df 100644 --- a/clang/test/CodeGenCXX/dependent-template-alias.cpp +++ b/clang/test/CodeGenCXX/dependent-template-alias.cpp @@ -1,9 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -gtemplate-alias %s -gsimple-template-names=simple \ // RUN: | FileCheck %s -//// Check that -gtemplate-alias falls back to DW_TAG_typedef emission -//// for instantiation dependent type aliases. - template <int> using A = int; @@ -16,6 +13,6 @@ struct S { S<0> s; // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[AA:[0-9]+]], size: 32) -// CHECK: [[AA]] = !DIDerivedType(tag: DW_TAG_typedef, name: "AA", file: ![[#]], line: [[#]], baseType: ![[A:[0-9]+]]) -// CHECK: [[A]] = !DIDerivedType(tag: DW_TAG_typedef, name: "A<I>", file: ![[#]], line: [[#]], baseType: ![[int:[0-9]+]]) +// CHECK: [[AA]] = !DIDerivedType(tag: DW_TAG_typedef, name: "AA", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[A:[0-9]+]]) +// CHECK: [[A]] = !DIDerivedType(tag: DW_TAG_template_alias, name: "A", file: ![[#]], line: [[#]], baseType: ![[int:[0-9]+]], extraData: ![[#]]) // CHECK: [[int]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits