@@ -6597,10 +6597,12 @@ class FreeFunctionPrinter {
65976597 raw_ostream &O;
65986598 PrintingPolicy &Policy;
65996599 bool NSInserted = false ;
6600+ ASTContext &Context;
66006601
66016602public:
6602- FreeFunctionPrinter (raw_ostream &O, PrintingPolicy &PrintPolicy)
6603- : O(O), Policy(PrintPolicy) {}
6603+ FreeFunctionPrinter (raw_ostream &O, PrintingPolicy &PrintPolicy,
6604+ ASTContext &Context)
6605+ : O(O), Policy(PrintPolicy), Context(Context) {}
66046606
66056607 // / Emits the function declaration of template free function.
66066608 // / \param FTD The function declaration to print.
@@ -6797,18 +6799,42 @@ class FreeFunctionPrinter {
67976799 CTN.getAsTemplateDecl ()->printQualifiedName (ParmListOstream);
67986800 ParmListOstream << " <" ;
67996801
6800- auto SpecArgs = TST->template_arguments ();
6801- auto DeclArgs = CTST->template_arguments ();
6802+ ArrayRef<TemplateArgument> SpecArgs = TST->template_arguments ();
6803+ ArrayRef<TemplateArgument> DeclArgs = CTST->template_arguments ();
6804+
6805+ auto TemplateArgPrinter = [&](const TemplateArgument &Arg) {
6806+ if (Arg.getKind () != TemplateArgument::ArgKind::Expression ||
6807+ Arg.isInstantiationDependent ()) {
6808+ Arg.print (Policy, ParmListOstream, /* IncludeType = */ false );
6809+ return ;
6810+ }
6811+
6812+ Expr *E = Arg.getAsExpr ();
6813+ assert (E && " Failed to get an Expr for an Expression template arg?" );
6814+ if (E->getType ().getTypePtr ()->isScopedEnumeralType ()) {
6815+ // Scoped enumerations can't be implicitly cast from integers, so
6816+ // we don't need to evaluate them.
6817+ Arg.print (Policy, ParmListOstream, /* IncludeType = */ false );
6818+ return ;
6819+ }
6820+
6821+ Expr::EvalResult Res;
6822+ [[maybe_unused]] bool Success =
6823+ Arg.getAsExpr ()->EvaluateAsConstantExpr (Res, Context);
6824+ assert (Success && " invalid non-type template argument?" );
6825+ assert (!Res.Val .isAbsent () && " couldn't read the evaulation result?" );
6826+ Res.Val .printPretty (ParmListOstream, Policy, Arg.getAsExpr ()->getType (),
6827+ &Context);
6828+ };
68026829
68036830 for (size_t I = 0 , E = std::max (DeclArgs.size (), SpecArgs.size ()),
68046831 SE = SpecArgs.size ();
68056832 I < E; ++I) {
68066833 if (I != 0 )
68076834 ParmListOstream << " , " ;
6808- if (I < SE) // A specialized argument exists, use it
6809- SpecArgs[I].print (Policy, ParmListOstream, false /* IncludeType */ );
6810- else // Print a canonical form of a default argument
6811- DeclArgs[I].print (Policy, ParmListOstream, false /* IncludeType */ );
6835+ // If we have a specialized argument, use it. Otherwise fallback to a
6836+ // default argument.
6837+ TemplateArgPrinter (I < SE ? SpecArgs[I] : DeclArgs[I]);
68126838 }
68136839
68146840 ParmListOstream << " >" ;
@@ -7207,7 +7233,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
72077233 // template arguments that match default template arguments while printing
72087234 // template-ids, even if the source code doesn't reference them.
72097235 Policy.EnforceDefaultTemplateArgs = true ;
7210- FreeFunctionPrinter FFPrinter (O, Policy);
7236+ FreeFunctionPrinter FFPrinter (O, Policy, S. getASTContext () );
72117237 if (FTD) {
72127238 FFPrinter.printFreeFunctionDeclaration (FTD);
72137239 if (const auto kind = K.SyclKernel ->getTemplateSpecializationKind ();
0 commit comments