PrintfFormatString.cpp revision cc9aa159c15c524f4a5fc73ac90e02a8578e9d29
1//= PrintfFormatStrings.cpp - Analysis of printf format strings --*- C++ -*-==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Handling of format string in printf and friends. The structure of format 11// strings for fprintf() are described in C99 7.19.6.1. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/Analysis/Analyses/PrintfFormatString.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/Type.h" 18#include "llvm/Support/raw_ostream.h" 19 20using clang::analyze_printf::ArgTypeResult; 21using clang::analyze_printf::FormatSpecifier; 22using clang::analyze_printf::FormatStringHandler; 23using clang::analyze_printf::OptionalAmount; 24using clang::analyze_printf::PositionContext; 25using clang::analyze_printf::ConversionSpecifier; 26using clang::analyze_printf::LengthModifier; 27 28using namespace clang; 29 30namespace { 31class FormatSpecifierResult { 32 FormatSpecifier FS; 33 const char *Start; 34 bool Stop; 35public: 36 FormatSpecifierResult(bool stop = false) 37 : Start(0), Stop(stop) {} 38 FormatSpecifierResult(const char *start, 39 const FormatSpecifier &fs) 40 : FS(fs), Start(start), Stop(false) {} 41 42 const char *getStart() const { return Start; } 43 bool shouldStop() const { return Stop; } 44 bool hasValue() const { return Start != 0; } 45 const FormatSpecifier &getValue() const { 46 assert(hasValue()); 47 return FS; 48 } 49 const FormatSpecifier &getValue() { return FS; } 50}; 51} // end anonymous namespace 52 53template <typename T> 54class UpdateOnReturn { 55 T &ValueToUpdate; 56 const T &ValueToCopy; 57public: 58 UpdateOnReturn(T &valueToUpdate, const T &valueToCopy) 59 : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {} 60 61 ~UpdateOnReturn() { 62 ValueToUpdate = ValueToCopy; 63 } 64}; 65 66//===----------------------------------------------------------------------===// 67// Methods for parsing format strings. 68//===----------------------------------------------------------------------===// 69 70static OptionalAmount ParseAmount(const char *&Beg, const char *E) { 71 const char *I = Beg; 72 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 73 74 unsigned accumulator = 0; 75 bool hasDigits = false; 76 77 for ( ; I != E; ++I) { 78 char c = *I; 79 if (c >= '0' && c <= '9') { 80 hasDigits = true; 81 accumulator = (accumulator * 10) + (c - '0'); 82 continue; 83 } 84 85 if (hasDigits) 86 return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg, 87 false); 88 89 break; 90 } 91 92 return OptionalAmount(); 93} 94 95static OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, 96 unsigned &argIndex) { 97 if (*Beg == '*') { 98 ++Beg; 99 return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false); 100 } 101 102 return ParseAmount(Beg, E); 103} 104 105static OptionalAmount ParsePositionAmount(FormatStringHandler &H, 106 const char *Start, 107 const char *&Beg, const char *E, 108 PositionContext p) { 109 if (*Beg == '*') { 110 const char *I = Beg + 1; 111 const OptionalAmount &Amt = ParseAmount(I, E); 112 113 if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) { 114 H.HandleInvalidPosition(Beg, I - Beg, p); 115 return OptionalAmount(false); 116 } 117 118 if (I== E) { 119 // No more characters left? 120 H.HandleIncompleteFormatSpecifier(Start, E - Start); 121 return OptionalAmount(false); 122 } 123 124 assert(Amt.getHowSpecified() == OptionalAmount::Constant); 125 126 if (*I == '$') { 127 // Handle positional arguments 128 129 // Special case: '*0$', since this is an easy mistake. 130 if (Amt.getConstantAmount() == 0) { 131 H.HandleZeroPosition(Beg, I - Beg + 1); 132 return OptionalAmount(false); 133 } 134 135 const char *Tmp = Beg; 136 Beg = ++I; 137 138 return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1, 139 Tmp, 0, true); 140 } 141 142 H.HandleInvalidPosition(Beg, I - Beg, p); 143 return OptionalAmount(false); 144 } 145 146 return ParseAmount(Beg, E); 147} 148 149static bool ParsePrecision(FormatStringHandler &H, FormatSpecifier &FS, 150 const char *Start, const char *&Beg, const char *E, 151 unsigned *argIndex) { 152 if (argIndex) { 153 FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 154 } 155 else { 156 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 157 analyze_printf::PrecisionPos); 158 if (Amt.isInvalid()) 159 return true; 160 FS.setPrecision(Amt); 161 } 162 return false; 163} 164 165static bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &FS, 166 const char *Start, const char *&Beg, const char *E, 167 unsigned *argIndex) { 168 // FIXME: Support negative field widths. 169 if (argIndex) { 170 FS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex)); 171 } 172 else { 173 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 174 analyze_printf::FieldWidthPos); 175 if (Amt.isInvalid()) 176 return true; 177 FS.setFieldWidth(Amt); 178 } 179 return false; 180} 181 182static bool ParseArgPosition(FormatStringHandler &H, 183 FormatSpecifier &FS, const char *Start, 184 const char *&Beg, const char *E) { 185 186 using namespace clang::analyze_printf; 187 const char *I = Beg; 188 189 const OptionalAmount &Amt = ParseAmount(I, E); 190 191 if (I == E) { 192 // No more characters left? 193 H.HandleIncompleteFormatSpecifier(Start, E - Start); 194 return true; 195 } 196 197 if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') { 198 // Special case: '%0$', since this is an easy mistake. 199 if (Amt.getConstantAmount() == 0) { 200 H.HandleZeroPosition(Start, I - Start); 201 return true; 202 } 203 204 FS.setArgIndex(Amt.getConstantAmount() - 1); 205 FS.setUsesPositionalArg(); 206 // Update the caller's pointer if we decided to consume 207 // these characters. 208 Beg = I; 209 return false; 210 } 211 212 return false; 213} 214 215static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H, 216 const char *&Beg, 217 const char *E, 218 unsigned &argIndex) { 219 220 using namespace clang::analyze_printf; 221 222 const char *I = Beg; 223 const char *Start = 0; 224 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 225 226 // Look for a '%' character that indicates the start of a format specifier. 227 for ( ; I != E ; ++I) { 228 char c = *I; 229 if (c == '\0') { 230 // Detect spurious null characters, which are likely errors. 231 H.HandleNullChar(I); 232 return true; 233 } 234 if (c == '%') { 235 Start = I++; // Record the start of the format specifier. 236 break; 237 } 238 } 239 240 // No format specifier found? 241 if (!Start) 242 return false; 243 244 if (I == E) { 245 // No more characters left? 246 H.HandleIncompleteFormatSpecifier(Start, E - Start); 247 return true; 248 } 249 250 FormatSpecifier FS; 251 if (ParseArgPosition(H, FS, Start, I, E)) 252 return true; 253 254 if (I == E) { 255 // No more characters left? 256 H.HandleIncompleteFormatSpecifier(Start, E - Start); 257 return true; 258 } 259 260 // Look for flags (if any). 261 bool hasMore = true; 262 for ( ; I != E; ++I) { 263 switch (*I) { 264 default: hasMore = false; break; 265 case '-': FS.setIsLeftJustified(I); break; 266 case '+': FS.setHasPlusPrefix(I); break; 267 case ' ': FS.setHasSpacePrefix(I); break; 268 case '#': FS.setHasAlternativeForm(I); break; 269 case '0': FS.setHasLeadingZeros(I); break; 270 } 271 if (!hasMore) 272 break; 273 } 274 275 if (I == E) { 276 // No more characters left? 277 H.HandleIncompleteFormatSpecifier(Start, E - Start); 278 return true; 279 } 280 281 // Look for the field width (if any). 282 if (ParseFieldWidth(H, FS, Start, I, E, 283 FS.usesPositionalArg() ? 0 : &argIndex)) 284 return true; 285 286 if (I == E) { 287 // No more characters left? 288 H.HandleIncompleteFormatSpecifier(Start, E - Start); 289 return true; 290 } 291 292 // Look for the precision (if any). 293 if (*I == '.') { 294 ++I; 295 if (I == E) { 296 H.HandleIncompleteFormatSpecifier(Start, E - Start); 297 return true; 298 } 299 300 if (ParsePrecision(H, FS, Start, I, E, 301 FS.usesPositionalArg() ? 0 : &argIndex)) 302 return true; 303 304 if (I == E) { 305 // No more characters left? 306 H.HandleIncompleteFormatSpecifier(Start, E - Start); 307 return true; 308 } 309 } 310 311 // Look for the length modifier. 312 LengthModifier::Kind lmKind = LengthModifier::None; 313 const char *lmPosition = I; 314 switch (*I) { 315 default: 316 break; 317 case 'h': 318 ++I; 319 lmKind = (I != E && *I == 'h') ? 320 ++I, LengthModifier::AsChar : LengthModifier::AsShort; 321 break; 322 case 'l': 323 ++I; 324 lmKind = (I != E && *I == 'l') ? 325 ++I, LengthModifier::AsLongLong : LengthModifier::AsLong; 326 break; 327 case 'j': lmKind = LengthModifier::AsIntMax; ++I; break; 328 case 'z': lmKind = LengthModifier::AsSizeT; ++I; break; 329 case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break; 330 case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break; 331 case 'q': lmKind = LengthModifier::AsLongLong; ++I; break; 332 } 333 LengthModifier lm(lmPosition, lmKind); 334 FS.setLengthModifier(lm); 335 336 if (I == E) { 337 // No more characters left? 338 H.HandleIncompleteFormatSpecifier(Start, E - Start); 339 return true; 340 } 341 342 if (*I == '\0') { 343 // Detect spurious null characters, which are likely errors. 344 H.HandleNullChar(I); 345 return true; 346 } 347 348 // Finally, look for the conversion specifier. 349 const char *conversionPosition = I++; 350 ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 351 switch (*conversionPosition) { 352 default: 353 break; 354 // C99: 7.19.6.1 (section 8). 355 case '%': k = ConversionSpecifier::PercentArg; break; 356 case 'A': k = ConversionSpecifier::AArg; break; 357 case 'E': k = ConversionSpecifier::EArg; break; 358 case 'F': k = ConversionSpecifier::FArg; break; 359 case 'G': k = ConversionSpecifier::GArg; break; 360 case 'X': k = ConversionSpecifier::XArg; break; 361 case 'a': k = ConversionSpecifier::aArg; break; 362 case 'c': k = ConversionSpecifier::IntAsCharArg; break; 363 case 'd': k = ConversionSpecifier::dArg; break; 364 case 'e': k = ConversionSpecifier::eArg; break; 365 case 'f': k = ConversionSpecifier::fArg; break; 366 case 'g': k = ConversionSpecifier::gArg; break; 367 case 'i': k = ConversionSpecifier::iArg; break; 368 case 'n': k = ConversionSpecifier::OutIntPtrArg; break; 369 case 'o': k = ConversionSpecifier::oArg; break; 370 case 'p': k = ConversionSpecifier::VoidPtrArg; break; 371 case 's': k = ConversionSpecifier::CStrArg; break; 372 case 'u': k = ConversionSpecifier::uArg; break; 373 case 'x': k = ConversionSpecifier::xArg; break; 374 // Mac OS X (unicode) specific 375 case 'C': k = ConversionSpecifier::CArg; break; 376 case 'S': k = ConversionSpecifier::UnicodeStrArg; break; 377 // Objective-C. 378 case '@': k = ConversionSpecifier::ObjCObjArg; break; 379 // Glibc specific. 380 case 'm': k = ConversionSpecifier::PrintErrno; break; 381 } 382 ConversionSpecifier CS(conversionPosition, k); 383 FS.setConversionSpecifier(CS); 384 if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 385 FS.setArgIndex(argIndex++); 386 387 if (k == ConversionSpecifier::InvalidSpecifier) { 388 // Assume the conversion takes one argument. 389 return !H.HandleInvalidConversionSpecifier(FS, Beg, I - Beg); 390 } 391 return FormatSpecifierResult(Start, FS); 392} 393 394bool clang::analyze_printf::ParseFormatString(FormatStringHandler &H, 395 const char *I, const char *E) { 396 397 unsigned argIndex = 0; 398 399 // Keep looking for a format specifier until we have exhausted the string. 400 while (I != E) { 401 const FormatSpecifierResult &FSR = ParseFormatSpecifier(H, I, E, argIndex); 402 // Did a fail-stop error of any kind occur when parsing the specifier? 403 // If so, don't do any more processing. 404 if (FSR.shouldStop()) 405 return true;; 406 // Did we exhaust the string or encounter an error that 407 // we can recover from? 408 if (!FSR.hasValue()) 409 continue; 410 // We have a format specifier. Pass it to the callback. 411 if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(), 412 I - FSR.getStart())) 413 return true; 414 } 415 assert(I == E && "Format string not exhausted"); 416 return false; 417} 418 419FormatStringHandler::~FormatStringHandler() {} 420 421//===----------------------------------------------------------------------===// 422// Methods on ArgTypeResult. 423//===----------------------------------------------------------------------===// 424 425bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const { 426 switch (K) { 427 case InvalidTy: 428 assert(false && "ArgTypeResult must be valid"); 429 return true; 430 431 case UnknownTy: 432 return true; 433 434 case SpecificTy: { 435 argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 436 if (T == argTy) 437 return true; 438 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 439 switch (BT->getKind()) { 440 default: 441 break; 442 case BuiltinType::Char_S: 443 case BuiltinType::SChar: 444 return T == C.UnsignedCharTy; 445 case BuiltinType::Char_U: 446 case BuiltinType::UChar: 447 return T == C.SignedCharTy; 448 case BuiltinType::Short: 449 return T == C.UnsignedShortTy; 450 case BuiltinType::UShort: 451 return T == C.ShortTy; 452 case BuiltinType::Int: 453 return T == C.UnsignedIntTy; 454 case BuiltinType::UInt: 455 return T == C.IntTy; 456 case BuiltinType::Long: 457 return T == C.UnsignedLongTy; 458 case BuiltinType::ULong: 459 return T == C.LongTy; 460 case BuiltinType::LongLong: 461 return T == C.UnsignedLongLongTy; 462 case BuiltinType::ULongLong: 463 return T == C.LongLongTy; 464 } 465 return false; 466 } 467 468 case CStrTy: { 469 const PointerType *PT = argTy->getAs<PointerType>(); 470 if (!PT) 471 return false; 472 QualType pointeeTy = PT->getPointeeType(); 473 if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 474 switch (BT->getKind()) { 475 case BuiltinType::Void: 476 case BuiltinType::Char_U: 477 case BuiltinType::UChar: 478 case BuiltinType::Char_S: 479 case BuiltinType::SChar: 480 return true; 481 default: 482 break; 483 } 484 485 return false; 486 } 487 488 case WCStrTy: { 489 const PointerType *PT = argTy->getAs<PointerType>(); 490 if (!PT) 491 return false; 492 QualType pointeeTy = 493 C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 494 return pointeeTy == C.getWCharType(); 495 } 496 497 case CPointerTy: 498 return argTy->getAs<PointerType>() != NULL || 499 argTy->getAs<ObjCObjectPointerType>() != NULL; 500 501 case ObjCPointerTy: 502 return argTy->getAs<ObjCObjectPointerType>() != NULL; 503 } 504 505 // FIXME: Should be unreachable, but Clang is currently emitting 506 // a warning. 507 return false; 508} 509 510QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const { 511 switch (K) { 512 case InvalidTy: 513 assert(false && "No representative type for Invalid ArgTypeResult"); 514 // Fall-through. 515 case UnknownTy: 516 return QualType(); 517 case SpecificTy: 518 return T; 519 case CStrTy: 520 return C.getPointerType(C.CharTy); 521 case WCStrTy: 522 return C.getPointerType(C.getWCharType()); 523 case ObjCPointerTy: 524 return C.ObjCBuiltinIdTy; 525 case CPointerTy: 526 return C.VoidPtrTy; 527 } 528 529 // FIXME: Should be unreachable, but Clang is currently emitting 530 // a warning. 531 return QualType(); 532} 533 534//===----------------------------------------------------------------------===// 535// Methods on OptionalAmount. 536//===----------------------------------------------------------------------===// 537 538ArgTypeResult OptionalAmount::getArgType(ASTContext &Ctx) const { 539 return Ctx.IntTy; 540} 541 542//===----------------------------------------------------------------------===// 543// Methods on ConversionSpecifier. 544//===----------------------------------------------------------------------===// 545const char *ConversionSpecifier::toString() const { 546 switch (kind) { 547 case dArg: return "d"; 548 case iArg: return "i"; 549 case oArg: return "o"; 550 case uArg: return "u"; 551 case xArg: return "x"; 552 case XArg: return "X"; 553 case fArg: return "f"; 554 case FArg: return "F"; 555 case eArg: return "e"; 556 case EArg: return "E"; 557 case gArg: return "g"; 558 case GArg: return "G"; 559 case aArg: return "a"; 560 case AArg: return "A"; 561 case IntAsCharArg: return "c"; 562 case CStrArg: return "s"; 563 case VoidPtrArg: return "p"; 564 case OutIntPtrArg: return "n"; 565 case PercentArg: return "%"; 566 case InvalidSpecifier: return NULL; 567 568 // MacOS X unicode extensions. 569 case CArg: return "C"; 570 case UnicodeStrArg: return "S"; 571 572 // Objective-C specific specifiers. 573 case ObjCObjArg: return "@"; 574 575 // GlibC specific specifiers. 576 case PrintErrno: return "m"; 577 } 578 return NULL; 579} 580 581//===----------------------------------------------------------------------===// 582// Methods on LengthModifier. 583//===----------------------------------------------------------------------===// 584 585const char *LengthModifier::toString() const { 586 switch (kind) { 587 case AsChar: 588 return "hh"; 589 case AsShort: 590 return "h"; 591 case AsLong: // or AsWideChar 592 return "l"; 593 case AsLongLong: 594 return "ll"; 595 case AsIntMax: 596 return "j"; 597 case AsSizeT: 598 return "z"; 599 case AsPtrDiff: 600 return "t"; 601 case AsLongDouble: 602 return "L"; 603 case None: 604 return ""; 605 } 606 return NULL; 607} 608 609//===----------------------------------------------------------------------===// 610// Methods on OptionalAmount. 611//===----------------------------------------------------------------------===// 612 613void OptionalAmount::toString(llvm::raw_ostream &os) const { 614 switch (hs) { 615 case Invalid: 616 case NotSpecified: 617 return; 618 case Arg: 619 if (usesPositionalArg()) 620 os << "*" << getPositionalArgIndex() << "$"; 621 else 622 os << "*"; 623 break; 624 case Constant: 625 os << amt; 626 break; 627 } 628} 629 630//===----------------------------------------------------------------------===// 631// Methods on FormatSpecifier. 632//===----------------------------------------------------------------------===// 633 634ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const { 635 if (!CS.consumesDataArgument()) 636 return ArgTypeResult::Invalid(); 637 638 if (CS.isIntArg()) 639 switch (LM.getKind()) { 640 case LengthModifier::AsLongDouble: 641 return ArgTypeResult::Invalid(); 642 case LengthModifier::None: return Ctx.IntTy; 643 case LengthModifier::AsChar: return Ctx.SignedCharTy; 644 case LengthModifier::AsShort: return Ctx.ShortTy; 645 case LengthModifier::AsLong: return Ctx.LongTy; 646 case LengthModifier::AsLongLong: return Ctx.LongLongTy; 647 case LengthModifier::AsIntMax: 648 // FIXME: Return unknown for now. 649 return ArgTypeResult(); 650 case LengthModifier::AsSizeT: return Ctx.getSizeType(); 651 case LengthModifier::AsPtrDiff: return Ctx.getPointerDiffType(); 652 } 653 654 if (CS.isUIntArg()) 655 switch (LM.getKind()) { 656 case LengthModifier::AsLongDouble: 657 return ArgTypeResult::Invalid(); 658 case LengthModifier::None: return Ctx.UnsignedIntTy; 659 case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 660 case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 661 case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 662 case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy; 663 case LengthModifier::AsIntMax: 664 // FIXME: Return unknown for now. 665 return ArgTypeResult(); 666 case LengthModifier::AsSizeT: 667 // FIXME: How to get the corresponding unsigned 668 // version of size_t? 669 return ArgTypeResult(); 670 case LengthModifier::AsPtrDiff: 671 // FIXME: How to get the corresponding unsigned 672 // version of ptrdiff_t? 673 return ArgTypeResult(); 674 } 675 676 if (CS.isDoubleArg()) { 677 if (LM.getKind() == LengthModifier::AsLongDouble) 678 return Ctx.LongDoubleTy; 679 return Ctx.DoubleTy; 680 } 681 682 switch (CS.getKind()) { 683 case ConversionSpecifier::CStrArg: 684 return ArgTypeResult(LM.getKind() == LengthModifier::AsWideChar ? 685 ArgTypeResult::WCStrTy : ArgTypeResult::CStrTy); 686 case ConversionSpecifier::UnicodeStrArg: 687 // FIXME: This appears to be Mac OS X specific. 688 return ArgTypeResult::WCStrTy; 689 case ConversionSpecifier::CArg: 690 return Ctx.WCharTy; 691 case ConversionSpecifier::VoidPtrArg: 692 return ArgTypeResult::CPointerTy; 693 default: 694 break; 695 } 696 697 // FIXME: Handle other cases. 698 return ArgTypeResult(); 699} 700 701bool FormatSpecifier::fixType(QualType QT) { 702 // Handle strings first (char *, wchar_t *) 703 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 704 CS.setKind(ConversionSpecifier::CStrArg); 705 706 // Disable irrelevant flags 707 HasAlternativeForm = 0; 708 HasLeadingZeroes = 0; 709 710 // Set the long length modifier for wide characters 711 if (QT->getPointeeType()->isWideCharType()) 712 LM.setKind(LengthModifier::AsWideChar); 713 714 return true; 715 } 716 717 // We can only work with builtin types. 718 if (!QT->isBuiltinType()) 719 return false; 720 721 // Everything else should be a base type 722 const BuiltinType *BT = QT->getAs<BuiltinType>(); 723 724 // Set length modifier 725 switch (BT->getKind()) { 726 default: 727 // The rest of the conversions are either optional or for non-builtin types 728 LM.setKind(LengthModifier::None); 729 break; 730 731 case BuiltinType::WChar: 732 case BuiltinType::Long: 733 case BuiltinType::ULong: 734 LM.setKind(LengthModifier::AsLong); 735 break; 736 737 case BuiltinType::LongLong: 738 case BuiltinType::ULongLong: 739 LM.setKind(LengthModifier::AsLongLong); 740 break; 741 742 case BuiltinType::LongDouble: 743 LM.setKind(LengthModifier::AsLongDouble); 744 break; 745 } 746 747 // Set conversion specifier and disable any flags which do not apply to it. 748 if (QT->isAnyCharacterType()) { 749 CS.setKind(ConversionSpecifier::IntAsCharArg); 750 Precision.setHowSpecified(OptionalAmount::NotSpecified); 751 HasAlternativeForm = 0; 752 HasLeadingZeroes = 0; 753 HasPlusPrefix = 0; 754 } 755 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 756 else if (QT->isFloatingType()) { 757 CS.setKind(ConversionSpecifier::fArg); 758 } 759 else if (QT->isPointerType()) { 760 CS.setKind(ConversionSpecifier::VoidPtrArg); 761 Precision.setHowSpecified(OptionalAmount::NotSpecified); 762 HasAlternativeForm = 0; 763 HasLeadingZeroes = 0; 764 HasPlusPrefix = 0; 765 } 766 else if (QT->isSignedIntegerType()) { 767 CS.setKind(ConversionSpecifier::dArg); 768 HasAlternativeForm = 0; 769 } 770 else if (QT->isUnsignedIntegerType()) { 771 CS.setKind(ConversionSpecifier::uArg); 772 HasAlternativeForm = 0; 773 HasPlusPrefix = 0; 774 } 775 else { 776 return false; 777 } 778 779 return true; 780} 781 782void FormatSpecifier::toString(llvm::raw_ostream &os) const { 783 // Whilst some features have no defined order, we are using the order 784 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) �7.19.6.1) 785 os << "%"; 786 787 // Positional args 788 if (usesPositionalArg()) { 789 os << getPositionalArgIndex() << "$"; 790 } 791 792 // Conversion flags 793 if (IsLeftJustified) os << "-"; 794 if (HasPlusPrefix) os << "+"; 795 if (HasSpacePrefix) os << " "; 796 if (HasAlternativeForm) os << "#"; 797 if (HasLeadingZeroes) os << "0"; 798 799 // Minimum field width 800 FieldWidth.toString(os); 801 // Precision 802 Precision.toString(os); 803 // Length modifier 804 os << LM.toString(); 805 // Conversion specifier 806 os << CS.toString(); 807} 808 809bool FormatSpecifier::hasValidPlusPrefix() const { 810 if (!HasPlusPrefix) 811 return true; 812 813 // The plus prefix only makes sense for signed conversions 814 switch (CS.getKind()) { 815 case ConversionSpecifier::dArg: 816 case ConversionSpecifier::iArg: 817 case ConversionSpecifier::fArg: 818 case ConversionSpecifier::FArg: 819 case ConversionSpecifier::eArg: 820 case ConversionSpecifier::EArg: 821 case ConversionSpecifier::gArg: 822 case ConversionSpecifier::GArg: 823 case ConversionSpecifier::aArg: 824 case ConversionSpecifier::AArg: 825 return true; 826 827 default: 828 return false; 829 } 830} 831 832bool FormatSpecifier::hasValidAlternativeForm() const { 833 if (!HasAlternativeForm) 834 return true; 835 836 // Alternate form flag only valid with the oxaAeEfFgG conversions 837 switch (CS.getKind()) { 838 case ConversionSpecifier::oArg: 839 case ConversionSpecifier::xArg: 840 case ConversionSpecifier::aArg: 841 case ConversionSpecifier::AArg: 842 case ConversionSpecifier::eArg: 843 case ConversionSpecifier::EArg: 844 case ConversionSpecifier::fArg: 845 case ConversionSpecifier::FArg: 846 case ConversionSpecifier::gArg: 847 case ConversionSpecifier::GArg: 848 return true; 849 850 default: 851 return false; 852 } 853} 854 855bool FormatSpecifier::hasValidLeadingZeros() const { 856 if (!HasLeadingZeroes) 857 return true; 858 859 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 860 switch (CS.getKind()) { 861 case ConversionSpecifier::dArg: 862 case ConversionSpecifier::iArg: 863 case ConversionSpecifier::oArg: 864 case ConversionSpecifier::uArg: 865 case ConversionSpecifier::xArg: 866 case ConversionSpecifier::XArg: 867 case ConversionSpecifier::aArg: 868 case ConversionSpecifier::AArg: 869 case ConversionSpecifier::eArg: 870 case ConversionSpecifier::EArg: 871 case ConversionSpecifier::fArg: 872 case ConversionSpecifier::FArg: 873 case ConversionSpecifier::gArg: 874 case ConversionSpecifier::GArg: 875 return true; 876 877 default: 878 return false; 879 } 880} 881 882bool FormatSpecifier::hasValidSpacePrefix() const { 883 if (!HasSpacePrefix) 884 return true; 885 886 // The space prefix only makes sense for signed conversions 887 switch (CS.getKind()) { 888 case ConversionSpecifier::dArg: 889 case ConversionSpecifier::iArg: 890 case ConversionSpecifier::fArg: 891 case ConversionSpecifier::FArg: 892 case ConversionSpecifier::eArg: 893 case ConversionSpecifier::EArg: 894 case ConversionSpecifier::gArg: 895 case ConversionSpecifier::GArg: 896 case ConversionSpecifier::aArg: 897 case ConversionSpecifier::AArg: 898 return true; 899 900 default: 901 return false; 902 } 903} 904 905bool FormatSpecifier::hasValidLeftJustified() const { 906 if (!IsLeftJustified) 907 return true; 908 909 // The left justified flag is valid for all conversions except n 910 switch (CS.getKind()) { 911 case ConversionSpecifier::OutIntPtrArg: 912 return false; 913 914 default: 915 return true; 916 } 917} 918 919bool FormatSpecifier::hasValidLengthModifier() const { 920 switch (LM.getKind()) { 921 case LengthModifier::None: 922 return true; 923 924 // Handle most integer flags 925 case LengthModifier::AsChar: 926 case LengthModifier::AsShort: 927 case LengthModifier::AsLongLong: 928 case LengthModifier::AsIntMax: 929 case LengthModifier::AsSizeT: 930 case LengthModifier::AsPtrDiff: 931 switch (CS.getKind()) { 932 case ConversionSpecifier::dArg: 933 case ConversionSpecifier::iArg: 934 case ConversionSpecifier::oArg: 935 case ConversionSpecifier::uArg: 936 case ConversionSpecifier::xArg: 937 case ConversionSpecifier::XArg: 938 case ConversionSpecifier::OutIntPtrArg: 939 return true; 940 default: 941 return false; 942 } 943 944 // Handle 'l' flag 945 case LengthModifier::AsLong: 946 switch (CS.getKind()) { 947 case ConversionSpecifier::dArg: 948 case ConversionSpecifier::iArg: 949 case ConversionSpecifier::oArg: 950 case ConversionSpecifier::uArg: 951 case ConversionSpecifier::xArg: 952 case ConversionSpecifier::XArg: 953 case ConversionSpecifier::aArg: 954 case ConversionSpecifier::AArg: 955 case ConversionSpecifier::fArg: 956 case ConversionSpecifier::FArg: 957 case ConversionSpecifier::eArg: 958 case ConversionSpecifier::EArg: 959 case ConversionSpecifier::gArg: 960 case ConversionSpecifier::GArg: 961 case ConversionSpecifier::OutIntPtrArg: 962 case ConversionSpecifier::IntAsCharArg: 963 case ConversionSpecifier::CStrArg: 964 return true; 965 default: 966 return false; 967 } 968 969 case LengthModifier::AsLongDouble: 970 switch (CS.getKind()) { 971 case ConversionSpecifier::aArg: 972 case ConversionSpecifier::AArg: 973 case ConversionSpecifier::fArg: 974 case ConversionSpecifier::FArg: 975 case ConversionSpecifier::eArg: 976 case ConversionSpecifier::EArg: 977 case ConversionSpecifier::gArg: 978 case ConversionSpecifier::GArg: 979 return true; 980 default: 981 return false; 982 } 983 } 984 return false; 985} 986 987bool FormatSpecifier::hasValidPrecision() const { 988 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 989 return true; 990 991 // Precision is only valid with the diouxXaAeEfFgGs conversions 992 switch (CS.getKind()) { 993 case ConversionSpecifier::dArg: 994 case ConversionSpecifier::iArg: 995 case ConversionSpecifier::oArg: 996 case ConversionSpecifier::uArg: 997 case ConversionSpecifier::xArg: 998 case ConversionSpecifier::XArg: 999 case ConversionSpecifier::aArg: 1000 case ConversionSpecifier::AArg: 1001 case ConversionSpecifier::eArg: 1002 case ConversionSpecifier::EArg: 1003 case ConversionSpecifier::fArg: 1004 case ConversionSpecifier::FArg: 1005 case ConversionSpecifier::gArg: 1006 case ConversionSpecifier::GArg: 1007 case ConversionSpecifier::CStrArg: 1008 return true; 1009 1010 default: 1011 return false; 1012 } 1013} 1014bool FormatSpecifier::hasValidFieldWidth() const { 1015 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 1016 return true; 1017 1018 // The field width is valid for all conversions except n 1019 switch (CS.getKind()) { 1020 case ConversionSpecifier::OutIntPtrArg: 1021 return false; 1022 1023 default: 1024 return true; 1025 } 1026} 1027