clang API Documentation
00001 // FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*- 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Shared details for processing format strings of printf and scanf 00011 // (and friends). 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "FormatStringParsing.h" 00016 #include "clang/Basic/LangOptions.h" 00017 #include "clang/Basic/TargetInfo.h" 00018 00019 using clang::analyze_format_string::ArgType; 00020 using clang::analyze_format_string::FormatStringHandler; 00021 using clang::analyze_format_string::FormatSpecifier; 00022 using clang::analyze_format_string::LengthModifier; 00023 using clang::analyze_format_string::OptionalAmount; 00024 using clang::analyze_format_string::PositionContext; 00025 using clang::analyze_format_string::ConversionSpecifier; 00026 using namespace clang; 00027 00028 // Key function to FormatStringHandler. 00029 FormatStringHandler::~FormatStringHandler() {} 00030 00031 //===----------------------------------------------------------------------===// 00032 // Functions for parsing format strings components in both printf and 00033 // scanf format strings. 00034 //===----------------------------------------------------------------------===// 00035 00036 OptionalAmount 00037 clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) { 00038 const char *I = Beg; 00039 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 00040 00041 unsigned accumulator = 0; 00042 bool hasDigits = false; 00043 00044 for ( ; I != E; ++I) { 00045 char c = *I; 00046 if (c >= '0' && c <= '9') { 00047 hasDigits = true; 00048 accumulator = (accumulator * 10) + (c - '0'); 00049 continue; 00050 } 00051 00052 if (hasDigits) 00053 return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg, 00054 false); 00055 00056 break; 00057 } 00058 00059 return OptionalAmount(); 00060 } 00061 00062 OptionalAmount 00063 clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg, 00064 const char *E, 00065 unsigned &argIndex) { 00066 if (*Beg == '*') { 00067 ++Beg; 00068 return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false); 00069 } 00070 00071 return ParseAmount(Beg, E); 00072 } 00073 00074 OptionalAmount 00075 clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H, 00076 const char *Start, 00077 const char *&Beg, 00078 const char *E, 00079 PositionContext p) { 00080 if (*Beg == '*') { 00081 const char *I = Beg + 1; 00082 const OptionalAmount &Amt = ParseAmount(I, E); 00083 00084 if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) { 00085 H.HandleInvalidPosition(Beg, I - Beg, p); 00086 return OptionalAmount(false); 00087 } 00088 00089 if (I == E) { 00090 // No more characters left? 00091 H.HandleIncompleteSpecifier(Start, E - Start); 00092 return OptionalAmount(false); 00093 } 00094 00095 assert(Amt.getHowSpecified() == OptionalAmount::Constant); 00096 00097 if (*I == '$') { 00098 // Handle positional arguments 00099 00100 // Special case: '*0$', since this is an easy mistake. 00101 if (Amt.getConstantAmount() == 0) { 00102 H.HandleZeroPosition(Beg, I - Beg + 1); 00103 return OptionalAmount(false); 00104 } 00105 00106 const char *Tmp = Beg; 00107 Beg = ++I; 00108 00109 return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1, 00110 Tmp, 0, true); 00111 } 00112 00113 H.HandleInvalidPosition(Beg, I - Beg, p); 00114 return OptionalAmount(false); 00115 } 00116 00117 return ParseAmount(Beg, E); 00118 } 00119 00120 00121 bool 00122 clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H, 00123 FormatSpecifier &CS, 00124 const char *Start, 00125 const char *&Beg, const char *E, 00126 unsigned *argIndex) { 00127 // FIXME: Support negative field widths. 00128 if (argIndex) { 00129 CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex)); 00130 } 00131 else { 00132 const OptionalAmount Amt = 00133 ParsePositionAmount(H, Start, Beg, E, 00134 analyze_format_string::FieldWidthPos); 00135 00136 if (Amt.isInvalid()) 00137 return true; 00138 CS.setFieldWidth(Amt); 00139 } 00140 return false; 00141 } 00142 00143 bool 00144 clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H, 00145 FormatSpecifier &FS, 00146 const char *Start, 00147 const char *&Beg, 00148 const char *E) { 00149 const char *I = Beg; 00150 00151 const OptionalAmount &Amt = ParseAmount(I, E); 00152 00153 if (I == E) { 00154 // No more characters left? 00155 H.HandleIncompleteSpecifier(Start, E - Start); 00156 return true; 00157 } 00158 00159 if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') { 00160 // Warn that positional arguments are non-standard. 00161 H.HandlePosition(Start, I - Start); 00162 00163 // Special case: '%0$', since this is an easy mistake. 00164 if (Amt.getConstantAmount() == 0) { 00165 H.HandleZeroPosition(Start, I - Start); 00166 return true; 00167 } 00168 00169 FS.setArgIndex(Amt.getConstantAmount() - 1); 00170 FS.setUsesPositionalArg(); 00171 // Update the caller's pointer if we decided to consume 00172 // these characters. 00173 Beg = I; 00174 return false; 00175 } 00176 00177 return false; 00178 } 00179 00180 bool 00181 clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS, 00182 const char *&I, 00183 const char *E, 00184 const LangOptions &LO, 00185 bool IsScanf) { 00186 LengthModifier::Kind lmKind = LengthModifier::None; 00187 const char *lmPosition = I; 00188 switch (*I) { 00189 default: 00190 return false; 00191 case 'h': 00192 ++I; 00193 lmKind = (I != E && *I == 'h') ? (++I, LengthModifier::AsChar) 00194 : LengthModifier::AsShort; 00195 break; 00196 case 'l': 00197 ++I; 00198 lmKind = (I != E && *I == 'l') ? (++I, LengthModifier::AsLongLong) 00199 : LengthModifier::AsLong; 00200 break; 00201 case 'j': lmKind = LengthModifier::AsIntMax; ++I; break; 00202 case 'z': lmKind = LengthModifier::AsSizeT; ++I; break; 00203 case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break; 00204 case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break; 00205 case 'q': lmKind = LengthModifier::AsQuad; ++I; break; 00206 case 'a': 00207 if (IsScanf && !LO.C99 && !LO.CPlusPlus11) { 00208 // For scanf in C90, look at the next character to see if this should 00209 // be parsed as the GNU extension 'a' length modifier. If not, this 00210 // will be parsed as a conversion specifier. 00211 ++I; 00212 if (I != E && (*I == 's' || *I == 'S' || *I == '[')) { 00213 lmKind = LengthModifier::AsAllocate; 00214 break; 00215 } 00216 --I; 00217 } 00218 return false; 00219 case 'm': 00220 if (IsScanf) { 00221 lmKind = LengthModifier::AsMAllocate; 00222 ++I; 00223 break; 00224 } 00225 return false; 00226 // printf: AsInt64, AsInt32, AsInt3264 00227 // scanf: AsInt64 00228 case 'I': 00229 if (I + 1 != E && I + 2 != E) { 00230 if (I[1] == '6' && I[2] == '4') { 00231 I += 3; 00232 lmKind = LengthModifier::AsInt64; 00233 break; 00234 } 00235 if (IsScanf) 00236 return false; 00237 00238 if (I[1] == '3' && I[2] == '2') { 00239 I += 3; 00240 lmKind = LengthModifier::AsInt32; 00241 break; 00242 } 00243 } 00244 ++I; 00245 lmKind = LengthModifier::AsInt3264; 00246 break; 00247 case 'w': 00248 lmKind = LengthModifier::AsWide; ++I; break; 00249 } 00250 LengthModifier lm(lmPosition, lmKind); 00251 FS.setLengthModifier(lm); 00252 return true; 00253 } 00254 00255 //===----------------------------------------------------------------------===// 00256 // Methods on ArgType. 00257 //===----------------------------------------------------------------------===// 00258 00259 bool ArgType::matchesType(ASTContext &C, QualType argTy) const { 00260 if (Ptr) { 00261 // It has to be a pointer. 00262 const PointerType *PT = argTy->getAs<PointerType>(); 00263 if (!PT) 00264 return false; 00265 00266 // We cannot write through a const qualified pointer. 00267 if (PT->getPointeeType().isConstQualified()) 00268 return false; 00269 00270 argTy = PT->getPointeeType(); 00271 } 00272 00273 switch (K) { 00274 case InvalidTy: 00275 llvm_unreachable("ArgType must be valid"); 00276 00277 case UnknownTy: 00278 return true; 00279 00280 case AnyCharTy: { 00281 if (const EnumType *ETy = argTy->getAs<EnumType>()) 00282 argTy = ETy->getDecl()->getIntegerType(); 00283 00284 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 00285 switch (BT->getKind()) { 00286 default: 00287 break; 00288 case BuiltinType::Char_S: 00289 case BuiltinType::SChar: 00290 case BuiltinType::UChar: 00291 case BuiltinType::Char_U: 00292 return true; 00293 } 00294 return false; 00295 } 00296 00297 case SpecificTy: { 00298 if (const EnumType *ETy = argTy->getAs<EnumType>()) 00299 argTy = ETy->getDecl()->getIntegerType(); 00300 argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 00301 00302 if (T == argTy) 00303 return true; 00304 // Check for "compatible types". 00305 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 00306 switch (BT->getKind()) { 00307 default: 00308 break; 00309 case BuiltinType::Char_S: 00310 case BuiltinType::SChar: 00311 case BuiltinType::Char_U: 00312 case BuiltinType::UChar: 00313 return T == C.UnsignedCharTy || T == C.SignedCharTy; 00314 case BuiltinType::Short: 00315 return T == C.UnsignedShortTy; 00316 case BuiltinType::UShort: 00317 return T == C.ShortTy; 00318 case BuiltinType::Int: 00319 return T == C.UnsignedIntTy; 00320 case BuiltinType::UInt: 00321 return T == C.IntTy; 00322 case BuiltinType::Long: 00323 return T == C.UnsignedLongTy; 00324 case BuiltinType::ULong: 00325 return T == C.LongTy; 00326 case BuiltinType::LongLong: 00327 return T == C.UnsignedLongLongTy; 00328 case BuiltinType::ULongLong: 00329 return T == C.LongLongTy; 00330 } 00331 return false; 00332 } 00333 00334 case CStrTy: { 00335 const PointerType *PT = argTy->getAs<PointerType>(); 00336 if (!PT) 00337 return false; 00338 QualType pointeeTy = PT->getPointeeType(); 00339 if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 00340 switch (BT->getKind()) { 00341 case BuiltinType::Void: 00342 case BuiltinType::Char_U: 00343 case BuiltinType::UChar: 00344 case BuiltinType::Char_S: 00345 case BuiltinType::SChar: 00346 return true; 00347 default: 00348 break; 00349 } 00350 00351 return false; 00352 } 00353 00354 case WCStrTy: { 00355 const PointerType *PT = argTy->getAs<PointerType>(); 00356 if (!PT) 00357 return false; 00358 QualType pointeeTy = 00359 C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 00360 return pointeeTy == C.getWideCharType(); 00361 } 00362 00363 case WIntTy: { 00364 00365 QualType PromoArg = 00366 argTy->isPromotableIntegerType() 00367 ? C.getPromotedIntegerType(argTy) : argTy; 00368 00369 QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); 00370 PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); 00371 00372 // If the promoted argument is the corresponding signed type of the 00373 // wint_t type, then it should match. 00374 if (PromoArg->hasSignedIntegerRepresentation() && 00375 C.getCorrespondingUnsignedType(PromoArg) == WInt) 00376 return true; 00377 00378 return WInt == PromoArg; 00379 } 00380 00381 case CPointerTy: 00382 return argTy->isPointerType() || argTy->isObjCObjectPointerType() || 00383 argTy->isBlockPointerType() || argTy->isNullPtrType(); 00384 00385 case ObjCPointerTy: { 00386 if (argTy->getAs<ObjCObjectPointerType>() || 00387 argTy->getAs<BlockPointerType>()) 00388 return true; 00389 00390 // Handle implicit toll-free bridging. 00391 if (const PointerType *PT = argTy->getAs<PointerType>()) { 00392 // Things such as CFTypeRef are really just opaque pointers 00393 // to C structs representing CF types that can often be bridged 00394 // to Objective-C objects. Since the compiler doesn't know which 00395 // structs can be toll-free bridged, we just accept them all. 00396 QualType pointee = PT->getPointeeType(); 00397 if (pointee->getAsStructureType() || pointee->isVoidType()) 00398 return true; 00399 } 00400 return false; 00401 } 00402 } 00403 00404 llvm_unreachable("Invalid ArgType Kind!"); 00405 } 00406 00407 QualType ArgType::getRepresentativeType(ASTContext &C) const { 00408 QualType Res; 00409 switch (K) { 00410 case InvalidTy: 00411 llvm_unreachable("No representative type for Invalid ArgType"); 00412 case UnknownTy: 00413 llvm_unreachable("No representative type for Unknown ArgType"); 00414 case AnyCharTy: 00415 Res = C.CharTy; 00416 break; 00417 case SpecificTy: 00418 Res = T; 00419 break; 00420 case CStrTy: 00421 Res = C.getPointerType(C.CharTy); 00422 break; 00423 case WCStrTy: 00424 Res = C.getPointerType(C.getWideCharType()); 00425 break; 00426 case ObjCPointerTy: 00427 Res = C.ObjCBuiltinIdTy; 00428 break; 00429 case CPointerTy: 00430 Res = C.VoidPtrTy; 00431 break; 00432 case WIntTy: { 00433 Res = C.getWIntType(); 00434 break; 00435 } 00436 } 00437 00438 if (Ptr) 00439 Res = C.getPointerType(Res); 00440 return Res; 00441 } 00442 00443 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const { 00444 std::string S = getRepresentativeType(C).getAsString(); 00445 00446 std::string Alias; 00447 if (Name) { 00448 // Use a specific name for this type, e.g. "size_t". 00449 Alias = Name; 00450 if (Ptr) { 00451 // If ArgType is actually a pointer to T, append an asterisk. 00452 Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *"; 00453 } 00454 // If Alias is the same as the underlying type, e.g. wchar_t, then drop it. 00455 if (S == Alias) 00456 Alias.clear(); 00457 } 00458 00459 if (!Alias.empty()) 00460 return std::string("'") + Alias + "' (aka '" + S + "')"; 00461 return std::string("'") + S + "'"; 00462 } 00463 00464 00465 //===----------------------------------------------------------------------===// 00466 // Methods on OptionalAmount. 00467 //===----------------------------------------------------------------------===// 00468 00469 ArgType 00470 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { 00471 return Ctx.IntTy; 00472 } 00473 00474 //===----------------------------------------------------------------------===// 00475 // Methods on LengthModifier. 00476 //===----------------------------------------------------------------------===// 00477 00478 const char * 00479 analyze_format_string::LengthModifier::toString() const { 00480 switch (kind) { 00481 case AsChar: 00482 return "hh"; 00483 case AsShort: 00484 return "h"; 00485 case AsLong: // or AsWideChar 00486 return "l"; 00487 case AsLongLong: 00488 return "ll"; 00489 case AsQuad: 00490 return "q"; 00491 case AsIntMax: 00492 return "j"; 00493 case AsSizeT: 00494 return "z"; 00495 case AsPtrDiff: 00496 return "t"; 00497 case AsInt32: 00498 return "I32"; 00499 case AsInt3264: 00500 return "I"; 00501 case AsInt64: 00502 return "I64"; 00503 case AsLongDouble: 00504 return "L"; 00505 case AsAllocate: 00506 return "a"; 00507 case AsMAllocate: 00508 return "m"; 00509 case AsWide: 00510 return "w"; 00511 case None: 00512 return ""; 00513 } 00514 return nullptr; 00515 } 00516 00517 //===----------------------------------------------------------------------===// 00518 // Methods on ConversionSpecifier. 00519 //===----------------------------------------------------------------------===// 00520 00521 const char *ConversionSpecifier::toString() const { 00522 switch (kind) { 00523 case dArg: return "d"; 00524 case DArg: return "D"; 00525 case iArg: return "i"; 00526 case oArg: return "o"; 00527 case OArg: return "O"; 00528 case uArg: return "u"; 00529 case UArg: return "U"; 00530 case xArg: return "x"; 00531 case XArg: return "X"; 00532 case fArg: return "f"; 00533 case FArg: return "F"; 00534 case eArg: return "e"; 00535 case EArg: return "E"; 00536 case gArg: return "g"; 00537 case GArg: return "G"; 00538 case aArg: return "a"; 00539 case AArg: return "A"; 00540 case cArg: return "c"; 00541 case sArg: return "s"; 00542 case pArg: return "p"; 00543 case nArg: return "n"; 00544 case PercentArg: return "%"; 00545 case ScanListArg: return "["; 00546 case InvalidSpecifier: return nullptr; 00547 00548 // POSIX unicode extensions. 00549 case CArg: return "C"; 00550 case SArg: return "S"; 00551 00552 // Objective-C specific specifiers. 00553 case ObjCObjArg: return "@"; 00554 00555 // GlibC specific specifiers. 00556 case PrintErrno: return "m"; 00557 00558 // MS specific specifiers. 00559 case ZArg: return "Z"; 00560 } 00561 return nullptr; 00562 } 00563 00564 Optional<ConversionSpecifier> 00565 ConversionSpecifier::getStandardSpecifier() const { 00566 ConversionSpecifier::Kind NewKind; 00567 00568 switch (getKind()) { 00569 default: 00570 return None; 00571 case DArg: 00572 NewKind = dArg; 00573 break; 00574 case UArg: 00575 NewKind = uArg; 00576 break; 00577 case OArg: 00578 NewKind = oArg; 00579 break; 00580 } 00581 00582 ConversionSpecifier FixedCS(*this); 00583 FixedCS.setKind(NewKind); 00584 return FixedCS; 00585 } 00586 00587 //===----------------------------------------------------------------------===// 00588 // Methods on OptionalAmount. 00589 //===----------------------------------------------------------------------===// 00590 00591 void OptionalAmount::toString(raw_ostream &os) const { 00592 switch (hs) { 00593 case Invalid: 00594 case NotSpecified: 00595 return; 00596 case Arg: 00597 if (UsesDotPrefix) 00598 os << "."; 00599 if (usesPositionalArg()) 00600 os << "*" << getPositionalArgIndex() << "$"; 00601 else 00602 os << "*"; 00603 break; 00604 case Constant: 00605 if (UsesDotPrefix) 00606 os << "."; 00607 os << amt; 00608 break; 00609 } 00610 } 00611 00612 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { 00613 switch (LM.getKind()) { 00614 case LengthModifier::None: 00615 return true; 00616 00617 // Handle most integer flags 00618 case LengthModifier::AsShort: 00619 if (Target.getTriple().isOSMSVCRT()) { 00620 switch (CS.getKind()) { 00621 case ConversionSpecifier::cArg: 00622 case ConversionSpecifier::CArg: 00623 case ConversionSpecifier::sArg: 00624 case ConversionSpecifier::SArg: 00625 case ConversionSpecifier::ZArg: 00626 return true; 00627 default: 00628 break; 00629 } 00630 } 00631 // Fall through. 00632 case LengthModifier::AsChar: 00633 case LengthModifier::AsLongLong: 00634 case LengthModifier::AsQuad: 00635 case LengthModifier::AsIntMax: 00636 case LengthModifier::AsSizeT: 00637 case LengthModifier::AsPtrDiff: 00638 switch (CS.getKind()) { 00639 case ConversionSpecifier::dArg: 00640 case ConversionSpecifier::DArg: 00641 case ConversionSpecifier::iArg: 00642 case ConversionSpecifier::oArg: 00643 case ConversionSpecifier::OArg: 00644 case ConversionSpecifier::uArg: 00645 case ConversionSpecifier::UArg: 00646 case ConversionSpecifier::xArg: 00647 case ConversionSpecifier::XArg: 00648 case ConversionSpecifier::nArg: 00649 return true; 00650 default: 00651 return false; 00652 } 00653 00654 // Handle 'l' flag 00655 case LengthModifier::AsLong: // or AsWideChar 00656 switch (CS.getKind()) { 00657 case ConversionSpecifier::dArg: 00658 case ConversionSpecifier::DArg: 00659 case ConversionSpecifier::iArg: 00660 case ConversionSpecifier::oArg: 00661 case ConversionSpecifier::OArg: 00662 case ConversionSpecifier::uArg: 00663 case ConversionSpecifier::UArg: 00664 case ConversionSpecifier::xArg: 00665 case ConversionSpecifier::XArg: 00666 case ConversionSpecifier::aArg: 00667 case ConversionSpecifier::AArg: 00668 case ConversionSpecifier::fArg: 00669 case ConversionSpecifier::FArg: 00670 case ConversionSpecifier::eArg: 00671 case ConversionSpecifier::EArg: 00672 case ConversionSpecifier::gArg: 00673 case ConversionSpecifier::GArg: 00674 case ConversionSpecifier::nArg: 00675 case ConversionSpecifier::cArg: 00676 case ConversionSpecifier::sArg: 00677 case ConversionSpecifier::ScanListArg: 00678 case ConversionSpecifier::ZArg: 00679 return true; 00680 default: 00681 return false; 00682 } 00683 00684 case LengthModifier::AsLongDouble: 00685 switch (CS.getKind()) { 00686 case ConversionSpecifier::aArg: 00687 case ConversionSpecifier::AArg: 00688 case ConversionSpecifier::fArg: 00689 case ConversionSpecifier::FArg: 00690 case ConversionSpecifier::eArg: 00691 case ConversionSpecifier::EArg: 00692 case ConversionSpecifier::gArg: 00693 case ConversionSpecifier::GArg: 00694 return true; 00695 // GNU libc extension. 00696 case ConversionSpecifier::dArg: 00697 case ConversionSpecifier::iArg: 00698 case ConversionSpecifier::oArg: 00699 case ConversionSpecifier::uArg: 00700 case ConversionSpecifier::xArg: 00701 case ConversionSpecifier::XArg: 00702 return !Target.getTriple().isOSDarwin() && 00703 !Target.getTriple().isOSWindows(); 00704 default: 00705 return false; 00706 } 00707 00708 case LengthModifier::AsAllocate: 00709 switch (CS.getKind()) { 00710 case ConversionSpecifier::sArg: 00711 case ConversionSpecifier::SArg: 00712 case ConversionSpecifier::ScanListArg: 00713 return true; 00714 default: 00715 return false; 00716 } 00717 00718 case LengthModifier::AsMAllocate: 00719 switch (CS.getKind()) { 00720 case ConversionSpecifier::cArg: 00721 case ConversionSpecifier::CArg: 00722 case ConversionSpecifier::sArg: 00723 case ConversionSpecifier::SArg: 00724 case ConversionSpecifier::ScanListArg: 00725 return true; 00726 default: 00727 return false; 00728 } 00729 case LengthModifier::AsInt32: 00730 case LengthModifier::AsInt3264: 00731 case LengthModifier::AsInt64: 00732 switch (CS.getKind()) { 00733 case ConversionSpecifier::dArg: 00734 case ConversionSpecifier::iArg: 00735 case ConversionSpecifier::oArg: 00736 case ConversionSpecifier::uArg: 00737 case ConversionSpecifier::xArg: 00738 case ConversionSpecifier::XArg: 00739 return Target.getTriple().isOSMSVCRT(); 00740 default: 00741 return false; 00742 } 00743 case LengthModifier::AsWide: 00744 switch (CS.getKind()) { 00745 case ConversionSpecifier::cArg: 00746 case ConversionSpecifier::CArg: 00747 case ConversionSpecifier::sArg: 00748 case ConversionSpecifier::SArg: 00749 case ConversionSpecifier::ZArg: 00750 return Target.getTriple().isOSMSVCRT(); 00751 default: 00752 return false; 00753 } 00754 } 00755 llvm_unreachable("Invalid LengthModifier Kind!"); 00756 } 00757 00758 bool FormatSpecifier::hasStandardLengthModifier() const { 00759 switch (LM.getKind()) { 00760 case LengthModifier::None: 00761 case LengthModifier::AsChar: 00762 case LengthModifier::AsShort: 00763 case LengthModifier::AsLong: 00764 case LengthModifier::AsLongLong: 00765 case LengthModifier::AsIntMax: 00766 case LengthModifier::AsSizeT: 00767 case LengthModifier::AsPtrDiff: 00768 case LengthModifier::AsLongDouble: 00769 return true; 00770 case LengthModifier::AsAllocate: 00771 case LengthModifier::AsMAllocate: 00772 case LengthModifier::AsQuad: 00773 case LengthModifier::AsInt32: 00774 case LengthModifier::AsInt3264: 00775 case LengthModifier::AsInt64: 00776 case LengthModifier::AsWide: 00777 return false; 00778 } 00779 llvm_unreachable("Invalid LengthModifier Kind!"); 00780 } 00781 00782 bool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt) const { 00783 switch (CS.getKind()) { 00784 case ConversionSpecifier::cArg: 00785 case ConversionSpecifier::dArg: 00786 case ConversionSpecifier::iArg: 00787 case ConversionSpecifier::oArg: 00788 case ConversionSpecifier::uArg: 00789 case ConversionSpecifier::xArg: 00790 case ConversionSpecifier::XArg: 00791 case ConversionSpecifier::fArg: 00792 case ConversionSpecifier::FArg: 00793 case ConversionSpecifier::eArg: 00794 case ConversionSpecifier::EArg: 00795 case ConversionSpecifier::gArg: 00796 case ConversionSpecifier::GArg: 00797 case ConversionSpecifier::aArg: 00798 case ConversionSpecifier::AArg: 00799 case ConversionSpecifier::sArg: 00800 case ConversionSpecifier::pArg: 00801 case ConversionSpecifier::nArg: 00802 case ConversionSpecifier::ObjCObjArg: 00803 case ConversionSpecifier::ScanListArg: 00804 case ConversionSpecifier::PercentArg: 00805 return true; 00806 case ConversionSpecifier::CArg: 00807 case ConversionSpecifier::SArg: 00808 return LangOpt.ObjC1 || LangOpt.ObjC2; 00809 case ConversionSpecifier::InvalidSpecifier: 00810 case ConversionSpecifier::PrintErrno: 00811 case ConversionSpecifier::DArg: 00812 case ConversionSpecifier::OArg: 00813 case ConversionSpecifier::UArg: 00814 case ConversionSpecifier::ZArg: 00815 return false; 00816 } 00817 llvm_unreachable("Invalid ConversionSpecifier Kind!"); 00818 } 00819 00820 bool FormatSpecifier::hasStandardLengthConversionCombination() const { 00821 if (LM.getKind() == LengthModifier::AsLongDouble) { 00822 switch(CS.getKind()) { 00823 case ConversionSpecifier::dArg: 00824 case ConversionSpecifier::iArg: 00825 case ConversionSpecifier::oArg: 00826 case ConversionSpecifier::uArg: 00827 case ConversionSpecifier::xArg: 00828 case ConversionSpecifier::XArg: 00829 return false; 00830 default: 00831 return true; 00832 } 00833 } 00834 return true; 00835 } 00836 00837 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { 00838 if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { 00839 if (LM.getKind() == LengthModifier::AsLongDouble || 00840 LM.getKind() == LengthModifier::AsQuad) { 00841 LengthModifier FixedLM(LM); 00842 FixedLM.setKind(LengthModifier::AsLongLong); 00843 return FixedLM; 00844 } 00845 } 00846 00847 return None; 00848 } 00849 00850 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 00851 LengthModifier &LM) { 00852 assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 00853 const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 00854 00855 for (;;) { 00856 const IdentifierInfo *Identifier = Typedef->getIdentifier(); 00857 if (Identifier->getName() == "size_t") { 00858 LM.setKind(LengthModifier::AsSizeT); 00859 return true; 00860 } else if (Identifier->getName() == "ssize_t") { 00861 // Not C99, but common in Unix. 00862 LM.setKind(LengthModifier::AsSizeT); 00863 return true; 00864 } else if (Identifier->getName() == "intmax_t") { 00865 LM.setKind(LengthModifier::AsIntMax); 00866 return true; 00867 } else if (Identifier->getName() == "uintmax_t") { 00868 LM.setKind(LengthModifier::AsIntMax); 00869 return true; 00870 } else if (Identifier->getName() == "ptrdiff_t") { 00871 LM.setKind(LengthModifier::AsPtrDiff); 00872 return true; 00873 } 00874 00875 QualType T = Typedef->getUnderlyingType(); 00876 if (!isa<TypedefType>(T)) 00877 break; 00878 00879 Typedef = cast<TypedefType>(T)->getDecl(); 00880 } 00881 return false; 00882 }