-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[clang] AST: fix dependency calculation for TypedefTypes #143291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Matheus Izvekov (mizvekov) ChangesThe 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 #90032 Fixes #89774 Full diff: https://github.com/llvm/llvm-project/pull/143291.diff 6 Files Affected:
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)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
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 #90032 Fixes #89774
6ef4b07
to
d623054
Compare
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 llvm#90032 Fixes llvm#89774
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 llvm#90032 Fixes llvm#89774
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 llvm#90032 Fixes llvm#89774
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 #90032
Fixes #89774