Skip to content

Commit cb29d45

Browse files
committed
[Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType
1 parent ee56373 commit cb29d45

File tree

3 files changed

+52
-40
lines changed

3 files changed

+52
-40
lines changed

clang/lib/Sema/TreeTransform.h

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@
2929
#include "clang/AST/StmtObjC.h"
3030
#include "clang/AST/StmtOpenACC.h"
3131
#include "clang/AST/StmtOpenMP.h"
32-
#include "clang/AST/TypeLoc.h"
3332
#include "clang/Basic/DiagnosticParse.h"
3433
#include "clang/Basic/OpenMPKinds.h"
35-
#include "clang/Sema/DeclSpec.h"
3634
#include "clang/Sema/Designator.h"
3735
#include "clang/Sema/EnterExpressionEvaluationContext.h"
3836
#include "clang/Sema/Lookup.h"
@@ -7219,48 +7217,30 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
72197217
}
72207218

72217219
QualType NamedT;
7222-
if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && isa<TemplateSpecializationType>(TL.getNamedTypeLoc().getType())) {
7223-
const TemplateSpecializationType *TST = TL.getNamedTypeLoc().getType()->getAs<TemplateSpecializationType>();
7220+
if (SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc &&
7221+
isa<TemplateSpecializationType>(TL.getNamedTypeLoc().getType())) {
72247222
TemplateSpecializationTypeLoc SpecTL =
72257223
TL.getNamedTypeLoc().castAs<TemplateSpecializationTypeLoc>();
7226-
// TemplateArgumentListInfo NewTemplateArgs;
7227-
// NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
7228-
// NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
7229-
7230-
// typedef TemplateArgumentLocContainerIterator<
7231-
// TemplateSpecializationTypeLoc> ArgIterator;
7232-
// if (getDerived().TransformTemplateArguments(ArgIterator(SpecTL, 0),
7233-
// ArgIterator(SpecTL, SpecTL.getNumArgs()),
7234-
// NewTemplateArgs))
7235-
// return QualType();
7236-
7224+
const TemplateSpecializationType *TST =
7225+
SpecTL.getType()->castAs<TemplateSpecializationType>();
72377226
CXXScopeSpec SS;
72387227
SS.Adopt(QualifierLoc);
7239-
TemplateName InstName = getDerived().RebuildTemplateName(
7240-
SS, TL.getTemplateKeywordLoc(), *TST->getTemplateName().getAsTemplateDecl()->getIdentifier(), TL.getNamedTypeLoc().getBeginLoc(), QualType(), nullptr,
7241-
false);
7242-
7243-
if (InstName.isNull())
7244-
return QualType();
7245-
7246-
// If it's still dependent, make a dependent specialization.
7247-
// if (InstName.getAsDependentTemplateName())
7248-
// return SemaRef.Context.getDependentTemplateSpecializationType(
7249-
// Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
7250-
// Args.arguments());
7251-
7252-
// Otherwise, make an elaborated type wrapping a non-dependent
7253-
// specialization.
7254-
// NamedT = getDerived().RebuildTemplateSpecializationType(InstName, TL.getNamedTypeLoc().getBeginLoc(), NewTemplateArgs);
7255-
NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
7256-
} else {
7228+
if (TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl()) {
7229+
TemplateName InstName = getDerived().RebuildTemplateName(
7230+
SS, TL.getTemplateKeywordLoc(), *TD->getIdentifier(),
7231+
TL.getNamedTypeLoc().getBeginLoc(), /*ObjectType=*/QualType(),
7232+
/*FirstQualifierInScope=*/nullptr, /*AllowInjectedClassName=*/false);
7233+
if (InstName.isNull())
7234+
return QualType();
7235+
NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
7236+
}
7237+
}
7238+
if (NamedT.isNull()) {
72577239
NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7258-
7240+
if (NamedT.isNull())
7241+
return QualType();
72597242
}
72607243

7261-
if (NamedT.isNull())
7262-
return QualType();
7263-
72647244
// C++0x [dcl.type.elab]p2:
72657245
// If the identifier resolves to a typedef-name or the simple-template-id
72667246
// resolves to an alias template specialization, the

clang/test/SemaCXX/PR91677.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
2+
// expected-no-diagnostics
3+
4+
template <typename> struct t1 {
5+
template <typename>
6+
struct t2 {};
7+
};
8+
9+
template <typename T>
10+
t1<T>::template t2<T> f1();
11+
12+
void f2() {
13+
f1<bool>();
14+
}
15+
16+
namespace N {
17+
template <typename T> struct A {
18+
struct B {
19+
template <typename U> struct X {};
20+
typedef int arg;
21+
};
22+
struct C {
23+
typedef B::template X<B::arg> x;
24+
};
25+
};
26+
27+
template <> struct A<int>::B {
28+
template <int N> struct X {};
29+
static const int arg = 0;
30+
};
31+
}

clang/test/SemaTemplate/typename-specifier-3.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,17 @@ namespace PR12884_original {
2828
typedef int arg;
2929
};
3030
struct C {
31-
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}}
31+
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}} \
32+
cxx17-error{{typename specifier refers to non-type member 'arg' in 'PR12884_original::A<int>::B'}}
3233
};
3334
};
3435

3536
template <> struct A<int>::B {
3637
template <int N> struct X {};
37-
static const int arg = 0;
38+
static const int arg = 0; // cxx17-note{{referenced member 'arg' is declared here}}
3839
};
3940

40-
A<int>::C::x a;
41+
A<int>::C::x a; // cxx17-note{{in instantiation of member class 'PR12884_original::A<int>::C' requested here}}
4142
}
4243
namespace PR12884_half_fixed {
4344
template <typename T> struct A {

0 commit comments

Comments
 (0)