Home | History | Annotate | Line # | Download | only in AST
      1 // FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*-
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // Shared details for processing format strings of printf and scanf
     10 // (and friends).
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "FormatStringParsing.h"
     15 #include "clang/Basic/LangOptions.h"
     16 #include "clang/Basic/TargetInfo.h"
     17 #include "llvm/Support/ConvertUTF.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::ParseVectorModifier(FormatStringHandler &H,
    182                                                   FormatSpecifier &FS,
    183                                                   const char *&I,
    184                                                   const char *E,
    185                                                   const LangOptions &LO) {
    186   if (!LO.OpenCL)
    187     return false;
    188 
    189   const char *Start = I;
    190   if (*I == 'v') {
    191     ++I;
    192 
    193     if (I == E) {
    194       H.HandleIncompleteSpecifier(Start, E - Start);
    195       return true;
    196     }
    197 
    198     OptionalAmount NumElts = ParseAmount(I, E);
    199     if (NumElts.getHowSpecified() != OptionalAmount::Constant) {
    200       H.HandleIncompleteSpecifier(Start, E - Start);
    201       return true;
    202     }
    203 
    204     FS.setVectorNumElts(NumElts);
    205   }
    206 
    207   return false;
    208 }
    209 
    210 bool
    211 clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
    212                                                   const char *&I,
    213                                                   const char *E,
    214                                                   const LangOptions &LO,
    215                                                   bool IsScanf) {
    216   LengthModifier::Kind lmKind = LengthModifier::None;
    217   const char *lmPosition = I;
    218   switch (*I) {
    219     default:
    220       return false;
    221     case 'h':
    222       ++I;
    223       if (I != E && *I == 'h') {
    224         ++I;
    225         lmKind = LengthModifier::AsChar;
    226       } else if (I != E && *I == 'l' && LO.OpenCL) {
    227         ++I;
    228         lmKind = LengthModifier::AsShortLong;
    229       } else {
    230         lmKind = LengthModifier::AsShort;
    231       }
    232       break;
    233     case 'l':
    234       ++I;
    235       if (I != E && *I == 'l') {
    236         ++I;
    237         lmKind = LengthModifier::AsLongLong;
    238       } else {
    239         lmKind = LengthModifier::AsLong;
    240       }
    241       break;
    242     case 'j': lmKind = LengthModifier::AsIntMax;     ++I; break;
    243     case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
    244     case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
    245     case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
    246     case 'q': lmKind = LengthModifier::AsQuad;       ++I; break;
    247     case 'a':
    248       if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
    249         // For scanf in C90, look at the next character to see if this should
    250         // be parsed as the GNU extension 'a' length modifier. If not, this
    251         // will be parsed as a conversion specifier.
    252         ++I;
    253         if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
    254           lmKind = LengthModifier::AsAllocate;
    255           break;
    256         }
    257         --I;
    258       }
    259       return false;
    260     case 'm':
    261       if (IsScanf) {
    262         lmKind = LengthModifier::AsMAllocate;
    263         ++I;
    264         break;
    265       }
    266       return false;
    267     // printf: AsInt64, AsInt32, AsInt3264
    268     // scanf:  AsInt64
    269     case 'I':
    270       if (I + 1 != E && I + 2 != E) {
    271         if (I[1] == '6' && I[2] == '4') {
    272           I += 3;
    273           lmKind = LengthModifier::AsInt64;
    274           break;
    275         }
    276         if (IsScanf)
    277           return false;
    278 
    279         if (I[1] == '3' && I[2] == '2') {
    280           I += 3;
    281           lmKind = LengthModifier::AsInt32;
    282           break;
    283         }
    284       }
    285       ++I;
    286       lmKind = LengthModifier::AsInt3264;
    287       break;
    288     case 'w':
    289       lmKind = LengthModifier::AsWide; ++I; break;
    290   }
    291   LengthModifier lm(lmPosition, lmKind);
    292   FS.setLengthModifier(lm);
    293   return true;
    294 }
    295 
    296 bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
    297     const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
    298   if (SpecifierBegin + 1 >= FmtStrEnd)
    299     return false;
    300 
    301   const llvm::UTF8 *SB =
    302       reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1);
    303   const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd);
    304   const char FirstByte = *SB;
    305 
    306   // If the invalid specifier is a multibyte UTF-8 string, return the
    307   // total length accordingly so that the conversion specifier can be
    308   // properly updated to reflect a complete UTF-8 specifier.
    309   unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte);
    310   if (NumBytes == 1)
    311     return false;
    312   if (SB + NumBytes > SE)
    313     return false;
    314 
    315   Len = NumBytes + 1;
    316   return true;
    317 }
    318 
    319 //===----------------------------------------------------------------------===//
    320 // Methods on ArgType.
    321 //===----------------------------------------------------------------------===//
    322 
    323 clang::analyze_format_string::ArgType::MatchKind
    324 ArgType::matchesType(ASTContext &C, QualType argTy) const {
    325   if (Ptr) {
    326     // It has to be a pointer.
    327     const PointerType *PT = argTy->getAs<PointerType>();
    328     if (!PT)
    329       return NoMatch;
    330 
    331     // We cannot write through a const qualified pointer.
    332     if (PT->getPointeeType().isConstQualified())
    333       return NoMatch;
    334 
    335     argTy = PT->getPointeeType();
    336   }
    337 
    338   switch (K) {
    339     case InvalidTy:
    340       llvm_unreachable("ArgType must be valid");
    341 
    342     case UnknownTy:
    343       return Match;
    344 
    345     case AnyCharTy: {
    346       if (const EnumType *ETy = argTy->getAs<EnumType>()) {
    347         // If the enum is incomplete we know nothing about the underlying type.
    348         // Assume that it's 'int'.
    349         if (!ETy->getDecl()->isComplete())
    350           return NoMatch;
    351         argTy = ETy->getDecl()->getIntegerType();
    352       }
    353 
    354       if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
    355         switch (BT->getKind()) {
    356           default:
    357             break;
    358           case BuiltinType::Char_S:
    359           case BuiltinType::SChar:
    360           case BuiltinType::UChar:
    361           case BuiltinType::Char_U:
    362           case BuiltinType::Bool:
    363             return Match;
    364         }
    365       return NoMatch;
    366     }
    367 
    368     case SpecificTy: {
    369       if (const EnumType *ETy = argTy->getAs<EnumType>()) {
    370         // If the enum is incomplete we know nothing about the underlying type.
    371         // Assume that it's 'int'.
    372         if (!ETy->getDecl()->isComplete())
    373           argTy = C.IntTy;
    374         else
    375           argTy = ETy->getDecl()->getIntegerType();
    376       }
    377       argTy = C.getCanonicalType(argTy).getUnqualifiedType();
    378 
    379       if (T == argTy)
    380         return Match;
    381       // Check for "compatible types".
    382       if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
    383         switch (BT->getKind()) {
    384           default:
    385             break;
    386           case BuiltinType::Char_S:
    387           case BuiltinType::SChar:
    388           case BuiltinType::Char_U:
    389           case BuiltinType::UChar:
    390           case BuiltinType::Bool:
    391             if (T == C.UnsignedShortTy || T == C.ShortTy)
    392               return NoMatchTypeConfusion;
    393             return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match
    394                                                                 : NoMatch;
    395           case BuiltinType::Short:
    396             return T == C.UnsignedShortTy ? Match : NoMatch;
    397           case BuiltinType::UShort:
    398             return T == C.ShortTy ? Match : NoMatch;
    399           case BuiltinType::Int:
    400             return T == C.UnsignedIntTy ? Match : NoMatch;
    401           case BuiltinType::UInt:
    402             return T == C.IntTy ? Match : NoMatch;
    403           case BuiltinType::Long:
    404             return T == C.UnsignedLongTy ? Match : NoMatch;
    405           case BuiltinType::ULong:
    406             return T == C.LongTy ? Match : NoMatch;
    407           case BuiltinType::LongLong:
    408             return T == C.UnsignedLongLongTy ? Match : NoMatch;
    409           case BuiltinType::ULongLong:
    410             return T == C.LongLongTy ? Match : NoMatch;
    411         }
    412       return NoMatch;
    413     }
    414 
    415     case CStrTy: {
    416       const PointerType *PT = argTy->getAs<PointerType>();
    417       if (!PT)
    418         return NoMatch;
    419       QualType pointeeTy = PT->getPointeeType();
    420       if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
    421         switch (BT->getKind()) {
    422           case BuiltinType::Char_U:
    423           case BuiltinType::UChar:
    424           case BuiltinType::Char_S:
    425           case BuiltinType::SChar:
    426             return Match;
    427           default:
    428             break;
    429         }
    430 
    431       return NoMatch;
    432     }
    433 
    434     case WCStrTy: {
    435       const PointerType *PT = argTy->getAs<PointerType>();
    436       if (!PT)
    437         return NoMatch;
    438       QualType pointeeTy =
    439         C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
    440       return pointeeTy == C.getWideCharType() ? Match : NoMatch;
    441     }
    442 
    443     case WIntTy: {
    444       QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
    445 
    446       if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
    447         return Match;
    448 
    449       QualType PromoArg = argTy->isPromotableIntegerType()
    450                               ? C.getPromotedIntegerType(argTy)
    451                               : argTy;
    452       PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
    453 
    454       // If the promoted argument is the corresponding signed type of the
    455       // wint_t type, then it should match.
    456       if (PromoArg->hasSignedIntegerRepresentation() &&
    457           C.getCorrespondingUnsignedType(PromoArg) == WInt)
    458         return Match;
    459 
    460       return WInt == PromoArg ? Match : NoMatch;
    461     }
    462 
    463     case CPointerTy:
    464       if (argTy->isVoidPointerType()) {
    465         return Match;
    466       } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
    467             argTy->isBlockPointerType() || argTy->isNullPtrType()) {
    468         return NoMatchPedantic;
    469       } else {
    470         return NoMatch;
    471       }
    472 
    473     case ObjCPointerTy: {
    474       if (argTy->getAs<ObjCObjectPointerType>() ||
    475           argTy->getAs<BlockPointerType>())
    476         return Match;
    477 
    478       // Handle implicit toll-free bridging.
    479       if (const PointerType *PT = argTy->getAs<PointerType>()) {
    480         // Things such as CFTypeRef are really just opaque pointers
    481         // to C structs representing CF types that can often be bridged
    482         // to Objective-C objects.  Since the compiler doesn't know which
    483         // structs can be toll-free bridged, we just accept them all.
    484         QualType pointee = PT->getPointeeType();
    485         if (pointee->getAsStructureType() || pointee->isVoidType())
    486           return Match;
    487       }
    488       return NoMatch;
    489     }
    490   }
    491 
    492   llvm_unreachable("Invalid ArgType Kind!");
    493 }
    494 
    495 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
    496   // Check for valid vector element types.
    497   if (T.isNull())
    498     return ArgType::Invalid();
    499 
    500   QualType Vec = C.getExtVectorType(T, NumElts);
    501   return ArgType(Vec, Name);
    502 }
    503 
    504 QualType ArgType::getRepresentativeType(ASTContext &C) const {
    505   QualType Res;
    506   switch (K) {
    507     case InvalidTy:
    508       llvm_unreachable("No representative type for Invalid ArgType");
    509     case UnknownTy:
    510       llvm_unreachable("No representative type for Unknown ArgType");
    511     case AnyCharTy:
    512       Res = C.CharTy;
    513       break;
    514     case SpecificTy:
    515       Res = T;
    516       break;
    517     case CStrTy:
    518       Res = C.getPointerType(C.CharTy);
    519       break;
    520     case WCStrTy:
    521       Res = C.getPointerType(C.getWideCharType());
    522       break;
    523     case ObjCPointerTy:
    524       Res = C.ObjCBuiltinIdTy;
    525       break;
    526     case CPointerTy:
    527       Res = C.VoidPtrTy;
    528       break;
    529     case WIntTy: {
    530       Res = C.getWIntType();
    531       break;
    532     }
    533   }
    534 
    535   if (Ptr)
    536     Res = C.getPointerType(Res);
    537   return Res;
    538 }
    539 
    540 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
    541   std::string S = getRepresentativeType(C).getAsString(C.getPrintingPolicy());
    542 
    543   std::string Alias;
    544   if (Name) {
    545     // Use a specific name for this type, e.g. "size_t".
    546     Alias = Name;
    547     if (Ptr) {
    548       // If ArgType is actually a pointer to T, append an asterisk.
    549       Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
    550     }
    551     // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
    552     if (S == Alias)
    553       Alias.clear();
    554   }
    555 
    556   if (!Alias.empty())
    557     return std::string("'") + Alias + "' (aka '" + S + "')";
    558   return std::string("'") + S + "'";
    559 }
    560 
    561 
    562 //===----------------------------------------------------------------------===//
    563 // Methods on OptionalAmount.
    564 //===----------------------------------------------------------------------===//
    565 
    566 ArgType
    567 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
    568   return Ctx.IntTy;
    569 }
    570 
    571 //===----------------------------------------------------------------------===//
    572 // Methods on LengthModifier.
    573 //===----------------------------------------------------------------------===//
    574 
    575 const char *
    576 analyze_format_string::LengthModifier::toString() const {
    577   switch (kind) {
    578   case AsChar:
    579     return "hh";
    580   case AsShort:
    581     return "h";
    582   case AsShortLong:
    583     return "hl";
    584   case AsLong: // or AsWideChar
    585     return "l";
    586   case AsLongLong:
    587     return "ll";
    588   case AsQuad:
    589     return "q";
    590   case AsIntMax:
    591     return "j";
    592   case AsSizeT:
    593     return "z";
    594   case AsPtrDiff:
    595     return "t";
    596   case AsInt32:
    597     return "I32";
    598   case AsInt3264:
    599     return "I";
    600   case AsInt64:
    601     return "I64";
    602   case AsLongDouble:
    603     return "L";
    604   case AsAllocate:
    605     return "a";
    606   case AsMAllocate:
    607     return "m";
    608   case AsWide:
    609     return "w";
    610   case None:
    611     return "";
    612   }
    613   return nullptr;
    614 }
    615 
    616 //===----------------------------------------------------------------------===//
    617 // Methods on ConversionSpecifier.
    618 //===----------------------------------------------------------------------===//
    619 
    620 const char *ConversionSpecifier::toString() const {
    621   switch (kind) {
    622   case dArg: return "d";
    623   case DArg: return "D";
    624   case iArg: return "i";
    625   case oArg: return "o";
    626   case OArg: return "O";
    627   case uArg: return "u";
    628   case UArg: return "U";
    629   case xArg: return "x";
    630   case XArg: return "X";
    631   case fArg: return "f";
    632   case FArg: return "F";
    633   case eArg: return "e";
    634   case EArg: return "E";
    635   case gArg: return "g";
    636   case GArg: return "G";
    637   case aArg: return "a";
    638   case AArg: return "A";
    639   case cArg: return "c";
    640   case sArg: return "s";
    641   case pArg: return "p";
    642   case PArg:
    643     return "P";
    644   case nArg: return "n";
    645   case PercentArg:  return "%";
    646   case ScanListArg: return "[";
    647   case InvalidSpecifier: return nullptr;
    648 
    649   // POSIX unicode extensions.
    650   case CArg: return "C";
    651   case SArg: return "S";
    652 
    653   // Objective-C specific specifiers.
    654   case ObjCObjArg: return "@";
    655 
    656   // FreeBSD kernel specific specifiers.
    657   case FreeBSDbArg: return "b";
    658   case FreeBSDDArg: return "D";
    659   case FreeBSDrArg: return "r";
    660   case FreeBSDyArg: return "y";
    661 
    662   // GlibC specific specifiers.
    663   case PrintErrno: return "m";
    664 
    665   // MS specific specifiers.
    666   case ZArg: return "Z";
    667   }
    668   return nullptr;
    669 }
    670 
    671 Optional<ConversionSpecifier>
    672 ConversionSpecifier::getStandardSpecifier() const {
    673   ConversionSpecifier::Kind NewKind;
    674 
    675   switch (getKind()) {
    676   default:
    677     return None;
    678   case DArg:
    679     NewKind = dArg;
    680     break;
    681   case UArg:
    682     NewKind = uArg;
    683     break;
    684   case OArg:
    685     NewKind = oArg;
    686     break;
    687   }
    688 
    689   ConversionSpecifier FixedCS(*this);
    690   FixedCS.setKind(NewKind);
    691   return FixedCS;
    692 }
    693 
    694 //===----------------------------------------------------------------------===//
    695 // Methods on OptionalAmount.
    696 //===----------------------------------------------------------------------===//
    697 
    698 void OptionalAmount::toString(raw_ostream &os) const {
    699   switch (hs) {
    700   case Invalid:
    701   case NotSpecified:
    702     return;
    703   case Arg:
    704     if (UsesDotPrefix)
    705         os << ".";
    706     if (usesPositionalArg())
    707       os << "*" << getPositionalArgIndex() << "$";
    708     else
    709       os << "*";
    710     break;
    711   case Constant:
    712     if (UsesDotPrefix)
    713         os << ".";
    714     os << amt;
    715     break;
    716   }
    717 }
    718 
    719 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
    720                                              const LangOptions &LO) const {
    721   switch (LM.getKind()) {
    722     case LengthModifier::None:
    723       return true;
    724 
    725     // Handle most integer flags
    726     case LengthModifier::AsShort:
    727       // Length modifier only applies to FP vectors.
    728       if (LO.OpenCL && CS.isDoubleArg())
    729         return !VectorNumElts.isInvalid();
    730 
    731       if (Target.getTriple().isOSMSVCRT()) {
    732         switch (CS.getKind()) {
    733           case ConversionSpecifier::cArg:
    734           case ConversionSpecifier::CArg:
    735           case ConversionSpecifier::sArg:
    736           case ConversionSpecifier::SArg:
    737           case ConversionSpecifier::ZArg:
    738             return true;
    739           default:
    740             break;
    741         }
    742       }
    743       LLVM_FALLTHROUGH;
    744     case LengthModifier::AsChar:
    745     case LengthModifier::AsLongLong:
    746     case LengthModifier::AsQuad:
    747     case LengthModifier::AsIntMax:
    748     case LengthModifier::AsSizeT:
    749     case LengthModifier::AsPtrDiff:
    750       switch (CS.getKind()) {
    751         case ConversionSpecifier::dArg:
    752         case ConversionSpecifier::DArg:
    753         case ConversionSpecifier::iArg:
    754         case ConversionSpecifier::oArg:
    755         case ConversionSpecifier::OArg:
    756         case ConversionSpecifier::uArg:
    757         case ConversionSpecifier::UArg:
    758         case ConversionSpecifier::xArg:
    759         case ConversionSpecifier::XArg:
    760         case ConversionSpecifier::nArg:
    761           return true;
    762         case ConversionSpecifier::FreeBSDrArg:
    763         case ConversionSpecifier::FreeBSDyArg:
    764           return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
    765         default:
    766           return false;
    767       }
    768 
    769     case LengthModifier::AsShortLong:
    770       return LO.OpenCL && !VectorNumElts.isInvalid();
    771 
    772     // Handle 'l' flag
    773     case LengthModifier::AsLong: // or AsWideChar
    774       if (CS.isDoubleArg()) {
    775         // Invalid for OpenCL FP scalars.
    776         if (LO.OpenCL && VectorNumElts.isInvalid())
    777           return false;
    778         return true;
    779       }
    780 
    781       switch (CS.getKind()) {
    782         case ConversionSpecifier::dArg:
    783         case ConversionSpecifier::DArg:
    784         case ConversionSpecifier::iArg:
    785         case ConversionSpecifier::oArg:
    786         case ConversionSpecifier::OArg:
    787         case ConversionSpecifier::uArg:
    788         case ConversionSpecifier::UArg:
    789         case ConversionSpecifier::xArg:
    790         case ConversionSpecifier::XArg:
    791         case ConversionSpecifier::nArg:
    792         case ConversionSpecifier::cArg:
    793         case ConversionSpecifier::sArg:
    794         case ConversionSpecifier::ScanListArg:
    795         case ConversionSpecifier::ZArg:
    796           return true;
    797         case ConversionSpecifier::FreeBSDrArg:
    798         case ConversionSpecifier::FreeBSDyArg:
    799           return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
    800         default:
    801           return false;
    802       }
    803 
    804     case LengthModifier::AsLongDouble:
    805       switch (CS.getKind()) {
    806         case ConversionSpecifier::aArg:
    807         case ConversionSpecifier::AArg:
    808         case ConversionSpecifier::fArg:
    809         case ConversionSpecifier::FArg:
    810         case ConversionSpecifier::eArg:
    811         case ConversionSpecifier::EArg:
    812         case ConversionSpecifier::gArg:
    813         case ConversionSpecifier::GArg:
    814           return true;
    815         // GNU libc extension.
    816         case ConversionSpecifier::dArg:
    817         case ConversionSpecifier::iArg:
    818         case ConversionSpecifier::oArg:
    819         case ConversionSpecifier::uArg:
    820         case ConversionSpecifier::xArg:
    821         case ConversionSpecifier::XArg:
    822           return !Target.getTriple().isOSDarwin() &&
    823                  !Target.getTriple().isOSWindows();
    824         default:
    825           return false;
    826       }
    827 
    828     case LengthModifier::AsAllocate:
    829       switch (CS.getKind()) {
    830         case ConversionSpecifier::sArg:
    831         case ConversionSpecifier::SArg:
    832         case ConversionSpecifier::ScanListArg:
    833           return true;
    834         default:
    835           return false;
    836       }
    837 
    838     case LengthModifier::AsMAllocate:
    839       switch (CS.getKind()) {
    840         case ConversionSpecifier::cArg:
    841         case ConversionSpecifier::CArg:
    842         case ConversionSpecifier::sArg:
    843         case ConversionSpecifier::SArg:
    844         case ConversionSpecifier::ScanListArg:
    845           return true;
    846         default:
    847           return false;
    848       }
    849     case LengthModifier::AsInt32:
    850     case LengthModifier::AsInt3264:
    851     case LengthModifier::AsInt64:
    852       switch (CS.getKind()) {
    853         case ConversionSpecifier::dArg:
    854         case ConversionSpecifier::iArg:
    855         case ConversionSpecifier::oArg:
    856         case ConversionSpecifier::uArg:
    857         case ConversionSpecifier::xArg:
    858         case ConversionSpecifier::XArg:
    859           return Target.getTriple().isOSMSVCRT();
    860         default:
    861           return false;
    862       }
    863     case LengthModifier::AsWide:
    864       switch (CS.getKind()) {
    865         case ConversionSpecifier::cArg:
    866         case ConversionSpecifier::CArg:
    867         case ConversionSpecifier::sArg:
    868         case ConversionSpecifier::SArg:
    869         case ConversionSpecifier::ZArg:
    870           return Target.getTriple().isOSMSVCRT();
    871         default:
    872           return false;
    873       }
    874   }
    875   llvm_unreachable("Invalid LengthModifier Kind!");
    876 }
    877 
    878 bool FormatSpecifier::hasStandardLengthModifier() const {
    879   switch (LM.getKind()) {
    880     case LengthModifier::None:
    881     case LengthModifier::AsChar:
    882     case LengthModifier::AsShort:
    883     case LengthModifier::AsLong:
    884     case LengthModifier::AsLongLong:
    885     case LengthModifier::AsIntMax:
    886     case LengthModifier::AsSizeT:
    887     case LengthModifier::AsPtrDiff:
    888     case LengthModifier::AsLongDouble:
    889       return true;
    890     case LengthModifier::AsAllocate:
    891     case LengthModifier::AsMAllocate:
    892     case LengthModifier::AsQuad:
    893     case LengthModifier::AsInt32:
    894     case LengthModifier::AsInt3264:
    895     case LengthModifier::AsInt64:
    896     case LengthModifier::AsWide:
    897     case LengthModifier::AsShortLong: // ???
    898       return false;
    899   }
    900   llvm_unreachable("Invalid LengthModifier Kind!");
    901 }
    902 
    903 bool FormatSpecifier::hasStandardConversionSpecifier(
    904     const LangOptions &LangOpt) const {
    905   switch (CS.getKind()) {
    906     case ConversionSpecifier::cArg:
    907     case ConversionSpecifier::dArg:
    908     case ConversionSpecifier::iArg:
    909     case ConversionSpecifier::oArg:
    910     case ConversionSpecifier::uArg:
    911     case ConversionSpecifier::xArg:
    912     case ConversionSpecifier::XArg:
    913     case ConversionSpecifier::fArg:
    914     case ConversionSpecifier::FArg:
    915     case ConversionSpecifier::eArg:
    916     case ConversionSpecifier::EArg:
    917     case ConversionSpecifier::gArg:
    918     case ConversionSpecifier::GArg:
    919     case ConversionSpecifier::aArg:
    920     case ConversionSpecifier::AArg:
    921     case ConversionSpecifier::sArg:
    922     case ConversionSpecifier::pArg:
    923     case ConversionSpecifier::nArg:
    924     case ConversionSpecifier::ObjCObjArg:
    925     case ConversionSpecifier::ScanListArg:
    926     case ConversionSpecifier::PercentArg:
    927     case ConversionSpecifier::PArg:
    928       return true;
    929     case ConversionSpecifier::CArg:
    930     case ConversionSpecifier::SArg:
    931       return LangOpt.ObjC;
    932     case ConversionSpecifier::InvalidSpecifier:
    933     case ConversionSpecifier::FreeBSDbArg:
    934     case ConversionSpecifier::FreeBSDDArg:
    935     case ConversionSpecifier::FreeBSDrArg:
    936     case ConversionSpecifier::FreeBSDyArg:
    937     case ConversionSpecifier::PrintErrno:
    938     case ConversionSpecifier::DArg:
    939     case ConversionSpecifier::OArg:
    940     case ConversionSpecifier::UArg:
    941     case ConversionSpecifier::ZArg:
    942       return false;
    943   }
    944   llvm_unreachable("Invalid ConversionSpecifier Kind!");
    945 }
    946 
    947 bool FormatSpecifier::hasStandardLengthConversionCombination() const {
    948   if (LM.getKind() == LengthModifier::AsLongDouble) {
    949     switch(CS.getKind()) {
    950         case ConversionSpecifier::dArg:
    951         case ConversionSpecifier::iArg:
    952         case ConversionSpecifier::oArg:
    953         case ConversionSpecifier::uArg:
    954         case ConversionSpecifier::xArg:
    955         case ConversionSpecifier::XArg:
    956           return false;
    957         default:
    958           return true;
    959     }
    960   }
    961   return true;
    962 }
    963 
    964 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const {
    965   if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
    966     if (LM.getKind() == LengthModifier::AsLongDouble ||
    967         LM.getKind() == LengthModifier::AsQuad) {
    968       LengthModifier FixedLM(LM);
    969       FixedLM.setKind(LengthModifier::AsLongLong);
    970       return FixedLM;
    971     }
    972   }
    973 
    974   return None;
    975 }
    976 
    977 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
    978                                                 LengthModifier &LM) {
    979   assert(isa<TypedefType>(QT) && "Expected a TypedefType");
    980   const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
    981 
    982   for (;;) {
    983     const IdentifierInfo *Identifier = Typedef->getIdentifier();
    984     if (Identifier->getName() == "size_t") {
    985       LM.setKind(LengthModifier::AsSizeT);
    986       return true;
    987     } else if (Identifier->getName() == "ssize_t") {
    988       // Not C99, but common in Unix.
    989       LM.setKind(LengthModifier::AsSizeT);
    990       return true;
    991     } else if (Identifier->getName() == "intmax_t") {
    992       LM.setKind(LengthModifier::AsIntMax);
    993       return true;
    994     } else if (Identifier->getName() == "uintmax_t") {
    995       LM.setKind(LengthModifier::AsIntMax);
    996       return true;
    997     } else if (Identifier->getName() == "ptrdiff_t") {
    998       LM.setKind(LengthModifier::AsPtrDiff);
    999       return true;
   1000     }
   1001 
   1002     QualType T = Typedef->getUnderlyingType();
   1003     if (!isa<TypedefType>(T))
   1004       break;
   1005 
   1006     Typedef = cast<TypedefType>(T)->getDecl();
   1007   }
   1008   return false;
   1009 }
   1010