1 // FormatString.cpp - Common stuff for handling printf/scanf formats -*- 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 // Shared details for processing format strings of printf and scanf 11 // (and friends). 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "FormatStringParsing.h" 16 #include "clang/Basic/LangOptions.h" 17 #include "clang/Basic/TargetInfo.h" 18 #include "llvm/Support/ConvertUTF.h" 19 20 using clang::analyze_format_string::ArgType; 21 using clang::analyze_format_string::FormatStringHandler; 22 using clang::analyze_format_string::FormatSpecifier; 23 using clang::analyze_format_string::LengthModifier; 24 using clang::analyze_format_string::OptionalAmount; 25 using clang::analyze_format_string::PositionContext; 26 using clang::analyze_format_string::ConversionSpecifier; 27 using namespace clang; 28 29 // Key function to FormatStringHandler. 30 FormatStringHandler::~FormatStringHandler() {} 31 32 //===----------------------------------------------------------------------===// 33 // Functions for parsing format strings components in both printf and 34 // scanf format strings. 35 //===----------------------------------------------------------------------===// 36 37 OptionalAmount 38 clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) { 39 const char *I = Beg; 40 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 41 42 unsigned accumulator = 0; 43 bool hasDigits = false; 44 45 for ( ; I != E; ++I) { 46 char c = *I; 47 if (c >= '0' && c <= '9') { 48 hasDigits = true; 49 accumulator = (accumulator * 10) + (c - '0'); 50 continue; 51 } 52 53 if (hasDigits) 54 return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg, 55 false); 56 57 break; 58 } 59 60 return OptionalAmount(); 61 } 62 63 OptionalAmount 64 clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg, 65 const char *E, 66 unsigned &argIndex) { 67 if (*Beg == '*') { 68 ++Beg; 69 return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false); 70 } 71 72 return ParseAmount(Beg, E); 73 } 74 75 OptionalAmount 76 clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H, 77 const char *Start, 78 const char *&Beg, 79 const char *E, 80 PositionContext p) { 81 if (*Beg == '*') { 82 const char *I = Beg + 1; 83 const OptionalAmount &Amt = ParseAmount(I, E); 84 85 if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) { 86 H.HandleInvalidPosition(Beg, I - Beg, p); 87 return OptionalAmount(false); 88 } 89 90 if (I == E) { 91 // No more characters left? 92 H.HandleIncompleteSpecifier(Start, E - Start); 93 return OptionalAmount(false); 94 } 95 96 assert(Amt.getHowSpecified() == OptionalAmount::Constant); 97 98 if (*I == '$') { 99 // Handle positional arguments 100 101 // Special case: '*0$', since this is an easy mistake. 102 if (Amt.getConstantAmount() == 0) { 103 H.HandleZeroPosition(Beg, I - Beg + 1); 104 return OptionalAmount(false); 105 } 106 107 const char *Tmp = Beg; 108 Beg = ++I; 109 110 return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1, 111 Tmp, 0, true); 112 } 113 114 H.HandleInvalidPosition(Beg, I - Beg, p); 115 return OptionalAmount(false); 116 } 117 118 return ParseAmount(Beg, E); 119 } 120 121 122 bool 123 clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H, 124 FormatSpecifier &CS, 125 const char *Start, 126 const char *&Beg, const char *E, 127 unsigned *argIndex) { 128 // FIXME: Support negative field widths. 129 if (argIndex) { 130 CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex)); 131 } 132 else { 133 const OptionalAmount Amt = 134 ParsePositionAmount(H, Start, Beg, E, 135 analyze_format_string::FieldWidthPos); 136 137 if (Amt.isInvalid()) 138 return true; 139 CS.setFieldWidth(Amt); 140 } 141 return false; 142 } 143 144 bool 145 clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H, 146 FormatSpecifier &FS, 147 const char *Start, 148 const char *&Beg, 149 const char *E) { 150 const char *I = Beg; 151 152 const OptionalAmount &Amt = ParseAmount(I, E); 153 154 if (I == E) { 155 // No more characters left? 156 H.HandleIncompleteSpecifier(Start, E - Start); 157 return true; 158 } 159 160 if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') { 161 // Warn that positional arguments are non-standard. 162 H.HandlePosition(Start, I - Start); 163 164 // Special case: '%0$', since this is an easy mistake. 165 if (Amt.getConstantAmount() == 0) { 166 H.HandleZeroPosition(Start, I - Start); 167 return true; 168 } 169 170 FS.setArgIndex(Amt.getConstantAmount() - 1); 171 FS.setUsesPositionalArg(); 172 // Update the caller's pointer if we decided to consume 173 // these characters. 174 Beg = I; 175 return false; 176 } 177 178 return false; 179 } 180 181 bool 182 clang::analyze_format_string::ParseVectorModifier(FormatStringHandler &H, 183 FormatSpecifier &FS, 184 const char *&I, 185 const char *E, 186 const LangOptions &LO) { 187 if (!LO.OpenCL) 188 return false; 189 190 const char *Start = I; 191 if (*I == 'v') { 192 ++I; 193 194 if (I == E) { 195 H.HandleIncompleteSpecifier(Start, E - Start); 196 return true; 197 } 198 199 OptionalAmount NumElts = ParseAmount(I, E); 200 if (NumElts.getHowSpecified() != OptionalAmount::Constant) { 201 H.HandleIncompleteSpecifier(Start, E - Start); 202 return true; 203 } 204 205 FS.setVectorNumElts(NumElts); 206 } 207 208 return false; 209 } 210 211 bool 212 clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS, 213 const char *&I, 214 const char *E, 215 const LangOptions &LO, 216 bool IsScanf) { 217 LengthModifier::Kind lmKind = LengthModifier::None; 218 const char *lmPosition = I; 219 switch (*I) { 220 default: 221 return false; 222 case 'h': 223 ++I; 224 if (I != E && *I == 'h') { 225 ++I; 226 lmKind = LengthModifier::AsChar; 227 } else { 228 lmKind = LengthModifier::AsShort; 229 } 230 break; 231 case 'l': 232 ++I; 233 if (I != E && *I == 'l') { 234 ++I; 235 lmKind = LengthModifier::AsLongLong; 236 } else { 237 lmKind = LengthModifier::AsLong; 238 } 239 break; 240 case 'j': lmKind = LengthModifier::AsIntMax; ++I; break; 241 case 'z': lmKind = LengthModifier::AsSizeT; ++I; break; 242 case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break; 243 case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break; 244 case 'q': lmKind = LengthModifier::AsQuad; ++I; break; 245 case 'a': 246 if (IsScanf && !LO.C99 && !LO.CPlusPlus11) { 247 // For scanf in C90, look at the next character to see if this should 248 // be parsed as the GNU extension 'a' length modifier. If not, this 249 // will be parsed as a conversion specifier. 250 ++I; 251 if (I != E && (*I == 's' || *I == 'S' || *I == '[')) { 252 lmKind = LengthModifier::AsAllocate; 253 break; 254 } 255 --I; 256 } 257 return false; 258 case 'm': 259 if (IsScanf) { 260 lmKind = LengthModifier::AsMAllocate; 261 ++I; 262 break; 263 } 264 return false; 265 // printf: AsInt64, AsInt32, AsInt3264 266 // scanf: AsInt64 267 case 'I': 268 if (I + 1 != E && I + 2 != E) { 269 if (I[1] == '6' && I[2] == '4') { 270 I += 3; 271 lmKind = LengthModifier::AsInt64; 272 break; 273 } 274 if (IsScanf) 275 return false; 276 277 if (I[1] == '3' && I[2] == '2') { 278 I += 3; 279 lmKind = LengthModifier::AsInt32; 280 break; 281 } 282 } 283 ++I; 284 lmKind = LengthModifier::AsInt3264; 285 break; 286 case 'w': 287 lmKind = LengthModifier::AsWide; ++I; break; 288 } 289 LengthModifier lm(lmPosition, lmKind); 290 FS.setLengthModifier(lm); 291 return true; 292 } 293 294 bool clang::analyze_format_string::ParseUTF8InvalidSpecifier( 295 const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) { 296 if (SpecifierBegin + 1 >= FmtStrEnd) 297 return false; 298 299 const llvm::UTF8 *SB = 300 reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1); 301 const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd); 302 const char FirstByte = *SB; 303 304 // If the invalid specifier is a multibyte UTF-8 string, return the 305 // total length accordingly so that the conversion specifier can be 306 // properly updated to reflect a complete UTF-8 specifier. 307 unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte); 308 if (NumBytes == 1) 309 return false; 310 if (SB + NumBytes > SE) 311 return false; 312 313 Len = NumBytes + 1; 314 return true; 315 } 316 317 //===----------------------------------------------------------------------===// 318 // Methods on ArgType. 319 //===----------------------------------------------------------------------===// 320 321 clang::analyze_format_string::ArgType::MatchKind 322 ArgType::matchesType(ASTContext &C, QualType argTy) const { 323 if (Ptr) { 324 // It has to be a pointer. 325 const PointerType *PT = argTy->getAs<PointerType>(); 326 if (!PT) 327 return NoMatch; 328 329 // We cannot write through a const qualified pointer. 330 if (PT->getPointeeType().isConstQualified()) 331 return NoMatch; 332 333 argTy = PT->getPointeeType(); 334 } 335 336 switch (K) { 337 case InvalidTy: 338 llvm_unreachable("ArgType must be valid"); 339 340 case UnknownTy: 341 return Match; 342 343 case AnyCharTy: { 344 if (const EnumType *ETy = argTy->getAs<EnumType>()) { 345 // If the enum is incomplete we know nothing about the underlying type. 346 // Assume that it's 'int'. 347 if (!ETy->getDecl()->isComplete()) 348 return NoMatch; 349 argTy = ETy->getDecl()->getIntegerType(); 350 } 351 352 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 353 switch (BT->getKind()) { 354 default: 355 break; 356 case BuiltinType::Char_S: 357 case BuiltinType::SChar: 358 case BuiltinType::UChar: 359 case BuiltinType::Char_U: 360 return Match; 361 } 362 return NoMatch; 363 } 364 365 case SpecificTy: { 366 if (const EnumType *ETy = argTy->getAs<EnumType>()) { 367 // If the enum is incomplete we know nothing about the underlying type. 368 // Assume that it's 'int'. 369 if (!ETy->getDecl()->isComplete()) 370 argTy = C.IntTy; 371 else 372 argTy = ETy->getDecl()->getIntegerType(); 373 } 374 argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 375 376 if (T == argTy) 377 return Match; 378 // Check for "compatible types". 379 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 380 switch (BT->getKind()) { 381 default: 382 break; 383 case BuiltinType::Char_S: 384 case BuiltinType::SChar: 385 case BuiltinType::Char_U: 386 case BuiltinType::UChar: 387 return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match 388 : NoMatch; 389 case BuiltinType::Short: 390 return T == C.UnsignedShortTy ? Match : NoMatch; 391 case BuiltinType::UShort: 392 return T == C.ShortTy ? Match : NoMatch; 393 case BuiltinType::Int: 394 return T == C.UnsignedIntTy ? Match : NoMatch; 395 case BuiltinType::UInt: 396 return T == C.IntTy ? Match : NoMatch; 397 case BuiltinType::Long: 398 return T == C.UnsignedLongTy ? Match : NoMatch; 399 case BuiltinType::ULong: 400 return T == C.LongTy ? Match : NoMatch; 401 case BuiltinType::LongLong: 402 return T == C.UnsignedLongLongTy ? Match : NoMatch; 403 case BuiltinType::ULongLong: 404 return T == C.LongLongTy ? Match : NoMatch; 405 } 406 return NoMatch; 407 } 408 409 case CStrTy: { 410 const PointerType *PT = argTy->getAs<PointerType>(); 411 if (!PT) 412 return NoMatch; 413 QualType pointeeTy = PT->getPointeeType(); 414 if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 415 switch (BT->getKind()) { 416 case BuiltinType::Void: 417 case BuiltinType::Char_U: 418 case BuiltinType::UChar: 419 case BuiltinType::Char_S: 420 case BuiltinType::SChar: 421 return Match; 422 default: 423 break; 424 } 425 426 return NoMatch; 427 } 428 429 case WCStrTy: { 430 const PointerType *PT = argTy->getAs<PointerType>(); 431 if (!PT) 432 return NoMatch; 433 QualType pointeeTy = 434 C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 435 return pointeeTy == C.getWideCharType() ? Match : NoMatch; 436 } 437 438 case WIntTy: { 439 QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); 440 441 if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt) 442 return Match; 443 444 QualType PromoArg = argTy->isPromotableIntegerType() 445 ? C.getPromotedIntegerType(argTy) 446 : argTy; 447 PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); 448 449 // If the promoted argument is the corresponding signed type of the 450 // wint_t type, then it should match. 451 if (PromoArg->hasSignedIntegerRepresentation() && 452 C.getCorrespondingUnsignedType(PromoArg) == WInt) 453 return Match; 454 455 return WInt == PromoArg ? Match : NoMatch; 456 } 457 458 case CPointerTy: 459 if (argTy->isVoidPointerType()) { 460 return Match; 461 } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() || 462 argTy->isBlockPointerType() || argTy->isNullPtrType()) { 463 return NoMatchPedantic; 464 } else { 465 return NoMatch; 466 } 467 468 case ObjCPointerTy: { 469 if (argTy->getAs<ObjCObjectPointerType>() || 470 argTy->getAs<BlockPointerType>()) 471 return Match; 472 473 // Handle implicit toll-free bridging. 474 if (const PointerType *PT = argTy->getAs<PointerType>()) { 475 // Things such as CFTypeRef are really just opaque pointers 476 // to C structs representing CF types that can often be bridged 477 // to Objective-C objects. Since the compiler doesn't know which 478 // structs can be toll-free bridged, we just accept them all. 479 QualType pointee = PT->getPointeeType(); 480 if (pointee->getAsStructureType() || pointee->isVoidType()) 481 return Match; 482 } 483 return NoMatch; 484 } 485 } 486 487 llvm_unreachable("Invalid ArgType Kind!"); 488 } 489 490 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const { 491 if (K != SpecificTy) // Won't be a valid vector element type. 492 return ArgType::Invalid(); 493 494 QualType Vec = C.getExtVectorType(T, NumElts); 495 return ArgType(Vec, Name); 496 } 497 498 QualType ArgType::getRepresentativeType(ASTContext &C) const { 499 QualType Res; 500 switch (K) { 501 case InvalidTy: 502 llvm_unreachable("No representative type for Invalid ArgType"); 503 case UnknownTy: 504 llvm_unreachable("No representative type for Unknown ArgType"); 505 case AnyCharTy: 506 Res = C.CharTy; 507 break; 508 case SpecificTy: 509 Res = T; 510 break; 511 case CStrTy: 512 Res = C.getPointerType(C.CharTy); 513 break; 514 case WCStrTy: 515 Res = C.getPointerType(C.getWideCharType()); 516 break; 517 case ObjCPointerTy: 518 Res = C.ObjCBuiltinIdTy; 519 break; 520 case CPointerTy: 521 Res = C.VoidPtrTy; 522 break; 523 case WIntTy: { 524 Res = C.getWIntType(); 525 break; 526 } 527 } 528 529 if (Ptr) 530 Res = C.getPointerType(Res); 531 return Res; 532 } 533 534 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const { 535 std::string S = getRepresentativeType(C).getAsString(); 536 537 std::string Alias; 538 if (Name) { 539 // Use a specific name for this type, e.g. "size_t". 540 Alias = Name; 541 if (Ptr) { 542 // If ArgType is actually a pointer to T, append an asterisk. 543 Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *"; 544 } 545 // If Alias is the same as the underlying type, e.g. wchar_t, then drop it. 546 if (S == Alias) 547 Alias.clear(); 548 } 549 550 if (!Alias.empty()) 551 return std::string("'") + Alias + "' (aka '" + S + "')"; 552 return std::string("'") + S + "'"; 553 } 554 555 556 //===----------------------------------------------------------------------===// 557 // Methods on OptionalAmount. 558 //===----------------------------------------------------------------------===// 559 560 ArgType 561 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { 562 return Ctx.IntTy; 563 } 564 565 //===----------------------------------------------------------------------===// 566 // Methods on LengthModifier. 567 //===----------------------------------------------------------------------===// 568 569 const char * 570 analyze_format_string::LengthModifier::toString() const { 571 switch (kind) { 572 case AsChar: 573 return "hh"; 574 case AsShort: 575 return "h"; 576 case AsLong: // or AsWideChar 577 return "l"; 578 case AsLongLong: 579 return "ll"; 580 case AsQuad: 581 return "q"; 582 case AsIntMax: 583 return "j"; 584 case AsSizeT: 585 return "z"; 586 case AsPtrDiff: 587 return "t"; 588 case AsInt32: 589 return "I32"; 590 case AsInt3264: 591 return "I"; 592 case AsInt64: 593 return "I64"; 594 case AsLongDouble: 595 return "L"; 596 case AsAllocate: 597 return "a"; 598 case AsMAllocate: 599 return "m"; 600 case AsWide: 601 return "w"; 602 case None: 603 return ""; 604 } 605 return nullptr; 606 } 607 608 //===----------------------------------------------------------------------===// 609 // Methods on ConversionSpecifier. 610 //===----------------------------------------------------------------------===// 611 612 const char *ConversionSpecifier::toString() const { 613 switch (kind) { 614 case dArg: return "d"; 615 case DArg: return "D"; 616 case iArg: return "i"; 617 case oArg: return "o"; 618 case OArg: return "O"; 619 case uArg: return "u"; 620 case UArg: return "U"; 621 case xArg: return "x"; 622 case XArg: return "X"; 623 case fArg: return "f"; 624 case FArg: return "F"; 625 case eArg: return "e"; 626 case EArg: return "E"; 627 case gArg: return "g"; 628 case GArg: return "G"; 629 case aArg: return "a"; 630 case AArg: return "A"; 631 case cArg: return "c"; 632 case sArg: return "s"; 633 case pArg: return "p"; 634 case PArg: 635 return "P"; 636 case nArg: return "n"; 637 case PercentArg: return "%"; 638 case ScanListArg: return "["; 639 case InvalidSpecifier: return nullptr; 640 641 // POSIX unicode extensions. 642 case CArg: return "C"; 643 case SArg: return "S"; 644 645 // Objective-C specific specifiers. 646 case ObjCObjArg: return "@"; 647 648 // FreeBSD kernel specific specifiers. 649 case FreeBSDbArg: return "b"; 650 case FreeBSDDArg: return "D"; 651 case FreeBSDrArg: return "r"; 652 case FreeBSDyArg: return "y"; 653 654 // GlibC specific specifiers. 655 case PrintErrno: return "m"; 656 657 // MS specific specifiers. 658 case ZArg: return "Z"; 659 } 660 return nullptr; 661 } 662 663 Optional<ConversionSpecifier> 664 ConversionSpecifier::getStandardSpecifier() const { 665 ConversionSpecifier::Kind NewKind; 666 667 switch (getKind()) { 668 default: 669 return None; 670 case DArg: 671 NewKind = dArg; 672 break; 673 case UArg: 674 NewKind = uArg; 675 break; 676 case OArg: 677 NewKind = oArg; 678 break; 679 } 680 681 ConversionSpecifier FixedCS(*this); 682 FixedCS.setKind(NewKind); 683 return FixedCS; 684 } 685 686 //===----------------------------------------------------------------------===// 687 // Methods on OptionalAmount. 688 //===----------------------------------------------------------------------===// 689 690 void OptionalAmount::toString(raw_ostream &os) const { 691 switch (hs) { 692 case Invalid: 693 case NotSpecified: 694 return; 695 case Arg: 696 if (UsesDotPrefix) 697 os << "."; 698 if (usesPositionalArg()) 699 os << "*" << getPositionalArgIndex() << "$"; 700 else 701 os << "*"; 702 break; 703 case Constant: 704 if (UsesDotPrefix) 705 os << "."; 706 os << amt; 707 break; 708 } 709 } 710 711 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { 712 switch (LM.getKind()) { 713 case LengthModifier::None: 714 return true; 715 716 // Handle most integer flags 717 case LengthModifier::AsShort: 718 if (Target.getTriple().isOSMSVCRT()) { 719 switch (CS.getKind()) { 720 case ConversionSpecifier::cArg: 721 case ConversionSpecifier::CArg: 722 case ConversionSpecifier::sArg: 723 case ConversionSpecifier::SArg: 724 case ConversionSpecifier::ZArg: 725 return true; 726 default: 727 break; 728 } 729 } 730 LLVM_FALLTHROUGH; 731 case LengthModifier::AsChar: 732 case LengthModifier::AsLongLong: 733 case LengthModifier::AsQuad: 734 case LengthModifier::AsIntMax: 735 case LengthModifier::AsSizeT: 736 case LengthModifier::AsPtrDiff: 737 switch (CS.getKind()) { 738 case ConversionSpecifier::dArg: 739 case ConversionSpecifier::DArg: 740 case ConversionSpecifier::iArg: 741 case ConversionSpecifier::oArg: 742 case ConversionSpecifier::OArg: 743 case ConversionSpecifier::uArg: 744 case ConversionSpecifier::UArg: 745 case ConversionSpecifier::xArg: 746 case ConversionSpecifier::XArg: 747 case ConversionSpecifier::nArg: 748 return true; 749 case ConversionSpecifier::FreeBSDrArg: 750 case ConversionSpecifier::FreeBSDyArg: 751 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 752 default: 753 return false; 754 } 755 756 // Handle 'l' flag 757 case LengthModifier::AsLong: // or AsWideChar 758 switch (CS.getKind()) { 759 case ConversionSpecifier::dArg: 760 case ConversionSpecifier::DArg: 761 case ConversionSpecifier::iArg: 762 case ConversionSpecifier::oArg: 763 case ConversionSpecifier::OArg: 764 case ConversionSpecifier::uArg: 765 case ConversionSpecifier::UArg: 766 case ConversionSpecifier::xArg: 767 case ConversionSpecifier::XArg: 768 case ConversionSpecifier::aArg: 769 case ConversionSpecifier::AArg: 770 case ConversionSpecifier::fArg: 771 case ConversionSpecifier::FArg: 772 case ConversionSpecifier::eArg: 773 case ConversionSpecifier::EArg: 774 case ConversionSpecifier::gArg: 775 case ConversionSpecifier::GArg: 776 case ConversionSpecifier::nArg: 777 case ConversionSpecifier::cArg: 778 case ConversionSpecifier::sArg: 779 case ConversionSpecifier::ScanListArg: 780 case ConversionSpecifier::ZArg: 781 return true; 782 case ConversionSpecifier::FreeBSDrArg: 783 case ConversionSpecifier::FreeBSDyArg: 784 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 785 default: 786 return false; 787 } 788 789 case LengthModifier::AsLongDouble: 790 switch (CS.getKind()) { 791 case ConversionSpecifier::aArg: 792 case ConversionSpecifier::AArg: 793 case ConversionSpecifier::fArg: 794 case ConversionSpecifier::FArg: 795 case ConversionSpecifier::eArg: 796 case ConversionSpecifier::EArg: 797 case ConversionSpecifier::gArg: 798 case ConversionSpecifier::GArg: 799 return true; 800 // GNU libc extension. 801 case ConversionSpecifier::dArg: 802 case ConversionSpecifier::iArg: 803 case ConversionSpecifier::oArg: 804 case ConversionSpecifier::uArg: 805 case ConversionSpecifier::xArg: 806 case ConversionSpecifier::XArg: 807 return !Target.getTriple().isOSDarwin() && 808 !Target.getTriple().isOSWindows(); 809 default: 810 return false; 811 } 812 813 case LengthModifier::AsAllocate: 814 switch (CS.getKind()) { 815 case ConversionSpecifier::sArg: 816 case ConversionSpecifier::SArg: 817 case ConversionSpecifier::ScanListArg: 818 return true; 819 default: 820 return false; 821 } 822 823 case LengthModifier::AsMAllocate: 824 switch (CS.getKind()) { 825 case ConversionSpecifier::cArg: 826 case ConversionSpecifier::CArg: 827 case ConversionSpecifier::sArg: 828 case ConversionSpecifier::SArg: 829 case ConversionSpecifier::ScanListArg: 830 return true; 831 default: 832 return false; 833 } 834 case LengthModifier::AsInt32: 835 case LengthModifier::AsInt3264: 836 case LengthModifier::AsInt64: 837 switch (CS.getKind()) { 838 case ConversionSpecifier::dArg: 839 case ConversionSpecifier::iArg: 840 case ConversionSpecifier::oArg: 841 case ConversionSpecifier::uArg: 842 case ConversionSpecifier::xArg: 843 case ConversionSpecifier::XArg: 844 return Target.getTriple().isOSMSVCRT(); 845 default: 846 return false; 847 } 848 case LengthModifier::AsWide: 849 switch (CS.getKind()) { 850 case ConversionSpecifier::cArg: 851 case ConversionSpecifier::CArg: 852 case ConversionSpecifier::sArg: 853 case ConversionSpecifier::SArg: 854 case ConversionSpecifier::ZArg: 855 return Target.getTriple().isOSMSVCRT(); 856 default: 857 return false; 858 } 859 } 860 llvm_unreachable("Invalid LengthModifier Kind!"); 861 } 862 863 bool FormatSpecifier::hasStandardLengthModifier() const { 864 switch (LM.getKind()) { 865 case LengthModifier::None: 866 case LengthModifier::AsChar: 867 case LengthModifier::AsShort: 868 case LengthModifier::AsLong: 869 case LengthModifier::AsLongLong: 870 case LengthModifier::AsIntMax: 871 case LengthModifier::AsSizeT: 872 case LengthModifier::AsPtrDiff: 873 case LengthModifier::AsLongDouble: 874 return true; 875 case LengthModifier::AsAllocate: 876 case LengthModifier::AsMAllocate: 877 case LengthModifier::AsQuad: 878 case LengthModifier::AsInt32: 879 case LengthModifier::AsInt3264: 880 case LengthModifier::AsInt64: 881 case LengthModifier::AsWide: 882 return false; 883 } 884 llvm_unreachable("Invalid LengthModifier Kind!"); 885 } 886 887 bool FormatSpecifier::hasStandardConversionSpecifier( 888 const LangOptions &LangOpt) const { 889 switch (CS.getKind()) { 890 case ConversionSpecifier::cArg: 891 case ConversionSpecifier::dArg: 892 case ConversionSpecifier::iArg: 893 case ConversionSpecifier::oArg: 894 case ConversionSpecifier::uArg: 895 case ConversionSpecifier::xArg: 896 case ConversionSpecifier::XArg: 897 case ConversionSpecifier::fArg: 898 case ConversionSpecifier::FArg: 899 case ConversionSpecifier::eArg: 900 case ConversionSpecifier::EArg: 901 case ConversionSpecifier::gArg: 902 case ConversionSpecifier::GArg: 903 case ConversionSpecifier::aArg: 904 case ConversionSpecifier::AArg: 905 case ConversionSpecifier::sArg: 906 case ConversionSpecifier::pArg: 907 case ConversionSpecifier::nArg: 908 case ConversionSpecifier::ObjCObjArg: 909 case ConversionSpecifier::ScanListArg: 910 case ConversionSpecifier::PercentArg: 911 case ConversionSpecifier::PArg: 912 return true; 913 case ConversionSpecifier::CArg: 914 case ConversionSpecifier::SArg: 915 return LangOpt.ObjC; 916 case ConversionSpecifier::InvalidSpecifier: 917 case ConversionSpecifier::FreeBSDbArg: 918 case ConversionSpecifier::FreeBSDDArg: 919 case ConversionSpecifier::FreeBSDrArg: 920 case ConversionSpecifier::FreeBSDyArg: 921 case ConversionSpecifier::PrintErrno: 922 case ConversionSpecifier::DArg: 923 case ConversionSpecifier::OArg: 924 case ConversionSpecifier::UArg: 925 case ConversionSpecifier::ZArg: 926 return false; 927 } 928 llvm_unreachable("Invalid ConversionSpecifier Kind!"); 929 } 930 931 bool FormatSpecifier::hasStandardLengthConversionCombination() const { 932 if (LM.getKind() == LengthModifier::AsLongDouble) { 933 switch(CS.getKind()) { 934 case ConversionSpecifier::dArg: 935 case ConversionSpecifier::iArg: 936 case ConversionSpecifier::oArg: 937 case ConversionSpecifier::uArg: 938 case ConversionSpecifier::xArg: 939 case ConversionSpecifier::XArg: 940 return false; 941 default: 942 return true; 943 } 944 } 945 return true; 946 } 947 948 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { 949 if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { 950 if (LM.getKind() == LengthModifier::AsLongDouble || 951 LM.getKind() == LengthModifier::AsQuad) { 952 LengthModifier FixedLM(LM); 953 FixedLM.setKind(LengthModifier::AsLongLong); 954 return FixedLM; 955 } 956 } 957 958 return None; 959 } 960 961 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 962 LengthModifier &LM) { 963 assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 964 const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 965 966 for (;;) { 967 const IdentifierInfo *Identifier = Typedef->getIdentifier(); 968 if (Identifier->getName() == "size_t") { 969 LM.setKind(LengthModifier::AsSizeT); 970 return true; 971 } else if (Identifier->getName() == "ssize_t") { 972 // Not C99, but common in Unix. 973 LM.setKind(LengthModifier::AsSizeT); 974 return true; 975 } else if (Identifier->getName() == "intmax_t") { 976 LM.setKind(LengthModifier::AsIntMax); 977 return true; 978 } else if (Identifier->getName() == "uintmax_t") { 979 LM.setKind(LengthModifier::AsIntMax); 980 return true; 981 } else if (Identifier->getName() == "ptrdiff_t") { 982 LM.setKind(LengthModifier::AsPtrDiff); 983 return true; 984 } 985 986 QualType T = Typedef->getUnderlyingType(); 987 if (!isa<TypedefType>(T)) 988 break; 989 990 Typedef = cast<TypedefType>(T)->getDecl(); 991 } 992 return false; 993 } 994