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 return ArgType(Ctx.getSignedSizeType(), "ssize_t");
470 case LengthModifier::AsInt3264:
471 return Ctx.getTargetInfo().getTriple().isArch64Bit()
472 ? ArgType(Ctx.LongLongTy, "__int64")
473 : ArgType(Ctx.IntTy, "__int32");
474 case LengthModifier::AsPtrDiff:
475 return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
476 case LengthModifier::AsAllocate:
477 case LengthModifier::AsMAllocate:
478 case LengthModifier::AsWide:
479 return ArgType::Invalid();
483 switch (LM.getKind()) {
484 case LengthModifier::AsLongDouble:
486 return Ctx.UnsignedLongLongTy;
487 case LengthModifier::None:
488 return Ctx.UnsignedIntTy;
489 case LengthModifier::AsInt32:
490 return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
491 case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
492 case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
493 case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
494 case LengthModifier::AsLongLong:
495 case LengthModifier::AsQuad:
496 return Ctx.UnsignedLongLongTy;
497 case LengthModifier::AsInt64:
498 return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
499 case LengthModifier::AsIntMax:
500 return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
501 case LengthModifier::AsSizeT:
502 return ArgType(Ctx.getSizeType(), "size_t");
503 case LengthModifier::AsInt3264:
504 return Ctx.getTargetInfo().getTriple().isArch64Bit()
505 ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
506 : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
507 case LengthModifier::AsPtrDiff:
508 // FIXME: How to get the corresponding unsigned
509 // version of ptrdiff_t?
511 case LengthModifier::AsAllocate:
512 case LengthModifier::AsMAllocate:
513 case LengthModifier::AsWide:
514 return ArgType::Invalid();
517 if (CS.isDoubleArg()) {
518 if (LM.getKind() == LengthModifier::AsLongDouble)
519 return Ctx.LongDoubleTy;
523 if (CS.getKind() == ConversionSpecifier::nArg) {
524 switch (LM.getKind()) {
525 case LengthModifier::None:
526 return ArgType::PtrTo(Ctx.IntTy);
527 case LengthModifier::AsChar:
528 return ArgType::PtrTo(Ctx.SignedCharTy);
529 case LengthModifier::AsShort:
530 return ArgType::PtrTo(Ctx.ShortTy);
531 case LengthModifier::AsLong:
532 return ArgType::PtrTo(Ctx.LongTy);
533 case LengthModifier::AsLongLong:
534 case LengthModifier::AsQuad:
535 return ArgType::PtrTo(Ctx.LongLongTy);
536 case LengthModifier::AsIntMax:
537 return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
538 case LengthModifier::AsSizeT:
539 return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
540 case LengthModifier::AsPtrDiff:
541 return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
542 case LengthModifier::AsLongDouble:
543 return ArgType(); // FIXME: Is this a known extension?
544 case LengthModifier::AsAllocate:
545 case LengthModifier::AsMAllocate:
546 case LengthModifier::AsInt32:
547 case LengthModifier::AsInt3264:
548 case LengthModifier::AsInt64:
549 case LengthModifier::AsWide:
550 return ArgType::Invalid();
554 switch (CS.getKind()) {
555 case ConversionSpecifier::sArg:
556 if (LM.getKind() == LengthModifier::AsWideChar) {
558 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
560 return ArgType(ArgType::WCStrTy, "wchar_t *");
562 if (LM.getKind() == LengthModifier::AsWide)
563 return ArgType(ArgType::WCStrTy, "wchar_t *");
564 return ArgType::CStrTy;
565 case ConversionSpecifier::SArg:
567 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
569 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
570 LM.getKind() == LengthModifier::AsShort)
571 return ArgType::CStrTy;
572 return ArgType(ArgType::WCStrTy, "wchar_t *");
573 case ConversionSpecifier::CArg:
575 return ArgType(Ctx.UnsignedShortTy, "unichar");
576 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
577 LM.getKind() == LengthModifier::AsShort)
579 return ArgType(Ctx.WideCharTy, "wchar_t");
580 case ConversionSpecifier::pArg:
581 case ConversionSpecifier::PArg:
582 return ArgType::CPointerTy;
583 case ConversionSpecifier::ObjCObjArg:
584 return ArgType::ObjCPointerTy;
589 // FIXME: Handle other cases.
593 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
594 ASTContext &Ctx, bool IsObjCLiteral) {
595 // %n is different from other conversion specifiers; don't try to fix it.
596 if (CS.getKind() == ConversionSpecifier::nArg)
599 // Handle Objective-C objects first. Note that while the '%@' specifier will
600 // not warn for structure pointer or void pointer arguments (because that's
601 // how CoreFoundation objects are implemented), we only show a fixit for '%@'
602 // if we know it's an object (block, id, class, or __attribute__((NSObject))).
603 if (QT->isObjCRetainableType()) {
607 CS.setKind(ConversionSpecifier::ObjCObjArg);
609 // Disable irrelevant flags
610 HasThousandsGrouping = false;
611 HasPlusPrefix = false;
612 HasSpacePrefix = false;
613 HasAlternativeForm = false;
614 HasLeadingZeroes = false;
615 Precision.setHowSpecified(OptionalAmount::NotSpecified);
616 LM.setKind(LengthModifier::None);
621 // Handle strings next (char *, wchar_t *)
622 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
623 CS.setKind(ConversionSpecifier::sArg);
625 // Disable irrelevant flags
626 HasAlternativeForm = 0;
627 HasLeadingZeroes = 0;
629 // Set the long length modifier for wide characters
630 if (QT->getPointeeType()->isWideCharType())
631 LM.setKind(LengthModifier::AsWideChar);
633 LM.setKind(LengthModifier::None);
638 // If it's an enum, get its underlying type.
639 if (const EnumType *ETy = QT->getAs<EnumType>())
640 QT = ETy->getDecl()->getIntegerType();
642 // We can only work with builtin types.
643 const BuiltinType *BT = QT->getAs<BuiltinType>();
647 // Set length modifier
648 switch (BT->getKind()) {
649 case BuiltinType::Bool:
650 case BuiltinType::WChar_U:
651 case BuiltinType::WChar_S:
652 case BuiltinType::Char16:
653 case BuiltinType::Char32:
654 case BuiltinType::UInt128:
655 case BuiltinType::Int128:
656 case BuiltinType::Half:
657 case BuiltinType::Float128:
658 // Various types which are non-trivial to correct.
661 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
662 case BuiltinType::Id:
663 #include "clang/Basic/OpenCLImageTypes.def"
664 #define SIGNED_TYPE(Id, SingletonId)
665 #define UNSIGNED_TYPE(Id, SingletonId)
666 #define FLOATING_TYPE(Id, SingletonId)
667 #define BUILTIN_TYPE(Id, SingletonId) \
668 case BuiltinType::Id:
669 #include "clang/AST/BuiltinTypes.def"
670 // Misc other stuff which doesn't make sense here.
673 case BuiltinType::UInt:
674 case BuiltinType::Int:
675 case BuiltinType::Float:
676 case BuiltinType::Double:
677 LM.setKind(LengthModifier::None);
680 case BuiltinType::Char_U:
681 case BuiltinType::UChar:
682 case BuiltinType::Char_S:
683 case BuiltinType::SChar:
684 LM.setKind(LengthModifier::AsChar);
687 case BuiltinType::Short:
688 case BuiltinType::UShort:
689 LM.setKind(LengthModifier::AsShort);
692 case BuiltinType::Long:
693 case BuiltinType::ULong:
694 LM.setKind(LengthModifier::AsLong);
697 case BuiltinType::LongLong:
698 case BuiltinType::ULongLong:
699 LM.setKind(LengthModifier::AsLongLong);
702 case BuiltinType::LongDouble:
703 LM.setKind(LengthModifier::AsLongDouble);
707 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
708 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
709 namedTypeToLengthModifier(QT, LM);
711 // If fixing the length modifier was enough, we might be done.
712 if (hasValidLengthModifier(Ctx.getTargetInfo())) {
713 // If we're going to offer a fix anyway, make sure the sign matches.
714 switch (CS.getKind()) {
715 case ConversionSpecifier::uArg:
716 case ConversionSpecifier::UArg:
717 if (QT->isSignedIntegerType())
718 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
720 case ConversionSpecifier::dArg:
721 case ConversionSpecifier::DArg:
722 case ConversionSpecifier::iArg:
723 if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
724 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
727 // Other specifiers do not have signed/unsigned variants.
731 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
732 if (ATR.isValid() && ATR.matchesType(Ctx, QT))
736 // Set conversion specifier and disable any flags which do not apply to it.
737 // Let typedefs to char fall through to int, as %c is silly for uint8_t.
738 if (!isa<TypedefType>(QT) && QT->isCharType()) {
739 CS.setKind(ConversionSpecifier::cArg);
740 LM.setKind(LengthModifier::None);
741 Precision.setHowSpecified(OptionalAmount::NotSpecified);
742 HasAlternativeForm = 0;
743 HasLeadingZeroes = 0;
746 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
747 else if (QT->isRealFloatingType()) {
748 CS.setKind(ConversionSpecifier::fArg);
750 else if (QT->isSignedIntegerType()) {
751 CS.setKind(ConversionSpecifier::dArg);
752 HasAlternativeForm = 0;
754 else if (QT->isUnsignedIntegerType()) {
755 CS.setKind(ConversionSpecifier::uArg);
756 HasAlternativeForm = 0;
759 llvm_unreachable("Unexpected type");
765 void PrintfSpecifier::toString(raw_ostream &os) const {
766 // Whilst some features have no defined order, we are using the order
767 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
771 if (usesPositionalArg()) {
772 os << getPositionalArgIndex() << "$";
776 if (IsLeftJustified) os << "-";
777 if (HasPlusPrefix) os << "+";
778 if (HasSpacePrefix) os << " ";
779 if (HasAlternativeForm) os << "#";
780 if (HasLeadingZeroes) os << "0";
782 // Minimum field width
783 FieldWidth.toString(os);
785 Precision.toString(os);
788 // Conversion specifier
792 bool PrintfSpecifier::hasValidPlusPrefix() const {
796 // The plus prefix only makes sense for signed conversions
797 switch (CS.getKind()) {
798 case ConversionSpecifier::dArg:
799 case ConversionSpecifier::DArg:
800 case ConversionSpecifier::iArg:
801 case ConversionSpecifier::fArg:
802 case ConversionSpecifier::FArg:
803 case ConversionSpecifier::eArg:
804 case ConversionSpecifier::EArg:
805 case ConversionSpecifier::gArg:
806 case ConversionSpecifier::GArg:
807 case ConversionSpecifier::aArg:
808 case ConversionSpecifier::AArg:
809 case ConversionSpecifier::FreeBSDrArg:
810 case ConversionSpecifier::FreeBSDyArg:
818 bool PrintfSpecifier::hasValidAlternativeForm() const {
819 if (!HasAlternativeForm)
822 // Alternate form flag only valid with the oxXaAeEfFgG conversions
823 switch (CS.getKind()) {
824 case ConversionSpecifier::oArg:
825 case ConversionSpecifier::OArg:
826 case ConversionSpecifier::xArg:
827 case ConversionSpecifier::XArg:
828 case ConversionSpecifier::aArg:
829 case ConversionSpecifier::AArg:
830 case ConversionSpecifier::eArg:
831 case ConversionSpecifier::EArg:
832 case ConversionSpecifier::fArg:
833 case ConversionSpecifier::FArg:
834 case ConversionSpecifier::gArg:
835 case ConversionSpecifier::GArg:
836 case ConversionSpecifier::FreeBSDrArg:
837 case ConversionSpecifier::FreeBSDyArg:
845 bool PrintfSpecifier::hasValidLeadingZeros() const {
846 if (!HasLeadingZeroes)
849 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
850 switch (CS.getKind()) {
851 case ConversionSpecifier::dArg:
852 case ConversionSpecifier::DArg:
853 case ConversionSpecifier::iArg:
854 case ConversionSpecifier::oArg:
855 case ConversionSpecifier::OArg:
856 case ConversionSpecifier::uArg:
857 case ConversionSpecifier::UArg:
858 case ConversionSpecifier::xArg:
859 case ConversionSpecifier::XArg:
860 case ConversionSpecifier::aArg:
861 case ConversionSpecifier::AArg:
862 case ConversionSpecifier::eArg:
863 case ConversionSpecifier::EArg:
864 case ConversionSpecifier::fArg:
865 case ConversionSpecifier::FArg:
866 case ConversionSpecifier::gArg:
867 case ConversionSpecifier::GArg:
868 case ConversionSpecifier::FreeBSDrArg:
869 case ConversionSpecifier::FreeBSDyArg:
877 bool PrintfSpecifier::hasValidSpacePrefix() const {
881 // The space prefix only makes sense for signed conversions
882 switch (CS.getKind()) {
883 case ConversionSpecifier::dArg:
884 case ConversionSpecifier::DArg:
885 case ConversionSpecifier::iArg:
886 case ConversionSpecifier::fArg:
887 case ConversionSpecifier::FArg:
888 case ConversionSpecifier::eArg:
889 case ConversionSpecifier::EArg:
890 case ConversionSpecifier::gArg:
891 case ConversionSpecifier::GArg:
892 case ConversionSpecifier::aArg:
893 case ConversionSpecifier::AArg:
894 case ConversionSpecifier::FreeBSDrArg:
895 case ConversionSpecifier::FreeBSDyArg:
903 bool PrintfSpecifier::hasValidLeftJustified() const {
904 if (!IsLeftJustified)
907 // The left justified flag is valid for all conversions except n
908 switch (CS.getKind()) {
909 case ConversionSpecifier::nArg:
917 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
918 if (!HasThousandsGrouping)
921 switch (CS.getKind()) {
922 case ConversionSpecifier::dArg:
923 case ConversionSpecifier::DArg:
924 case ConversionSpecifier::iArg:
925 case ConversionSpecifier::uArg:
926 case ConversionSpecifier::UArg:
927 case ConversionSpecifier::fArg:
928 case ConversionSpecifier::FArg:
929 case ConversionSpecifier::gArg:
930 case ConversionSpecifier::GArg:
937 bool PrintfSpecifier::hasValidPrecision() const {
938 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
941 // Precision is only valid with the diouxXaAeEfFgGsP conversions
942 switch (CS.getKind()) {
943 case ConversionSpecifier::dArg:
944 case ConversionSpecifier::DArg:
945 case ConversionSpecifier::iArg:
946 case ConversionSpecifier::oArg:
947 case ConversionSpecifier::OArg:
948 case ConversionSpecifier::uArg:
949 case ConversionSpecifier::UArg:
950 case ConversionSpecifier::xArg:
951 case ConversionSpecifier::XArg:
952 case ConversionSpecifier::aArg:
953 case ConversionSpecifier::AArg:
954 case ConversionSpecifier::eArg:
955 case ConversionSpecifier::EArg:
956 case ConversionSpecifier::fArg:
957 case ConversionSpecifier::FArg:
958 case ConversionSpecifier::gArg:
959 case ConversionSpecifier::GArg:
960 case ConversionSpecifier::sArg:
961 case ConversionSpecifier::FreeBSDrArg:
962 case ConversionSpecifier::FreeBSDyArg:
963 case ConversionSpecifier::PArg:
970 bool PrintfSpecifier::hasValidFieldWidth() const {
971 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
974 // The field width is valid for all conversions except n
975 switch (CS.getKind()) {
976 case ConversionSpecifier::nArg: