mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
[clang] Instantiate NTTPs and template default arguments with sugar
This makes use of the changes introduced in D134604, in order to instantiate non-type template parameters and default template arguments with a final sugared substitution. This comes at no additional relevant cost. Since we don't track / unique them in specializations, we wouldn't be able to resugar them later anyway. Signed-off-by: Matheus Izvekov <mizvekov@gmail.com> Differential Revision: https://reviews.llvm.org/D136564
This commit is contained in:
parent
5f820c0f55
commit
ab1140874f
@ -8201,14 +8201,11 @@ public:
|
||||
SourceLocation TemplateLoc,
|
||||
Declarator &D);
|
||||
|
||||
TemplateArgumentLoc
|
||||
SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
|
||||
SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc,
|
||||
Decl *Param,
|
||||
SmallVectorImpl<TemplateArgument>
|
||||
&Converted,
|
||||
bool &HasDefaultArg);
|
||||
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(
|
||||
TemplateDecl *Template, SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc, Decl *Param,
|
||||
ArrayRef<TemplateArgument> SugaredConverted,
|
||||
ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg);
|
||||
|
||||
/// Specifies the context in which a particular template
|
||||
/// argument is being checked.
|
||||
|
@ -5261,27 +5261,25 @@ bool Sema::CheckTemplateTypeArgument(
|
||||
/// \param Converted the list of template arguments provided for template
|
||||
/// parameters that precede \p Param in the template parameter list.
|
||||
/// \returns the substituted template argument, or NULL if an error occurred.
|
||||
static TypeSourceInfo *
|
||||
SubstDefaultTemplateArgument(Sema &SemaRef,
|
||||
TemplateDecl *Template,
|
||||
SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc,
|
||||
TemplateTypeParmDecl *Param,
|
||||
SmallVectorImpl<TemplateArgument> &Converted) {
|
||||
static TypeSourceInfo *SubstDefaultTemplateArgument(
|
||||
Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc, TemplateTypeParmDecl *Param,
|
||||
ArrayRef<TemplateArgument> SugaredConverted,
|
||||
ArrayRef<TemplateArgument> CanonicalConverted) {
|
||||
TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo();
|
||||
|
||||
// If the argument type is dependent, instantiate it now based
|
||||
// on the previously-computed template arguments.
|
||||
if (ArgType->getType()->isInstantiationDependentType()) {
|
||||
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
|
||||
Param, Template, Converted,
|
||||
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template,
|
||||
SugaredConverted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return nullptr;
|
||||
|
||||
// Only substitute for the innermost template argument list.
|
||||
MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted,
|
||||
/*Final=*/false);
|
||||
MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted,
|
||||
/*Final=*/true);
|
||||
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
|
||||
TemplateArgLists.addOuterTemplateArguments(None);
|
||||
|
||||
@ -5320,22 +5318,20 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
|
||||
/// parameters that precede \p Param in the template parameter list.
|
||||
///
|
||||
/// \returns the substituted template argument, or NULL if an error occurred.
|
||||
static ExprResult
|
||||
SubstDefaultTemplateArgument(Sema &SemaRef,
|
||||
TemplateDecl *Template,
|
||||
SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc,
|
||||
NonTypeTemplateParmDecl *Param,
|
||||
SmallVectorImpl<TemplateArgument> &Converted) {
|
||||
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
|
||||
Param, Template, Converted,
|
||||
static ExprResult SubstDefaultTemplateArgument(
|
||||
Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc, NonTypeTemplateParmDecl *Param,
|
||||
ArrayRef<TemplateArgument> SugaredConverted,
|
||||
ArrayRef<TemplateArgument> CanonicalConverted) {
|
||||
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template,
|
||||
SugaredConverted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
// Only substitute for the innermost template argument list.
|
||||
MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted,
|
||||
/*Final=*/false);
|
||||
MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted,
|
||||
/*Final=*/true);
|
||||
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
|
||||
TemplateArgLists.addOuterTemplateArguments(None);
|
||||
|
||||
@ -5370,23 +5366,21 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
|
||||
/// source-location information) that precedes the template name.
|
||||
///
|
||||
/// \returns the substituted template argument, or NULL if an error occurred.
|
||||
static TemplateName
|
||||
SubstDefaultTemplateArgument(Sema &SemaRef,
|
||||
TemplateDecl *Template,
|
||||
SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc,
|
||||
TemplateTemplateParmDecl *Param,
|
||||
SmallVectorImpl<TemplateArgument> &Converted,
|
||||
NestedNameSpecifierLoc &QualifierLoc) {
|
||||
static TemplateName SubstDefaultTemplateArgument(
|
||||
Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc, TemplateTemplateParmDecl *Param,
|
||||
ArrayRef<TemplateArgument> SugaredConverted,
|
||||
ArrayRef<TemplateArgument> CanonicalConverted,
|
||||
NestedNameSpecifierLoc &QualifierLoc) {
|
||||
Sema::InstantiatingTemplate Inst(
|
||||
SemaRef, TemplateLoc, TemplateParameter(Param), Template, Converted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
SemaRef, TemplateLoc, TemplateParameter(Param), Template,
|
||||
SugaredConverted, SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return TemplateName();
|
||||
|
||||
// Only substitute for the innermost template argument list.
|
||||
MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted,
|
||||
/*Final=*/false);
|
||||
MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted,
|
||||
/*Final=*/true);
|
||||
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
|
||||
TemplateArgLists.addOuterTemplateArguments(None);
|
||||
|
||||
@ -5410,14 +5404,11 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
|
||||
/// If the given template parameter has a default template
|
||||
/// argument, substitute into that default template argument and
|
||||
/// return the corresponding template argument.
|
||||
TemplateArgumentLoc
|
||||
Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
|
||||
SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc,
|
||||
Decl *Param,
|
||||
SmallVectorImpl<TemplateArgument>
|
||||
&Converted,
|
||||
bool &HasDefaultArg) {
|
||||
TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
|
||||
TemplateDecl *Template, SourceLocation TemplateLoc,
|
||||
SourceLocation RAngleLoc, Decl *Param,
|
||||
ArrayRef<TemplateArgument> SugaredConverted,
|
||||
ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg) {
|
||||
HasDefaultArg = false;
|
||||
|
||||
if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) {
|
||||
@ -5425,11 +5416,9 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
|
||||
return TemplateArgumentLoc();
|
||||
|
||||
HasDefaultArg = true;
|
||||
TypeSourceInfo *DI = SubstDefaultTemplateArgument(*this, Template,
|
||||
TemplateLoc,
|
||||
RAngleLoc,
|
||||
TypeParm,
|
||||
Converted);
|
||||
TypeSourceInfo *DI = SubstDefaultTemplateArgument(
|
||||
*this, Template, TemplateLoc, RAngleLoc, TypeParm, SugaredConverted,
|
||||
CanonicalConverted);
|
||||
if (DI)
|
||||
return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
|
||||
|
||||
@ -5442,11 +5431,9 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
|
||||
return TemplateArgumentLoc();
|
||||
|
||||
HasDefaultArg = true;
|
||||
ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
|
||||
TemplateLoc,
|
||||
RAngleLoc,
|
||||
NonTypeParm,
|
||||
Converted);
|
||||
ExprResult Arg = SubstDefaultTemplateArgument(
|
||||
*this, Template, TemplateLoc, RAngleLoc, NonTypeParm, SugaredConverted,
|
||||
CanonicalConverted);
|
||||
if (Arg.isInvalid())
|
||||
return TemplateArgumentLoc();
|
||||
|
||||
@ -5461,12 +5448,9 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
|
||||
|
||||
HasDefaultArg = true;
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
TemplateName TName = SubstDefaultTemplateArgument(*this, Template,
|
||||
TemplateLoc,
|
||||
RAngleLoc,
|
||||
TempTempParm,
|
||||
Converted,
|
||||
QualifierLoc);
|
||||
TemplateName TName = SubstDefaultTemplateArgument(
|
||||
*this, Template, TemplateLoc, RAngleLoc, TempTempParm, SugaredConverted,
|
||||
CanonicalConverted, QualifierLoc);
|
||||
if (TName.isNull())
|
||||
return TemplateArgumentLoc();
|
||||
|
||||
@ -5562,13 +5546,13 @@ bool Sema::CheckTemplateArgument(
|
||||
!Template->getDeclContext()->isDependentContext()) {
|
||||
// Do substitution on the type of the non-type template parameter.
|
||||
InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP,
|
||||
CanonicalConverted,
|
||||
SugaredConverted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return true;
|
||||
|
||||
MultiLevelTemplateArgumentList MLTAL(Template, CanonicalConverted,
|
||||
/*Final=*/false);
|
||||
MultiLevelTemplateArgumentList MLTAL(Template, SugaredConverted,
|
||||
/*Final=*/true);
|
||||
// If the parameter is a pack expansion, expand this slice of the pack.
|
||||
if (auto *PET = NTTPType->getAs<PackExpansionType>()) {
|
||||
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this,
|
||||
@ -5733,7 +5717,7 @@ bool Sema::CheckTemplateArgument(
|
||||
Params =
|
||||
SubstTemplateParams(Params, CurContext,
|
||||
MultiLevelTemplateArgumentList(
|
||||
Template, CanonicalConverted, /*Final=*/false),
|
||||
Template, SugaredConverted, /*Final=*/true),
|
||||
/*EvaluateConstraints=*/false);
|
||||
if (!Params)
|
||||
return true;
|
||||
@ -6013,7 +5997,8 @@ bool Sema::CheckTemplateArgumentList(
|
||||
NewArgs);
|
||||
|
||||
TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(
|
||||
*this, Template, TemplateLoc, RAngleLoc, TTP, CanonicalConverted);
|
||||
*this, Template, TemplateLoc, RAngleLoc, TTP, SugaredConverted,
|
||||
CanonicalConverted);
|
||||
if (!ArgType)
|
||||
return true;
|
||||
|
||||
@ -6026,7 +6011,8 @@ bool Sema::CheckTemplateArgumentList(
|
||||
NewArgs);
|
||||
|
||||
ExprResult E = SubstDefaultTemplateArgument(
|
||||
*this, Template, TemplateLoc, RAngleLoc, NTTP, CanonicalConverted);
|
||||
*this, Template, TemplateLoc, RAngleLoc, NTTP, SugaredConverted,
|
||||
CanonicalConverted);
|
||||
if (E.isInvalid())
|
||||
return true;
|
||||
|
||||
@ -6042,8 +6028,8 @@ bool Sema::CheckTemplateArgumentList(
|
||||
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
TemplateName Name = SubstDefaultTemplateArgument(
|
||||
*this, Template, TemplateLoc, RAngleLoc, TempParm, CanonicalConverted,
|
||||
QualifierLoc);
|
||||
*this, Template, TemplateLoc, RAngleLoc, TempParm, SugaredConverted,
|
||||
CanonicalConverted, QualifierLoc);
|
||||
if (Name.isNull())
|
||||
return true;
|
||||
|
||||
@ -6057,7 +6043,7 @@ bool Sema::CheckTemplateArgumentList(
|
||||
// template here, we just create this object to put a note into the
|
||||
// context stack.
|
||||
InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param,
|
||||
CanonicalConverted,
|
||||
SugaredConverted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return true;
|
||||
|
@ -2687,12 +2687,12 @@ static bool ConvertDeducedTemplateArgument(
|
||||
// itself, in case that substitution fails.
|
||||
if (SugaredPackedArgsBuilder.empty()) {
|
||||
LocalInstantiationScope Scope(S);
|
||||
MultiLevelTemplateArgumentList Args(Template, CanonicalOutput,
|
||||
/*Final=*/false);
|
||||
MultiLevelTemplateArgumentList Args(Template, SugaredOutput,
|
||||
/*Final=*/true);
|
||||
|
||||
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
||||
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
|
||||
NTTP, CanonicalOutput,
|
||||
NTTP, SugaredOutput,
|
||||
Template->getSourceRange());
|
||||
if (Inst.isInvalid() ||
|
||||
S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
|
||||
@ -2700,7 +2700,7 @@ static bool ConvertDeducedTemplateArgument(
|
||||
return true;
|
||||
} else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
|
||||
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
|
||||
TTP, CanonicalOutput,
|
||||
TTP, SugaredOutput,
|
||||
Template->getSourceRange());
|
||||
if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
|
||||
return true;
|
||||
@ -2810,7 +2810,7 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
|
||||
|
||||
DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
|
||||
TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param,
|
||||
CanonicalBuilder, HasDefaultArg);
|
||||
SugaredBuilder, CanonicalBuilder, HasDefaultArg);
|
||||
}
|
||||
|
||||
// If there was no default argument, deduction is incomplete.
|
||||
@ -2960,10 +2960,9 @@ FinishTemplateArgumentDeduction(
|
||||
PartialTemplArgInfo->RAngleLoc);
|
||||
|
||||
if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(),
|
||||
MultiLevelTemplateArgumentList(
|
||||
Partial,
|
||||
CanonicalDeducedArgumentList->asArray(),
|
||||
/*Final=*/false),
|
||||
MultiLevelTemplateArgumentList(Partial,
|
||||
SugaredBuilder,
|
||||
/*Final=*/true),
|
||||
InstArgs)) {
|
||||
unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
|
||||
if (ParamIdx >= Partial->getTemplateParameters()->size())
|
||||
@ -3303,8 +3302,8 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
|
||||
ExtParameterInfoBuilder ExtParamInfos;
|
||||
|
||||
MultiLevelTemplateArgumentList MLTAL(FunctionTemplate,
|
||||
CanonicalExplicitArgumentList->asArray(),
|
||||
/*Final=*/false);
|
||||
SugaredExplicitArgumentList->asArray(),
|
||||
/*Final=*/true);
|
||||
|
||||
// Instantiate the types of each of the function parameters given the
|
||||
// explicitly-specified template arguments. If the function has a trailing
|
||||
|
@ -172,11 +172,9 @@ using test1 = D<E, int>;
|
||||
// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:1, col:23> col:7 test1 'D<subst_default_argument::E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>'
|
||||
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A<int>' sugar A
|
||||
// CHECK-NEXT: |-TemplateArgument type 'int':'int'
|
||||
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 E1
|
||||
// CHECK-NEXT: | |-ClassTemplate 0x{{[^ ]*}} 'E'
|
||||
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2
|
||||
// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D'
|
||||
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
|
||||
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2
|
||||
// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D'
|
||||
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
|
||||
// CHECK-NEXT: `-RecordType 0x{{[^ ]*}} 'subst_default_argument::A<int>'
|
||||
// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[^ ]*}} 'A'
|
||||
} // namespace subst_default_argument
|
||||
|
@ -924,9 +924,9 @@ namespace dr367 { // dr367: yes
|
||||
namespace dr368 { // dr368: yes
|
||||
template<typename T, T> struct S {}; // expected-note {{here}}
|
||||
template<typename T> int f(S<T, T()> *); // expected-error {{function type}}
|
||||
template<typename T> int g(S<T, (T())> *); // cxx98_17-note {{type 'dr368::X'}}
|
||||
template<typename T> int g(S<T, (T())> *); // cxx98_17-note {{type 'X'}}
|
||||
// cxx20_2b-note@-1 {{candidate function [with T = dr368::X]}}
|
||||
template<typename T> int g(S<T, true ? T() : T()> *); // cxx98_17-note {{type 'dr368::X'}}
|
||||
template<typename T> int g(S<T, true ? T() : T()> *); // cxx98_17-note {{type 'X'}}
|
||||
// cxx20_2b-note@-1 {{candidate function [with T = dr368::X]}}
|
||||
struct X {};
|
||||
int n = g<X>(0); // cxx98_17-error {{no matching}}
|
||||
|
@ -88,7 +88,7 @@ void noexcept_true() noexcept(true);
|
||||
Val<decltype(&noexcept_false), &noexcept_true> remove_noexcept;
|
||||
Val<decltype(&noexcept_true), &noexcept_false> add_noexcept;
|
||||
#if __cplusplus > 201402L
|
||||
// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'void (*)() noexcept'}}
|
||||
// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'decltype(&noexcept_true)' (aka 'void (*)() noexcept(true)')}}
|
||||
#endif
|
||||
|
||||
// (no other conversions are permitted)
|
||||
|
@ -1454,7 +1454,7 @@ void run() {
|
||||
D<X::X1>(VectorType<X::X2>());
|
||||
}
|
||||
// CHECK-ELIDE-NOTREE: error: no matching function for call to 'D'
|
||||
// CHECK-ELIDE-NOTREE: note: candidate function template not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument
|
||||
// CHECK-ELIDE-NOTREE: note: candidate function template not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(X)0>' for 1st argument
|
||||
}
|
||||
|
||||
namespace TypeAlias2 {
|
||||
|
@ -33,7 +33,7 @@ void test_Def2(Def2<int, int const*> *d2) {
|
||||
}
|
||||
|
||||
typedef int& int_ref_t;
|
||||
Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int &>' required here}}
|
||||
Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int_ref_t>' required here}}
|
||||
|
||||
|
||||
template<> struct Def1<const int> { }; // expected-error{{redefinition of 'Def1<const int>'}}
|
||||
|
@ -69,14 +69,14 @@ template <template <class T, T...> class S, class T, int N> struct C {
|
||||
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1
|
||||
// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T'
|
||||
// CHECK-NEXT: |-TemplateArgument expr
|
||||
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent>
|
||||
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent>
|
||||
// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
|
||||
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<type-parameter-0-1, N>' dependent __make_integer_seq
|
||||
// CHECK-NEXT: |-TemplateArgument template
|
||||
// CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-1'
|
||||
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent depth 0 index 1
|
||||
// CHECK-NEXT: `-TemplateArgument expr
|
||||
// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent>
|
||||
// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent>
|
||||
// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
|
||||
|
||||
using test4 = __make_integer_seq<A, T, 1>;
|
||||
@ -88,14 +88,14 @@ template <template <class T, T...> class S, class T, int N> struct C {
|
||||
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1
|
||||
// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T'
|
||||
// CHECK-NEXT: |-TemplateArgument expr
|
||||
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent>
|
||||
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent>
|
||||
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
|
||||
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, type-parameter-0-1, 1>' dependent __make_integer_seq
|
||||
// CHECK-NEXT: |-TemplateArgument template A
|
||||
// CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-1'
|
||||
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent depth 0 index 1
|
||||
// CHECK-NEXT: `-TemplateArgument expr
|
||||
// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent>
|
||||
// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent>
|
||||
// CHECK-NEXT: `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
|
||||
|
||||
using test5 = __make_integer_seq<A, int, N>;
|
||||
|
Loading…
Reference in New Issue
Block a user