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 return ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t");
509 case LengthModifier::AsAllocate:
510 case LengthModifier::AsMAllocate:
511 case LengthModifier::AsWide:
512 return ArgType::Invalid();
515 if (CS.isDoubleArg()) {
516 if (LM.getKind() == LengthModifier::AsLongDouble)
517 return Ctx.LongDoubleTy;
521 if (CS.getKind() == ConversionSpecifier::nArg) {
522 switch (LM.getKind()) {
523 case LengthModifier::None:
524 return ArgType::PtrTo(Ctx.IntTy);
525 case LengthModifier::AsChar:
526 return ArgType::PtrTo(Ctx.SignedCharTy);
527 case LengthModifier::AsShort:
528 return ArgType::PtrTo(Ctx.ShortTy);
529 case LengthModifier::AsLong:
530 return ArgType::PtrTo(Ctx.LongTy);
531 case LengthModifier::AsLongLong:
532 case LengthModifier::AsQuad:
533 return ArgType::PtrTo(Ctx.LongLongTy);
534 case LengthModifier::AsIntMax:
535 return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
536 case LengthModifier::AsSizeT:
537 return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
538 case LengthModifier::AsPtrDiff:
539 return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
540 case LengthModifier::AsLongDouble:
541 return ArgType(); // FIXME: Is this a known extension?
542 case LengthModifier::AsAllocate:
543 case LengthModifier::AsMAllocate:
544 case LengthModifier::AsInt32:
545 case LengthModifier::AsInt3264:
546 case LengthModifier::AsInt64:
547 case LengthModifier::AsWide:
548 return ArgType::Invalid();
552 switch (CS.getKind()) {
553 case ConversionSpecifier::sArg:
554 if (LM.getKind() == LengthModifier::AsWideChar) {
556 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
558 return ArgType(ArgType::WCStrTy, "wchar_t *");
560 if (LM.getKind() == LengthModifier::AsWide)
561 return ArgType(ArgType::WCStrTy, "wchar_t *");
562 return ArgType::CStrTy;
563 case ConversionSpecifier::SArg:
565 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
567 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
568 LM.getKind() == LengthModifier::AsShort)
569 return ArgType::CStrTy;
570 return ArgType(ArgType::WCStrTy, "wchar_t *");
571 case ConversionSpecifier::CArg:
573 return ArgType(Ctx.UnsignedShortTy, "unichar");
574 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
575 LM.getKind() == LengthModifier::AsShort)
577 return ArgType(Ctx.WideCharTy, "wchar_t");
578 case ConversionSpecifier::pArg:
579 case ConversionSpecifier::PArg:
580 return ArgType::CPointerTy;
581 case ConversionSpecifier::ObjCObjArg:
582 return ArgType::ObjCPointerTy;
587 // FIXME: Handle other cases.
591 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
592 ASTContext &Ctx, bool IsObjCLiteral) {
593 // %n is different from other conversion specifiers; don't try to fix it.
594 if (CS.getKind() == ConversionSpecifier::nArg)
597 // Handle Objective-C objects first. Note that while the '%@' specifier will
598 // not warn for structure pointer or void pointer arguments (because that's
599 // how CoreFoundation objects are implemented), we only show a fixit for '%@'
600 // if we know it's an object (block, id, class, or __attribute__((NSObject))).
601 if (QT->isObjCRetainableType()) {
605 CS.setKind(ConversionSpecifier::ObjCObjArg);
607 // Disable irrelevant flags
608 HasThousandsGrouping = false;
609 HasPlusPrefix = false;
610 HasSpacePrefix = false;
611 HasAlternativeForm = false;
612 HasLeadingZeroes = false;
613 Precision.setHowSpecified(OptionalAmount::NotSpecified);
614 LM.setKind(LengthModifier::None);
619 // Handle strings next (char *, wchar_t *)
620 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
621 CS.setKind(ConversionSpecifier::sArg);
623 // Disable irrelevant flags
624 HasAlternativeForm = 0;
625 HasLeadingZeroes = 0;
627 // Set the long length modifier for wide characters
628 if (QT->getPointeeType()->isWideCharType())
629 LM.setKind(LengthModifier::AsWideChar);
631 LM.setKind(LengthModifier::None);
636 // If it's an enum, get its underlying type.
637 if (const EnumType *ETy = QT->getAs<EnumType>())
638 QT = ETy->getDecl()->getIntegerType();
640 // We can only work with builtin types.
641 const BuiltinType *BT = QT->getAs<BuiltinType>();
645 // Set length modifier
646 switch (BT->getKind()) {
647 case BuiltinType::Bool:
648 case BuiltinType::WChar_U:
649 case BuiltinType::WChar_S:
650 case BuiltinType::Char16:
651 case BuiltinType::Char32:
652 case BuiltinType::UInt128:
653 case BuiltinType::Int128:
654 case BuiltinType::Half:
655 case BuiltinType::Float16:
656 case BuiltinType::Float128:
657 // Various types which are non-trivial to correct.
660 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
661 case BuiltinType::Id:
662 #include "clang/Basic/OpenCLImageTypes.def"
663 #define SIGNED_TYPE(Id, SingletonId)
664 #define UNSIGNED_TYPE(Id, SingletonId)
665 #define FLOATING_TYPE(Id, SingletonId)
666 #define BUILTIN_TYPE(Id, SingletonId) \
667 case BuiltinType::Id:
668 #include "clang/AST/BuiltinTypes.def"
669 // Misc other stuff which doesn't make sense here.
672 case BuiltinType::UInt:
673 case BuiltinType::Int:
674 case BuiltinType::Float:
675 case BuiltinType::Double:
676 LM.setKind(LengthModifier::None);
679 case BuiltinType::Char_U:
680 case BuiltinType::UChar:
681 case BuiltinType::Char_S:
682 case BuiltinType::SChar:
683 LM.setKind(LengthModifier::AsChar);
686 case BuiltinType::Short:
687 case BuiltinType::UShort:
688 LM.setKind(LengthModifier::AsShort);
691 case BuiltinType::Long:
692 case BuiltinType::ULong:
693 LM.setKind(LengthModifier::AsLong);
696 case BuiltinType::LongLong:
697 case BuiltinType::ULongLong:
698 LM.setKind(LengthModifier::AsLongLong);
701 case BuiltinType::LongDouble:
702 LM.setKind(LengthModifier::AsLongDouble);
706 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
707 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
708 namedTypeToLengthModifier(QT, LM);
710 // If fixing the length modifier was enough, we might be done.
711 if (hasValidLengthModifier(Ctx.getTargetInfo())) {
712 // If we're going to offer a fix anyway, make sure the sign matches.
713 switch (CS.getKind()) {
714 case ConversionSpecifier::uArg:
715 case ConversionSpecifier::UArg:
716 if (QT->isSignedIntegerType())
717 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
719 case ConversionSpecifier::dArg:
720 case ConversionSpecifier::DArg:
721 case ConversionSpecifier::iArg:
722 if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
723 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
726 // Other specifiers do not have signed/unsigned variants.
730 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
731 if (ATR.isValid() && ATR.matchesType(Ctx, QT))
735 // Set conversion specifier and disable any flags which do not apply to it.
736 // Let typedefs to char fall through to int, as %c is silly for uint8_t.
737 if (!isa<TypedefType>(QT) && QT->isCharType()) {
738 CS.setKind(ConversionSpecifier::cArg);
739 LM.setKind(LengthModifier::None);
740 Precision.setHowSpecified(OptionalAmount::NotSpecified);
741 HasAlternativeForm = 0;
742 HasLeadingZeroes = 0;
745 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
746 else if (QT->isRealFloatingType()) {
747 CS.setKind(ConversionSpecifier::fArg);
749 else if (QT->isSignedIntegerType()) {
750 CS.setKind(ConversionSpecifier::dArg);
751 HasAlternativeForm = 0;
753 else if (QT->isUnsignedIntegerType()) {
754 CS.setKind(ConversionSpecifier::uArg);
755 HasAlternativeForm = 0;
758 llvm_unreachable("Unexpected type");
764 void PrintfSpecifier::toString(raw_ostream &os) const {
765 // Whilst some features have no defined order, we are using the order
766 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
770 if (usesPositionalArg()) {
771 os << getPositionalArgIndex() << "$";
775 if (IsLeftJustified) os << "-";
776 if (HasPlusPrefix) os << "+";
777 if (HasSpacePrefix) os << " ";
778 if (HasAlternativeForm) os << "#";
779 if (HasLeadingZeroes) os << "0";
781 // Minimum field width
782 FieldWidth.toString(os);
784 Precision.toString(os);
787 // Conversion specifier
791 bool PrintfSpecifier::hasValidPlusPrefix() const {
795 // The plus prefix only makes sense for signed conversions
796 switch (CS.getKind()) {
797 case ConversionSpecifier::dArg:
798 case ConversionSpecifier::DArg:
799 case ConversionSpecifier::iArg:
800 case ConversionSpecifier::fArg:
801 case ConversionSpecifier::FArg:
802 case ConversionSpecifier::eArg:
803 case ConversionSpecifier::EArg:
804 case ConversionSpecifier::gArg:
805 case ConversionSpecifier::GArg:
806 case ConversionSpecifier::aArg:
807 case ConversionSpecifier::AArg:
808 case ConversionSpecifier::FreeBSDrArg:
809 case ConversionSpecifier::FreeBSDyArg:
817 bool PrintfSpecifier::hasValidAlternativeForm() const {
818 if (!HasAlternativeForm)
821 // Alternate form flag only valid with the oxXaAeEfFgG conversions
822 switch (CS.getKind()) {
823 case ConversionSpecifier::oArg:
824 case ConversionSpecifier::OArg:
825 case ConversionSpecifier::xArg:
826 case ConversionSpecifier::XArg:
827 case ConversionSpecifier::aArg:
828 case ConversionSpecifier::AArg:
829 case ConversionSpecifier::eArg:
830 case ConversionSpecifier::EArg:
831 case ConversionSpecifier::fArg:
832 case ConversionSpecifier::FArg:
833 case ConversionSpecifier::gArg:
834 case ConversionSpecifier::GArg:
835 case ConversionSpecifier::FreeBSDrArg:
836 case ConversionSpecifier::FreeBSDyArg:
844 bool PrintfSpecifier::hasValidLeadingZeros() const {
845 if (!HasLeadingZeroes)
848 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
849 switch (CS.getKind()) {
850 case ConversionSpecifier::dArg:
851 case ConversionSpecifier::DArg:
852 case ConversionSpecifier::iArg:
853 case ConversionSpecifier::oArg:
854 case ConversionSpecifier::OArg:
855 case ConversionSpecifier::uArg:
856 case ConversionSpecifier::UArg:
857 case ConversionSpecifier::xArg:
858 case ConversionSpecifier::XArg:
859 case ConversionSpecifier::aArg:
860 case ConversionSpecifier::AArg:
861 case ConversionSpecifier::eArg:
862 case ConversionSpecifier::EArg:
863 case ConversionSpecifier::fArg:
864 case ConversionSpecifier::FArg:
865 case ConversionSpecifier::gArg:
866 case ConversionSpecifier::GArg:
867 case ConversionSpecifier::FreeBSDrArg:
868 case ConversionSpecifier::FreeBSDyArg:
876 bool PrintfSpecifier::hasValidSpacePrefix() const {
880 // The space prefix only makes sense for signed conversions
881 switch (CS.getKind()) {
882 case ConversionSpecifier::dArg:
883 case ConversionSpecifier::DArg:
884 case ConversionSpecifier::iArg:
885 case ConversionSpecifier::fArg:
886 case ConversionSpecifier::FArg:
887 case ConversionSpecifier::eArg:
888 case ConversionSpecifier::EArg:
889 case ConversionSpecifier::gArg:
890 case ConversionSpecifier::GArg:
891 case ConversionSpecifier::aArg:
892 case ConversionSpecifier::AArg:
893 case ConversionSpecifier::FreeBSDrArg:
894 case ConversionSpecifier::FreeBSDyArg:
902 bool PrintfSpecifier::hasValidLeftJustified() const {
903 if (!IsLeftJustified)
906 // The left justified flag is valid for all conversions except n
907 switch (CS.getKind()) {
908 case ConversionSpecifier::nArg:
916 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
917 if (!HasThousandsGrouping)
920 switch (CS.getKind()) {
921 case ConversionSpecifier::dArg:
922 case ConversionSpecifier::DArg:
923 case ConversionSpecifier::iArg:
924 case ConversionSpecifier::uArg:
925 case ConversionSpecifier::UArg:
926 case ConversionSpecifier::fArg:
927 case ConversionSpecifier::FArg:
928 case ConversionSpecifier::gArg:
929 case ConversionSpecifier::GArg:
936 bool PrintfSpecifier::hasValidPrecision() const {
937 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
940 // Precision is only valid with the diouxXaAeEfFgGsP conversions
941 switch (CS.getKind()) {
942 case ConversionSpecifier::dArg:
943 case ConversionSpecifier::DArg:
944 case ConversionSpecifier::iArg:
945 case ConversionSpecifier::oArg:
946 case ConversionSpecifier::OArg:
947 case ConversionSpecifier::uArg:
948 case ConversionSpecifier::UArg:
949 case ConversionSpecifier::xArg:
950 case ConversionSpecifier::XArg:
951 case ConversionSpecifier::aArg:
952 case ConversionSpecifier::AArg:
953 case ConversionSpecifier::eArg:
954 case ConversionSpecifier::EArg:
955 case ConversionSpecifier::fArg:
956 case ConversionSpecifier::FArg:
957 case ConversionSpecifier::gArg:
958 case ConversionSpecifier::GArg:
959 case ConversionSpecifier::sArg:
960 case ConversionSpecifier::FreeBSDrArg:
961 case ConversionSpecifier::FreeBSDyArg:
962 case ConversionSpecifier::PArg:
969 bool PrintfSpecifier::hasValidFieldWidth() const {
970 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
973 // The field width is valid for all conversions except n
974 switch (CS.getKind()) {
975 case ConversionSpecifier::nArg: