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 bool ArgType::matchesType(ASTContext &C, QualType argTy) const { 260 if (Ptr) { 261 // It has to be a pointer. 262 const PointerType *PT = argTy->getAs<PointerType>(); 263 if (!PT) 264 return false; 265 266 // We cannot write through a const qualified pointer. 267 if (PT->getPointeeType().isConstQualified()) 268 return false; 269 270 argTy = PT->getPointeeType(); 271 } 272 273 switch (K) { 274 case InvalidTy: 275 llvm_unreachable("ArgType must be valid"); 276 277 case UnknownTy: 278 return true; 279 280 case AnyCharTy: { 281 if (const EnumType *ETy = argTy->getAs<EnumType>()) 282 argTy = ETy->getDecl()->getIntegerType(); 283 284 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 285 switch (BT->getKind()) { 286 default: 287 break; 288 case BuiltinType::Char_S: 289 case BuiltinType::SChar: 290 case BuiltinType::UChar: 291 case BuiltinType::Char_U: 292 return true; 293 } 294 return false; 295 } 296 297 case SpecificTy: { 298 if (const EnumType *ETy = argTy->getAs<EnumType>()) 299 argTy = ETy->getDecl()->getIntegerType(); 300 argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 301 302 if (T == argTy) 303 return true; 304 // Check for "compatible types". 305 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 306 switch (BT->getKind()) { 307 default: 308 break; 309 case BuiltinType::Char_S: 310 case BuiltinType::SChar: 311 case BuiltinType::Char_U: 312 case BuiltinType::UChar: 313 return T == C.UnsignedCharTy || T == C.SignedCharTy; 314 case BuiltinType::Short: 315 return T == C.UnsignedShortTy; 316 case BuiltinType::UShort: 317 return T == C.ShortTy; 318 case BuiltinType::Int: 319 return T == C.UnsignedIntTy; 320 case BuiltinType::UInt: 321 return T == C.IntTy; 322 case BuiltinType::Long: 323 return T == C.UnsignedLongTy; 324 case BuiltinType::ULong: 325 return T == C.LongTy; 326 case BuiltinType::LongLong: 327 return T == C.UnsignedLongLongTy; 328 case BuiltinType::ULongLong: 329 return T == C.LongLongTy; 330 } 331 return false; 332 } 333 334 case CStrTy: { 335 const PointerType *PT = argTy->getAs<PointerType>(); 336 if (!PT) 337 return false; 338 QualType pointeeTy = PT->getPointeeType(); 339 if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 340 switch (BT->getKind()) { 341 case BuiltinType::Void: 342 case BuiltinType::Char_U: 343 case BuiltinType::UChar: 344 case BuiltinType::Char_S: 345 case BuiltinType::SChar: 346 return true; 347 default: 348 break; 349 } 350 351 return false; 352 } 353 354 case WCStrTy: { 355 const PointerType *PT = argTy->getAs<PointerType>(); 356 if (!PT) 357 return false; 358 QualType pointeeTy = 359 C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 360 return pointeeTy == C.getWideCharType(); 361 } 362 363 case WIntTy: { 364 365 QualType PromoArg = 366 argTy->isPromotableIntegerType() 367 ? C.getPromotedIntegerType(argTy) : argTy; 368 369 QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); 370 PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); 371 372 // If the promoted argument is the corresponding signed type of the 373 // wint_t type, then it should match. 374 if (PromoArg->hasSignedIntegerRepresentation() && 375 C.getCorrespondingUnsignedType(PromoArg) == WInt) 376 return true; 377 378 return WInt == PromoArg; 379 } 380 381 case CPointerTy: 382 return argTy->isPointerType() || argTy->isObjCObjectPointerType() || 383 argTy->isBlockPointerType() || argTy->isNullPtrType(); 384 385 case ObjCPointerTy: { 386 if (argTy->getAs<ObjCObjectPointerType>() || 387 argTy->getAs<BlockPointerType>()) 388 return true; 389 390 // Handle implicit toll-free bridging. 391 if (const PointerType *PT = argTy->getAs<PointerType>()) { 392 // Things such as CFTypeRef are really just opaque pointers 393 // to C structs representing CF types that can often be bridged 394 // to Objective-C objects. Since the compiler doesn't know which 395 // structs can be toll-free bridged, we just accept them all. 396 QualType pointee = PT->getPointeeType(); 397 if (pointee->getAsStructureType() || pointee->isVoidType()) 398 return true; 399 } 400 return false; 401 } 402 } 403 404 llvm_unreachable("Invalid ArgType Kind!"); 405 } 406 407 QualType ArgType::getRepresentativeType(ASTContext &C) const { 408 QualType Res; 409 switch (K) { 410 case InvalidTy: 411 llvm_unreachable("No representative type for Invalid ArgType"); 412 case UnknownTy: 413 llvm_unreachable("No representative type for Unknown ArgType"); 414 case AnyCharTy: 415 Res = C.CharTy; 416 break; 417 case SpecificTy: 418 Res = T; 419 break; 420 case CStrTy: 421 Res = C.getPointerType(C.CharTy); 422 break; 423 case WCStrTy: 424 Res = C.getPointerType(C.getWideCharType()); 425 break; 426 case ObjCPointerTy: 427 Res = C.ObjCBuiltinIdTy; 428 break; 429 case CPointerTy: 430 Res = C.VoidPtrTy; 431 break; 432 case WIntTy: { 433 Res = C.getWIntType(); 434 break; 435 } 436 } 437 438 if (Ptr) 439 Res = C.getPointerType(Res); 440 return Res; 441 } 442 443 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const { 444 std::string S = getRepresentativeType(C).getAsString(); 445 446 std::string Alias; 447 if (Name) { 448 // Use a specific name for this type, e.g. "size_t". 449 Alias = Name; 450 if (Ptr) { 451 // If ArgType is actually a pointer to T, append an asterisk. 452 Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *"; 453 } 454 // If Alias is the same as the underlying type, e.g. wchar_t, then drop it. 455 if (S == Alias) 456 Alias.clear(); 457 } 458 459 if (!Alias.empty()) 460 return std::string("'") + Alias + "' (aka '" + S + "')"; 461 return std::string("'") + S + "'"; 462 } 463 464 465 //===----------------------------------------------------------------------===// 466 // Methods on OptionalAmount. 467 //===----------------------------------------------------------------------===// 468 469 ArgType 470 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { 471 return Ctx.IntTy; 472 } 473 474 //===----------------------------------------------------------------------===// 475 // Methods on LengthModifier. 476 //===----------------------------------------------------------------------===// 477 478 const char * 479 analyze_format_string::LengthModifier::toString() const { 480 switch (kind) { 481 case AsChar: 482 return "hh"; 483 case AsShort: 484 return "h"; 485 case AsLong: // or AsWideChar 486 return "l"; 487 case AsLongLong: 488 return "ll"; 489 case AsQuad: 490 return "q"; 491 case AsIntMax: 492 return "j"; 493 case AsSizeT: 494 return "z"; 495 case AsPtrDiff: 496 return "t"; 497 case AsInt32: 498 return "I32"; 499 case AsInt3264: 500 return "I"; 501 case AsInt64: 502 return "I64"; 503 case AsLongDouble: 504 return "L"; 505 case AsAllocate: 506 return "a"; 507 case AsMAllocate: 508 return "m"; 509 case AsWide: 510 return "w"; 511 case None: 512 return ""; 513 } 514 return nullptr; 515 } 516 517 //===----------------------------------------------------------------------===// 518 // Methods on ConversionSpecifier. 519 //===----------------------------------------------------------------------===// 520 521 const char *ConversionSpecifier::toString() const { 522 switch (kind) { 523 case dArg: return "d"; 524 case DArg: return "D"; 525 case iArg: return "i"; 526 case oArg: return "o"; 527 case OArg: return "O"; 528 case uArg: return "u"; 529 case UArg: return "U"; 530 case xArg: return "x"; 531 case XArg: return "X"; 532 case fArg: return "f"; 533 case FArg: return "F"; 534 case eArg: return "e"; 535 case EArg: return "E"; 536 case gArg: return "g"; 537 case GArg: return "G"; 538 case aArg: return "a"; 539 case AArg: return "A"; 540 case cArg: return "c"; 541 case sArg: return "s"; 542 case pArg: return "p"; 543 case nArg: return "n"; 544 case PercentArg: return "%"; 545 case ScanListArg: return "["; 546 case InvalidSpecifier: return nullptr; 547 548 // POSIX unicode extensions. 549 case CArg: return "C"; 550 case SArg: return "S"; 551 552 // Objective-C specific specifiers. 553 case ObjCObjArg: return "@"; 554 555 // GlibC specific specifiers. 556 case PrintErrno: return "m"; 557 558 // MS specific specifiers. 559 case ZArg: return "Z"; 560 } 561 return nullptr; 562 } 563 564 Optional<ConversionSpecifier> 565 ConversionSpecifier::getStandardSpecifier() const { 566 ConversionSpecifier::Kind NewKind; 567 568 switch (getKind()) { 569 default: 570 return None; 571 case DArg: 572 NewKind = dArg; 573 break; 574 case UArg: 575 NewKind = uArg; 576 break; 577 case OArg: 578 NewKind = oArg; 579 break; 580 } 581 582 ConversionSpecifier FixedCS(*this); 583 FixedCS.setKind(NewKind); 584 return FixedCS; 585 } 586 587 //===----------------------------------------------------------------------===// 588 // Methods on OptionalAmount. 589 //===----------------------------------------------------------------------===// 590 591 void OptionalAmount::toString(raw_ostream &os) const { 592 switch (hs) { 593 case Invalid: 594 case NotSpecified: 595 return; 596 case Arg: 597 if (UsesDotPrefix) 598 os << "."; 599 if (usesPositionalArg()) 600 os << "*" << getPositionalArgIndex() << "$"; 601 else 602 os << "*"; 603 break; 604 case Constant: 605 if (UsesDotPrefix) 606 os << "."; 607 os << amt; 608 break; 609 } 610 } 611 612 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { 613 switch (LM.getKind()) { 614 case LengthModifier::None: 615 return true; 616 617 // Handle most integer flags 618 case LengthModifier::AsShort: 619 if (Target.getTriple().isOSMSVCRT()) { 620 switch (CS.getKind()) { 621 case ConversionSpecifier::cArg: 622 case ConversionSpecifier::CArg: 623 case ConversionSpecifier::sArg: 624 case ConversionSpecifier::SArg: 625 case ConversionSpecifier::ZArg: 626 return true; 627 default: 628 break; 629 } 630 } 631 // Fall through. 632 case LengthModifier::AsChar: 633 case LengthModifier::AsLongLong: 634 case LengthModifier::AsQuad: 635 case LengthModifier::AsIntMax: 636 case LengthModifier::AsSizeT: 637 case LengthModifier::AsPtrDiff: 638 switch (CS.getKind()) { 639 case ConversionSpecifier::dArg: 640 case ConversionSpecifier::DArg: 641 case ConversionSpecifier::iArg: 642 case ConversionSpecifier::oArg: 643 case ConversionSpecifier::OArg: 644 case ConversionSpecifier::uArg: 645 case ConversionSpecifier::UArg: 646 case ConversionSpecifier::xArg: 647 case ConversionSpecifier::XArg: 648 case ConversionSpecifier::nArg: 649 return true; 650 default: 651 return false; 652 } 653 654 // Handle 'l' flag 655 case LengthModifier::AsLong: // or AsWideChar 656 switch (CS.getKind()) { 657 case ConversionSpecifier::dArg: 658 case ConversionSpecifier::DArg: 659 case ConversionSpecifier::iArg: 660 case ConversionSpecifier::oArg: 661 case ConversionSpecifier::OArg: 662 case ConversionSpecifier::uArg: 663 case ConversionSpecifier::UArg: 664 case ConversionSpecifier::xArg: 665 case ConversionSpecifier::XArg: 666 case ConversionSpecifier::aArg: 667 case ConversionSpecifier::AArg: 668 case ConversionSpecifier::fArg: 669 case ConversionSpecifier::FArg: 670 case ConversionSpecifier::eArg: 671 case ConversionSpecifier::EArg: 672 case ConversionSpecifier::gArg: 673 case ConversionSpecifier::GArg: 674 case ConversionSpecifier::nArg: 675 case ConversionSpecifier::cArg: 676 case ConversionSpecifier::sArg: 677 case ConversionSpecifier::ScanListArg: 678 case ConversionSpecifier::ZArg: 679 return true; 680 default: 681 return false; 682 } 683 684 case LengthModifier::AsLongDouble: 685 switch (CS.getKind()) { 686 case ConversionSpecifier::aArg: 687 case ConversionSpecifier::AArg: 688 case ConversionSpecifier::fArg: 689 case ConversionSpecifier::FArg: 690 case ConversionSpecifier::eArg: 691 case ConversionSpecifier::EArg: 692 case ConversionSpecifier::gArg: 693 case ConversionSpecifier::GArg: 694 return true; 695 // GNU libc extension. 696 case ConversionSpecifier::dArg: 697 case ConversionSpecifier::iArg: 698 case ConversionSpecifier::oArg: 699 case ConversionSpecifier::uArg: 700 case ConversionSpecifier::xArg: 701 case ConversionSpecifier::XArg: 702 return !Target.getTriple().isOSDarwin() && 703 !Target.getTriple().isOSWindows(); 704 default: 705 return false; 706 } 707 708 case LengthModifier::AsAllocate: 709 switch (CS.getKind()) { 710 case ConversionSpecifier::sArg: 711 case ConversionSpecifier::SArg: 712 case ConversionSpecifier::ScanListArg: 713 return true; 714 default: 715 return false; 716 } 717 718 case LengthModifier::AsMAllocate: 719 switch (CS.getKind()) { 720 case ConversionSpecifier::cArg: 721 case ConversionSpecifier::CArg: 722 case ConversionSpecifier::sArg: 723 case ConversionSpecifier::SArg: 724 case ConversionSpecifier::ScanListArg: 725 return true; 726 default: 727 return false; 728 } 729 case LengthModifier::AsInt32: 730 case LengthModifier::AsInt3264: 731 case LengthModifier::AsInt64: 732 switch (CS.getKind()) { 733 case ConversionSpecifier::dArg: 734 case ConversionSpecifier::iArg: 735 case ConversionSpecifier::oArg: 736 case ConversionSpecifier::uArg: 737 case ConversionSpecifier::xArg: 738 case ConversionSpecifier::XArg: 739 return Target.getTriple().isOSMSVCRT(); 740 default: 741 return false; 742 } 743 case LengthModifier::AsWide: 744 switch (CS.getKind()) { 745 case ConversionSpecifier::cArg: 746 case ConversionSpecifier::CArg: 747 case ConversionSpecifier::sArg: 748 case ConversionSpecifier::SArg: 749 case ConversionSpecifier::ZArg: 750 return Target.getTriple().isOSMSVCRT(); 751 default: 752 return false; 753 } 754 } 755 llvm_unreachable("Invalid LengthModifier Kind!"); 756 } 757 758 bool FormatSpecifier::hasStandardLengthModifier() const { 759 switch (LM.getKind()) { 760 case LengthModifier::None: 761 case LengthModifier::AsChar: 762 case LengthModifier::AsShort: 763 case LengthModifier::AsLong: 764 case LengthModifier::AsLongLong: 765 case LengthModifier::AsIntMax: 766 case LengthModifier::AsSizeT: 767 case LengthModifier::AsPtrDiff: 768 case LengthModifier::AsLongDouble: 769 return true; 770 case LengthModifier::AsAllocate: 771 case LengthModifier::AsMAllocate: 772 case LengthModifier::AsQuad: 773 case LengthModifier::AsInt32: 774 case LengthModifier::AsInt3264: 775 case LengthModifier::AsInt64: 776 case LengthModifier::AsWide: 777 return false; 778 } 779 llvm_unreachable("Invalid LengthModifier Kind!"); 780 } 781 782 bool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt) const { 783 switch (CS.getKind()) { 784 case ConversionSpecifier::cArg: 785 case ConversionSpecifier::dArg: 786 case ConversionSpecifier::iArg: 787 case ConversionSpecifier::oArg: 788 case ConversionSpecifier::uArg: 789 case ConversionSpecifier::xArg: 790 case ConversionSpecifier::XArg: 791 case ConversionSpecifier::fArg: 792 case ConversionSpecifier::FArg: 793 case ConversionSpecifier::eArg: 794 case ConversionSpecifier::EArg: 795 case ConversionSpecifier::gArg: 796 case ConversionSpecifier::GArg: 797 case ConversionSpecifier::aArg: 798 case ConversionSpecifier::AArg: 799 case ConversionSpecifier::sArg: 800 case ConversionSpecifier::pArg: 801 case ConversionSpecifier::nArg: 802 case ConversionSpecifier::ObjCObjArg: 803 case ConversionSpecifier::ScanListArg: 804 case ConversionSpecifier::PercentArg: 805 return true; 806 case ConversionSpecifier::CArg: 807 case ConversionSpecifier::SArg: 808 return LangOpt.ObjC1 || LangOpt.ObjC2; 809 case ConversionSpecifier::InvalidSpecifier: 810 case ConversionSpecifier::PrintErrno: 811 case ConversionSpecifier::DArg: 812 case ConversionSpecifier::OArg: 813 case ConversionSpecifier::UArg: 814 case ConversionSpecifier::ZArg: 815 return false; 816 } 817 llvm_unreachable("Invalid ConversionSpecifier Kind!"); 818 } 819 820 bool FormatSpecifier::hasStandardLengthConversionCombination() const { 821 if (LM.getKind() == LengthModifier::AsLongDouble) { 822 switch(CS.getKind()) { 823 case ConversionSpecifier::dArg: 824 case ConversionSpecifier::iArg: 825 case ConversionSpecifier::oArg: 826 case ConversionSpecifier::uArg: 827 case ConversionSpecifier::xArg: 828 case ConversionSpecifier::XArg: 829 return false; 830 default: 831 return true; 832 } 833 } 834 return true; 835 } 836 837 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { 838 if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { 839 if (LM.getKind() == LengthModifier::AsLongDouble || 840 LM.getKind() == LengthModifier::AsQuad) { 841 LengthModifier FixedLM(LM); 842 FixedLM.setKind(LengthModifier::AsLongLong); 843 return FixedLM; 844 } 845 } 846 847 return None; 848 } 849 850 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 851 LengthModifier &LM) { 852 assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 853 const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 854 855 for (;;) { 856 const IdentifierInfo *Identifier = Typedef->getIdentifier(); 857 if (Identifier->getName() == "size_t") { 858 LM.setKind(LengthModifier::AsSizeT); 859 return true; 860 } else if (Identifier->getName() == "ssize_t") { 861 // Not C99, but common in Unix. 862 LM.setKind(LengthModifier::AsSizeT); 863 return true; 864 } else if (Identifier->getName() == "intmax_t") { 865 LM.setKind(LengthModifier::AsIntMax); 866 return true; 867 } else if (Identifier->getName() == "uintmax_t") { 868 LM.setKind(LengthModifier::AsIntMax); 869 return true; 870 } else if (Identifier->getName() == "ptrdiff_t") { 871 LM.setKind(LengthModifier::AsPtrDiff); 872 return true; 873 } 874 875 QualType T = Typedef->getUnderlyingType(); 876 if (!isa<TypedefType>(T)) 877 break; 878 879 Typedef = cast<TypedefType>(T)->getDecl(); 880 } 881 return false; 882 } 883