@@ -348,6 +348,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
348
348
case ' r' :
349
349
if (isFreeBSDKPrintf)
350
350
k = ConversionSpecifier::FreeBSDrArg; // int
351
+ else if (LO.FixedPoint )
352
+ k = ConversionSpecifier::rArg;
351
353
break ;
352
354
case ' y' :
353
355
if (isFreeBSDKPrintf)
@@ -373,6 +375,20 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
373
375
if (Target.getTriple ().isOSMSVCRT ())
374
376
k = ConversionSpecifier::ZArg;
375
377
break ;
378
+ // ISO/IEC TR 18037 (fixed-point) specific.
379
+ // NOTE: 'r' is handled up above since FreeBSD also supports %r.
380
+ case ' k' :
381
+ if (LO.FixedPoint )
382
+ k = ConversionSpecifier::kArg ;
383
+ break ;
384
+ case ' K' :
385
+ if (LO.FixedPoint )
386
+ k = ConversionSpecifier::KArg;
387
+ break ;
388
+ case ' R' :
389
+ if (LO.FixedPoint )
390
+ k = ConversionSpecifier::RArg;
391
+ break ;
376
392
}
377
393
378
394
// Check to see if we used the Objective-C modifier flags with
@@ -627,6 +643,9 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
627
643
}
628
644
}
629
645
646
+ if (CS.isFixedPointArg () && !Ctx.getLangOpts ().FixedPoint )
647
+ return ArgType::Invalid ();
648
+
630
649
switch (CS.getKind ()) {
631
650
case ConversionSpecifier::sArg :
632
651
if (LM.getKind () == LengthModifier::AsWideChar) {
@@ -658,6 +677,50 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
658
677
return ArgType::CPointerTy;
659
678
case ConversionSpecifier::ObjCObjArg:
660
679
return ArgType::ObjCPointerTy;
680
+ case ConversionSpecifier::kArg :
681
+ switch (LM.getKind ()) {
682
+ case LengthModifier::None:
683
+ return Ctx.AccumTy ;
684
+ case LengthModifier::AsShort:
685
+ return Ctx.ShortAccumTy ;
686
+ case LengthModifier::AsLong:
687
+ return Ctx.LongAccumTy ;
688
+ default :
689
+ return ArgType::Invalid ();
690
+ }
691
+ case ConversionSpecifier::KArg:
692
+ switch (LM.getKind ()) {
693
+ case LengthModifier::None:
694
+ return Ctx.UnsignedAccumTy ;
695
+ case LengthModifier::AsShort:
696
+ return Ctx.UnsignedShortAccumTy ;
697
+ case LengthModifier::AsLong:
698
+ return Ctx.UnsignedLongAccumTy ;
699
+ default :
700
+ return ArgType::Invalid ();
701
+ }
702
+ case ConversionSpecifier::rArg:
703
+ switch (LM.getKind ()) {
704
+ case LengthModifier::None:
705
+ return Ctx.FractTy ;
706
+ case LengthModifier::AsShort:
707
+ return Ctx.ShortFractTy ;
708
+ case LengthModifier::AsLong:
709
+ return Ctx.LongFractTy ;
710
+ default :
711
+ return ArgType::Invalid ();
712
+ }
713
+ case ConversionSpecifier::RArg:
714
+ switch (LM.getKind ()) {
715
+ case LengthModifier::None:
716
+ return Ctx.UnsignedFractTy ;
717
+ case LengthModifier::AsShort:
718
+ return Ctx.UnsignedShortFractTy ;
719
+ case LengthModifier::AsLong:
720
+ return Ctx.UnsignedLongFractTy ;
721
+ default :
722
+ return ArgType::Invalid ();
723
+ }
661
724
default :
662
725
break ;
663
726
}
@@ -955,6 +1018,8 @@ bool PrintfSpecifier::hasValidPlusPrefix() const {
955
1018
case ConversionSpecifier::AArg:
956
1019
case ConversionSpecifier::FreeBSDrArg:
957
1020
case ConversionSpecifier::FreeBSDyArg:
1021
+ case ConversionSpecifier::rArg:
1022
+ case ConversionSpecifier::kArg :
958
1023
return true ;
959
1024
960
1025
default :
@@ -966,7 +1031,7 @@ bool PrintfSpecifier::hasValidAlternativeForm() const {
966
1031
if (!HasAlternativeForm)
967
1032
return true ;
968
1033
969
- // Alternate form flag only valid with the bBoxXaAeEfFgG conversions
1034
+ // Alternate form flag only valid with the bBoxXaAeEfFgGrRkK conversions
970
1035
switch (CS.getKind ()) {
971
1036
case ConversionSpecifier::bArg:
972
1037
case ConversionSpecifier::BArg:
@@ -984,6 +1049,10 @@ bool PrintfSpecifier::hasValidAlternativeForm() const {
984
1049
case ConversionSpecifier::GArg:
985
1050
case ConversionSpecifier::FreeBSDrArg:
986
1051
case ConversionSpecifier::FreeBSDyArg:
1052
+ case ConversionSpecifier::rArg:
1053
+ case ConversionSpecifier::RArg:
1054
+ case ConversionSpecifier::kArg :
1055
+ case ConversionSpecifier::KArg:
987
1056
return true ;
988
1057
989
1058
default :
@@ -995,7 +1064,7 @@ bool PrintfSpecifier::hasValidLeadingZeros() const {
995
1064
if (!HasLeadingZeroes)
996
1065
return true ;
997
1066
998
- // Leading zeroes flag only valid with the bBdiouxXaAeEfFgG conversions
1067
+ // Leading zeroes flag only valid with the bBdiouxXaAeEfFgGrRkK conversions
999
1068
switch (CS.getKind ()) {
1000
1069
case ConversionSpecifier::bArg:
1001
1070
case ConversionSpecifier::BArg:
@@ -1018,6 +1087,10 @@ bool PrintfSpecifier::hasValidLeadingZeros() const {
1018
1087
case ConversionSpecifier::GArg:
1019
1088
case ConversionSpecifier::FreeBSDrArg:
1020
1089
case ConversionSpecifier::FreeBSDyArg:
1090
+ case ConversionSpecifier::rArg:
1091
+ case ConversionSpecifier::RArg:
1092
+ case ConversionSpecifier::kArg :
1093
+ case ConversionSpecifier::KArg:
1021
1094
return true ;
1022
1095
1023
1096
default :
@@ -1044,6 +1117,8 @@ bool PrintfSpecifier::hasValidSpacePrefix() const {
1044
1117
case ConversionSpecifier::AArg:
1045
1118
case ConversionSpecifier::FreeBSDrArg:
1046
1119
case ConversionSpecifier::FreeBSDyArg:
1120
+ case ConversionSpecifier::rArg:
1121
+ case ConversionSpecifier::kArg :
1047
1122
return true ;
1048
1123
1049
1124
default :
@@ -1089,7 +1164,7 @@ bool PrintfSpecifier::hasValidPrecision() const {
1089
1164
if (Precision.getHowSpecified () == OptionalAmount::NotSpecified)
1090
1165
return true ;
1091
1166
1092
- // Precision is only valid with the bBdiouxXaAeEfFgGsP conversions
1167
+ // Precision is only valid with the bBdiouxXaAeEfFgGsPrRkK conversions
1093
1168
switch (CS.getKind ()) {
1094
1169
case ConversionSpecifier::bArg:
1095
1170
case ConversionSpecifier::BArg:
@@ -1114,6 +1189,10 @@ bool PrintfSpecifier::hasValidPrecision() const {
1114
1189
case ConversionSpecifier::FreeBSDrArg:
1115
1190
case ConversionSpecifier::FreeBSDyArg:
1116
1191
case ConversionSpecifier::PArg:
1192
+ case ConversionSpecifier::rArg:
1193
+ case ConversionSpecifier::RArg:
1194
+ case ConversionSpecifier::kArg :
1195
+ case ConversionSpecifier::KArg:
1117
1196
return true ;
1118
1197
1119
1198
default :
0 commit comments