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