@@ -6626,10 +6626,12 @@ class FreeFunctionPrinter {
66266626 raw_ostream &O;
66276627 PrintingPolicy &Policy;
66286628 bool NSInserted = false ;
6629+ ASTContext &Context;
66296630
66306631public:
6631- FreeFunctionPrinter (raw_ostream &O, PrintingPolicy &PrintPolicy)
6632- : O(O), Policy(PrintPolicy) {}
6632+ FreeFunctionPrinter (raw_ostream &O, PrintingPolicy &PrintPolicy,
6633+ ASTContext &Context)
6634+ : O(O), Policy(PrintPolicy), Context(Context) {}
66336635
66346636 // / Emits the function declaration of template free function.
66356637 // / \param FTD The function declaration to print.
@@ -6826,18 +6828,42 @@ class FreeFunctionPrinter {
68266828 CTN.getAsTemplateDecl ()->printQualifiedName (ParmListOstream);
68276829 ParmListOstream << " <" ;
68286830
6829- auto SpecArgs = TST->template_arguments ();
6830- auto DeclArgs = CTST->template_arguments ();
6831+ ArrayRef<TemplateArgument> SpecArgs = TST->template_arguments ();
6832+ ArrayRef<TemplateArgument> DeclArgs = CTST->template_arguments ();
6833+
6834+ auto TemplateArgPrinter = [&](const TemplateArgument &Arg) {
6835+ if (Arg.getKind () != TemplateArgument::ArgKind::Expression ||
6836+ Arg.isInstantiationDependent ()) {
6837+ Arg.print (Policy, ParmListOstream, /* IncludeType = */ false );
6838+ return ;
6839+ }
6840+
6841+ Expr *E = Arg.getAsExpr ();
6842+ assert (E && " Failed to get an Expr for an Expression template arg?" );
6843+ if (E->getType ().getTypePtr ()->isScopedEnumeralType ()) {
6844+ // Scoped enumerations can't be implicitly cast from integers, so
6845+ // we don't need to evaluate them.
6846+ Arg.print (Policy, ParmListOstream, /* IncludeType = */ false );
6847+ return ;
6848+ }
6849+
6850+ Expr::EvalResult Res;
6851+ [[maybe_unused]] bool Success =
6852+ Arg.getAsExpr ()->EvaluateAsConstantExpr (Res, Context);
6853+ assert (Success && " invalid non-type template argument?" );
6854+ assert (!Res.Val .isAbsent () && " couldn't read the evaulation result?" );
6855+ Res.Val .printPretty (ParmListOstream, Policy, Arg.getAsExpr ()->getType (),
6856+ &Context);
6857+ };
68316858
68326859 for (size_t I = 0 , E = std::max (DeclArgs.size (), SpecArgs.size ()),
68336860 SE = SpecArgs.size ();
68346861 I < E; ++I) {
68356862 if (I != 0 )
68366863 ParmListOstream << " , " ;
6837- if (I < SE) // A specialized argument exists, use it
6838- SpecArgs[I].print (Policy, ParmListOstream, false /* IncludeType */ );
6839- else // Print a canonical form of a default argument
6840- DeclArgs[I].print (Policy, ParmListOstream, false /* IncludeType */ );
6864+ // If we have a specialized argument, use it. Otherwise fallback to a
6865+ // default argument.
6866+ TemplateArgPrinter (I < SE ? SpecArgs[I] : DeclArgs[I]);
68416867 }
68426868
68436869 ParmListOstream << " >" ;
@@ -7236,7 +7262,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
72367262 // template arguments that match default template arguments while printing
72377263 // template-ids, even if the source code doesn't reference them.
72387264 Policy.EnforceDefaultTemplateArgs = true ;
7239- FreeFunctionPrinter FFPrinter (O, Policy);
7265+ FreeFunctionPrinter FFPrinter (O, Policy, S. getASTContext () );
72407266 if (FTD) {
72417267 FFPrinter.printFreeFunctionDeclaration (FTD);
72427268 if (const auto kind = K.SyclKernel ->getTemplateSpecializationKind ();
0 commit comments