@@ -6626,10 +6626,12 @@ class FreeFunctionPrinter {
6626
6626
raw_ostream &O;
6627
6627
PrintingPolicy &Policy;
6628
6628
bool NSInserted = false ;
6629
+ ASTContext &Context;
6629
6630
6630
6631
public:
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) {}
6633
6635
6634
6636
// / Emits the function declaration of template free function.
6635
6637
// / \param FTD The function declaration to print.
@@ -6826,18 +6828,42 @@ class FreeFunctionPrinter {
6826
6828
CTN.getAsTemplateDecl ()->printQualifiedName (ParmListOstream);
6827
6829
ParmListOstream << " <" ;
6828
6830
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
+ };
6831
6858
6832
6859
for (size_t I = 0 , E = std::max (DeclArgs.size (), SpecArgs.size ()),
6833
6860
SE = SpecArgs.size ();
6834
6861
I < E; ++I) {
6835
6862
if (I != 0 )
6836
6863
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]);
6841
6867
}
6842
6868
6843
6869
ParmListOstream << " >" ;
@@ -7236,7 +7262,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
7236
7262
// template arguments that match default template arguments while printing
7237
7263
// template-ids, even if the source code doesn't reference them.
7238
7264
Policy.EnforceDefaultTemplateArgs = true ;
7239
- FreeFunctionPrinter FFPrinter (O, Policy);
7265
+ FreeFunctionPrinter FFPrinter (O, Policy, S. getASTContext () );
7240
7266
if (FTD) {
7241
7267
FFPrinter.printFreeFunctionDeclaration (FTD);
7242
7268
if (const auto kind = K.SyclKernel ->getTemplateSpecializationKind ();
0 commit comments