107 changes: 91 additions & 16 deletions clang/lib/AST/TextNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,26 @@ void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
});
}

void TextNodeDumper::dumpTemplateArgument(const TemplateArgument &TA) {
llvm::SmallString<128> Str;
{
llvm::raw_svector_ostream SS(Str);
TA.print(PrintPolicy, SS, /*IncludeType=*/true);
}
OS << " '" << Str << "'";

if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA);
!CanonTA.structurallyEquals(TA)) {
llvm::SmallString<128> CanonStr;
{
llvm::raw_svector_ostream SS(CanonStr);
CanonTA.print(PrintPolicy, SS, /*IncludeType=*/true);
}
if (CanonStr != Str)
OS << ":'" << CanonStr << "'";
}
}

const char *TextNodeDumper::getCommandName(unsigned CommandID) {
if (Traits)
return Traits->getCommandInfo(CommandID)->Name;
Expand Down Expand Up @@ -1086,45 +1106,100 @@ void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {

void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
OS << " type";
dumpType(TA.getAsType());
dumpTemplateArgument(TA);
}

void TextNodeDumper::VisitDeclarationTemplateArgument(
const TemplateArgument &TA) {
OS << " decl";
dumpTemplateArgument(TA);
dumpDeclRef(TA.getAsDecl());
}

void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
OS << " nullptr";
dumpTemplateArgument(TA);
}

void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
OS << " integral " << TA.getAsIntegral();
OS << " integral";
dumpTemplateArgument(TA);
}

void TextNodeDumper::dumpTemplateName(TemplateName TN) {
switch (TN.getKind()) {
case TemplateName::Template:
AddChild([=] { Visit(TN.getAsTemplateDecl()); });
return;
case TemplateName::UsingTemplate: {
const UsingShadowDecl *USD = TN.getAsUsingShadowDecl();
AddChild([=] { Visit(USD); });
AddChild("target", [=] { Visit(USD->getTargetDecl()); });
return;
}
case TemplateName::QualifiedTemplate: {
OS << " qualified";
const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName();
if (QTN->hasTemplateKeyword())
OS << " keyword";
dumpNestedNameSpecifier(QTN->getQualifier());
dumpTemplateName(QTN->getUnderlyingTemplate());
return;
}
case TemplateName::DependentTemplate: {
OS << " dependent";
const DependentTemplateName *DTN = TN.getAsDependentTemplateName();
dumpNestedNameSpecifier(DTN->getQualifier());
return;
}
case TemplateName::SubstTemplateTemplateParm: {
const SubstTemplateTemplateParmStorage *STS =
TN.getAsSubstTemplateTemplateParm();
OS << " subst index " << STS->getIndex();
if (std::optional<unsigned int> PackIndex = STS->getPackIndex())
OS << " pack_index " << *PackIndex;
if (const TemplateTemplateParmDecl *P = STS->getParameter())
AddChild("parameter", [=] { Visit(P); });
dumpDeclRef(STS->getAssociatedDecl(), "associated");
AddChild("replacement", [=] { dumpTemplateName(STS->getReplacement()); });
return;
}
// FIXME: Implement these.
case TemplateName::OverloadedTemplate:
OS << " overloaded";
return;
case TemplateName::AssumedTemplate:
OS << " assumed";
return;
case TemplateName::SubstTemplateTemplateParmPack:
OS << " subst_pack";
return;
}
llvm_unreachable("Unexpected TemplateName Kind");
}

void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
if (TA.getAsTemplate().getKind() == TemplateName::UsingTemplate)
OS << " using";
OS << " template ";
TA.getAsTemplate().dump(OS);
OS << " template";
dumpTemplateArgument(TA);
dumpTemplateName(TA.getAsTemplate());
}

void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
const TemplateArgument &TA) {
if (TA.getAsTemplateOrTemplatePattern().getKind() ==
TemplateName::UsingTemplate)
OS << " using";
OS << " template expansion ";
TA.getAsTemplateOrTemplatePattern().dump(OS);
OS << " template expansion";
dumpTemplateArgument(TA);
dumpTemplateName(TA.getAsTemplateOrTemplatePattern());
}

void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
void TextNodeDumper::VisitExpressionTemplateArgument(
const TemplateArgument &TA) {
OS << " expr";
dumpTemplateArgument(TA);
}

void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
OS << " pack";
dumpTemplateArgument(TA);
}

static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
Expand Down Expand Up @@ -1913,15 +1988,15 @@ void TextNodeDumper::VisitAutoType(const AutoType *T) {

void TextNodeDumper::VisitDeducedTemplateSpecializationType(
const DeducedTemplateSpecializationType *T) {
if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
if (T->getTemplateName().getAsUsingShadowDecl())
OS << " using";
}

void TextNodeDumper::VisitTemplateSpecializationType(
const TemplateSpecializationType *T) {
if (T->isTypeAlias())
OS << " alias";
if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
if (T->getTemplateName().getAsUsingShadowDecl())
OS << " using";
OS << " ";
T->getTemplateName().dump(OS);
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4251,7 +4251,8 @@ TemplateSpecializationType::TemplateSpecializationType(
assert((T.getKind() == TemplateName::Template ||
T.getKind() == TemplateName::SubstTemplateTemplateParm ||
T.getKind() == TemplateName::SubstTemplateTemplateParmPack ||
T.getKind() == TemplateName::UsingTemplate) &&
T.getKind() == TemplateName::UsingTemplate ||
T.getKind() == TemplateName::QualifiedTemplate) &&
"Unexpected template name for TemplateSpecializationType");

auto *TemplateArgs = reinterpret_cast<TemplateArgument *>(this + 1);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1586,14 +1586,14 @@ void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
IncludeStrongLifetimeRAII Strong(Policy);

TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
// FIXME: Null TD never excercised in test suite.
// FIXME: Null TD never exercised in test suite.
if (FullyQualify && TD) {
if (!Policy.SuppressScope)
AppendScope(TD->getDeclContext(), OS, TD->getDeclName());

OS << TD->getName();
} else {
T->getTemplateName().print(OS, Policy);
T->getTemplateName().print(OS, Policy, TemplateName::Qualified::None);
}

DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
Expand Down
15 changes: 7 additions & 8 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,9 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
} else if (AllowDeducedTemplate) {
if (auto *TD = getAsTypeTemplateDecl(IIDecl)) {
assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD);
TemplateName Template =
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD);
TemplateName Template = Context.getQualifiedTemplateName(
SS ? SS->getScopeRep() : nullptr, /*TemplateKeyword=*/false,
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD));
T = Context.getDeducedTemplateSpecializationType(Template, QualType(),
false);
// Don't wrap in a further UsingType.
Expand Down Expand Up @@ -1137,12 +1138,10 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
dyn_cast<UsingShadowDecl>(*Result.begin());
assert(!FoundUsingShadow ||
TD == cast<TemplateDecl>(FoundUsingShadow->getTargetDecl()));
Template =
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD);
if (SS.isNotEmpty())
Template = Context.getQualifiedTemplateName(SS.getScopeRep(),
/*TemplateKeyword=*/false,
Template);
Template = Context.getQualifiedTemplateName(
SS.getScopeRep(),
/*TemplateKeyword=*/false,
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD));
} else {
// All results were non-template functions. This is a function template
// name.
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11547,12 +11547,12 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
bool TemplateMatches =
Context.hasSameTemplateName(SpecifiedName, GuidedTemplate);
auto TKind = SpecifiedName.getKind();
// A Using TemplateName can't actually be valid (either it's qualified, or
// we're in the wrong scope). But we have diagnosed these problems
// already.
bool SimplyWritten = TKind == TemplateName::Template ||
TKind == TemplateName::UsingTemplate;

const QualifiedTemplateName *Qualifiers =
SpecifiedName.getAsQualifiedTemplateName();
assert(Qualifiers && "expected QualifiedTemplate");
bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
Qualifiers->getQualifier() == nullptr;
if (SimplyWritten && TemplateMatches)
AcceptableReturnType = true;
else {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3284,10 +3284,10 @@ ExprResult Sema::BuildDeclarationNameExpr(
return CreateRecoveryExpr(NameInfo.getBeginLoc(), NameInfo.getEndLoc(), {});
}

if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
// Specifically diagnose references to class templates that are missing
// a template argument list.
diagnoseMissingTemplateArguments(TemplateName(Template), Loc);
diagnoseMissingTemplateArguments(SS, /*TemplateKeyword=*/false, TD, Loc);
return ExprError();
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaExprMember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,

if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
if (!TemplateArgs) {
diagnoseMissingTemplateArguments(TemplateName(VarTempl), MemberLoc);
diagnoseMissingTemplateArguments(
SS, /*TemplateKeyword=*/TemplateKWLoc.isValid(), VarTempl, MemberLoc);
return ExprError();
}

Expand Down
25 changes: 17 additions & 8 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
Template =
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD);
assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD);
if (SS.isSet() && !SS.isInvalid()) {
if (!SS.isInvalid()) {
NestedNameSpecifier *Qualifier = SS.getScopeRep();
Template = Context.getQualifiedTemplateName(Qualifier, hasTemplateKeyword,
Template);
Expand Down Expand Up @@ -342,8 +342,11 @@ bool Sema::isDeductionGuideName(Scope *S, const IdentifierInfo &Name,
if (!TD || !getAsTypeTemplateDecl(TD))
return false;

if (Template)
*Template = TemplateTy::make(TemplateName(TD));
if (Template) {
TemplateName Name = Context.getQualifiedTemplateName(
SS.getScopeRep(), /*TemplateKeyword=*/false, TemplateName(TD));
*Template = TemplateTy::make(Name);
}
return true;
}

Expand Down Expand Up @@ -983,10 +986,6 @@ ParsedTemplateArgument Sema::ActOnTemplateTypeArgument(TypeResult ParsedType) {

if (auto DTST = TL.getAs<DeducedTemplateSpecializationTypeLoc>()) {
TemplateName Name = DTST.getTypePtr()->getTemplateName();
if (SS.isSet())
Name = Context.getQualifiedTemplateName(SS.getScopeRep(),
/*HasTemplateKeyword=*/false,
Name);
ParsedTemplateArgument Result(SS, TemplateTy::make(Name),
DTST.getTemplateNameLoc());
if (EllipsisLoc.isValid())
Expand Down Expand Up @@ -5621,6 +5620,15 @@ void Sema::diagnoseMissingTemplateArguments(TemplateName Name,
}
}

void Sema::diagnoseMissingTemplateArguments(const CXXScopeSpec &SS,
bool TemplateKeyword,
TemplateDecl *TD,
SourceLocation Loc) {
TemplateName Name = Context.getQualifiedTemplateName(
SS.getScopeRep(), TemplateKeyword, TemplateName(TD));
diagnoseMissingTemplateArguments(Name, Loc);
}

ExprResult
Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
Expand Down Expand Up @@ -5691,7 +5699,8 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
// Non-function templates require a template argument list.
if (auto *TD = R.getAsSingle<TemplateDecl>()) {
if (!TemplateArgs && !isa<FunctionTemplateDecl>(TD)) {
diagnoseMissingTemplateArguments(TemplateName(TD), R.getNameLoc());
diagnoseMissingTemplateArguments(
SS, /*TemplateKeyword=*/TemplateKWLoc.isValid(), TD, R.getNameLoc());
return ExprError();
}
}
Expand Down
62 changes: 47 additions & 15 deletions clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,6 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
// arguments as defaults.
if (auto *TempArg = dyn_cast_or_null<TemplateTemplateParmDecl>(
Arg.getAsTemplateDecl())) {
assert(Arg.getKind() == TemplateName::Template);
assert(!TempArg->isExpandedParameterPack());

TemplateParameterList *As = TempArg->getTemplateParameters();
Expand Down Expand Up @@ -658,6 +657,18 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
/// \returns the result of template argument deduction so far. Note that a
/// "success" result means that template argument deduction has not yet failed,
/// but it may still fail, later, for other reasons.

static const TemplateSpecializationType *getLastTemplateSpecType(QualType QT) {
for (const Type *T = QT.getTypePtr(); /**/; /**/) {
const TemplateSpecializationType *TST =
T->getAs<TemplateSpecializationType>();
assert(TST && "Expected a TemplateSpecializationType");
if (!TST->isSugared())
return TST;
T = TST->desugar().getTypePtr();
}
}

static TemplateDeductionResult
DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
const QualType P, QualType A,
Expand All @@ -666,26 +677,35 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
QualType UP = P;
if (const auto *IP = P->getAs<InjectedClassNameType>())
UP = IP->getInjectedSpecializationType();
// FIXME: Try to preserve type sugar here, which is hard
// because of the unresolved template arguments.
const auto *TP = UP.getCanonicalType()->castAs<TemplateSpecializationType>();

assert(isa<TemplateSpecializationType>(UP.getCanonicalType()));
const TemplateSpecializationType *TP = ::getLastTemplateSpecType(UP);
TemplateName TNP = TP->getTemplateName();

// If the parameter is an alias template, there is nothing to deduce.
if (const auto *TD = TNP.getAsTemplateDecl(); TD && TD->isTypeAlias())
return TemplateDeductionResult::Success;

ArrayRef<TemplateArgument> PResolved = TP->template_arguments();
// FIXME: To preserve sugar, the TST needs to carry sugared resolved
// arguments.
ArrayRef<TemplateArgument> PResolved =
TP->getCanonicalTypeInternal()
->castAs<TemplateSpecializationType>()
->template_arguments();

QualType UA = A;
std::optional<NestedNameSpecifier *> NNS;
// Treat an injected-class-name as its underlying template-id.
if (const auto *Injected = A->getAs<InjectedClassNameType>())
if (const auto *Elaborated = A->getAs<ElaboratedType>()) {
NNS = Elaborated->getQualifier();
} else if (const auto *Injected = A->getAs<InjectedClassNameType>()) {
UA = Injected->getInjectedSpecializationType();
NNS = nullptr;
}

// Check whether the template argument is a dependent template-id.
// FIXME: Should not lose sugar here.
if (const auto *SA =
dyn_cast<TemplateSpecializationType>(UA.getCanonicalType())) {
if (isa<TemplateSpecializationType>(UA.getCanonicalType())) {
const TemplateSpecializationType *SA = ::getLastTemplateSpecType(UA);
TemplateName TNA = SA->getTemplateName();

// If the argument is an alias template, there is nothing to deduce.
Expand All @@ -698,11 +718,19 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
SA->template_arguments(), Deduced);
Result != TemplateDeductionResult::Success)
return Result;

// FIXME: To preserve sugar, the TST needs to carry sugared resolved
// arguments.
ArrayRef<TemplateArgument> AResolved =
SA->getCanonicalTypeInternal()
->castAs<TemplateSpecializationType>()
->template_arguments();

// Perform template argument deduction on each template
// argument. Ignore any missing/extra arguments, since they could be
// filled in by default arguments.
return DeduceTemplateArguments(S, TemplateParams, PResolved,
SA->template_arguments(), Info, Deduced,
return DeduceTemplateArguments(S, TemplateParams, PResolved, AResolved,
Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false);
}

Expand All @@ -718,11 +746,15 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
return TemplateDeductionResult::NonDeducedMismatch;
}

TemplateName TNA = TemplateName(SA->getSpecializedTemplate());
if (NNS)
TNA = S.Context.getQualifiedTemplateName(
*NNS, false, TemplateName(SA->getSpecializedTemplate()));

// Perform template argument deduction for the template name.
if (auto Result = DeduceTemplateArguments(
S, TemplateParams, TP->getTemplateName(),
TemplateName(SA->getSpecializedTemplate()), Info,
SA->getTemplateArgs().asArray(), Deduced);
if (auto Result =
DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info,
SA->getTemplateArgs().asArray(), Deduced);
Result != TemplateDeductionResult::Success)
return Result;

Expand Down
14 changes: 9 additions & 5 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6005,12 +6005,16 @@ namespace {
DeclarationNameInfo DNI = DeclarationNameInfo(
TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
TemplateId->TemplateNameLoc);
auto TN = TemplateId->Template.get();

NamedDecl *FoundDecl;
if (auto TN = TemplateId->Template.get();
UsingShadowDecl *USD = TN.getAsUsingShadowDecl())
FoundDecl = cast<NamedDecl>(USD);
else
FoundDecl = cast_if_present<NamedDecl>(TN.getAsTemplateDecl());

auto *CR = ConceptReference::Create(
Context, NNS, TemplateId->TemplateKWLoc, DNI,
/*FoundDecl=*/TN.getKind() == TemplateName::NameKind::UsingTemplate
? cast<NamedDecl>(TN.getAsUsingShadowDecl())
: cast_if_present<NamedDecl>(TN.getAsTemplateDecl()),
Context, NNS, TemplateId->TemplateKWLoc, DNI, FoundDecl,
/*NamedDecl=*/TL.getTypePtr()->getTypeConstraintConcept(),
ASTTemplateArgumentListInfo::Create(Context, TemplateArgsInfo));
TL.setConceptReference(CR);
Expand Down
8 changes: 3 additions & 5 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -4604,18 +4604,16 @@ TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
ObjectType, AllowInjectedClassName);
}

// FIXME: Try to preserve more of the TemplateName.
if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
TemplateDecl *TransTemplate
= cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
Template));
if (!TransTemplate)
return TemplateName();

if (!getDerived().AlwaysRebuild() &&
TransTemplate == Template)
return Name;

return TemplateName(TransTemplate);
return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
TransTemplate);
}

if (SubstTemplateTemplateParmPackStorage *SubstPack
Expand Down
6 changes: 3 additions & 3 deletions clang/test/AST/ast-dump-ctad-alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ Out2<double>::AInner t(1.0);
// CHECK: | `-FunctionTemplateDecl {{.*}} <deduction guide for AInner>
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 Y
// CHECK-NEXT: | |-BinaryOperator {{.*}} '<dependent type>' '&&'
// CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} '<dependent type>' lvalue (no ADL) = 'Concept'
// CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} '<dependent type>' lvalue (no ADL) = 'Concept'
// CHECK-NEXT: | | | |-TemplateArgument type 'int'
// CHECK-NEXT: | | | | `-BuiltinType {{.*}} 'int'
// CHECK-NEXT: | | | `-TemplateArgument type 'type-parameter-1-0'
// CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent depth 1 index 0
// CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible
// CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'AInner' dependent
// CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'Out2<double>::AInner' dependent
// CHECK-NEXT: | | `-ElaboratedType {{.*}} 'Inner<type-parameter-1-0>' sugar dependent
// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner<type-parameter-1-0>' dependent Inner
// CHECK-NEXT: | | `-TemplateArgument type 'type-parameter-1-0'
// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'type-parameter-1-0'
// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'type-parameter-1-0'
// CHECK-NEXT: | | |-FunctionTemplate {{.*}} '<deduction guide for Inner>'
// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent depth 1 index 0
// CHECK-NEXT: | |-CXXDeductionGuideDecl {{.*}} <deduction guide for AInner> 'auto (type-parameter-0-0) -> Inner<type-parameter-0-0>'
Expand Down
25 changes: 14 additions & 11 deletions clang/test/AST/ast-dump-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,21 +459,23 @@ namespace testClassTemplateDecl {

// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-148]]:3, col:31> col:31 TestTemplateDefaultNonType{{$}}
// CHECK-NEXT: |-NonTypeTemplateParmDecl 0x{{.+}} <col:12, col:20> col:16 'int' depth 0 index 0 I{{$}}
// CHECK-NEXT: | `-TemplateArgument <col:20> expr{{$}}
// CHECK-NEXT: | `-TemplateArgument <col:20> expr '42'{{$}}
// CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} <col:20> 'int' 42{{$}}
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:24, col:31> col:31 struct TestTemplateDefaultNonType{{$}}

// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:{{.*}}:3, col:68> col:68 TestTemplateTemplateDefaultType{{$}}
// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:42> col:37 depth 0 index 0 TT{{$}}
// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:29 typename depth 1 index 0{{$}}
// CHECK-NEXT: | `-TemplateArgument <col:42> template TestClassTemplate{{$}}
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:61, col:68> col:68 struct TestTemplateTemplateDefaultType{{$}}
// CHECK-NEXT: | `-TemplateArgument <col:42> template 'TestClassTemplate':'testClassTemplateDecl::TestClassTemplate' qualified{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:3, line:{{.+}}:3> line:{{.+}}:30 TestClassTemplate{{$}}
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <line:{{.*}}:61, col:68> col:68 struct TestTemplateTemplateDefaultType{{$}}

// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:{{.*}}:3, col:82> col:48 TestTemplateTemplateDefaultType{{$}}
// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:37> col:37 depth 0 index 0 TT{{$}}
// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:29 typename depth 1 index 0{{$}}
// CHECK-NEXT: | `-TemplateArgument <line:{{.*}}:42> template TestClassTemplate{{$}}
// CHECK-NEXT: | `-inherited from TemplateTemplateParm 0x{{.+}} 'TT'{{$}}
// CHECK-NEXT: | `-TemplateArgument <line:{{.*}}:42> template 'TestClassTemplate':'testClassTemplateDecl::TestClassTemplate' qualified{{$}}
// CHECK-NEXT: | |-inherited from TemplateTemplateParm 0x{{.+}} 'TT'{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:3, line:{{.+}}:3> line:{{.+}}:30 TestClassTemplate
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <line:{{.*}}:41, col:82> col:48 struct TestTemplateTemplateDefaultType definition{{$}}
// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr{{$}}
Expand Down Expand Up @@ -683,7 +685,8 @@ namespace TestTemplateTemplateParmDecl {
// CHECK: FunctionTemplateDecl
// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} T
// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename
// CHECK-NEXT: TemplateArgument{{.*}} template A
// CHECK-NEXT: TemplateArgument{{.*}} template 'A':'TestTemplateTemplateParmDecl::A' qualified{{$}}
// CHECK-NEXT: ClassTemplateDecl {{.*}} A
// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} ... U
// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename

Expand All @@ -710,12 +713,12 @@ namespace TestTemplateArgument {
template<int> class testIntegral { };
template class testIntegral<1>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral
// CHECK: TemplateArgument{{.*}} integral 1
// CHECK: TemplateArgument{{.*}} integral '1'

template<template<typename> class> class testTemplate { };
template class testTemplate<A>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate
// CHECK: TemplateArgument{{.*}} A
// CHECK: TemplateArgument{{.*}} 'TestTemplateArgument::A'{{$}}

template<template<typename> class ...T> class C {
B<T...> testTemplateExpansion;
Expand All @@ -731,10 +734,10 @@ namespace TestTemplateArgument {
template<int, int ...> class testPack { };
template class testPack<0, 1, 2>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack
// CHECK: TemplateArgument{{.*}} integral 0
// CHECK: TemplateArgument{{.*}} integral '0'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
}

namespace testUsingDecl {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/AST/ast-dump-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void PostfixExpressions(S a, S *p, U<int> *r) {
r->template U<int>::~U();
// CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:26> 'void'
// CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:24> '<bound member function type>' ->~U 0x{{[^ ]*}}
// CHECK-NEXT: NestedNameSpecifier TypeSpecWithTemplate 'U<int>'
// CHECK-NEXT: NestedNameSpecifier TypeSpecWithTemplate 'template U<int>':'U<int>'
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'U<int> *' lvalue ParmVar 0x{{[^ ]*}} 'r' 'U<int> *'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ int test() {
// CHECK-NEXT: | | `-ReturnStmt [[ADDR_22:0x[a-z0-9]*]] <line:10:3, col:10>
// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_23:0x[a-z0-9]*]] <col:10> 'int' 0
// CHECK-NEXT: | `-FunctionDecl [[ADDR_24:0x[a-z0-9]*]] <line:9:1, line:11:1> line:9:5 used also_before_mismatch 'int ({{.*}})'
// CHECK-NEXT: | |-TemplateArgument integral 0
// CHECK-NEXT: | |-TemplateArgument integral '0'
// CHECK-NEXT: | `-CompoundStmt [[ADDR_25:0x[a-z0-9]*]] <col:32, line:11:1>
// CHECK-NEXT: | `-ReturnStmt [[ADDR_26:0x[a-z0-9]*]] <line:10:3, col:10>
// CHECK-NEXT: | `-IntegerLiteral [[ADDR_23]] <col:10> 'int' 0
Expand Down Expand Up @@ -179,7 +179,7 @@ int test() {
// CHECK-NEXT: | | `-OMPDeclareVariantAttr [[ADDR_101:0x[a-z0-9]*]] <<invalid sloc>> Implicit implementation={extension(allow_templates)}
// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_102:0x[a-z0-9]*]] <col:1> 'int ({{.*}})' {{.*}}Function [[ADDR_103:0x[a-z0-9]*]] 'only_def[implementation={extension(allow_templates)}]' 'int ({{.*}})'
// CHECK-NEXT: | `-FunctionDecl [[ADDR_104:0x[a-z0-9]*]] <col:1, col:18> col:5 used only_def 'int ({{.*}})'
// CHECK-NEXT: | |-TemplateArgument integral 0
// CHECK-NEXT: | |-TemplateArgument integral '0'
// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_105:0x[a-z0-9]*]] <<invalid sloc>> Implicit implementation={extension(allow_templates)}
// CHECK-NEXT: | `-DeclRefExpr [[ADDR_106:0x[a-z0-9]*]] <col:1> 'int ({{.*}})' {{.*}}Function [[ADDR_107:0x[a-z0-9]*]] 'only_def[implementation={extension(allow_templates)}]' 'int ({{.*}})'
// CHECK-NEXT: |-FunctionTemplateDecl [[ADDR_108:0x[a-z0-9]*]] <line:37:1, line:40:1> line:38:1 only_def[implementation={extension(allow_templates)}]
Expand All @@ -189,7 +189,7 @@ int test() {
// CHECK-NEXT: | | `-ReturnStmt [[ADDR_110:0x[a-z0-9]*]] <line:39:3, col:10>
// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_111:0x[a-z0-9]*]] <col:10> 'int' 0
// CHECK-NEXT: | `-FunctionDecl [[ADDR_107]] <line:38:1, line:40:1> line:38:1 only_def[implementation={extension(allow_templates)}] 'int ({{.*}})'
// CHECK-NEXT: | |-TemplateArgument integral 0
// CHECK-NEXT: | |-TemplateArgument integral '0'
// CHECK-NEXT: | `-CompoundStmt [[ADDR_112:0x[a-z0-9]*]] <col:20, line:40:1>
// CHECK-NEXT: | `-ReturnStmt [[ADDR_113:0x[a-z0-9]*]] <line:39:3, col:10>
// CHECK-NEXT: | `-IntegerLiteral [[ADDR_111]] <col:10> 'int' 0
Expand Down
6 changes: 3 additions & 3 deletions clang/test/AST/ast-dump-template-decls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ template <class T> struct C {
using type2 = typename C<int>::type1<void>;
// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:42> col:7 type2 'typename C<int>::type1<void>':'void (int)'
// CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C<int>::type1<void>' sugar
// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1<void>' sugar alias type1
// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1<void>' sugar alias C<int>::type1
// CHECK-NEXT: TemplateArgument type 'void'
// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
// CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
Expand Down Expand Up @@ -149,7 +149,7 @@ template <typename... T> struct D {
template <typename... U> using B = int(int (*...p)(T, U));
};
using t2 = D<float, char>::B<int, short>;
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias B
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias D<float, char>::B{{$}}
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 1
Expand All @@ -169,7 +169,7 @@ template<template<class C1, class C2 = A<C1>> class D1, class D2> using D = D1<D

template<class E1, class E2> class E {};
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: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:1, col:23> col:7 test1 'D<E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>'
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A<int>' sugar A
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2
Expand Down
54 changes: 54 additions & 0 deletions clang/test/AST/ast-dump-template-name.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// RUN: %clang_cc1 -std=c++26 -ast-dump -ast-dump-filter=Test %s | FileCheck %s

template <template <class> class TT> using N = TT<int>;

namespace qualified {
namespace foo {
template <class T> struct A;
} // namespace foo
using TestQualified = N<foo::A>;
} // namespace qualified

// CHECK: Dumping qualified::TestQualified:
// CHECK-NEXT: TypeAliasDecl
// CHECK-NEXT: `-ElaboratedType
// CHECK-NEXT: `-TemplateSpecializationType
// CHECK-NEXT: |-TemplateArgument template 'foo::A':'qualified::foo::A' qualified{{$}}
// CHECK-NEXT: | |-NestedNameSpecifier Namespace 0x{{.+}} 'foo'{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}

namespace dependent {
template <class T> struct B {
using TestDependent = N<T::template X>;
};
} // namespace dependent

// CHECK: Dumping dependent::B::TestDependent:
// CHECK-NEXT: TypeAliasDecl
// CHECK-NEXT: `-ElaboratedType
// CHECK-NEXT: `-TemplateSpecializationType
// CHECK-NEXT: |-TemplateArgument template 'T::template X':'type-parameter-0-0::template X' dependent{{$}}
// CHECK-NEXT: | `-NestedNameSpecifier TypeSpec 'T'{{$}}

namespace subst {
template <class> struct A;

template <template <class> class TT> struct B {
template <template <class> class> struct C {};
using type = C<TT>;
};
using TestSubst = B<A>::type;
} // namespace subst

// CHECK: Dumping subst::TestSubst:
// CHECK-NEXT: TypeAliasDecl
// CHECK-NEXT: `-ElaboratedType
// CHECK-NEXT: `-TypedefType
// CHECK-NEXT: |-TypeAlias
// CHECK-NEXT: `-ElaboratedType
// CHECK-NEXT: `-TemplateSpecializationType
// CHECK-NEXT: |-TemplateArgument template 'subst::A' subst index 0
// CHECK-NEXT: | |-parameter: TemplateTemplateParmDecl {{.+}} depth 0 index 0 TT{{$}}
// CHECK-NEXT: | |-associated ClassTemplateSpecialization {{.+}} 'B'{{$}}
// CHECK-NEXT: | `-replacement:
// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
12 changes: 7 additions & 5 deletions clang/test/AST/ast-dump-using-template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ using A = S<T>;
template <template <typename> class T> class X {};
using B = X<S>;
// CHECK: TypeAliasDecl
// CHECK-NEXT: `-ElaboratedType {{.*}} 'X<ns::S>' sugar
// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'X<ns::S>' sugar X
// CHECK-NEXT: |-TemplateArgument using template S
// CHECK-NEXT: `-RecordType {{.*}} 'X<ns::S>'
// CHECK-NEXT: `-ClassTemplateSpecialization {{.*}} 'X'
// CHECK-NEXT: `-ElaboratedType {{.*}} 'X<S>' sugar
// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'X<S>' sugar X
// CHECK-NEXT: |-TemplateArgument template 'S'
// CHECK-NEXT: | |-UsingShadowDecl {{.*}} implicit ClassTemplate {{.*}} 'S'
// CHECK-NEXT: | `-target: ClassTemplateDecl {{.*}} S
// CHECK-NEXT: `-RecordType {{.*}} 'X<ns::S>'
// CHECK-NEXT: `-ClassTemplateSpecialization {{.*}} 'X'

// TemplateName in DeducedTemplateSpecializationType.
S DeducedTemplateSpecializationT(123);
Expand Down
6 changes: 3 additions & 3 deletions clang/test/AST/constraints-explicit-instantiation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ struct A {

// This checks that `canary1<1>` and `canaray2<2>` are instantiated, thus
// indirectly validating that the correct candidates of `A::f` were really
// instantiated each time.
// instantiated each time.
// The `static_assert`s validate we don't instantiate wrong candidates.

// CHECK:{{.*}}FunctionTemplateDecl {{.*}} canary1
// CHECK: {{.*}}TemplateArgument integral
// CHECK-SAME: {{1$}}
// CHECK-SAME: {{'1'$}}
template struct A<1>;

// CHECK: {{.*}}FunctionTemplateDecl {{.*}} canary2
// CHECK: {{.*}}TemplateArgument integral
// CHECK-SAME: {{2$}}
// CHECK-SAME: {{'2'$}}
template struct A<2>;

template struct A<3>;
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CXX/drs/cwg1xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ namespace cwg136 { // cwg136: 3.4
void q() {
j(A(), A()); // ok, has default argument
}
extern "C" void k(int, int, int, int); // #cwg136-k
extern "C" void k(int, int, int, int); // #cwg136-k
namespace NSA {
struct A {
friend void cwg136::k(int, int, int, int = 0);
Expand Down Expand Up @@ -1048,7 +1048,7 @@ namespace cwg176 { // cwg176: 3.1
cwg176::X *p4; // #cwg176-p4
// cxx98-14-error@#cwg176-p4 {{use of class template 'cwg176::X' requires template arguments}}
// cxx98-14-note@#cwg176-X {{template is declared here}}
// since-cxx17-error@#cwg176-p4 {{use of class template 'X' requires template arguments; argument deduction not allowed in non-static class member}}
// since-cxx17-error@#cwg176-p4 {{use of class template 'cwg176::X' requires template arguments; argument deduction not allowed in non-static class member}}
// since-cxx17-note@#cwg176-X {{template is declared here}}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ int a1 = 0 == A<1>(); // Should not find 2 as the requires clause does not match

namespace static_operators {
// Verify no crash.
struct X {
struct X {
bool operator ==(X const&); // expected-note {{ambiguity is between a regular call}}
// expected-note@-1 {{mark 'operator==' as const or add a matching 'operator!=' to resolve the ambiguity}}
static bool operator !=(X const&, X const&); // expected-error {{overloaded 'operator!=' cannot be a static member function}}
Expand Down Expand Up @@ -474,7 +474,7 @@ namespace ns {
template <class T> struct A {};
template <class T> struct B : A<T> {};

template <class T> bool operator==(B<T>, A<T>); // expected-note {{candidate template ignored: could not match 'B' against 'A'}}
template <class T> bool operator==(B<T>, A<T>); // expected-note {{candidate template ignored: could not match 'B' against 'ns::A'}}
template <class T> bool operator!=(B<T>, A<T>);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
template<typename ...Types> struct tuple;
template<unsigned> struct unsigned_c;

template<typename T, typename U>
template<typename T, typename U>
struct is_same {
static const bool value = false;
};
Expand Down Expand Up @@ -93,7 +93,7 @@ namespace DeduceNonTypeTemplateArgsInArray {
}

namespace DeduceWithDefaultArgs {
template<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = DeduceWithDefaultArgs::X]}}
template<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = X]}}
template<typename, typename = int> struct X {};
void g() {
// OK, use default argument for the second template parameter.
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Index/print-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ inline namespace InlineNS {}
// CHECK: TypedefDecl=OtherType:26:18 (Definition) [type=outer::inner::Bar::OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
// CHECK: TypedefDecl=ArrayType:27:15 (Definition) [type=outer::inner::Bar::ArrayType] [typekind=Typedef] [canonicaltype=int[5]] [canonicaltypekind=ConstantArray] [isPOD=1]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, outer::Foo>] [typekind=Elaborated] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, outer::Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, Foo>] [typekind=Elaborated] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, outer::Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
// CHECK: TemplateRef=Baz:9:8 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
Expand Down
2 changes: 1 addition & 1 deletion clang/test/OpenMP/align_clause_ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ int template_test() {
// DUMP: FunctionDecl {{.*}}run 'double ()'
// DUMP: TemplateArgument type 'double'
// DUMP: BuiltinType {{.*}}'double'
// DUMP: TemplateArgument integral 1
// DUMP: TemplateArgument integral '1U'
// DUMP: OMPAllocateDeclAttr {{.*}}Implicit OMPNullMemAlloc
// DUMP: ConstantExpr {{.*}}'unsigned int'
// DUMP: value: Int 1
Expand Down
2 changes: 1 addition & 1 deletion clang/test/OpenMP/declare_mapper_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class stack { // expec
};

#pragma omp declare mapper(default : N1::stack s) map(s.len) // precxx17-error {{use of class template 'N1::stack' requires template arguments}} \
cxx17-error {{use of class template 'stack' requires template arguments; argument deduction not allowed in function prototype}}
cxx17-error {{use of class template 'N1::stack' requires template arguments; argument deduction not allowed in function prototype}}
#pragma omp declare mapper(id1: N1::stack<int> s) map(s.data)
#pragma omp declare mapper(default : S<int> s) map(s.len) // expected-error {{no template named 'S'}}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/OpenMP/generic_loop_ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
//PRINT: }
//DUMP: FunctionDecl{{.*}}templ_foo 'void (int)'
//DUMP: TemplateArgument type 'int'
//DUMP: TemplateArgument integral 2
//DUMP: TemplateArgument integral '2'
//DUMP: ParmVarDecl{{.*}}'int'
//DUMP: OMPSimdDirective
//DUMP: OMPCollapseClause
Expand Down
2 changes: 1 addition & 1 deletion clang/test/OpenMP/interop_ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ void fooTemp() {

//PRINT: #pragma omp interop init(prefer_type(3,4,"level_one"), target : interop_var)
//DUMP: FunctionDecl{{.*}}fooTemp
//DUMP: TemplateArgument integral 3
//DUMP: TemplateArgument integral '3'
//DUMP: OMPInteropDirective
//DUMP: OMPInitClause
//DUMP: DeclRefExpr{{.*}}'omp_interop_t'{{.*}}'interop_var'
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Parser/cxx-template-template-recovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ static_assert(test<a::b::C2>); // expected-error {{too few template arguments fo
static_assert(test<C3>); // expected-error {{too few template arguments for concept 'C3'}} \
// expected-note@#C3 {{here}}

static_assert(test<a::V1>); // expected-error {{use of variable template 'V1' requires template arguments}} \
static_assert(test<a::V1>); // expected-error {{use of variable template 'a::V1' requires template arguments}} \
// expected-note@#V1 {{here}}
static_assert(test<a::b::V2>); // expected-error {{use of variable template 'V2' requires template arguments}} \
static_assert(test<a::b::V2>); // expected-error {{use of variable template 'a::b::V2' requires template arguments}} \
// expected-note@#V2 {{here}}
static_assert(test<V3>); // expected-error {{use of variable template 'V3' requires template arguments}} \
// expected-note@#V3 {{here}}
Expand Down
10 changes: 5 additions & 5 deletions clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ namespace ns2 {
};
template<class T> template<class U, T N, U M> T&& A<T>::Var = T(N + M);
int *AV = &A<int>().Var<char, 5, 'A'>;

} //end ns2
} // end ns member_access_is_ok

Expand All @@ -372,7 +372,7 @@ struct Something
}
};

int main() {
int main() {
Something<Value>{}.foo();
return 0;
}
Expand All @@ -384,16 +384,16 @@ namespace dependent_static_var_template {
struct A {
template<int = 0> static int n; // expected-note 2{{here}}
};
int &r = A::template n; // expected-error {{use of variable template 'n' requires template arguments}}
int &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}}

template<typename T>
int &f() { return T::template n; } // expected-error {{use of variable template 'n' requires template arguments}}
int &f() { return T::template n; } // expected-error {{use of variable template 'A::template n' requires template arguments}}
int &s = f<A>(); // expected-note {{instantiation of}}

namespace B {
template<int = 0> static int n; // expected-note {{here}}
}
int &t = B::template n; // expected-error {{use of variable template 'n' requires template arguments}}
int &t = B::template n; // expected-error {{use of variable template 'B::template n' requires template arguments}}

struct C {
template <class T> static T G;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaOpenACC/sub-array-ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ void Templ(int i){
// CHECK-NEXT: FunctionDecl{{.*}} Templ 'void (int)' implicit_instantiation
// CHECK-NEXT: TemplateArgument{{.*}} 'int'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: TemplateArgument integral 3
// CHECK-NEXT: TemplateArgument integral '3U'
// CHECK-NEXT: TemplateArgument decl
// CHECK-NEXT: Var{{.*}} 'CEArray' 'const int[5]'
// CHECK-NEXT: ParmVarDecl{{.*}} i 'int'
Expand Down
18 changes: 9 additions & 9 deletions clang/test/SemaTemplate/aggregate-deduction-candidate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace Basic {
D d2 = {1, 2, 3}; // cxx17-error {{no viable}}

D d3(1, 2); // expected-error {{no viable}}
// CTAD succeed but brace elision is not allowed for parenthesized aggregate init.
// CTAD succeed but brace elision is not allowed for parenthesized aggregate init.
D d4(1, 2, 3); // expected-error {{no viable}}

// CHECK-LABEL: Dumping Basic::<deduction guide for C>:
Expand Down Expand Up @@ -160,7 +160,7 @@ namespace Basic {
}

namespace Array {
typedef __SIZE_TYPE__ size_t;
typedef unsigned long size_t;
template <typename T, size_t N> struct A { // cxx20-note 2 {{candidate}} cxx17-note 14 {{candidate}}
T array[N];
};
Expand All @@ -183,7 +183,7 @@ namespace Array {
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (int (&&)[3]) -> Array::A<int, 3>'
// CHECK: |-TemplateArgument type 'int'
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: |-TemplateArgument integral 3
// CHECK: |-TemplateArgument integral '3UL'
// CHECK: `-ParmVarDecl {{.*}} 'int (&&)[3]'
// CHECK: FunctionProtoType {{.*}} 'auto (T (&&)[N]) -> A<T, N>' dependent trailing_return cdecl
// CHECK: |-InjectedClassNameType {{.*}} 'A<T, N>' dependent
Expand All @@ -203,7 +203,7 @@ namespace Array {
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (const char (&)[5]) -> Array::A<char, 5>'
// CHECK: |-TemplateArgument type 'char'
// CHECK: | `-BuiltinType {{.*}} 'char'
// CHECK: |-TemplateArgument integral 5
// CHECK: |-TemplateArgument integral '5UL'
// CHECK: `-ParmVarDecl {{.*}} 'const char (&)[5]'
// CHECK: FunctionProtoType {{.*}} 'auto (const T (&)[N]) -> A<T, N>' dependent trailing_return cdecl
// CHECK: |-InjectedClassNameType {{.*}} 'A<T, N>' dependent
Expand All @@ -223,7 +223,7 @@ namespace BraceElision {

A a1 = {0, 1}; // cxx17-error {{no viable}}

// CTAD succeed but brace elision is not allowed for parenthesized aggregate init.
// CTAD succeed but brace elision is not allowed for parenthesized aggregate init.
A a2(0, 1); // cxx20-error {{array initializer must be an initializer list}} cxx17-error {{no viable}}

// CHECK-LABEL: Dumping BraceElision::<deduction guide for A>:
Expand Down Expand Up @@ -265,8 +265,8 @@ namespace TrailingPack {
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 ... T
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T...) -> A<T...>'
// CHECK: | `-ParmVarDecl {{.*}} 'T...' pack
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A>
// CHECK-SAME: 'auto (TrailingPack::(lambda at {{.*}}), TrailingPack::(lambda at {{.*}})) ->
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A>
// CHECK-SAME: 'auto (TrailingPack::(lambda at {{.*}}), TrailingPack::(lambda at {{.*}})) ->
// CHECK-SAME: TrailingPack::A<TrailingPack::(lambda at {{.*}}), TrailingPack::(lambda at {{.*}})>'
// CHECK: |-TemplateArgument pack
// CHECK: | |-TemplateArgument type 'TrailingPack::(lambda at {{.*}})'
Expand Down Expand Up @@ -326,8 +326,8 @@ namespace DeduceArity {
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for F> 'auto (Types<T...>, T...) -> F<T...>'
// CHECK: | |-ParmVarDecl {{.*}} 'Types<T...>'
// CHECK: | `-ParmVarDecl {{.*}} 'T...' pack
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for F>
// CHECK-SAME: 'auto (Types<X, Y, Z>, DeduceArity::X, DeduceArity::Y, DeduceArity::Z) ->
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for F>
// CHECK-SAME: 'auto (Types<X, Y, Z>, DeduceArity::X, DeduceArity::Y, DeduceArity::Z) ->
// CHECK-SAME: DeduceArity::F<DeduceArity::X, DeduceArity::Y, DeduceArity::Z>'
// CHECK: | |-TemplateArgument pack
// CHECK: | | |-TemplateArgument type 'DeduceArity::X'
Expand Down
64 changes: 32 additions & 32 deletions clang/test/SemaTemplate/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ namespace attribute_aligned {
static_assert(sizeof(t) == sizeof(T), "my_aligned_storage size wrong");
static_assert(alignof(t) == alignof(T), "my_aligned_storage align wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}}
}

private:
my_aligned_storage<sizeof(T), alignof(T)> t;
};

C<double> cd;
}

Expand Down Expand Up @@ -73,9 +73,9 @@ void UseAnnotations() { HasAnnotations<int>(); }
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: FunctionDecl {{.*}} used HasPackAnnotations 'void ()'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral 3
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BAZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 1
Expand Down Expand Up @@ -128,9 +128,9 @@ void UseOnlyPackAnnotations() {
// CHECK-NEXT: TemplateArgument{{.*}} type 'int'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral 3
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BOO"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 1
Expand Down Expand Up @@ -159,9 +159,9 @@ void UseOnlyPackAnnotations() {
// CHECK-NEXT: TemplateArgument type 'float'
// CHECK-NEXT: BuiltinType {{.*}} 'float'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 3
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FOZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 4
Expand All @@ -184,9 +184,9 @@ void UseOnlyPackAnnotations() {
// CHECK-NEXT: TemplateArgument type 'bool'
// CHECK-NEXT: BuiltinType {{.*}} 'bool'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 7
// CHECK-NEXT: TemplateArgument{{.*}} integral 8
// CHECK-NEXT: TemplateArgument{{.*}} integral 9
// CHECK-NEXT: TemplateArgument{{.*}} integral '7'
// CHECK-NEXT: TemplateArgument{{.*}} integral '8'
// CHECK-NEXT: TemplateArgument{{.*}} integral '9'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FOZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 7
Expand Down Expand Up @@ -215,9 +215,9 @@ void UseOnlyPackAnnotations() {
// CHECK-NEXT: TemplateArgument type 'char'
// CHECK-NEXT: BuiltinType {{.*}} 'char'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral 3
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
Expand Down Expand Up @@ -312,9 +312,9 @@ void UseAnnotatedPackTemplateStructSpecializations() {
// CHECK-NEXT: TemplateArgument{{.*}} type 'int'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral 3
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BIR"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 1
Expand Down Expand Up @@ -343,9 +343,9 @@ void UseAnnotatedPackTemplateStructSpecializations() {
// CHECK-NEXT: TemplateArgument{{.*}} type 'float'
// CHECK-NEXT: BuiltinType {{.*}} 'float'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 3
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
Expand All @@ -358,9 +358,9 @@ void UseAnnotatedPackTemplateStructSpecializations() {
// CHECK-NEXT: TemplateArgument{{.*}} type 'bool'
// CHECK-NEXT: BuiltinType {{.*}} 'bool'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 7
// CHECK-NEXT: TemplateArgument{{.*}} integral 8
// CHECK-NEXT: TemplateArgument{{.*}} integral 9
// CHECK-NEXT: TemplateArgument{{.*}} integral '7'
// CHECK-NEXT: TemplateArgument{{.*}} integral '8'
// CHECK-NEXT: TemplateArgument{{.*}} integral '9'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
Expand Down Expand Up @@ -420,9 +420,9 @@ void UseAnnotatedPackTemplateStructSpecializations() {
// CHECK-NEXT: TemplateArgument{{.*}} type 'char'
// CHECK-NEXT: BuiltinType {{.*}} 'char'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 5
// CHECK-NEXT: TemplateArgument{{.*}} integral 6
// CHECK-NEXT: TemplateArgument{{.*}} integral 7
// CHECK-NEXT: TemplateArgument{{.*}} integral '5'
// CHECK-NEXT: TemplateArgument{{.*}} integral '6'
// CHECK-NEXT: TemplateArgument{{.*}} integral '7'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
template <typename T, int... Is> struct InvalidAnnotatedPackTemplateStruct{};
template <int... Is> struct [[clang::annotate("ANNOTATE_BIR", Is...)]] InvalidAnnotatedPackTemplateStruct<int, Is...>{};
Expand All @@ -444,9 +444,9 @@ void UseInvalidAnnotatedPackTemplateStruct() {
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: FunctionDecl {{.*}} used RedeclaredAnnotatedFunc 'void ()'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
// CHECK-NEXT: TemplateArgument{{.*}} integral 3
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FAR"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaTemplate/cwg2398.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace issue1 {
template<class T, class U = T> class B {};
template<template<class> class P, class T> void f(P<T>);
// new-note@-1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = issue1::B, T = int]}}
// new-note@-1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = B, T = int]}}
// old-note@-2 2{{template template argument has different template parameters}}

void g() {
Expand Down
29 changes: 15 additions & 14 deletions clang/test/SemaTemplate/deduction-guide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ using AT = A<int[3], int, int, short>;
// CHECK: | |-TemplateArgument type 'int'
// CHECK: | `-TemplateArgument type 'short'
// CHECK: |-TemplateArgument pack
// CHECK: | |-TemplateArgument integral 3
// CHECK: | |-TemplateArgument integral 3
// CHECK: | `-TemplateArgument integral 4
// CHECK: | |-TemplateArgument integral '3'
// CHECK: | |-TemplateArgument integral '3'
// CHECK: | `-TemplateArgument integral '(short)4'
// CHECK: |-TemplateArgument pack
// CHECK: | |-TemplateArgument decl
// CHECK: | | `-Var {{.*}} 'arr1' 'int[3]'
Expand Down Expand Up @@ -73,7 +73,7 @@ using BT = B<char, 'x'>;
// CHECK: | `-ParmVarDecl {{.*}} 'X<W, V>'
// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (X<nullptr, 'x'>) -> B<char, 'x'>'
// CHECK: |-TemplateArgument type 'char'
// CHECK: |-TemplateArgument integral 120
// CHECK: |-TemplateArgument integral ''x''
// CHECK: |-TemplateArgument type 'std::nullptr_t'
// CHECK: |-TemplateArgument nullptr
// CHECK: `-ParmVarDecl {{.*}} 'X<nullptr, 'x'>'
Expand Down Expand Up @@ -108,9 +108,9 @@ using CT = C<int>;
// CHECK: | `-ParmVarDecl {{.*}} 'type-parameter-0-2'
// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (int, Y<B>, int) -> C<int>'
// CHECK: |-TemplateArgument type 'int'
// CHECK: |-TemplateArgument template B
// CHECK: |-TemplateArgument template 'B'
// CHECK: |-TemplateArgument type 'int'
// CHECK: |-TemplateArgument integral 0
// CHECK: |-TemplateArgument integral '0'
// CHECK: |-ParmVarDecl {{.*}} 'int'
// CHECK: |-ParmVarDecl {{.*}} 'Y<B>'
// CHECK: `-ParmVarDecl {{.*}} 'int'
Expand Down Expand Up @@ -231,7 +231,7 @@ F s(0);
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for F> 'auto (type-parameter-0-1) -> F<>'
// CHECK: | `-ParmVarDecl {{.*}} 'type-parameter-0-1'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for F> 'auto (int) -> F<>'
// CHECK: |-TemplateArgument integral 120
// CHECK: |-TemplateArgument integral ''x''
// CHECK: |-TemplateArgument type 'int'
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'
Expand Down Expand Up @@ -315,18 +315,19 @@ namespace TTP {
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 0 T{{$}}
// CHECK-NEXT: |-TemplateTemplateParmDecl {{.+}} depth 0 index 1 TT{{$}}
// CHECK-NEXT: | `-TemplateTypeParmDecl {{.+}} class depth 1 index 0{{$}}
// CHECK-NEXT: |-CXXDeductionGuideDecl {{.+}} 'auto (<T>) -> B<T>'{{$}}
// CHECK-NEXT: | `-ParmVarDecl {{.+}} '<T>'{{$}}
// CHECK-NEXT: |-CXXDeductionGuideDecl {{.+}} 'auto (template-parameter-0-1<T>) -> B<T>'{{$}}
// CHECK-NEXT: | `-ParmVarDecl {{.+}} 'template-parameter-0-1<T>'{{$}}
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} 'auto (A<int>) -> TTP::B<int>'
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'{{$}}
// CHECK-NEXT: |-TemplateArgument template A
// CHECK-NEXT: |-TemplateArgument template 'TTP::A'{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'A<int>':'TTP::A<int>'{{$}}
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (<T>) -> B<T>' dependent trailing_return cdecl{{$}}
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (template-parameter-0-1<T>) -> B<T>' dependent trailing_return cdecl{{$}}
// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'B<T>' dependent{{$}}
// CHECK-NEXT: | `-CXXRecord {{.+}} 'B'{{$}}
// CHECK-NEXT: `-ElaboratedType {{.+}} '<T>' sugar dependent{{$}}
// CHECK-NEXT: `-TemplateSpecializationType {{.+}} '<T>' dependent {{$}}
// CHECK-NEXT: `-TemplateArgument type 'T'{{$}}
// CHECK-NEXT: `-ElaboratedType {{.+}} 'template-parameter-0-1<T>' sugar dependent{{$}}
// CHECK-NEXT: `-TemplateSpecializationType {{.+}} 'template-parameter-0-1<T>' dependent template-parameter-0-1{{$}}
// CHECK-NEXT: `-TemplateArgument type 'T':'type-parameter-0-0'{{$}}
// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0{{$}}
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'T'{{$}}
4 changes: 2 additions & 2 deletions clang/test/SemaTemplate/instantiate-requires-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ namespace type_requirement {

template<typename T> requires
false_v<requires { typename T::template temp<T>; }>
// expected-note@-1 {{because 'false_v<requires { typename contains_template<int>::temp<contains_template<int> >; }>' evaluated to false}}
// expected-note@-2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}}
// expected-note@-1 {{because 'false_v<requires { typename contains_template<int>::template temp<contains_template<int> >; }>' evaluated to false}}
// expected-note@-2 {{because 'false_v<requires { typename contains_template<short>::template temp<contains_template<short> >; }>' evaluated to false}}
struct r2 {};

using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}}
Expand Down
68 changes: 38 additions & 30 deletions clang/test/SemaTemplate/make_integer_seq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ using test1 = __make_integer_seq<A, int, 1>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:5:1, col:43> col:7 test1 '__make_integer_seq<A, int, 1>':'A<int, 0>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
// CHECK-NEXT: |-TemplateArgument template 'A'
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int'
// CHECK-NEXT: |-TemplateArgument expr '1'
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'int'
// CHECK-NEXT: | |-value: Int 1
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar A
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr '0'
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int'
// CHECK-NEXT: | |-value: Int 0
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 0
Expand All @@ -25,24 +26,25 @@ using test1 = __make_integer_seq<A, int, 1>;

template <class B1, B1 B2> using B = __make_integer_seq<A, B1, B2>;
using test2 = B<int, 1>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:27:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar alias B
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr '1'
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:22> 'int'
// CHECK-NEXT: | |-value: Int 1
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:22> 'int' 1
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
// CHECK-NEXT: |-TemplateArgument template 'A'
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1
// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:26:64> 'int'
// CHECK-NEXT: |-TemplateArgument expr '1'
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:64> 'int'
// CHECK-NEXT: | |-value: Int 1
// CHECK-NEXT: | `-SubstNonTypeTemplateParmExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
// CHECK-NEXT: | |-NonTypeTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <col:21, col:24> col:24 referenced 'B1' depth 0 index 1 B2
Expand All @@ -52,7 +54,7 @@ using test2 = B<int, 1>;
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1
// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr '0'
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
// CHECK-NEXT: | |-value: Int 0
// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 0
Expand All @@ -61,58 +63,64 @@ using test2 = B<int, 1>;

template <template <class T, T...> class S, class T, int N> struct C {
using test3 = __make_integer_seq<S, T, N>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:63:3, col:43> col:9 test3 '__make_integer_seq<S, T, N>':'__make_integer_seq<template-parameter-0-0, type-parameter-0-1, N>'
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:43> col:9 test3 '__make_integer_seq<S, T, N>':'__make_integer_seq<template-parameter-0-0, type-parameter-0-1, N>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<S, T, N>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<S, T, N>' sugar dependent alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template S
// CHECK-NEXT: |-TemplateArgument template 'S'
// CHECK-NEXT: | | `-TemplateTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:11, col:42> col:42 depth 0 index 0 S
// CHECK-NEXT: |-TemplateArgument type 'T'
// 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> 'T' <Dependent>
// CHECK-NEXT: |-TemplateArgument expr 'N'
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}: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<template-parameter-0-0, type-parameter-0-1, N>' dependent __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template
// CHECK-NEXT: |-TemplateArgument template 'template-parameter-0-0'
// CHECK-NEXT: | `-TemplateTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> depth 0 index 0
// 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: `-TemplateArgument expr 'N'
// 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>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:82:3, col:43> col:9 test4 '__make_integer_seq<A, T, 1>':'__make_integer_seq<A, type-parameter-0-1, 1>'
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:43> col:9 test4 '__make_integer_seq<A, T, 1>':'__make_integer_seq<A, type-parameter-0-1, 1>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, T, 1>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, T, 1>' sugar dependent alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
// CHECK-NEXT: |-TemplateArgument template 'A'
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
// CHECK-NEXT: |-TemplateArgument type 'T'
// 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> 'T' <Dependent>
// CHECK-NEXT: |-TemplateArgument expr '1'
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}: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 template 'A'
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 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> 'T' <Dependent>
// CHECK-NEXT: `-TemplateArgument expr '1'
// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'T' <Dependent>
// CHECK-NEXT: `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1

using test5 = __make_integer_seq<A, int, N>;
// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:101:3, col:45> col:9 test5 '__make_integer_seq<A, int, N>'
// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:45> col:9 test5 '__make_integer_seq<A, int, N>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' sugar dependent alias __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
// CHECK-NEXT: |-TemplateArgument template 'A'
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:1, col:41> col:38 A
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:44> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
// CHECK-NEXT: |-TemplateArgument expr 'N'
// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:44> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' dependent __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template A
// CHECK-NEXT: |-TemplateArgument template 'A'
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: `-TemplateArgument expr
// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:44> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
// CHECK-NEXT: `-TemplateArgument expr 'N'
// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:44> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
};

// expected-no-diagnostics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ nested_init_list<int>::B nil {1, 2};
using NIL = decltype(nil);
using NIL = nested_init_list<int>::B<int>;

// expected-error@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'concept_fail'}}
// expected-error@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'nested_init_list<int>::concept_fail'}}
nested_init_list<int>::concept_fail nil_invalid{1, ""};
// expected-note@#INIT_LIST_INNER_INVALID {{candidate template ignored: substitution failure [with F = const char *]: constraints not satisfied for class template 'concept_fail' [with F = const char *]}}
// expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not viable: requires 1 argument, but 2 were provided}}
Expand Down
20 changes: 10 additions & 10 deletions clang/test/SemaTemplate/type_pack_element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using test1 = __type_pack_element<0, int>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <<stdin>:3:1, col:41> col:7 test1 '__type_pack_element<0, int>':'int'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, int>' sugar
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, int>' sugar alias __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr '0'
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:35> 'unsigned long'
// CHECK-NEXT: | |-value: Int 0
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:35> 'unsigned long' <IntegralCast>
Expand All @@ -18,18 +18,18 @@ template<int N, class ...Ts> struct A {
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:17:3, col:45> col:9 test2 '__type_pack_element<N, Ts...>':'__type_pack_element<N, type-parameter-0-1...>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, Ts...>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, Ts...>' sugar dependent alias __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr 'N'
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
// CHECK-NEXT: |-TemplateArgument type 'Ts...'
// CHECK-NEXT: | `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'Ts...' dependent
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'Ts'
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, type-parameter-0-1...>' dependent __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr 'N'
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
// CHECK-NEXT: `-TemplateArgument pack
// CHECK-NEXT: `-TemplateArgument pack '<type-parameter-0-1...>'
// CHECK-NEXT: `-TemplateArgument type 'type-parameter-0-1...'
// CHECK-NEXT: `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1...' dependent
// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent contains_unexpanded_pack depth 0 index 1 pack
Expand All @@ -38,7 +38,7 @@ template<int N, class ...Ts> struct A {
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:37:3, col:45> col:9 test3 '__type_pack_element<0, Ts...>':'__type_pack_element<0, type-parameter-0-1...>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, Ts...>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, Ts...>' sugar dependent alias __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr '0'
// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long'
// CHECK-NEXT: | |-value: Int 0
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
Expand All @@ -48,8 +48,8 @@ template<int N, class ...Ts> struct A {
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'Ts'
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, type-parameter-0-1...>' dependent __type_pack_element
// CHECK-NEXT: |-TemplateArgument integral 0
// CHECK-NEXT: `-TemplateArgument pack
// CHECK-NEXT: |-TemplateArgument integral '0UL'
// CHECK-NEXT: `-TemplateArgument pack '<type-parameter-0-1...>'
// CHECK-NEXT: `-TemplateArgument type 'type-parameter-0-1...'
// CHECK-NEXT: `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1...' dependent
// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent contains_unexpanded_pack depth 0 index 1 pack
Expand All @@ -58,16 +58,16 @@ template<int N, class ...Ts> struct A {
// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:57:3, col:43> col:9 test4 '__type_pack_element<N, int>'
// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' sugar dependent
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' sugar dependent alias __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr 'N'
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' dependent __type_pack_element
// CHECK-NEXT: |-TemplateArgument expr
// CHECK-NEXT: |-TemplateArgument expr 'N'
// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
// CHECK-NEXT: `-TemplateArgument pack
// CHECK-NEXT: `-TemplateArgument pack '<int>'
// CHECK-NEXT: `-TemplateArgument type 'int'
// CHECK-NEXT: `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
};
Expand Down
40 changes: 33 additions & 7 deletions clang/unittests/AST/TemplateNameTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,31 @@ std::string printTemplateName(TemplateName TN, const PrintingPolicy &Policy,
return Out.str();
}

TEST(TemplateName, PrintTemplate) {
std::string Code = R"cpp(
namespace std {
template <typename> struct vector {};
}
template<template <typename> class T> class X;
using A = X<std::vector>;
)cpp";
auto AST = tooling::buildASTFromCode(Code);
ASTContext &Ctx = AST->getASTContext();
// Match the template argument vector in X<std::vector>.
auto MatchResults = match(templateArgumentLoc().bind("id"), Ctx);
const auto *Template = selectFirst<TemplateArgumentLoc>("id", MatchResults);
ASSERT_TRUE(Template);

TemplateName TN = Template->getArgument().getAsTemplate();
EXPECT_EQ(TN.getKind(), TemplateName::QualifiedTemplate);
EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
TemplateName::Qualified::AsWritten),
"std::vector");
EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
TemplateName::Qualified::None),
"vector");
}

TEST(TemplateName, PrintUsingTemplate) {
std::string Code = R"cpp(
namespace std {
Expand All @@ -44,12 +69,11 @@ TEST(TemplateName, PrintUsingTemplate) {
ASSERT_TRUE(Template);

TemplateName TN = Template->getArgument().getAsTemplate();
EXPECT_EQ(TN.getKind(), TemplateName::UsingTemplate);
EXPECT_EQ(TN.getAsUsingShadowDecl()->getTargetDecl(), TN.getAsTemplateDecl());
EXPECT_EQ(TN.getKind(), TemplateName::QualifiedTemplate);
UsingShadowDecl *USD = TN.getAsUsingShadowDecl();
EXPECT_TRUE(USD != nullptr);
EXPECT_EQ(USD->getTargetDecl(), TN.getAsTemplateDecl());

EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
TemplateName::Qualified::Fully),
"std::vector");
EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
TemplateName::Qualified::AsWritten),
"vector");
Expand Down Expand Up @@ -102,7 +126,8 @@ TEST(TemplateName, UsingTemplate) {
const auto *TST =
MatchResults.front().getNodeAs<TemplateSpecializationType>("id");
ASSERT_TRUE(TST);
EXPECT_EQ(TST->getTemplateName().getKind(), TemplateName::UsingTemplate);
EXPECT_EQ(TST->getTemplateName().getKind(), TemplateName::QualifiedTemplate);
EXPECT_TRUE(TST->getTemplateName().getAsUsingShadowDecl() != nullptr);

AST = tooling::buildASTFromCodeWithArgs(R"cpp(
namespace std {
Expand All @@ -120,7 +145,8 @@ TEST(TemplateName, UsingTemplate) {
const auto *DTST =
MatchResults.front().getNodeAs<DeducedTemplateSpecializationType>("id");
ASSERT_TRUE(DTST);
EXPECT_EQ(DTST->getTemplateName().getKind(), TemplateName::UsingTemplate);
EXPECT_EQ(DTST->getTemplateName().getKind(), TemplateName::QualifiedTemplate);
EXPECT_TRUE(DTST->getTemplateName().getAsUsingShadowDecl() != nullptr);
}

} // namespace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,63 +42,63 @@ int main(int, char**)
{
{
// cannot deduce Key and T from nothing
std::map m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
std::map m; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce Key and T from just (Compare)
std::map m(std::less<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce Key and T from just (Compare, Allocator)
std::map m(std::less<int>{}, std::allocator<PC>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce Key and T from just (Allocator)
std::map m(std::allocator<PC>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// refuse to rebind the allocator if Allocator::value_type is not exactly what we expect
const P arr[] = { {1,1L}, {2,2L}, {3,3L} };
std::map m(arr, arr + 3, std::allocator<P>());
// expected-error-re@map:* {{static assertion failed{{( due to requirement '.*')?}}{{.*}}Allocator::value_type must be same type as value_type}}
// expected-error-re@map:*{{static assertion failed{{( due to requirement '.*')?}}{{.*}}Allocator::value_type must be same type as value_type}}
}
{
// cannot convert from some arbitrary unrelated type
NotAnAllocator a;
std::map m(a); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
std::map m(a); // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m{ {1,1L}, {2,2L}, {3,3L} };
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>());
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>(), std::allocator<PC>());
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::allocator<PC>());
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::map m(P{1,1L});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::map m(PC{1,1L});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ int main(int, char**)
{
{
// cannot deduce Key and T from nothing
std::multimap m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
std::multimap m; // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce Key and T from just (Compare)
std::multimap m(std::less<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce Key and T from just (Compare, Allocator)
std::multimap m(std::less<int>{}, std::allocator<PC>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce Key and T from just (Allocator)
std::multimap m(std::allocator<PC>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// refuse to rebind the allocator if Allocator::value_type is not exactly what we expect
Expand All @@ -68,37 +68,37 @@ int main(int, char**)
{
// cannot convert from some arbitrary unrelated type
NotAnAllocator a;
std::multimap m(a); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
std::multimap m(a); // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m{ {1,1L}, {2,2L}, {3,3L} };
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>());
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>(), std::allocator<PC>());
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::allocator<PC>());
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::multimap m(P{1,1L});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::multimap m(PC{1,1L});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,29 @@ int main(int, char **) {
{
// cannot deduce Key from nothing
std::multiset s;
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// cannot deduce Key from just (Compare)
std::multiset s(std::less<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// cannot deduce Key from just (Compare, Allocator)
std::multiset s(std::less<int>{}, std::allocator<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// cannot deduce Key from multiset(Allocator)
std::multiset s(std::allocator<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// since we have parens, not braces, this deliberately does not find the
// initializer_list constructor
NotAnAllocator a;
std::multiset s(a);
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,29 @@ int main(int, char **) {
{
// cannot deduce Key from nothing
std::set s;
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// cannot deduce Key from just (Compare)
std::set s(std::less<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// cannot deduce Key from just (Compare, Allocator)
std::set s(std::less<int>{}, std::allocator<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// cannot deduce Key from just (Allocator)
std::set s(std::allocator<int>{});
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// since we have parens, not braces, this deliberately does not find the
// initializer_list constructor
NotAnAllocator a;
std::set s(a);
// expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
// expected-error-re@-1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,32 @@ int main(int, char**)
{
// queue(Compare, Container, const Alloc);
// The '45' is not an allocator
std::priority_queue pri(std::greater<int>(), std::deque<int>({1,2,3}), 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
std::priority_queue pri(std::greater<int>(), std::deque<int>({1,2,3}), 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}

{
// queue(const queue&, const Alloc&);
// The '45' is not an allocator
std::priority_queue<int> source;
std::priority_queue pri(source, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
std::priority_queue pri(source, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}

{
// priority_queue(Iter, Iter, Comp)
// int is not an iterator
std::priority_queue pri(15, 17, std::greater<double>()); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
std::priority_queue pri(15, 17, std::greater<double>()); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}

{
// priority_queue(Iter, Iter, Comp, Container)
// float is not an iterator
std::priority_queue pri(23.f, 2.f, std::greater<float>(), std::deque<float>()); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
std::priority_queue pri(23.f, 2.f, std::greater<float>(), std::deque<float>()); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}

// Test the implicit deduction guides
{
// priority_queue (allocator &)
std::priority_queue pri((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
std::priority_queue pri((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// stack<allocator<int>, allocator<allocator<int>>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ int main(int, char**)
{
// queue(const Container&, const Alloc&);
// The '45' is not an allocator
std::queue que(std::list<int>{1,2,3}, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'queue'}}
std::queue que(std::list<int>{1,2,3}, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}queue'}}
}

{
// queue(const queue&, const Alloc&);
// The '45' is not an allocator
std::queue<int> source;
std::queue que(source, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'queue'}}
std::queue que(source, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}queue'}}
}

// Test the implicit deduction guides
{
// queue (allocator &)
std::queue que((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'queue'}}
std::queue que((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}queue'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// stack<allocator<int>, allocator<allocator<int>>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ int main(int, char**)
{
// stack(const Container&, const Alloc&);
// The '45' is not an allocator
std::stack stk(std::list<int>({1,2,3}), 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'stack'}}
std::stack stk(std::list<int>({1,2,3}), 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}stack'}}
}

{
// stack(const stack&, const Alloc&);
// The '45' is not an allocator
std::stack<int> source;
std::stack stk(source, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'stack'}}
std::stack stk(source, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}stack'}}
}

// Test the implicit deduction guides
{
// stack (allocator &)
std::stack stk((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'stack'}}
std::stack stk((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}stack'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// stack<allocator<int>, allocator<allocator<int>>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
int main(int, char**)
{
{
std::array arr{1,2,3L}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'array'}}
std::array arr{1,2,3L}; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}array'}}
}

return 0;
Expand Down
Loading