if (TTPD->hasDefaultArgument()) {
P.Default.emplace();
llvm::raw_string_ostream Out(*P.Default);
- TTPD->getDefaultArgument().getArgument().print(PP, Out);
+ TTPD->getDefaultArgument().getArgument().print(PP, Out,
+ /*IncludeType*/ false);
}
}
TempParameters.push_back(std::move(P));
bool OmitTemplateKW = false) const;
void print(raw_ostream &Out, const ASTContext &Context,
const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
+
+ static bool shouldIncludeTypeForArgument(const TemplateParameterList *TPL,
+ unsigned Idx);
};
/// Stores a list of template parameters and the associated
return T->getStmtClass() == CharacterLiteralClass;
}
+ static void print(unsigned val, CharacterKind Kind, raw_ostream &OS);
+
// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
// Print all template arguments into ArgString
llvm::raw_string_ostream OS(ArgString);
for (unsigned i = 0; i < Args->size(); ++i) {
- Args->get(i).print(Context.getLangOpts(), OS);
+ Args->get(i).print(Context.getLangOpts(), OS, /*IncludeType*/ true);
// Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
OS << '\n';
}
TemplateArgument getPackExpansionPattern() const;
/// Print this template argument to the given output stream.
- void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
+ void print(const PrintingPolicy &Policy, raw_ostream &Out,
+ bool IncludeType) const;
/// Debugging aid that dumps the template argument.
void dump(raw_ostream &Out) const;
void DynTypedNode::print(llvm::raw_ostream &OS,
const PrintingPolicy &PP) const {
if (const TemplateArgument *TA = get<TemplateArgument>())
- TA->print(PP, OS);
+ TA->print(PP, OS, /*IncludeType*/ true);
else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>())
- TAL->getArgument().print(PP, OS);
+ TAL->getArgument().print(PP, OS, /*IncludeType*/ true);
else if (const TemplateName *TN = get<TemplateName>())
TN->print(OS, PP);
else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
void printTemplateParameters(const TemplateParameterList *Params,
bool OmitTemplateKW = false);
- void printTemplateArguments(llvm::ArrayRef<TemplateArgument> Args);
- void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args);
+ void printTemplateArguments(llvm::ArrayRef<TemplateArgument> Args,
+ const TemplateParameterList *Params,
+ bool TemplOverloaded);
+ void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args,
+ const TemplateParameterList *Params,
+ bool TemplOverloaded);
void prettyPrintAttributes(Decl *D);
void prettyPrintPragmas(Decl *D);
void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
llvm::raw_string_ostream POut(Proto);
DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
const auto *TArgAsWritten = D->getTemplateSpecializationArgsAsWritten();
+ const TemplateParameterList *TPL = D->getTemplateSpecializationInfo()
+ ->getTemplate()
+ ->getTemplateParameters();
if (TArgAsWritten && !Policy.PrintCanonicalTypes)
- TArgPrinter.printTemplateArguments(TArgAsWritten->arguments());
+ TArgPrinter.printTemplateArguments(TArgAsWritten->arguments(), TPL,
+ /*TemplOverloaded*/ true);
else if (const TemplateArgumentList *TArgs =
D->getTemplateSpecializationArgs())
- TArgPrinter.printTemplateArguments(TArgs->asArray());
+ TArgPrinter.printTemplateArguments(TArgs->asArray(), TPL,
+ /*TemplOverloaded*/ true);
}
QualType Ty = D->getType();
if (const auto *TST =
dyn_cast<TemplateSpecializationType>(TSI->getType()))
Args = TST->template_arguments();
- printTemplateArguments(Args);
+ printTemplateArguments(
+ Args, S->getSpecializedTemplate()->getTemplateParameters(),
+ /*TemplOverloaded*/ false);
}
}
Out << ' ';
}
-void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args) {
+void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args,
+ const TemplateParameterList *Params,
+ bool TemplOverloaded) {
Out << "<";
for (size_t I = 0, E = Args.size(); I < E; ++I) {
if (I)
Out << ", ";
- Args[I].print(Policy, Out);
+ if (TemplOverloaded || !Params)
+ Args[I].print(Policy, Out, /*IncludeType*/ true);
+ else
+ Args[I].print(
+ Policy, Out,
+ TemplateParameterList::shouldIncludeTypeForArgument(Params, I));
}
Out << ">";
}
-void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args) {
+void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
+ const TemplateParameterList *Params,
+ bool TemplOverloaded) {
Out << "<";
for (size_t I = 0, E = Args.size(); I < E; ++I) {
if (I)
Out << ", ";
- Args[I].getArgument().print(Policy, Out);
+ if (TemplOverloaded)
+ Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
+ else
+ Args[I].getArgument().print(
+ Policy, Out,
+ TemplateParameterList::shouldIncludeTypeForArgument(Params, I));
}
Out << ">";
}
return HasRequiresClause || HasConstrainedParameters;
}
+bool TemplateParameterList::shouldIncludeTypeForArgument(
+ const TemplateParameterList *TPL, unsigned Idx) {
+ if (!TPL || Idx >= TPL->size())
+ return true;
+ const NamedDecl *TemplParam = TPL->getParam(Idx);
+ if (const auto *ParamValueDecl =
+ dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
+ if (ParamValueDecl->getType()->getContainedDeducedType())
+ return true;
+ return false;
+}
+
namespace clang {
void *allocateDefaultArgStorageChain(const ASTContext &C) {
ConceptName.printName(OS, Policy);
if (hasExplicitTemplateArgs()) {
OS << "<";
+ // FIXME: Find corresponding parameter for argument
for (auto &ArgLoc : ArgsAsWritten->arguments())
- ArgLoc.getArgument().print(Policy, OS);
+ ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
OS << ">";
}
}
#include "clang/Lex/Lexer.h"
#include "clang/Lex/LiteralSupport.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
StringRef Param = Params->getParam(i)->getName();
if (Param.empty()) continue;
TOut << Param << " = ";
- Args.get(i).print(Policy, TOut);
+ Args.get(i).print(
+ Policy, TOut,
+ TemplateParameterList::shouldIncludeTypeForArgument(Params, i));
TOut << ", ";
}
}
StringRef Param = Params->getParam(i)->getName();
if (Param.empty()) continue;
TOut << Param << " = ";
- Args->get(i).print(Policy, TOut);
+ Args->get(i).print(Policy, TOut, /*IncludeType*/ true);
TOut << ", ";
}
}
return std::string(S.str());
}
+void CharacterLiteral::print(unsigned Val, CharacterKind Kind,
+ raw_ostream &OS) {
+ switch (Kind) {
+ case CharacterLiteral::Ascii:
+ break; // no prefix.
+ case CharacterLiteral::Wide:
+ OS << 'L';
+ break;
+ case CharacterLiteral::UTF8:
+ OS << "u8";
+ break;
+ case CharacterLiteral::UTF16:
+ OS << 'u';
+ break;
+ case CharacterLiteral::UTF32:
+ OS << 'U';
+ break;
+ }
+
+ switch (Val) {
+ case '\\':
+ OS << "'\\\\'";
+ break;
+ case '\'':
+ OS << "'\\''";
+ break;
+ case '\a':
+ // TODO: K&R: the meaning of '\\a' is different in traditional C
+ OS << "'\\a'";
+ break;
+ case '\b':
+ OS << "'\\b'";
+ break;
+ // Nonstandard escape sequence.
+ /*case '\e':
+ OS << "'\\e'";
+ break;*/
+ case '\f':
+ OS << "'\\f'";
+ break;
+ case '\n':
+ OS << "'\\n'";
+ break;
+ case '\r':
+ OS << "'\\r'";
+ break;
+ case '\t':
+ OS << "'\\t'";
+ break;
+ case '\v':
+ OS << "'\\v'";
+ break;
+ default:
+ // A character literal might be sign-extended, which
+ // would result in an invalid \U escape sequence.
+ // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF'
+ // are not correctly handled.
+ if ((Val & ~0xFFu) == ~0xFFu && Kind == CharacterLiteral::Ascii)
+ Val &= 0xFFu;
+ if (Val < 256 && isPrintable((unsigned char)Val))
+ OS << "'" << (char)Val << "'";
+ else if (Val < 256)
+ OS << "'\\x" << llvm::format("%02x", Val) << "'";
+ else if (Val <= 0xFFFF)
+ OS << "'\\u" << llvm::format("%04x", Val) << "'";
+ else
+ OS << "'\\U" << llvm::format("%08x", Val) << "'";
+ }
+}
+
FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V,
bool isexact, QualType Type, SourceLocation L)
: Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary), Loc(L) {
if (ResolveTemplateArguments && Record) {
// Print the type trait with resolved template parameters.
Record->printName(OS);
- printTemplateArgumentList(OS, Record->getTemplateArgs().asArray(),
- Policy);
+ printTemplateArgumentList(
+ OS, Record->getTemplateArgs().asArray(), Policy,
+ Record->getSpecializedTemplate()->getTemplateParameters());
break;
}
const Type *T = getAsType();
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <string>
if (Node->hasTemplateKeyword())
OS << "template ";
OS << Node->getNameInfo();
- if (Node->hasExplicitTemplateArgs())
- printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+ if (Node->hasExplicitTemplateArgs()) {
+ const TemplateParameterList *TPL = nullptr;
+ if (!Node->hadMultipleCandidates())
+ if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
+ TPL = TD->getTemplateParameters();
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
+ }
}
void StmtPrinter::VisitDependentScopeDeclRefExpr(
}
void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
- unsigned value = Node->getValue();
-
- switch (Node->getKind()) {
- case CharacterLiteral::Ascii: break; // no prefix.
- case CharacterLiteral::Wide: OS << 'L'; break;
- case CharacterLiteral::UTF8: OS << "u8"; break;
- case CharacterLiteral::UTF16: OS << 'u'; break;
- case CharacterLiteral::UTF32: OS << 'U'; break;
- }
-
- switch (value) {
- case '\\':
- OS << "'\\\\'";
- break;
- case '\'':
- OS << "'\\''";
- break;
- case '\a':
- // TODO: K&R: the meaning of '\\a' is different in traditional C
- OS << "'\\a'";
- break;
- case '\b':
- OS << "'\\b'";
- break;
- // Nonstandard escape sequence.
- /*case '\e':
- OS << "'\\e'";
- break;*/
- case '\f':
- OS << "'\\f'";
- break;
- case '\n':
- OS << "'\\n'";
- break;
- case '\r':
- OS << "'\\r'";
- break;
- case '\t':
- OS << "'\\t'";
- break;
- case '\v':
- OS << "'\\v'";
- break;
- default:
- // A character literal might be sign-extended, which
- // would result in an invalid \U escape sequence.
- // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF'
- // are not correctly handled.
- if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii)
- value &= 0xFFu;
- if (value < 256 && isPrintable((unsigned char)value))
- OS << "'" << (char)value << "'";
- else if (value < 256)
- OS << "'\\x" << llvm::format("%02x", value) << "'";
- else if (value <= 0xFFFF)
- OS << "'\\u" << llvm::format("%04x", value) << "'";
- else
- OS << "'\\U" << llvm::format("%08x", value) << "'";
- }
+ CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
}
/// Prints the given expression using the original source text. Returns true on
if (Node->hasTemplateKeyword())
OS << "template ";
OS << Node->getMemberNameInfo();
+ const TemplateParameterList *TPL = nullptr;
+ if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
+ if (!Node->hadMultipleCandidates())
+ if (auto *FTD = FD->getPrimaryTemplate())
+ TPL = FTD->getTemplateParameters();
+ } else if (auto *VTSD =
+ dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
+ TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
if (Node->hasExplicitTemplateArgs())
- printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
}
void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
assert(Args);
if (Args->size() != 1) {
+ const TemplateParameterList *TPL = nullptr;
+ if (!DRE->hadMultipleCandidates())
+ if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
+ TPL = TD->getTemplateParameters();
OS << "operator\"\"" << Node->getUDSuffix()->getName();
- printTemplateArgumentList(OS, Args->asArray(), Policy);
+ printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
OS << "()";
return;
}
OS << "template ";
OS << E->getFoundDecl()->getName();
printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
- Policy);
+ Policy,
+ E->getNamedConcept()->getTemplateParameters());
}
void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
/// \param Out the raw_ostream instance to use for printing.
///
/// \param Policy the printing policy for EnumConstantDecl printing.
-static void printIntegral(const TemplateArgument &TemplArg,
- raw_ostream &Out, const PrintingPolicy& Policy) {
+///
+/// \param IncludeType If set, ensure that the type of the expression printed
+/// matches the type of the template argument.
+static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
+ const PrintingPolicy &Policy, bool IncludeType) {
const Type *T = TemplArg.getIntegralType().getTypePtr();
const llvm::APSInt &Val = TemplArg.getAsIntegral();
}
}
- if (T->isBooleanType() && !Policy.MSVCFormatting) {
- Out << (Val.getBoolValue() ? "true" : "false");
+ if (Policy.MSVCFormatting)
+ IncludeType = false;
+
+ if (T->isBooleanType()) {
+ if (!Policy.MSVCFormatting)
+ Out << (Val.getBoolValue() ? "true" : "false");
+ else
+ Out << Val;
} else if (T->isCharType()) {
- const char Ch = Val.getZExtValue();
- Out << ((Ch == '\'') ? "'\\" : "'");
- Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
- Out << "'";
- } else {
+ if (IncludeType) {
+ if (T->isSpecificBuiltinType(BuiltinType::SChar))
+ Out << "(signed char)";
+ else if (T->isSpecificBuiltinType(BuiltinType::UChar))
+ Out << "(unsigned char)";
+ }
+ CharacterLiteral::print(Val.getZExtValue(), CharacterLiteral::Ascii, Out);
+ } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
+ CharacterLiteral::CharacterKind Kind;
+ if (T->isWideCharType())
+ Kind = CharacterLiteral::Wide;
+ else if (T->isChar8Type())
+ Kind = CharacterLiteral::UTF8;
+ else if (T->isChar16Type())
+ Kind = CharacterLiteral::UTF16;
+ else if (T->isChar32Type())
+ Kind = CharacterLiteral::UTF32;
+ else
+ Kind = CharacterLiteral::Ascii;
+ CharacterLiteral::print(Val.getExtValue(), Kind, Out);
+ } else if (IncludeType) {
+ if (const auto *BT = T->getAs<BuiltinType>()) {
+ switch (BT->getKind()) {
+ case BuiltinType::ULongLong:
+ Out << Val << "ULL";
+ break;
+ case BuiltinType::LongLong:
+ Out << Val << "LL";
+ break;
+ case BuiltinType::ULong:
+ Out << Val << "UL";
+ break;
+ case BuiltinType::Long:
+ Out << Val << "L";
+ break;
+ case BuiltinType::UInt:
+ Out << Val << "U";
+ break;
+ case BuiltinType::Int:
+ Out << Val;
+ break;
+ default:
+ Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
+ << Val;
+ break;
+ }
+ } else
+ Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
+ << Val;
+ } else
Out << Val;
- }
}
static unsigned getArrayDepth(QualType type) {
llvm_unreachable("Invalid TemplateArgument Kind!");
}
-void TemplateArgument::print(const PrintingPolicy &Policy,
- raw_ostream &Out) const {
+void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
+ bool IncludeType) const {
+
switch (getKind()) {
case Null:
Out << "(no value)";
}
case Declaration: {
+ // FIXME: Include the type if it's not obvious from the context.
NamedDecl *ND = getAsDecl();
if (getParamTypeForDecl()->isRecordType()) {
if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
- // FIXME: Include the type if it's not obvious from the context.
TPO->printAsInit(Out);
break;
}
}
case NullPtr:
+ // FIXME: Include the type if it's not obvious from the context.
Out << "nullptr";
break;
break;
case Integral:
- printIntegral(*this, Out, Policy);
+ printIntegral(*this, Out, Policy, IncludeType);
break;
case Expression:
else
Out << ", ";
- P.print(Policy, Out);
+ P.print(Policy, Out, IncludeType);
}
Out << ">";
break;
LangOptions LO; // FIXME! see also TemplateName::dump().
LO.CPlusPlus = true;
LO.Bool = true;
- print(PrintingPolicy(LO), Out);
+ print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
}
LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
LangOptions LangOpts;
LangOpts.CPlusPlus = true;
PrintingPolicy Policy(LangOpts);
- Arg.print(Policy, OS);
+ Arg.print(Policy, OS, /*IncludeType*/ true);
return DB << OS.str();
}
}
}
static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
- llvm::raw_ostream &OS) {
- A.print(PP, OS);
+ llvm::raw_ostream &OS, bool IncludeType) {
+ A.print(PP, OS, IncludeType);
}
static void printArgument(const TemplateArgumentLoc &A,
- const PrintingPolicy &PP, llvm::raw_ostream &OS) {
+ const PrintingPolicy &PP, llvm::raw_ostream &OS,
+ bool IncludeType) {
const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
if (Kind == TemplateArgument::ArgKind::Type)
return A.getTypeSourceInfo()->getType().print(OS, PP);
- return A.getArgument().print(PP, OS);
+ return A.getArgument().print(PP, OS, IncludeType);
}
static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
return false;
}
-template<typename TA>
+template <typename TA>
static void printTo(raw_ostream &OS, ArrayRef<TA> Args,
const PrintingPolicy &Policy, bool SkipBrackets,
- const TemplateParameterList *TPL) {
+ const TemplateParameterList *TPL, bool IsPack,
+ unsigned ParmIndex) {
// Drop trailing template arguments that match default arguments.
if (TPL && Policy.SuppressDefaultTemplateArgs &&
- !Policy.PrintCanonicalTypes && !Args.empty() &&
+ !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
Args.size() <= TPL->size()) {
ASTContext &Ctx = TPL->getParam(0)->getASTContext();
llvm::SmallVector<TemplateArgument, 8> OrigArgs;
if (Argument.getKind() == TemplateArgument::Pack) {
if (Argument.pack_size() && !FirstArg)
OS << Comma;
- printTo(ArgOS, Argument.getPackAsArray(), Policy, true, nullptr);
+ printTo(ArgOS, Argument.getPackAsArray(), Policy, true, TPL,
+ /*IsPack*/ true, ParmIndex);
} else {
if (!FirstArg)
OS << Comma;
// Tries to print the argument with location info if exists.
- printArgument(Arg, Policy, ArgOS);
+ printArgument(
+ Arg, Policy, ArgOS,
+ TemplateParameterList::shouldIncludeTypeForArgument(TPL, ParmIndex));
}
StringRef ArgString = ArgOS.str();
NeedSpace = Policy.SplitTemplateClosers && !ArgString.empty() &&
ArgString.back() == '>';
FirstArg = false;
+
+ // Use same template parameter for all elements of Pack
+ if (!IsPack)
+ ParmIndex++;
}
if (NeedSpace)
ArrayRef<TemplateArgument> Args,
const PrintingPolicy &Policy,
const TemplateParameterList *TPL) {
- printTo(OS, Args, Policy, false, TPL);
+ printTo(OS, Args, Policy, false, TPL, /*isPack*/ false, /*parmIndex*/ 0);
}
void clang::printTemplateArgumentList(raw_ostream &OS,
ArrayRef<TemplateArgumentLoc> Args,
const PrintingPolicy &Policy,
const TemplateParameterList *TPL) {
- printTo(OS, Args, Policy, false, TPL);
+ printTo(OS, Args, Policy, false, TPL, /*isPack*/ false, /*parmIndex*/ 0);
}
std::string Qualifiers::getAsString() const {
if (TArg.getKind() == TemplateArgument::ArgKind::Pack) {
describeTemplateParameters(Out, TArg.getPackAsArray(), LO);
} else {
- TArg.print(PrintingPolicy(LO), Out);
+ TArg.print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
}
}
}
static std::string printTemplateArgs(const PrintingPolicy &PrintingPolicy,
- TemplateArgumentListInfo &Args) {
+ TemplateArgumentListInfo &Args,
+ const TemplateParameterList *Params) {
SmallString<128> SS;
llvm::raw_svector_ostream OS(SS);
bool First = true;
+ unsigned I = 0;
for (auto &Arg : Args.arguments()) {
if (!First)
OS << ", ";
- Arg.getArgument().print(PrintingPolicy, OS);
+ Arg.getArgument().print(
+ PrintingPolicy, OS,
+ TemplateParameterList::shouldIncludeTypeForArgument(Params, I));
First = false;
+ I++;
}
return std::string(OS.str());
}
auto DiagnoseMissing = [&] {
if (DiagID)
S.Diag(Loc, DiagID) << printTemplateArgs(S.Context.getPrintingPolicy(),
- Args);
+ Args, /*Params*/ nullptr);
return true;
};
if (DiagID)
S.RequireCompleteType(
Loc, TraitTy, DiagID,
- printTemplateArgs(S.Context.getPrintingPolicy(), Args));
+ printTemplateArgs(S.Context.getPrintingPolicy(), Args,
+ TraitTD->getTemplateParameters()));
return true;
}
Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
SourceLocation Loc) override {
return S.Diag(Loc, diag::err_decomp_decl_std_tuple_size_not_constant)
- << printTemplateArgs(S.Context.getPrintingPolicy(), Args);
+ << printTemplateArgs(S.Context.getPrintingPolicy(), Args,
+ /*Params*/ nullptr);
}
} Diagnoser(R, Args);
if (!TD) {
R.suppressDiagnostics();
S.Diag(Loc, diag::err_decomp_decl_std_tuple_element_not_specialized)
- << printTemplateArgs(S.Context.getPrintingPolicy(), Args);
+ << printTemplateArgs(S.Context.getPrintingPolicy(), Args,
+ /*Params*/ nullptr);
if (!R.empty())
S.Diag(R.getRepresentativeDecl()->getLocation(), diag::note_declared_at);
return QualType();
OS << VD->getName();
if (const auto *IV = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
// This is a template variable, print the expanded template arguments.
- printTemplateArgumentList(OS, IV->getTemplateArgs().asArray(), Policy);
+ printTemplateArgumentList(
+ OS, IV->getTemplateArgs().asArray(), Policy,
+ IV->getSpecializedTemplate()->getTemplateParameters());
}
return true;
}
}
Out << " = ";
- Args[I].print(getPrintingPolicy(), Out);
+ Args[I].print(
+ getPrintingPolicy(), Out,
+ TemplateParameterList::shouldIncludeTypeForArgument(Params, I));
}
Out << ']';
llvm::raw_string_ostream OS(Buf);
OS << "'" << Concept->getName();
if (TypeLoc.hasExplicitTemplateArgs()) {
- OS << "<";
- for (const auto &Arg : Type.getTypeConstraintArguments())
- Arg.print(S.getPrintingPolicy(), OS);
- OS << ">";
+ printTemplateArgumentList(
+ OS, Type.getTypeConstraintArguments(), S.getPrintingPolicy(),
+ Type.getTypeConstraintConcept()->getTemplateParameters());
}
OS << "'";
OS.flush();
SmallString<128> TemplateArgsStr;
llvm::raw_svector_ostream OS(TemplateArgsStr);
cast<NamedDecl>(Active->Entity)->printName(OS);
- if (!isa<FunctionDecl>(Active->Entity))
+ if (!isa<FunctionDecl>(Active->Entity)) {
printTemplateArgumentList(OS, Active->template_arguments(),
getPrintingPolicy());
+ }
Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()
<< Active->InstantiationRange;
break;
clang_analyzer_dump(__PRETTY_FUNCTION__);
// expected-warning@-3 {{&Element{"func",0 S64b,char}}}
// expected-warning@-3 {{&Element{"func",0 S64b,char}}}
- // expected-warning@-3 {{&Element{"void func(U) [T = Class, Value = 42, U = char]",0 S64b,char}}}
+ // expected-warning@-3 {{&Element{"void func(U) [T = Class, Value = 42ULL, U = char]",0 S64b,char}}}
#ifdef ANALYZER_MS
clang_analyzer_dump(__FUNCDNAME__);
clang_analyzer_dump(L__FUNCSIG__);
// expected-warning@-4 {{&Element{"??$func@UClass@?1??foo@@YAXXZ@$0CK@D@@YAXD@Z",0 S64b,char}}}
// expected-warning@-4 {{&Element{L"func",0 S64b,wchar_t}}}
- // expected-warning@-4 {{&Element{"void __cdecl func(U) [T = Class, Value = 42, U = char]",0 S64b,char}}}
- // expected-warning@-4 {{&Element{L"void __cdecl func(U) [T = Class, Value = 42, U = char]",0 S64b,wchar_t}}}
+ // expected-warning@-4 {{&Element{"void __cdecl func(U) [T = Class, Value = 42ULL, U = char]",0 S64b,char}}}
+ // expected-warning@-4 {{&Element{L"void __cdecl func(U) [T = Class, Value = 42ULL, U = char]",0 S64b,wchar_t}}}
#endif
}
template<>
struct check<char32_t, 34, 1090, 1077, 1089, 1090, 32, 65536>{};
template<typename T, T... str> int operator""_x() { // #1 expected-warning {{string literal operator templates are a GNU extension}}
- check<T, str...> chars; // expected-error {{implicit instantiation of undefined template 'check<char, 't', 'e', 's', 't'>'}} expected-error {{implicit instantiation of undefined template 'check<char32_t, 34, 1090, 1077, 1089, 1090, 95, 65536>'}}
+ check<T, str...> chars; // expected-error {{implicit instantiation of undefined template 'check<char, 't', 'e', 's', 't'>'}} \
+ // expected-error {{implicit instantiation of undefined template 'check<char32_t, U'"', U'\u0442', U'\u0435', U'\u0441', U'\u0442', U'_', U'\U00010000'>'}}
return 1;
}
void *operator""_x(const char*); // #2
int d = "test"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char, 't', 'e', 's', 't'>' requested here}}
int e = uR"("тест 𐀀)"_x;
int f = UR"("тест 𐀀)"_x;
-int g = UR"("тест_𐀀)"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char32_t, 34, 1090, 1077, 1089, 1090, 95, 65536>' requested here}}
+int g = UR"("тест_𐀀)"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char32_t, U'"', U'\u0442', U'\u0435', U'\u0441', U'\u0442', U'_', U'\U00010000'>' requested here}}
--- /dev/null
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+template <typename T, T... cs> struct check; // expected-note {{template is declared here}}
+template <>
+struct check<char8_t, 34, 209, 130, 208, 181, 209, 129, 209, 130, 32, 240, 144, 128, 128> {};
+template <typename T, T... str> int operator""_x() { // #1 expected-warning {{string literal operator templates are a GNU extension}}
+ check<T, str...> chars; // expected-error {{implicit instantiation of undefined template 'check<char8_t, u8'"', u8'\xd1', u8'\x82', u8'\xd0', u8'\xb5', u8'\xd1', u8'\x81', u8'\xd1', u8'\x82', u8'_', u8'\xf0', u8'\x90', u8'\x80', u8'\x80'>'}}
+ return 1;
+}
+int a = u8"\"тест 𐀀"_x;
+int b = u8"\"тест_𐀀"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char8_t, u8'"', u8'\xd1', u8'\x82', u8'\xd0', u8'\xb5', u8'\xd1', u8'\x81', u8'\xd1', u8'\x82', u8'_', u8'\xf0', u8'\x90', u8'\x80', u8'\x80'>' requested here}}
+
+template <auto> struct C{};
+C<u8'x'>::D d; // expected-error {{no type named 'D' in 'C<u8'x'>'}}
--- /dev/null
+// RUN: %clang_cc1 -std=c++2a -verify -triple x86_64-unknown-linux %s
+
+template <typename T, T... cs> struct check; // expected-note {{template is declared here}}
+template <>
+struct check<wchar_t, 34, 1090, 1077, 1089, 1090, 32, 65536> {};
+template <typename T, T... str> int operator""_x() { // #1 expected-warning {{string literal operator templates are a GNU extension}}
+ check<T, str...> chars; // expected-error {{implicit instantiation of undefined template 'check<wchar_t, L'"', L'\u0442', L'\u0435', L'\u0441', L'\u0442', L'_', L'\U00010000'>'}}
+ return 1;
+}
+void *operator""_x(const char *); // #2
+int h = LR"("тест_𐀀)"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<wchar_t, L'"', L'\u0442', L'\u0435', L'\u0441', L'\u0442', L'_', L'\U00010000'>' requested here}}
--- /dev/null
+// RUN: %clang -g -std=c++2a -target x86_64-windows-msvc -Wno-gnu-string-literal-operator-template %s -S -emit-llvm -o - | FileCheck %s
+
+template <typename T, T... cs> struct check;
+template <typename T, T... str> int operator""_x() {
+ return 1;
+}
+
+int b = u8"\"тест_𐀀"_x;
+// CHECK: _x<char8_t,34,209,130,208,181,209,129,209,130,95,240,144,128,128>
--- /dev/null
+// RUN: %clang -std=c++11 -g -target x86_64-windows-msvc -S -emit-llvm -o - %s | FileCheck %s
+
+template <unsigned N>
+void foo() {
+}
+
+void instantiate_foo() {
+ foo<10>();
+ // CHECK: foo<10>
+ foo<true>();
+ // CHECK: foo<1>
+}
void test() {
test_templated_arguments<int, 32>(); // fine
test_templated_arguments<struct fwddecl, 16>();
- // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<fwddecl, 16, 16>'}}
+ // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<fwddecl, 16L, 16L>'}}
// expected-note@-2{{forward declaration of 'fwddecl'}}
test_templated_arguments<int, 7>(); // invalid alignment value
- // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<int, 7, 16>'}}
+ // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<int, 7L, 16L>'}}
}
template <typename T, long ArraySize>
const char *p10 = 3.300e+15_fritz;
template <class C, C...> const char *operator"" _suffix();
-// CHECK: const char *PR23120 = operator""_suffix<char32_t, 66615>();
+// CHECK: const char *PR23120 = operator""_suffix<char32_t, U'\U00010437'>();
const char *PR23120 = U"𐐷"_suffix;
// PR28885
--- /dev/null
+//RUN: %clang_cc1 -std=c++1z -verify -ast-print %s | FileCheck %s
+
+struct TypeSuffix {
+ template <long> static int x; // expected-note {{forward declaration of template entity is here}}
+ template <auto> static int y; // expected-note {{forward declaration of template entity is here}}
+};
+// CHECK: int k = TypeSuffix().x + TypeSuffix().y;
+int k = TypeSuffix().x<0L> + TypeSuffix().y<0L>; // expected-warning {{instantiation of variable 'TypeSuffix::x<0>' required here, but no definition is available}} \
+ // expected-note {{add an explicit instantiation declaration to suppress this warning if 'TypeSuffix::x<0>' is explicitly instantiated in another translation unit}} \
+ // expected-warning {{instantiation of variable 'TypeSuffix::y<0L>' required here, but no definition is available}} \
+ // expected-note {{add an explicit instantiation declaration to suppress this warning if 'TypeSuffix::y<0L>' is explicitly instantiated in another translation unit}}
MyMatrix<unsigned, 3, 3> Mat2;
Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
Mat1.value = transpose<unsigned, 2, 3, unsigned, 2, 3>(Mat1);
- // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 2, 3, unsigned int, 2, 3>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 2U, 3U, unsigned int, 2U, 3U>' requested here}}
Mat1.value = transpose<unsigned, 3, 3, unsigned, 2, 3>(Mat2);
- // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3, 3, unsigned int, 2, 3>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3U, 3U, unsigned int, 2U, 3U>' requested here}}
MyMatrix<float, 3, 3> Mat3;
Mat3.value = transpose<unsigned, 3, 3, float, 3, 3>(Mat2);
- // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3, 3, float, 3, 3>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3U, 3U, float, 3U, 3U>' requested here}}
}
template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1>
void test_column_major_loads_template(unsigned *Ptr1, float *Ptr2) {
MyMatrix<unsigned, 2, 3> Mat1;
Mat1.value = column_major_load<unsigned, 2, 3, unsigned, 2, 3>(Mat1, Ptr1);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2, 3, unsigned int, 2, 3>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2U, 3U, unsigned int, 2U, 3U>' requested here}}
column_major_load<unsigned, 2, 3, unsigned, 5, 5>(Mat1, Ptr1);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2, 3, unsigned int, 5, 5>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2U, 3U, unsigned int, 5U, 5U>' requested here}}
MyMatrix<float, 2, 3> Mat2;
Mat1.value = column_major_load<float, 2, 3, unsigned, 2, 3>(Mat2, Ptr2);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<float, 2, 3, unsigned int, 2, 3>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<float, 2U, 3U, unsigned int, 2U, 3U>' requested here}}
}
constexpr int constexpr1() { return 1; }
void test_column_major_stores_template(MyMatrix<unsigned, 2, 3> &M1, unsigned *Ptr1, MyMatrix<float, 3, 4> &M2, float *Ptr2) {
column_major_store(M1, Ptr2, 10);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2, 3, float *>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2U, 3U, float *>' requested here}}
column_major_store<decltype(M2), float *, 1>(M2, Ptr2);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<MyMatrix<float, 3, 4> &, float *, 1>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<MyMatrix<float, 3, 4> &, float *, 1U>' requested here}}
}
template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1>
void test_column_major_store_template(unsigned *Ptr1, float *Ptr2) {
MyMatrix<unsigned, 2, 3> Mat1;
column_major_store<unsigned, 2, 3, unsigned>(Mat1, Ptr1);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2, 3, unsigned int>'}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2U, 3U, unsigned int>'}}
column_major_store<unsigned, 2, 3, float>(Mat1, Ptr2);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2, 3, float>'}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2U, 3U, float>'}}
MyMatrix<float, 2, 3> Mat2;
column_major_store<float, 2, 3, unsigned>(Mat2, Ptr1);
- // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<float, 2, 3, unsigned int>'}}
+ // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<float, 2U, 3U, unsigned int>'}}
}
void test_column_major_store_constexpr(unsigned *Ptr, MyMatrix<unsigned, 3, 3> &M) {
Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
unsigned v1 = add<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
// expected-error@-1 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
- // expected-note@-2 {{in instantiation of function template specialization 'add<unsigned int, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+ // expected-note@-2 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
Mat1.value = add<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2);
- // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 2, 2, unsigned int, 3, 3, unsigned int, 2, 2>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
Mat1.value = add<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3);
- // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 3, 3, float, 2, 2, unsigned int, 2, 2>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
}
template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
unsigned v1 = subtract<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
// expected-error@-1 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
- // expected-note@-2 {{in instantiation of function template specialization 'subtract<unsigned int, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+ // expected-note@-2 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
Mat1.value = subtract<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2);
- // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 2, 2, unsigned int, 3, 3, unsigned int, 2, 2>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
Mat1.value = subtract<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3);
- // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 3, 3, float, 2, 2, unsigned int, 2, 2>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
}
template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
MyMatrix<float, 2, 2> Mat3;
Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
unsigned v1 = multiply<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
- // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
// expected-error@-2 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
MyMatrix<unsigned, 3, 2> Mat4;
Mat1.value = multiply<unsigned, 3, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat4, Mat2);
- // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 3, 2, unsigned int, 3, 3, unsigned int, 2, 2>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 3U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
Mat1.value = multiply<float, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat3, Mat1);
- // expected-note@-1 {{in instantiation of function template specialization 'multiply<float, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+ // expected-note@-1 {{in instantiation of function template specialization 'multiply<float, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
Mat4.value = Mat4.value * Mat1;
// expected-error@-1 {{no viable conversion from 'MyMatrix<unsigned int, 2, 2>' to 'unsigned int'}}
HasASTemplateFields<1> HASTF;
neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
correct<0x7FFFED>();
- tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650>' requested here}}
+ tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
__attribute__((address_space(1))) char *x;
__attribute__((address_space(2))) char *y;
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -ast-print %s | FileCheck %s
+
+template <typename T, typename U = double> class Foo;
+
+template <> class Foo<int, double> { int method1(); };
+
+using int_type = int;
+
+int Foo<int_type, double>::method1() {
+ // CHECK: int Foo<int_type, double>::method1()
+ return 10;
+}
public:
template <unsigned N>
string(const char (&str)[N])
- : string(str) {} // expected-error{{constructor for 'string<6>' creates a delegation cycle}}
+ : string(str) {} // expected-error{{constructor for 'string<6U>' creates a delegation cycle}}
};
void f() {
void instantiate_template_3() {
matrix_template_3<1, 10>();
- matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0, 10>' requested here}}
+ matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0U, 10U>' requested here}}
}
template <int Rows, unsigned Cols>
void instantiate_template_4() {
matrix_template_4<2, 10>();
- matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10>' requested here}}
+ matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10U>' requested here}}
}
template <class T, unsigned long R, unsigned long C>
NamedEnumNS::foo<Val0>();
// CHECK: template<> void foo<NamedEnumNS::Val1>()
NamedEnumNS::foo<(NamedEnum)1>();
- // CHECK: template<> void foo<2>()
+ // CHECK: template<> void foo<(NamedEnumNS::NamedEnum)2>()
NamedEnumNS::foo<(NamedEnum)2>();
}
void test_char_possibly_negative() { enable_if_char<'\x02'>::type i; } // expected-error{{enable_if_char<'\x02'>'; did you mean 'enable_if_char<'a'>::type'?}}
void test_char_single_quote() { enable_if_char<'\''>::type i; } // expected-error{{enable_if_char<'\''>'; did you mean 'enable_if_char<'a'>::type'?}}
void test_char_backslash() { enable_if_char<'\\'>::type i; } // expected-error{{enable_if_char<'\\'>'; did you mean 'enable_if_char<'a'>::type'?}}
+
+ template <int N> struct enable_if_int {};
+ template <> struct enable_if_int<1> { typedef int type; }; // expected-note{{'enable_if_int<1>::type' declared here}}
+ void test_int() { enable_if_int<2>::type i; } // expected-error{{enable_if_int<2>'; did you mean 'enable_if_int<1>::type'?}}
+
+ template <unsigned int N> struct enable_if_unsigned_int {};
+ template <> struct enable_if_unsigned_int<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_int<1>::type' declared here}}
+ void test_unsigned_int() { enable_if_unsigned_int<2>::type i; } // expected-error{{enable_if_unsigned_int<2>'; did you mean 'enable_if_unsigned_int<1>::type'?}}
+
+ template <unsigned long long N> struct enable_if_unsigned_long_long {};
+ template <> struct enable_if_unsigned_long_long<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_long_long<1>::type' declared here}}
+ void test_unsigned_long_long() { enable_if_unsigned_long_long<2>::type i; } // expected-error{{enable_if_unsigned_long_long<2>'; did you mean 'enable_if_unsigned_long_long<1>::type'?}}
+
+ template <long long N> struct enable_if_long_long {};
+ template <> struct enable_if_long_long<1> { typedef int type; }; // expected-note{{'enable_if_long_long<1>::type' declared here}}
+ void test_long_long() { enable_if_long_long<2>::type i; } // expected-error{{enable_if_long_long<2>'; did you mean 'enable_if_long_long<1>::type'?}}
+
}
namespace PR10579 {
x1.f(x2);
}
}
+
+namespace TypeSuffix {
+ template <auto N> struct A {};
+ template <> struct A<1> { using type = int; }; // expected-note {{'A<1>::type' declared here}}
+ A<1L>::type a; // expected-error {{no type named 'type' in 'TypeSuffix::A<1L>'; did you mean 'A<1>::type'?}}
+
+ template <auto N> struct B {};
+ template <> struct B<1> { using type = int; }; // expected-note {{'B<1>::type' declared here}}
+ B<2>::type b; // expected-error {{no type named 'type' in 'TypeSuffix::B<2>'; did you mean 'B<1>::type'?}}
+
+ template <auto N> struct C {};
+ template <> struct C<'a'> { using type = signed char; }; // expected-note {{'C<'a'>::type' declared here}}
+ C<(signed char)'a'>::type c; // expected-error {{no type named 'type' in 'TypeSuffix::C<(signed char)'a'>'; did you mean 'C<'a'>::type'?}}
+
+ template <auto N> struct D {};
+ template <> struct D<'a'> { using type = signed char; }; // expected-note {{'D<'a'>::type' declared here}}
+ D<'b'>::type d; // expected-error {{no type named 'type' in 'TypeSuffix::D<'b'>'; did you mean 'D<'a'>::type'?}}
+
+ template <auto N> struct E {};
+ template <> struct E<'a'> { using type = unsigned char; }; // expected-note {{'E<'a'>::type' declared here}}
+ E<(unsigned char)'a'>::type e; // expected-error {{no type named 'type' in 'TypeSuffix::E<(unsigned char)'a'>'; did you mean 'E<'a'>::type'?}}
+
+ template <auto N> struct F {};
+ template <> struct F<'a'> { using type = unsigned char; }; // expected-note {{'F<'a'>::type' declared here}}
+ F<'b'>::type f; // expected-error {{no type named 'type' in 'TypeSuffix::F<'b'>'; did you mean 'F<'a'>::type'?}}
+
+ template <auto... N> struct X {};
+ X<1, 1u>::type y; // expected-error {{no type named 'type' in 'TypeSuffix::X<1, 1U>'}}
+ X<1, 1>::type z; // expected-error {{no type named 'type' in 'TypeSuffix::X<1, 1>'}}
+}
SmallString<128> Str;
llvm::raw_svector_ostream OS(Str);
OS << *ClassSpec;
- printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
- Policy);
+ printTemplateArgumentList(
+ OS, ClassSpec->getTemplateArgs().asArray(), Policy,
+ ClassSpec->getSpecializedTemplate()->getTemplateParameters());
return cxstring::createDup(OS.str());
}
llvm::raw_string_ostream Stream(ArgStr);
const TemplateArgument &Arg = ArgLoc.getArgument();
- Arg.print(Context->getPrintingPolicy(), Stream);
+ Arg.print(Context->getPrintingPolicy(), Stream, /*IncludeType*/ true);
Match(Stream.str(), ArgLoc.getLocation());
return ExpectedLocationVisitor<TemplateArgumentLocTraverser>::
TraverseTemplateArgumentLoc(ArgLoc);