1 //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 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. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/Analysis/Analyses/FormatString.h" 16 #include "FormatStringParsing.h" 17 #include "clang/Basic/TargetInfo.h" 18 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; 25 26 using namespace clang; 27 28 typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 29 PrintfSpecifierResult; 30 31 //===----------------------------------------------------------------------===// 32 // Methods for parsing format strings. 33 //===----------------------------------------------------------------------===// 34 35 using analyze_format_string::ParseNonPositionAmount; 36 37 static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 38 const char *Start, const char *&Beg, const char *E, 39 unsigned *argIndex) { 40 if (argIndex) { 41 FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 42 } else { 43 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 44 analyze_format_string::PrecisionPos); 45 if (Amt.isInvalid()) 46 return true; 47 FS.setPrecision(Amt); 48 } 49 return false; 50 } 51 52 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 53 const char *&Beg, 54 const char *E, 55 unsigned &argIndex, 56 const LangOptions &LO, 57 const TargetInfo &Target, 58 bool Warn, 59 bool isFreeBSDKPrintf) { 60 61 using namespace clang::analyze_format_string; 62 using namespace clang::analyze_printf; 63 64 const char *I = Beg; 65 const char *Start = nullptr; 66 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 67 68 // Look for a '%' character that indicates the start of a format specifier. 69 for ( ; I != E ; ++I) { 70 char c = *I; 71 if (c == '\0') { 72 // Detect spurious null characters, which are likely errors. 73 H.HandleNullChar(I); 74 return true; 75 } 76 if (c == '%') { 77 Start = I++; // Record the start of the format specifier. 78 break; 79 } 80 } 81 82 // No format specifier found? 83 if (!Start) 84 return false; 85 86 if (I == E) { 87 // No more characters left? 88 if (Warn) 89 H.HandleIncompleteSpecifier(Start, E - Start); 90 return true; 91 } 92 93 PrintfSpecifier FS; 94 if (ParseArgPosition(H, FS, Start, I, E)) 95 return true; 96 97 if (I == E) { 98 // No more characters left? 99 if (Warn) 100 H.HandleIncompleteSpecifier(Start, E - Start); 101 return true; 102 } 103 104 // Look for flags (if any). 105 bool hasMore = true; 106 for ( ; I != E; ++I) { 107 switch (*I) { 108 default: hasMore = false; break; 109 case '\'': 110 // FIXME: POSIX specific. Always accept? 111 FS.setHasThousandsGrouping(I); 112 break; 113 case '-': FS.setIsLeftJustified(I); break; 114 case '+': FS.setHasPlusPrefix(I); break; 115 case ' ': FS.setHasSpacePrefix(I); break; 116 case '#': FS.setHasAlternativeForm(I); break; 117 case '0': FS.setHasLeadingZeros(I); break; 118 } 119 if (!hasMore) 120 break; 121 } 122 123 if (I == E) { 124 // No more characters left? 125 if (Warn) 126 H.HandleIncompleteSpecifier(Start, E - Start); 127 return true; 128 } 129 130 // Look for the field width (if any). 131 if (ParseFieldWidth(H, FS, Start, I, E, 132 FS.usesPositionalArg() ? nullptr : &argIndex)) 133 return true; 134 135 if (I == E) { 136 // No more characters left? 137 if (Warn) 138 H.HandleIncompleteSpecifier(Start, E - Start); 139 return true; 140 } 141 142 // Look for the precision (if any). 143 if (*I == '.') { 144 ++I; 145 if (I == E) { 146 if (Warn) 147 H.HandleIncompleteSpecifier(Start, E - Start); 148 return true; 149 } 150 151 if (ParsePrecision(H, FS, Start, I, E, 152 FS.usesPositionalArg() ? nullptr : &argIndex)) 153 return true; 154 155 if (I == E) { 156 // No more characters left? 157 if (Warn) 158 H.HandleIncompleteSpecifier(Start, E - Start); 159 return true; 160 } 161 } 162 163 // Look for the length modifier. 164 if (ParseLengthModifier(FS, I, E, LO) && I == E) { 165 // No more characters left? 166 if (Warn) 167 H.HandleIncompleteSpecifier(Start, E - Start); 168 return true; 169 } 170 171 if (*I == '\0') { 172 // Detect spurious null characters, which are likely errors. 173 H.HandleNullChar(I); 174 return true; 175 } 176 177 // Finally, look for the conversion specifier. 178 const char *conversionPosition = I++; 179 ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 180 switch (*conversionPosition) { 181 default: 182 break; 183 // C99: 7.19.6.1 (section 8). 184 case '%': k = ConversionSpecifier::PercentArg; break; 185 case 'A': k = ConversionSpecifier::AArg; break; 186 case 'E': k = ConversionSpecifier::EArg; break; 187 case 'F': k = ConversionSpecifier::FArg; break; 188 case 'G': k = ConversionSpecifier::GArg; break; 189 case 'X': k = ConversionSpecifier::XArg; break; 190 case 'a': k = ConversionSpecifier::aArg; break; 191 case 'c': k = ConversionSpecifier::cArg; break; 192 case 'd': k = ConversionSpecifier::dArg; break; 193 case 'e': k = ConversionSpecifier::eArg; break; 194 case 'f': k = ConversionSpecifier::fArg; break; 195 case 'g': k = ConversionSpecifier::gArg; break; 196 case 'i': k = ConversionSpecifier::iArg; break; 197 case 'n': k = ConversionSpecifier::nArg; break; 198 case 'o': k = ConversionSpecifier::oArg; break; 199 case 'p': k = ConversionSpecifier::pArg; break; 200 case 's': k = ConversionSpecifier::sArg; break; 201 case 'u': k = ConversionSpecifier::uArg; break; 202 case 'x': k = ConversionSpecifier::xArg; break; 203 // POSIX specific. 204 case 'C': k = ConversionSpecifier::CArg; break; 205 case 'S': k = ConversionSpecifier::SArg; break; 206 // Objective-C. 207 case '@': k = ConversionSpecifier::ObjCObjArg; break; 208 // Glibc specific. 209 case 'm': k = ConversionSpecifier::PrintErrno; break; 210 // FreeBSD kernel specific. 211 case 'b': 212 if (isFreeBSDKPrintf) 213 k = ConversionSpecifier::FreeBSDbArg; // int followed by char * 214 break; 215 case 'r': 216 if (isFreeBSDKPrintf) 217 k = ConversionSpecifier::FreeBSDrArg; // int 218 break; 219 case 'y': 220 if (isFreeBSDKPrintf) 221 k = ConversionSpecifier::FreeBSDyArg; // int 222 break; 223 // Apple-specific. 224 case 'D': 225 if (isFreeBSDKPrintf) 226 k = ConversionSpecifier::FreeBSDDArg; // void * followed by char * 227 else if (Target.getTriple().isOSDarwin()) 228 k = ConversionSpecifier::DArg; 229 break; 230 case 'O': 231 if (Target.getTriple().isOSDarwin()) 232 k = ConversionSpecifier::OArg; 233 break; 234 case 'U': 235 if (Target.getTriple().isOSDarwin()) 236 k = ConversionSpecifier::UArg; 237 break; 238 // MS specific. 239 case 'Z': 240 if (Target.getTriple().isOSMSVCRT()) 241 k = ConversionSpecifier::ZArg; 242 } 243 PrintfConversionSpecifier CS(conversionPosition, k); 244 FS.setConversionSpecifier(CS); 245 if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 246 FS.setArgIndex(argIndex++); 247 // FreeBSD kernel specific. 248 if (k == ConversionSpecifier::FreeBSDbArg || 249 k == ConversionSpecifier::FreeBSDDArg) 250 argIndex++; 251 252 if (k == ConversionSpecifier::InvalidSpecifier) { 253 // Assume the conversion takes one argument. 254 return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 255 } 256 return PrintfSpecifierResult(Start, FS); 257 } 258 259 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 260 const char *I, 261 const char *E, 262 const LangOptions &LO, 263 const TargetInfo &Target, 264 bool isFreeBSDKPrintf) { 265 266 unsigned argIndex = 0; 267 268 // Keep looking for a format specifier until we have exhausted the string. 269 while (I != E) { 270 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 271 LO, Target, true, 272 isFreeBSDKPrintf); 273 // Did a fail-stop error of any kind occur when parsing the specifier? 274 // If so, don't do any more processing. 275 if (FSR.shouldStop()) 276 return true; 277 // Did we exhaust the string or encounter an error that 278 // we can recover from? 279 if (!FSR.hasValue()) 280 continue; 281 // We have a format specifier. Pass it to the callback. 282 if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 283 I - FSR.getStart())) 284 return true; 285 } 286 assert(I == E && "Format string not exhausted"); 287 return false; 288 } 289 290 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I, 291 const char *E, 292 const LangOptions &LO, 293 const TargetInfo &Target) { 294 295 unsigned argIndex = 0; 296 297 // Keep looking for a %s format specifier until we have exhausted the string. 298 FormatStringHandler H; 299 while (I != E) { 300 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 301 LO, Target, false, 302 false); 303 // Did a fail-stop error of any kind occur when parsing the specifier? 304 // If so, don't do any more processing. 305 if (FSR.shouldStop()) 306 return false; 307 // Did we exhaust the string or encounter an error that 308 // we can recover from? 309 if (!FSR.hasValue()) 310 continue; 311 const analyze_printf::PrintfSpecifier &FS = FSR.getValue(); 312 // Return true if this a %s format specifier. 313 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg) 314 return true; 315 } 316 return false; 317 } 318 319 //===----------------------------------------------------------------------===// 320 // Methods on PrintfSpecifier. 321 //===----------------------------------------------------------------------===// 322 323 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, 324 bool IsObjCLiteral) const { 325 const PrintfConversionSpecifier &CS = getConversionSpecifier(); 326 327 if (!CS.consumesDataArgument()) 328 return ArgType::Invalid(); 329 330 if (CS.getKind() == ConversionSpecifier::cArg) 331 switch (LM.getKind()) { 332 case LengthModifier::None: 333 return Ctx.IntTy; 334 case LengthModifier::AsLong: 335 case LengthModifier::AsWide: 336 return ArgType(ArgType::WIntTy, "wint_t"); 337 case LengthModifier::AsShort: 338 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT()) 339 return Ctx.IntTy; 340 default: 341 return ArgType::Invalid(); 342 } 343 344 if (CS.isIntArg()) 345 switch (LM.getKind()) { 346 case LengthModifier::AsLongDouble: 347 // GNU extension. 348 return Ctx.LongLongTy; 349 case LengthModifier::None: 350 return Ctx.IntTy; 351 case LengthModifier::AsInt32: 352 return ArgType(Ctx.IntTy, "__int32"); 353 case LengthModifier::AsChar: return ArgType::AnyCharTy; 354 case LengthModifier::AsShort: return Ctx.ShortTy; 355 case LengthModifier::AsLong: return Ctx.LongTy; 356 case LengthModifier::AsLongLong: 357 case LengthModifier::AsQuad: 358 return Ctx.LongLongTy; 359 case LengthModifier::AsInt64: 360 return ArgType(Ctx.LongLongTy, "__int64"); 361 case LengthModifier::AsIntMax: 362 return ArgType(Ctx.getIntMaxType(), "intmax_t"); 363 case LengthModifier::AsSizeT: 364 // FIXME: How to get the corresponding signed version of size_t? 365 return ArgType(); 366 case LengthModifier::AsInt3264: 367 return Ctx.getTargetInfo().getTriple().isArch64Bit() 368 ? ArgType(Ctx.LongLongTy, "__int64") 369 : ArgType(Ctx.IntTy, "__int32"); 370 case LengthModifier::AsPtrDiff: 371 return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"); 372 case LengthModifier::AsAllocate: 373 case LengthModifier::AsMAllocate: 374 case LengthModifier::AsWide: 375 return ArgType::Invalid(); 376 } 377 378 if (CS.isUIntArg()) 379 switch (LM.getKind()) { 380 case LengthModifier::AsLongDouble: 381 // GNU extension. 382 return Ctx.UnsignedLongLongTy; 383 case LengthModifier::None: 384 return Ctx.UnsignedIntTy; 385 case LengthModifier::AsInt32: 386 return ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 387 case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 388 case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 389 case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 390 case LengthModifier::AsLongLong: 391 case LengthModifier::AsQuad: 392 return Ctx.UnsignedLongLongTy; 393 case LengthModifier::AsInt64: 394 return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64"); 395 case LengthModifier::AsIntMax: 396 return ArgType(Ctx.getUIntMaxType(), "uintmax_t"); 397 case LengthModifier::AsSizeT: 398 return ArgType(Ctx.getSizeType(), "size_t"); 399 case LengthModifier::AsInt3264: 400 return Ctx.getTargetInfo().getTriple().isArch64Bit() 401 ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64") 402 : ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 403 case LengthModifier::AsPtrDiff: 404 // FIXME: How to get the corresponding unsigned 405 // version of ptrdiff_t? 406 return ArgType(); 407 case LengthModifier::AsAllocate: 408 case LengthModifier::AsMAllocate: 409 case LengthModifier::AsWide: 410 return ArgType::Invalid(); 411 } 412 413 if (CS.isDoubleArg()) { 414 if (LM.getKind() == LengthModifier::AsLongDouble) 415 return Ctx.LongDoubleTy; 416 return Ctx.DoubleTy; 417 } 418 419 if (CS.getKind() == ConversionSpecifier::nArg) { 420 switch (LM.getKind()) { 421 case LengthModifier::None: 422 return ArgType::PtrTo(Ctx.IntTy); 423 case LengthModifier::AsChar: 424 return ArgType::PtrTo(Ctx.SignedCharTy); 425 case LengthModifier::AsShort: 426 return ArgType::PtrTo(Ctx.ShortTy); 427 case LengthModifier::AsLong: 428 return ArgType::PtrTo(Ctx.LongTy); 429 case LengthModifier::AsLongLong: 430 case LengthModifier::AsQuad: 431 return ArgType::PtrTo(Ctx.LongLongTy); 432 case LengthModifier::AsIntMax: 433 return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); 434 case LengthModifier::AsSizeT: 435 return ArgType(); // FIXME: ssize_t 436 case LengthModifier::AsPtrDiff: 437 return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); 438 case LengthModifier::AsLongDouble: 439 return ArgType(); // FIXME: Is this a known extension? 440 case LengthModifier::AsAllocate: 441 case LengthModifier::AsMAllocate: 442 case LengthModifier::AsInt32: 443 case LengthModifier::AsInt3264: 444 case LengthModifier::AsInt64: 445 case LengthModifier::AsWide: 446 return ArgType::Invalid(); 447 } 448 } 449 450 switch (CS.getKind()) { 451 case ConversionSpecifier::sArg: 452 if (LM.getKind() == LengthModifier::AsWideChar) { 453 if (IsObjCLiteral) 454 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 455 "const unichar *"); 456 return ArgType(ArgType::WCStrTy, "wchar_t *"); 457 } 458 if (LM.getKind() == LengthModifier::AsWide) 459 return ArgType(ArgType::WCStrTy, "wchar_t *"); 460 return ArgType::CStrTy; 461 case ConversionSpecifier::SArg: 462 if (IsObjCLiteral) 463 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 464 "const unichar *"); 465 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() && 466 LM.getKind() == LengthModifier::AsShort) 467 return ArgType::CStrTy; 468 return ArgType(ArgType::WCStrTy, "wchar_t *"); 469 case ConversionSpecifier::CArg: 470 if (IsObjCLiteral) 471 return ArgType(Ctx.UnsignedShortTy, "unichar"); 472 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() && 473 LM.getKind() == LengthModifier::AsShort) 474 return Ctx.IntTy; 475 return ArgType(Ctx.WideCharTy, "wchar_t"); 476 case ConversionSpecifier::pArg: 477 return ArgType::CPointerTy; 478 case ConversionSpecifier::ObjCObjArg: 479 return ArgType::ObjCPointerTy; 480 default: 481 break; 482 } 483 484 // FIXME: Handle other cases. 485 return ArgType(); 486 } 487 488 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, 489 ASTContext &Ctx, bool IsObjCLiteral) { 490 // %n is different from other conversion specifiers; don't try to fix it. 491 if (CS.getKind() == ConversionSpecifier::nArg) 492 return false; 493 494 // Handle Objective-C objects first. Note that while the '%@' specifier will 495 // not warn for structure pointer or void pointer arguments (because that's 496 // how CoreFoundation objects are implemented), we only show a fixit for '%@' 497 // if we know it's an object (block, id, class, or __attribute__((NSObject))). 498 if (QT->isObjCRetainableType()) { 499 if (!IsObjCLiteral) 500 return false; 501 502 CS.setKind(ConversionSpecifier::ObjCObjArg); 503 504 // Disable irrelevant flags 505 HasThousandsGrouping = false; 506 HasPlusPrefix = false; 507 HasSpacePrefix = false; 508 HasAlternativeForm = false; 509 HasLeadingZeroes = false; 510 Precision.setHowSpecified(OptionalAmount::NotSpecified); 511 LM.setKind(LengthModifier::None); 512 513 return true; 514 } 515 516 // Handle strings next (char *, wchar_t *) 517 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 518 CS.setKind(ConversionSpecifier::sArg); 519 520 // Disable irrelevant flags 521 HasAlternativeForm = 0; 522 HasLeadingZeroes = 0; 523 524 // Set the long length modifier for wide characters 525 if (QT->getPointeeType()->isWideCharType()) 526 LM.setKind(LengthModifier::AsWideChar); 527 else 528 LM.setKind(LengthModifier::None); 529 530 return true; 531 } 532 533 // If it's an enum, get its underlying type. 534 if (const EnumType *ETy = QT->getAs<EnumType>()) 535 QT = ETy->getDecl()->getIntegerType(); 536 537 // We can only work with builtin types. 538 const BuiltinType *BT = QT->getAs<BuiltinType>(); 539 if (!BT) 540 return false; 541 542 // Set length modifier 543 switch (BT->getKind()) { 544 case BuiltinType::Bool: 545 case BuiltinType::WChar_U: 546 case BuiltinType::WChar_S: 547 case BuiltinType::Char16: 548 case BuiltinType::Char32: 549 case BuiltinType::UInt128: 550 case BuiltinType::Int128: 551 case BuiltinType::Half: 552 // Various types which are non-trivial to correct. 553 return false; 554 555 #define SIGNED_TYPE(Id, SingletonId) 556 #define UNSIGNED_TYPE(Id, SingletonId) 557 #define FLOATING_TYPE(Id, SingletonId) 558 #define BUILTIN_TYPE(Id, SingletonId) \ 559 case BuiltinType::Id: 560 #include "clang/AST/BuiltinTypes.def" 561 // Misc other stuff which doesn't make sense here. 562 return false; 563 564 case BuiltinType::UInt: 565 case BuiltinType::Int: 566 case BuiltinType::Float: 567 case BuiltinType::Double: 568 LM.setKind(LengthModifier::None); 569 break; 570 571 case BuiltinType::Char_U: 572 case BuiltinType::UChar: 573 case BuiltinType::Char_S: 574 case BuiltinType::SChar: 575 LM.setKind(LengthModifier::AsChar); 576 break; 577 578 case BuiltinType::Short: 579 case BuiltinType::UShort: 580 LM.setKind(LengthModifier::AsShort); 581 break; 582 583 case BuiltinType::Long: 584 case BuiltinType::ULong: 585 LM.setKind(LengthModifier::AsLong); 586 break; 587 588 case BuiltinType::LongLong: 589 case BuiltinType::ULongLong: 590 LM.setKind(LengthModifier::AsLongLong); 591 break; 592 593 case BuiltinType::LongDouble: 594 LM.setKind(LengthModifier::AsLongDouble); 595 break; 596 } 597 598 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 599 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11)) 600 namedTypeToLengthModifier(QT, LM); 601 602 // If fixing the length modifier was enough, we might be done. 603 if (hasValidLengthModifier(Ctx.getTargetInfo())) { 604 // If we're going to offer a fix anyway, make sure the sign matches. 605 switch (CS.getKind()) { 606 case ConversionSpecifier::uArg: 607 case ConversionSpecifier::UArg: 608 if (QT->isSignedIntegerType()) 609 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg); 610 break; 611 case ConversionSpecifier::dArg: 612 case ConversionSpecifier::DArg: 613 case ConversionSpecifier::iArg: 614 if (QT->isUnsignedIntegerType() && !HasPlusPrefix) 615 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg); 616 break; 617 default: 618 // Other specifiers do not have signed/unsigned variants. 619 break; 620 } 621 622 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral); 623 if (ATR.isValid() && ATR.matchesType(Ctx, QT)) 624 return true; 625 } 626 627 // Set conversion specifier and disable any flags which do not apply to it. 628 // Let typedefs to char fall through to int, as %c is silly for uint8_t. 629 if (!isa<TypedefType>(QT) && QT->isCharType()) { 630 CS.setKind(ConversionSpecifier::cArg); 631 LM.setKind(LengthModifier::None); 632 Precision.setHowSpecified(OptionalAmount::NotSpecified); 633 HasAlternativeForm = 0; 634 HasLeadingZeroes = 0; 635 HasPlusPrefix = 0; 636 } 637 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 638 else if (QT->isRealFloatingType()) { 639 CS.setKind(ConversionSpecifier::fArg); 640 } 641 else if (QT->isSignedIntegerType()) { 642 CS.setKind(ConversionSpecifier::dArg); 643 HasAlternativeForm = 0; 644 } 645 else if (QT->isUnsignedIntegerType()) { 646 CS.setKind(ConversionSpecifier::uArg); 647 HasAlternativeForm = 0; 648 HasPlusPrefix = 0; 649 } else { 650 llvm_unreachable("Unexpected type"); 651 } 652 653 return true; 654 } 655 656 void PrintfSpecifier::toString(raw_ostream &os) const { 657 // Whilst some features have no defined order, we are using the order 658 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 659 os << "%"; 660 661 // Positional args 662 if (usesPositionalArg()) { 663 os << getPositionalArgIndex() << "$"; 664 } 665 666 // Conversion flags 667 if (IsLeftJustified) os << "-"; 668 if (HasPlusPrefix) os << "+"; 669 if (HasSpacePrefix) os << " "; 670 if (HasAlternativeForm) os << "#"; 671 if (HasLeadingZeroes) os << "0"; 672 673 // Minimum field width 674 FieldWidth.toString(os); 675 // Precision 676 Precision.toString(os); 677 // Length modifier 678 os << LM.toString(); 679 // Conversion specifier 680 os << CS.toString(); 681 } 682 683 bool PrintfSpecifier::hasValidPlusPrefix() const { 684 if (!HasPlusPrefix) 685 return true; 686 687 // The plus prefix only makes sense for signed conversions 688 switch (CS.getKind()) { 689 case ConversionSpecifier::dArg: 690 case ConversionSpecifier::DArg: 691 case ConversionSpecifier::iArg: 692 case ConversionSpecifier::fArg: 693 case ConversionSpecifier::FArg: 694 case ConversionSpecifier::eArg: 695 case ConversionSpecifier::EArg: 696 case ConversionSpecifier::gArg: 697 case ConversionSpecifier::GArg: 698 case ConversionSpecifier::aArg: 699 case ConversionSpecifier::AArg: 700 case ConversionSpecifier::FreeBSDrArg: 701 case ConversionSpecifier::FreeBSDyArg: 702 return true; 703 704 default: 705 return false; 706 } 707 } 708 709 bool PrintfSpecifier::hasValidAlternativeForm() const { 710 if (!HasAlternativeForm) 711 return true; 712 713 // Alternate form flag only valid with the oxXaAeEfFgG conversions 714 switch (CS.getKind()) { 715 case ConversionSpecifier::oArg: 716 case ConversionSpecifier::OArg: 717 case ConversionSpecifier::xArg: 718 case ConversionSpecifier::XArg: 719 case ConversionSpecifier::aArg: 720 case ConversionSpecifier::AArg: 721 case ConversionSpecifier::eArg: 722 case ConversionSpecifier::EArg: 723 case ConversionSpecifier::fArg: 724 case ConversionSpecifier::FArg: 725 case ConversionSpecifier::gArg: 726 case ConversionSpecifier::GArg: 727 case ConversionSpecifier::FreeBSDrArg: 728 case ConversionSpecifier::FreeBSDyArg: 729 return true; 730 731 default: 732 return false; 733 } 734 } 735 736 bool PrintfSpecifier::hasValidLeadingZeros() const { 737 if (!HasLeadingZeroes) 738 return true; 739 740 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 741 switch (CS.getKind()) { 742 case ConversionSpecifier::dArg: 743 case ConversionSpecifier::DArg: 744 case ConversionSpecifier::iArg: 745 case ConversionSpecifier::oArg: 746 case ConversionSpecifier::OArg: 747 case ConversionSpecifier::uArg: 748 case ConversionSpecifier::UArg: 749 case ConversionSpecifier::xArg: 750 case ConversionSpecifier::XArg: 751 case ConversionSpecifier::aArg: 752 case ConversionSpecifier::AArg: 753 case ConversionSpecifier::eArg: 754 case ConversionSpecifier::EArg: 755 case ConversionSpecifier::fArg: 756 case ConversionSpecifier::FArg: 757 case ConversionSpecifier::gArg: 758 case ConversionSpecifier::GArg: 759 case ConversionSpecifier::FreeBSDrArg: 760 case ConversionSpecifier::FreeBSDyArg: 761 return true; 762 763 default: 764 return false; 765 } 766 } 767 768 bool PrintfSpecifier::hasValidSpacePrefix() const { 769 if (!HasSpacePrefix) 770 return true; 771 772 // The space prefix only makes sense for signed conversions 773 switch (CS.getKind()) { 774 case ConversionSpecifier::dArg: 775 case ConversionSpecifier::DArg: 776 case ConversionSpecifier::iArg: 777 case ConversionSpecifier::fArg: 778 case ConversionSpecifier::FArg: 779 case ConversionSpecifier::eArg: 780 case ConversionSpecifier::EArg: 781 case ConversionSpecifier::gArg: 782 case ConversionSpecifier::GArg: 783 case ConversionSpecifier::aArg: 784 case ConversionSpecifier::AArg: 785 case ConversionSpecifier::FreeBSDrArg: 786 case ConversionSpecifier::FreeBSDyArg: 787 return true; 788 789 default: 790 return false; 791 } 792 } 793 794 bool PrintfSpecifier::hasValidLeftJustified() const { 795 if (!IsLeftJustified) 796 return true; 797 798 // The left justified flag is valid for all conversions except n 799 switch (CS.getKind()) { 800 case ConversionSpecifier::nArg: 801 return false; 802 803 default: 804 return true; 805 } 806 } 807 808 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 809 if (!HasThousandsGrouping) 810 return true; 811 812 switch (CS.getKind()) { 813 case ConversionSpecifier::dArg: 814 case ConversionSpecifier::DArg: 815 case ConversionSpecifier::iArg: 816 case ConversionSpecifier::uArg: 817 case ConversionSpecifier::UArg: 818 case ConversionSpecifier::fArg: 819 case ConversionSpecifier::FArg: 820 case ConversionSpecifier::gArg: 821 case ConversionSpecifier::GArg: 822 return true; 823 default: 824 return false; 825 } 826 } 827 828 bool PrintfSpecifier::hasValidPrecision() const { 829 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 830 return true; 831 832 // Precision is only valid with the diouxXaAeEfFgGs conversions 833 switch (CS.getKind()) { 834 case ConversionSpecifier::dArg: 835 case ConversionSpecifier::DArg: 836 case ConversionSpecifier::iArg: 837 case ConversionSpecifier::oArg: 838 case ConversionSpecifier::OArg: 839 case ConversionSpecifier::uArg: 840 case ConversionSpecifier::UArg: 841 case ConversionSpecifier::xArg: 842 case ConversionSpecifier::XArg: 843 case ConversionSpecifier::aArg: 844 case ConversionSpecifier::AArg: 845 case ConversionSpecifier::eArg: 846 case ConversionSpecifier::EArg: 847 case ConversionSpecifier::fArg: 848 case ConversionSpecifier::FArg: 849 case ConversionSpecifier::gArg: 850 case ConversionSpecifier::GArg: 851 case ConversionSpecifier::sArg: 852 case ConversionSpecifier::FreeBSDrArg: 853 case ConversionSpecifier::FreeBSDyArg: 854 return true; 855 856 default: 857 return false; 858 } 859 } 860 bool PrintfSpecifier::hasValidFieldWidth() const { 861 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 862 return true; 863 864 // The field width is valid for all conversions except n 865 switch (CS.getKind()) { 866 case ConversionSpecifier::nArg: 867 return false; 868 869 default: 870 return true; 871 } 872 } 873