[clang] [Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType (PR #93411)
Qizhi Hu via cfe-commits
cfe-commits at lists.llvm.org
Sun May 26 05:41:39 PDT 2024
https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/93411
>From f5f0b14945a70e3e4fd92d5e5cbdb428334fe2b8 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744285 at qq.com>
Date: Sat, 25 May 2024 16:30:27 +0800
Subject: [PATCH 1/2] [Clang][Sema] Use correct TemplateName when transforming
TemplateSpecializationType
---
clang/lib/Sema/TreeTransform.h | 43 +++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dee335b526991..7e8b080a347e8 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,8 +29,10 @@
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/Basic/DiagnosticParse.h"
#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Lookup.h"
@@ -7216,7 +7218,46 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
return QualType();
}
- QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+ QualType NamedT;
+ if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && isa<TemplateSpecializationType>(TL.getNamedTypeLoc().getType())) {
+ const TemplateSpecializationType *TST = TL.getNamedTypeLoc().getType()->getAs<TemplateSpecializationType>();
+ TemplateSpecializationTypeLoc SpecTL =
+ TL.getNamedTypeLoc().castAs<TemplateSpecializationTypeLoc>();
+ // TemplateArgumentListInfo NewTemplateArgs;
+ // NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
+ // NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
+
+ // typedef TemplateArgumentLocContainerIterator<
+ // TemplateSpecializationTypeLoc> ArgIterator;
+ // if (getDerived().TransformTemplateArguments(ArgIterator(SpecTL, 0),
+ // ArgIterator(SpecTL, SpecTL.getNumArgs()),
+ // NewTemplateArgs))
+ // return QualType();
+
+ CXXScopeSpec SS;
+ SS.Adopt(QualifierLoc);
+ TemplateName InstName = getDerived().RebuildTemplateName(
+ SS, TL.getTemplateKeywordLoc(), *TST->getTemplateName().getAsTemplateDecl()->getIdentifier(), TL.getNamedTypeLoc().getBeginLoc(), QualType(), nullptr,
+ false);
+
+ if (InstName.isNull())
+ return QualType();
+
+ // If it's still dependent, make a dependent specialization.
+ // if (InstName.getAsDependentTemplateName())
+ // return SemaRef.Context.getDependentTemplateSpecializationType(
+ // Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
+ // Args.arguments());
+
+ // Otherwise, make an elaborated type wrapping a non-dependent
+ // specialization.
+ // NamedT = getDerived().RebuildTemplateSpecializationType(InstName, TL.getNamedTypeLoc().getBeginLoc(), NewTemplateArgs);
+ NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
+ } else {
+ NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+
+ }
+
if (NamedT.isNull())
return QualType();
>From 3ebed0fecd90101b57082909348a60070c689d12 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744285 at qq.com>
Date: Sun, 26 May 2024 19:35:17 +0800
Subject: [PATCH 2/2] [Clang][Sema] Use correct TemplateName when transforming
TemplateSpecializationType
---
clang/lib/Sema/TreeTransform.h | 54 ++++++-------------
clang/test/SemaCXX/PR91677.cpp | 14 +++++
.../SemaTemplate/typename-specifier-3.cpp | 7 +--
3 files changed, 35 insertions(+), 40 deletions(-)
create mode 100644 clang/test/SemaCXX/PR91677.cpp
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7e8b080a347e8..6ef2eec09ec02 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,10 +29,8 @@
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/TypeLoc.h"
#include "clang/Basic/DiagnosticParse.h"
#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Lookup.h"
@@ -7219,48 +7217,30 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
}
QualType NamedT;
- if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && isa<TemplateSpecializationType>(TL.getNamedTypeLoc().getType())) {
- const TemplateSpecializationType *TST = TL.getNamedTypeLoc().getType()->getAs<TemplateSpecializationType>();
+ if (SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc &&
+ isa<TemplateSpecializationType>(TL.getNamedTypeLoc().getType())) {
TemplateSpecializationTypeLoc SpecTL =
TL.getNamedTypeLoc().castAs<TemplateSpecializationTypeLoc>();
- // TemplateArgumentListInfo NewTemplateArgs;
- // NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
- // NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
-
- // typedef TemplateArgumentLocContainerIterator<
- // TemplateSpecializationTypeLoc> ArgIterator;
- // if (getDerived().TransformTemplateArguments(ArgIterator(SpecTL, 0),
- // ArgIterator(SpecTL, SpecTL.getNumArgs()),
- // NewTemplateArgs))
- // return QualType();
-
+ const TemplateSpecializationType *TST =
+ SpecTL.getType()->castAs<TemplateSpecializationType>();
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
- TemplateName InstName = getDerived().RebuildTemplateName(
- SS, TL.getTemplateKeywordLoc(), *TST->getTemplateName().getAsTemplateDecl()->getIdentifier(), TL.getNamedTypeLoc().getBeginLoc(), QualType(), nullptr,
- false);
-
- if (InstName.isNull())
- return QualType();
-
- // If it's still dependent, make a dependent specialization.
- // if (InstName.getAsDependentTemplateName())
- // return SemaRef.Context.getDependentTemplateSpecializationType(
- // Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
- // Args.arguments());
-
- // Otherwise, make an elaborated type wrapping a non-dependent
- // specialization.
- // NamedT = getDerived().RebuildTemplateSpecializationType(InstName, TL.getNamedTypeLoc().getBeginLoc(), NewTemplateArgs);
- NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
- } else {
+ if (TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl()) {
+ TemplateName InstName = getDerived().RebuildTemplateName(
+ SS, TL.getTemplateKeywordLoc(), *TD->getIdentifier(),
+ TL.getNamedTypeLoc().getBeginLoc(), /*ObjectType=*/QualType(),
+ /*FirstQualifierInScope=*/nullptr, /*AllowInjectedClassName=*/false);
+ if (InstName.isNull())
+ return QualType();
+ NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
+ }
+ }
+ if (NamedT.isNull()) {
NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
-
+ if (NamedT.isNull())
+ return QualType();
}
- if (NamedT.isNull())
- return QualType();
-
// C++0x [dcl.type.elab]p2:
// If the identifier resolves to a typedef-name or the simple-template-id
// resolves to an alias template specialization, the
diff --git a/clang/test/SemaCXX/PR91677.cpp b/clang/test/SemaCXX/PR91677.cpp
new file mode 100644
index 0000000000000..cc8db60a438ea
--- /dev/null
+++ b/clang/test/SemaCXX/PR91677.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template <typename> struct t1 {
+ template <typename>
+ struct t2 {};
+};
+
+template <typename T>
+t1<T>::template t2<T> f1();
+
+void f2() {
+ f1<bool>();
+}
diff --git a/clang/test/SemaTemplate/typename-specifier-3.cpp b/clang/test/SemaTemplate/typename-specifier-3.cpp
index 714830f0032d2..a62a1fc5ab39c 100644
--- a/clang/test/SemaTemplate/typename-specifier-3.cpp
+++ b/clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,16 +28,17 @@ namespace PR12884_original {
typedef int arg;
};
struct C {
- typedef B::X<typename B::arg> x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
+ typedef B::X<typename B::arg> x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}} \
+ cxx17-error{{typename specifier refers to non-type member 'arg' in 'PR12884_original::A<int>::B'}}
};
};
template <> struct A<int>::B {
template <int N> struct X {};
- static const int arg = 0;
+ static const int arg = 0; // cxx17-note{{referenced member 'arg' is declared here}}
};
- A<int>::C::x a;
+ A<int>::C::x a; // cxx17-note{{in instantiation of member class 'PR12884_original::A<int>::C' requested here}}
}
namespace PR12884_half_fixed {
template <typename T> struct A {
More information about the cfe-commits
mailing list