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 <836744...@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 e60cdac25c4ea2e85894e51dfd5268544cadd27d Mon Sep 17 00:00:00 2001 From: Qizhi Hu <836744...@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 | 31 +++++++++++ .../SemaTemplate/typename-specifier-3.cpp | 7 +-- 3 files changed, 52 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..66c3c11834832 --- /dev/null +++ b/clang/test/SemaCXX/PR91677.cpp @@ -0,0 +1,31 @@ +// 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>(); +} + +namespace N { + template <typename T> struct A { + struct B { + template <typename U> struct X {}; + typedef int arg; + }; + struct C { + typedef typename B::template X<B::arg> x; + }; + }; + + template <> struct A<int>::B { + template <int N> struct X {}; + static const int arg = 0; + }; +} 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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits