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