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