1 //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Handling of format string in printf and friends. The structure of format
11 // strings for fprintf() are described in C99 7.19.6.1.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Analysis/Analyses/FormatString.h"
16 #include "FormatStringParsing.h"
17 #include "clang/Basic/TargetInfo.h"
19 using clang::analyze_format_string::ArgType;
20 using clang::analyze_format_string::FormatStringHandler;
21 using clang::analyze_format_string::LengthModifier;
22 using clang::analyze_format_string::OptionalAmount;
23 using clang::analyze_format_string::ConversionSpecifier;
24 using clang::analyze_printf::PrintfSpecifier;
26 using namespace clang;
28 typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
29 PrintfSpecifierResult;
31 //===----------------------------------------------------------------------===//
32 // Methods for parsing format strings.
33 //===----------------------------------------------------------------------===//
35 using analyze_format_string::ParseNonPositionAmount;
37 static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
38 const char *Start, const char *&Beg, const char *E,
41 FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
43 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
44 analyze_format_string::PrecisionPos);
52 static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS,
53 const char *FlagBeg, const char *E, bool Warn) {
54 StringRef Flag(FlagBeg, E - FlagBeg);
55 // Currently there is only one flag.
57 FS.setHasObjCTechnicalTerm(FlagBeg);
60 // Handle either the case of no flag or an invalid flag.
63 H.HandleEmptyObjCModifierFlag(FlagBeg, E - FlagBeg);
65 H.HandleInvalidObjCModifierFlag(FlagBeg, E - FlagBeg);
70 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
74 const LangOptions &LO,
75 const TargetInfo &Target,
77 bool isFreeBSDKPrintf) {
79 using namespace clang::analyze_format_string;
80 using namespace clang::analyze_printf;
83 const char *Start = nullptr;
84 UpdateOnReturn <const char*> UpdateBeg(Beg, I);
86 // Look for a '%' character that indicates the start of a format specifier.
87 for ( ; I != E ; ++I) {
90 // Detect spurious null characters, which are likely errors.
95 Start = I++; // Record the start of the format specifier.
100 // No format specifier found?
105 // No more characters left?
107 H.HandleIncompleteSpecifier(Start, E - Start);
112 if (ParseArgPosition(H, FS, Start, I, E))
116 // No more characters left?
118 H.HandleIncompleteSpecifier(Start, E - Start);
122 const char *OSLogVisibilityFlagsStart = nullptr,
123 *OSLogVisibilityFlagsEnd = nullptr;
125 OSLogVisibilityFlagsStart = I++;
126 // Find the end of the modifier.
127 while (I != E && *I != '}') {
132 H.HandleIncompleteSpecifier(Start, E - Start);
136 OSLogVisibilityFlagsEnd = I++;
138 // Just see if 'private' or 'public' is the first word. os_log itself will
139 // do any further parsing.
140 const char *P = OSLogVisibilityFlagsStart + 1;
141 while (P < OSLogVisibilityFlagsEnd && isspace(*P))
143 const char *WordStart = P;
144 while (P < OSLogVisibilityFlagsEnd && (isalnum(*P) || *P == '_'))
146 const char *WordEnd = P;
147 StringRef Word(WordStart, WordEnd - WordStart);
148 if (Word == "private") {
149 FS.setIsPrivate(WordStart);
150 } else if (Word == "public") {
151 FS.setIsPublic(WordStart);
155 // Look for flags (if any).
157 for ( ; I != E; ++I) {
159 default: hasMore = false; break;
161 // FIXME: POSIX specific. Always accept?
162 FS.setHasThousandsGrouping(I);
164 case '-': FS.setIsLeftJustified(I); break;
165 case '+': FS.setHasPlusPrefix(I); break;
166 case ' ': FS.setHasSpacePrefix(I); break;
167 case '#': FS.setHasAlternativeForm(I); break;
168 case '0': FS.setHasLeadingZeros(I); break;
175 // No more characters left?
177 H.HandleIncompleteSpecifier(Start, E - Start);
181 // Look for the field width (if any).
182 if (ParseFieldWidth(H, FS, Start, I, E,
183 FS.usesPositionalArg() ? nullptr : &argIndex))
187 // No more characters left?
189 H.HandleIncompleteSpecifier(Start, E - Start);
193 // Look for the precision (if any).
198 H.HandleIncompleteSpecifier(Start, E - Start);
202 if (ParsePrecision(H, FS, Start, I, E,
203 FS.usesPositionalArg() ? nullptr : &argIndex))
207 // No more characters left?
209 H.HandleIncompleteSpecifier(Start, E - Start);
214 // Look for the length modifier.
215 if (ParseLengthModifier(FS, I, E, LO) && I == E) {
216 // No more characters left?
218 H.HandleIncompleteSpecifier(Start, E - Start);
222 // Look for the Objective-C modifier flags, if any.
223 // We parse these here, even if they don't apply to
224 // the conversion specifier, and then emit an error
225 // later if the conversion specifier isn't '@'. This
226 // enables better recovery, and we don't know if
227 // these flags are applicable until later.
228 const char *ObjCModifierFlagsStart = nullptr,
229 *ObjCModifierFlagsEnd = nullptr;
231 ObjCModifierFlagsStart = I;
235 ObjCModifierFlagsEnd = I;
238 H.HandleIncompleteSpecifier(Start, E - Start);
241 // Did we find the closing ']'?
243 if (ParseObjCFlags(H, FS, flagStart, I, Warn))
248 // There are no separators defined yet for multiple
249 // Objective-C modifier flags. When those are
250 // defined, this is the place to check.
255 // Detect spurious null characters, which are likely errors.
260 // Finally, look for the conversion specifier.
261 const char *conversionPosition = I++;
262 ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
263 switch (*conversionPosition) {
266 // C99: 7.19.6.1 (section 8).
267 case '%': k = ConversionSpecifier::PercentArg; break;
268 case 'A': k = ConversionSpecifier::AArg; break;
269 case 'E': k = ConversionSpecifier::EArg; break;
270 case 'F': k = ConversionSpecifier::FArg; break;
271 case 'G': k = ConversionSpecifier::GArg; break;
272 case 'X': k = ConversionSpecifier::XArg; break;
273 case 'a': k = ConversionSpecifier::aArg; break;
274 case 'c': k = ConversionSpecifier::cArg; break;
275 case 'd': k = ConversionSpecifier::dArg; break;
276 case 'e': k = ConversionSpecifier::eArg; break;
277 case 'f': k = ConversionSpecifier::fArg; break;
278 case 'g': k = ConversionSpecifier::gArg; break;
279 case 'i': k = ConversionSpecifier::iArg; break;
280 case 'n': k = ConversionSpecifier::nArg; break;
281 case 'o': k = ConversionSpecifier::oArg; break;
282 case 'p': k = ConversionSpecifier::pArg; break;
283 case 's': k = ConversionSpecifier::sArg; break;
284 case 'u': k = ConversionSpecifier::uArg; break;
285 case 'x': k = ConversionSpecifier::xArg; break;
287 case 'C': k = ConversionSpecifier::CArg; break;
288 case 'S': k = ConversionSpecifier::SArg; break;
289 // Apple extension for os_log
291 k = ConversionSpecifier::PArg;
294 case '@': k = ConversionSpecifier::ObjCObjArg; break;
296 case 'm': k = ConversionSpecifier::PrintErrno; break;
297 // FreeBSD kernel specific.
299 if (isFreeBSDKPrintf)
300 k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
303 if (isFreeBSDKPrintf)
304 k = ConversionSpecifier::FreeBSDrArg; // int
307 if (isFreeBSDKPrintf)
308 k = ConversionSpecifier::FreeBSDyArg; // int
312 if (isFreeBSDKPrintf)
313 k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
314 else if (Target.getTriple().isOSDarwin())
315 k = ConversionSpecifier::DArg;
318 if (Target.getTriple().isOSDarwin())
319 k = ConversionSpecifier::OArg;
322 if (Target.getTriple().isOSDarwin())
323 k = ConversionSpecifier::UArg;
327 if (Target.getTriple().isOSMSVCRT())
328 k = ConversionSpecifier::ZArg;
331 // Check to see if we used the Objective-C modifier flags with
332 // a conversion specifier other than '@'.
333 if (k != ConversionSpecifier::ObjCObjArg &&
334 k != ConversionSpecifier::InvalidSpecifier &&
335 ObjCModifierFlagsStart) {
336 H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
337 ObjCModifierFlagsEnd + 1,
342 PrintfConversionSpecifier CS(conversionPosition, k);
343 FS.setConversionSpecifier(CS);
344 if (CS.consumesDataArgument() && !FS.usesPositionalArg())
345 FS.setArgIndex(argIndex++);
346 // FreeBSD kernel specific.
347 if (k == ConversionSpecifier::FreeBSDbArg ||
348 k == ConversionSpecifier::FreeBSDDArg)
351 if (k == ConversionSpecifier::InvalidSpecifier) {
352 unsigned Len = I - Start;
353 if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
354 CS.setEndScanList(Start + Len);
355 FS.setConversionSpecifier(CS);
357 // Assume the conversion takes one argument.
358 return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
360 return PrintfSpecifierResult(Start, FS);
363 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
366 const LangOptions &LO,
367 const TargetInfo &Target,
368 bool isFreeBSDKPrintf) {
370 unsigned argIndex = 0;
372 // Keep looking for a format specifier until we have exhausted the string.
374 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
377 // Did a fail-stop error of any kind occur when parsing the specifier?
378 // If so, don't do any more processing.
379 if (FSR.shouldStop())
381 // Did we exhaust the string or encounter an error that
382 // we can recover from?
385 // We have a format specifier. Pass it to the callback.
386 if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
390 assert(I == E && "Format string not exhausted");
394 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
396 const LangOptions &LO,
397 const TargetInfo &Target) {
399 unsigned argIndex = 0;
401 // Keep looking for a %s format specifier until we have exhausted the string.
402 FormatStringHandler H;
404 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
407 // Did a fail-stop error of any kind occur when parsing the specifier?
408 // If so, don't do any more processing.
409 if (FSR.shouldStop())
411 // Did we exhaust the string or encounter an error that
412 // we can recover from?
415 const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
416 // Return true if this a %s format specifier.
417 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
423 //===----------------------------------------------------------------------===//
424 // Methods on PrintfSpecifier.
425 //===----------------------------------------------------------------------===//
427 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
428 bool IsObjCLiteral) const {
429 const PrintfConversionSpecifier &CS = getConversionSpecifier();
431 if (!CS.consumesDataArgument())
432 return ArgType::Invalid();
434 if (CS.getKind() == ConversionSpecifier::cArg)
435 switch (LM.getKind()) {
436 case LengthModifier::None:
438 case LengthModifier::AsLong:
439 case LengthModifier::AsWide:
440 return ArgType(ArgType::WIntTy, "wint_t");
441 case LengthModifier::AsShort:
442 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
446 return ArgType::Invalid();
450 switch (LM.getKind()) {
451 case LengthModifier::AsLongDouble:
453 return Ctx.LongLongTy;
454 case LengthModifier::None:
456 case LengthModifier::AsInt32:
457 return ArgType(Ctx.IntTy, "__int32");
458 case LengthModifier::AsChar: return ArgType::AnyCharTy;
459 case LengthModifier::AsShort: return Ctx.ShortTy;
460 case LengthModifier::AsLong: return Ctx.LongTy;
461 case LengthModifier::AsLongLong:
462 case LengthModifier::AsQuad:
463 return Ctx.LongLongTy;
464 case LengthModifier::AsInt64:
465 return ArgType(Ctx.LongLongTy, "__int64");
466 case LengthModifier::AsIntMax:
467 return ArgType(Ctx.getIntMaxType(), "intmax_t");
468 case LengthModifier::AsSizeT:
469 // FIXME: How to get the corresponding signed version of size_t?
471 case LengthModifier::AsInt3264:
472 return Ctx.getTargetInfo().getTriple().isArch64Bit()
473 ? ArgType(Ctx.LongLongTy, "__int64")
474 : ArgType(Ctx.IntTy, "__int32");
475 case LengthModifier::AsPtrDiff:
476 return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
477 case LengthModifier::AsAllocate:
478 case LengthModifier::AsMAllocate:
479 case LengthModifier::AsWide:
480 return ArgType::Invalid();
484 switch (LM.getKind()) {
485 case LengthModifier::AsLongDouble:
487 return Ctx.UnsignedLongLongTy;
488 case LengthModifier::None:
489 return Ctx.UnsignedIntTy;
490 case LengthModifier::AsInt32:
491 return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
492 case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
493 case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
494 case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
495 case LengthModifier::AsLongLong:
496 case LengthModifier::AsQuad:
497 return Ctx.UnsignedLongLongTy;
498 case LengthModifier::AsInt64:
499 return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
500 case LengthModifier::AsIntMax:
501 return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
502 case LengthModifier::AsSizeT:
503 return ArgType(Ctx.getSizeType(), "size_t");
504 case LengthModifier::AsInt3264:
505 return Ctx.getTargetInfo().getTriple().isArch64Bit()
506 ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
507 : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
508 case LengthModifier::AsPtrDiff:
509 // FIXME: How to get the corresponding unsigned
510 // version of ptrdiff_t?
512 case LengthModifier::AsAllocate:
513 case LengthModifier::AsMAllocate:
514 case LengthModifier::AsWide:
515 return ArgType::Invalid();
518 if (CS.isDoubleArg()) {
519 if (LM.getKind() == LengthModifier::AsLongDouble)
520 return Ctx.LongDoubleTy;
524 if (CS.getKind() == ConversionSpecifier::nArg) {
525 switch (LM.getKind()) {
526 case LengthModifier::None:
527 return ArgType::PtrTo(Ctx.IntTy);
528 case LengthModifier::AsChar:
529 return ArgType::PtrTo(Ctx.SignedCharTy);
530 case LengthModifier::AsShort:
531 return ArgType::PtrTo(Ctx.ShortTy);
532 case LengthModifier::AsLong:
533 return ArgType::PtrTo(Ctx.LongTy);
534 case LengthModifier::AsLongLong:
535 case LengthModifier::AsQuad:
536 return ArgType::PtrTo(Ctx.LongLongTy);
537 case LengthModifier::AsIntMax:
538 return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
539 case LengthModifier::AsSizeT:
540 return ArgType(); // FIXME: ssize_t
541 case LengthModifier::AsPtrDiff:
542 return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
543 case LengthModifier::AsLongDouble:
544 return ArgType(); // FIXME: Is this a known extension?
545 case LengthModifier::AsAllocate:
546 case LengthModifier::AsMAllocate:
547 case LengthModifier::AsInt32:
548 case LengthModifier::AsInt3264:
549 case LengthModifier::AsInt64:
550 case LengthModifier::AsWide:
551 return ArgType::Invalid();
555 switch (CS.getKind()) {
556 case ConversionSpecifier::sArg:
557 if (LM.getKind() == LengthModifier::AsWideChar) {
559 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
561 return ArgType(ArgType::WCStrTy, "wchar_t *");
563 if (LM.getKind() == LengthModifier::AsWide)
564 return ArgType(ArgType::WCStrTy, "wchar_t *");
565 return ArgType::CStrTy;
566 case ConversionSpecifier::SArg:
568 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
570 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
571 LM.getKind() == LengthModifier::AsShort)
572 return ArgType::CStrTy;
573 return ArgType(ArgType::WCStrTy, "wchar_t *");
574 case ConversionSpecifier::CArg:
576 return ArgType(Ctx.UnsignedShortTy, "unichar");
577 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
578 LM.getKind() == LengthModifier::AsShort)
580 return ArgType(Ctx.WideCharTy, "wchar_t");
581 case ConversionSpecifier::pArg:
582 case ConversionSpecifier::PArg:
583 return ArgType::CPointerTy;
584 case ConversionSpecifier::ObjCObjArg:
585 return ArgType::ObjCPointerTy;
590 // FIXME: Handle other cases.
594 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
595 ASTContext &Ctx, bool IsObjCLiteral) {
596 // %n is different from other conversion specifiers; don't try to fix it.
597 if (CS.getKind() == ConversionSpecifier::nArg)
600 // Handle Objective-C objects first. Note that while the '%@' specifier will
601 // not warn for structure pointer or void pointer arguments (because that's
602 // how CoreFoundation objects are implemented), we only show a fixit for '%@'
603 // if we know it's an object (block, id, class, or __attribute__((NSObject))).
604 if (QT->isObjCRetainableType()) {
608 CS.setKind(ConversionSpecifier::ObjCObjArg);
610 // Disable irrelevant flags
611 HasThousandsGrouping = false;
612 HasPlusPrefix = false;
613 HasSpacePrefix = false;
614 HasAlternativeForm = false;
615 HasLeadingZeroes = false;
616 Precision.setHowSpecified(OptionalAmount::NotSpecified);
617 LM.setKind(LengthModifier::None);
622 // Handle strings next (char *, wchar_t *)
623 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
624 CS.setKind(ConversionSpecifier::sArg);
626 // Disable irrelevant flags
627 HasAlternativeForm = 0;
628 HasLeadingZeroes = 0;
630 // Set the long length modifier for wide characters
631 if (QT->getPointeeType()->isWideCharType())
632 LM.setKind(LengthModifier::AsWideChar);
634 LM.setKind(LengthModifier::None);
639 // If it's an enum, get its underlying type.
640 if (const EnumType *ETy = QT->getAs<EnumType>())
641 QT = ETy->getDecl()->getIntegerType();
643 // We can only work with builtin types.
644 const BuiltinType *BT = QT->getAs<BuiltinType>();
648 // Set length modifier
649 switch (BT->getKind()) {
650 case BuiltinType::Bool:
651 case BuiltinType::WChar_U:
652 case BuiltinType::WChar_S:
653 case BuiltinType::Char16:
654 case BuiltinType::Char32:
655 case BuiltinType::UInt128:
656 case BuiltinType::Int128:
657 case BuiltinType::Half:
658 case BuiltinType::Float128:
659 // Various types which are non-trivial to correct.
662 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
663 case BuiltinType::Id:
664 #include "clang/Basic/OpenCLImageTypes.def"
665 #define SIGNED_TYPE(Id, SingletonId)
666 #define UNSIGNED_TYPE(Id, SingletonId)
667 #define FLOATING_TYPE(Id, SingletonId)
668 #define BUILTIN_TYPE(Id, SingletonId) \
669 case BuiltinType::Id:
670 #include "clang/AST/BuiltinTypes.def"
671 // Misc other stuff which doesn't make sense here.
674 case BuiltinType::UInt:
675 case BuiltinType::Int:
676 case BuiltinType::Float:
677 case BuiltinType::Double:
678 LM.setKind(LengthModifier::None);
681 case BuiltinType::Char_U:
682 case BuiltinType::UChar:
683 case BuiltinType::Char_S:
684 case BuiltinType::SChar:
685 LM.setKind(LengthModifier::AsChar);
688 case BuiltinType::Short:
689 case BuiltinType::UShort:
690 LM.setKind(LengthModifier::AsShort);
693 case BuiltinType::Long:
694 case BuiltinType::ULong:
695 LM.setKind(LengthModifier::AsLong);
698 case BuiltinType::LongLong:
699 case BuiltinType::ULongLong:
700 LM.setKind(LengthModifier::AsLongLong);
703 case BuiltinType::LongDouble:
704 LM.setKind(LengthModifier::AsLongDouble);
708 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
709 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
710 namedTypeToLengthModifier(QT, LM);
712 // If fixing the length modifier was enough, we might be done.
713 if (hasValidLengthModifier(Ctx.getTargetInfo())) {
714 // If we're going to offer a fix anyway, make sure the sign matches.
715 switch (CS.getKind()) {
716 case ConversionSpecifier::uArg:
717 case ConversionSpecifier::UArg:
718 if (QT->isSignedIntegerType())
719 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
721 case ConversionSpecifier::dArg:
722 case ConversionSpecifier::DArg:
723 case ConversionSpecifier::iArg:
724 if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
725 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
728 // Other specifiers do not have signed/unsigned variants.
732 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
733 if (ATR.isValid() && ATR.matchesType(Ctx, QT))
737 // Set conversion specifier and disable any flags which do not apply to it.
738 // Let typedefs to char fall through to int, as %c is silly for uint8_t.
739 if (!isa<TypedefType>(QT) && QT->isCharType()) {
740 CS.setKind(ConversionSpecifier::cArg);
741 LM.setKind(LengthModifier::None);
742 Precision.setHowSpecified(OptionalAmount::NotSpecified);
743 HasAlternativeForm = 0;
744 HasLeadingZeroes = 0;
747 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
748 else if (QT->isRealFloatingType()) {
749 CS.setKind(ConversionSpecifier::fArg);
751 else if (QT->isSignedIntegerType()) {
752 CS.setKind(ConversionSpecifier::dArg);
753 HasAlternativeForm = 0;
755 else if (QT->isUnsignedIntegerType()) {
756 CS.setKind(ConversionSpecifier::uArg);
757 HasAlternativeForm = 0;
760 llvm_unreachable("Unexpected type");
766 void PrintfSpecifier::toString(raw_ostream &os) const {
767 // Whilst some features have no defined order, we are using the order
768 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
772 if (usesPositionalArg()) {
773 os << getPositionalArgIndex() << "$";
777 if (IsLeftJustified) os << "-";
778 if (HasPlusPrefix) os << "+";
779 if (HasSpacePrefix) os << " ";
780 if (HasAlternativeForm) os << "#";
781 if (HasLeadingZeroes) os << "0";
783 // Minimum field width
784 FieldWidth.toString(os);
786 Precision.toString(os);
789 // Conversion specifier
793 bool PrintfSpecifier::hasValidPlusPrefix() const {
797 // The plus prefix only makes sense for signed conversions
798 switch (CS.getKind()) {
799 case ConversionSpecifier::dArg:
800 case ConversionSpecifier::DArg:
801 case ConversionSpecifier::iArg:
802 case ConversionSpecifier::fArg:
803 case ConversionSpecifier::FArg:
804 case ConversionSpecifier::eArg:
805 case ConversionSpecifier::EArg:
806 case ConversionSpecifier::gArg:
807 case ConversionSpecifier::GArg:
808 case ConversionSpecifier::aArg:
809 case ConversionSpecifier::AArg:
810 case ConversionSpecifier::FreeBSDrArg:
811 case ConversionSpecifier::FreeBSDyArg:
819 bool PrintfSpecifier::hasValidAlternativeForm() const {
820 if (!HasAlternativeForm)
823 // Alternate form flag only valid with the oxXaAeEfFgG conversions
824 switch (CS.getKind()) {
825 case ConversionSpecifier::oArg:
826 case ConversionSpecifier::OArg:
827 case ConversionSpecifier::xArg:
828 case ConversionSpecifier::XArg:
829 case ConversionSpecifier::aArg:
830 case ConversionSpecifier::AArg:
831 case ConversionSpecifier::eArg:
832 case ConversionSpecifier::EArg:
833 case ConversionSpecifier::fArg:
834 case ConversionSpecifier::FArg:
835 case ConversionSpecifier::gArg:
836 case ConversionSpecifier::GArg:
837 case ConversionSpecifier::FreeBSDrArg:
838 case ConversionSpecifier::FreeBSDyArg:
846 bool PrintfSpecifier::hasValidLeadingZeros() const {
847 if (!HasLeadingZeroes)
850 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
851 switch (CS.getKind()) {
852 case ConversionSpecifier::dArg:
853 case ConversionSpecifier::DArg:
854 case ConversionSpecifier::iArg:
855 case ConversionSpecifier::oArg:
856 case ConversionSpecifier::OArg:
857 case ConversionSpecifier::uArg:
858 case ConversionSpecifier::UArg:
859 case ConversionSpecifier::xArg:
860 case ConversionSpecifier::XArg:
861 case ConversionSpecifier::aArg:
862 case ConversionSpecifier::AArg:
863 case ConversionSpecifier::eArg:
864 case ConversionSpecifier::EArg:
865 case ConversionSpecifier::fArg:
866 case ConversionSpecifier::FArg:
867 case ConversionSpecifier::gArg:
868 case ConversionSpecifier::GArg:
869 case ConversionSpecifier::FreeBSDrArg:
870 case ConversionSpecifier::FreeBSDyArg:
878 bool PrintfSpecifier::hasValidSpacePrefix() const {
882 // The space prefix only makes sense for signed conversions
883 switch (CS.getKind()) {
884 case ConversionSpecifier::dArg:
885 case ConversionSpecifier::DArg:
886 case ConversionSpecifier::iArg:
887 case ConversionSpecifier::fArg:
888 case ConversionSpecifier::FArg:
889 case ConversionSpecifier::eArg:
890 case ConversionSpecifier::EArg:
891 case ConversionSpecifier::gArg:
892 case ConversionSpecifier::GArg:
893 case ConversionSpecifier::aArg:
894 case ConversionSpecifier::AArg:
895 case ConversionSpecifier::FreeBSDrArg:
896 case ConversionSpecifier::FreeBSDyArg:
904 bool PrintfSpecifier::hasValidLeftJustified() const {
905 if (!IsLeftJustified)
908 // The left justified flag is valid for all conversions except n
909 switch (CS.getKind()) {
910 case ConversionSpecifier::nArg:
918 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
919 if (!HasThousandsGrouping)
922 switch (CS.getKind()) {
923 case ConversionSpecifier::dArg:
924 case ConversionSpecifier::DArg:
925 case ConversionSpecifier::iArg:
926 case ConversionSpecifier::uArg:
927 case ConversionSpecifier::UArg:
928 case ConversionSpecifier::fArg:
929 case ConversionSpecifier::FArg:
930 case ConversionSpecifier::gArg:
931 case ConversionSpecifier::GArg:
938 bool PrintfSpecifier::hasValidPrecision() const {
939 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
942 // Precision is only valid with the diouxXaAeEfFgGsP conversions
943 switch (CS.getKind()) {
944 case ConversionSpecifier::dArg:
945 case ConversionSpecifier::DArg:
946 case ConversionSpecifier::iArg:
947 case ConversionSpecifier::oArg:
948 case ConversionSpecifier::OArg:
949 case ConversionSpecifier::uArg:
950 case ConversionSpecifier::UArg:
951 case ConversionSpecifier::xArg:
952 case ConversionSpecifier::XArg:
953 case ConversionSpecifier::aArg:
954 case ConversionSpecifier::AArg:
955 case ConversionSpecifier::eArg:
956 case ConversionSpecifier::EArg:
957 case ConversionSpecifier::fArg:
958 case ConversionSpecifier::FArg:
959 case ConversionSpecifier::gArg:
960 case ConversionSpecifier::GArg:
961 case ConversionSpecifier::sArg:
962 case ConversionSpecifier::FreeBSDrArg:
963 case ConversionSpecifier::FreeBSDyArg:
964 case ConversionSpecifier::PArg:
971 bool PrintfSpecifier::hasValidFieldWidth() const {
972 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
975 // The field width is valid for all conversions except n
976 switch (CS.getKind()) {
977 case ConversionSpecifier::nArg: