//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Handling of format string in printf and friends.  The structure of format
// strings for fprintf() are described in C99 7.19.6.1.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/FormatString.h"
#include "FormatStringParsing.h"
#include "clang/Basic/TargetInfo.h"

using clang::analyze_format_string::ArgType;
using clang::analyze_format_string::FormatStringHandler;
using clang::analyze_format_string::LengthModifier;
using clang::analyze_format_string::OptionalAmount;
using clang::analyze_format_string::ConversionSpecifier;
using clang::analyze_printf::PrintfSpecifier;

using namespace clang;

typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
        PrintfSpecifierResult;

//===----------------------------------------------------------------------===//
// Methods for parsing format strings.
//===----------------------------------------------------------------------===//

using analyze_format_string::ParseNonPositionAmount;

static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
                           const char *Start, const char *&Beg, const char *E,
                           unsigned *argIndex) {
  if (argIndex) {
    FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
  } else {
    const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
                                           analyze_format_string::PrecisionPos);
    if (Amt.isInvalid())
      return true;
    FS.setPrecision(Amt);
  }
  return false;
}

static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS,
                           const char *FlagBeg, const char *E, bool Warn) {
   StringRef Flag(FlagBeg, E - FlagBeg);
   // Currently there is only one flag.
   if (Flag == "tt") {
     FS.setHasObjCTechnicalTerm(FlagBeg);
     return false;
   }
   // Handle either the case of no flag or an invalid flag.
   if (Warn) {
     if (Flag == "")
       H.HandleEmptyObjCModifierFlag(FlagBeg, E  - FlagBeg);
     else
       H.HandleInvalidObjCModifierFlag(FlagBeg, E  - FlagBeg);
   }
   return true;
}

static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
                                                  const char *&Beg,
                                                  const char *E,
                                                  unsigned &argIndex,
                                                  const LangOptions &LO,
                                                  const TargetInfo &Target,
                                                  bool Warn,
                                                  bool isFreeBSDKPrintf) {

  using namespace clang::analyze_format_string;
  using namespace clang::analyze_printf;

  const char *I = Beg;
  const char *Start = nullptr;
  UpdateOnReturn <const char*> UpdateBeg(Beg, I);

  // Look for a '%' character that indicates the start of a format specifier.
  for ( ; I != E ; ++I) {
    char c = *I;
    if (c == '\0') {
      // Detect spurious null characters, which are likely errors.
      H.HandleNullChar(I);
      return true;
    }
    if (c == '%') {
      Start = I++;  // Record the start of the format specifier.
      break;
    }
  }

  // No format specifier found?
  if (!Start)
    return false;

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  PrintfSpecifier FS;
  if (ParseArgPosition(H, FS, Start, I, E))
    return true;

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  const char *OSLogVisibilityFlagsStart = nullptr,
             *OSLogVisibilityFlagsEnd = nullptr;
  if (*I == '{') {
    OSLogVisibilityFlagsStart = I++;
    // Find the end of the modifier.
    while (I != E && *I != '}') { I++; }
    if (I == E) {
      if (Warn)
        H.HandleIncompleteSpecifier(Start, E - Start);
      return true;
    }
    assert(*I == '}');
    OSLogVisibilityFlagsEnd = I++;

    // Just see if 'private' or 'public' is the first word. os_log itself will
    // do any further parsing.
    const char *P = OSLogVisibilityFlagsStart + 1;
    while (P < OSLogVisibilityFlagsEnd && isspace(*P)) P++;
    const char *WordStart = P;
    while (P < OSLogVisibilityFlagsEnd && (isalnum(*P) || *P == '_')) P++;
    const char *WordEnd = P;
    StringRef Word(WordStart, WordEnd - WordStart);
    if (Word == "private") {
      FS.setIsPrivate(WordStart);
    } else if (Word == "public") {
      FS.setIsPublic(WordStart);
    }
  }

  // Look for flags (if any).
  bool hasMore = true;
  for ( ; I != E; ++I) {
    switch (*I) {
      default: hasMore = false; break;
      case '\'':
        // FIXME: POSIX specific.  Always accept?
        FS.setHasThousandsGrouping(I);
        break;
      case '-': FS.setIsLeftJustified(I); break;
      case '+': FS.setHasPlusPrefix(I); break;
      case ' ': FS.setHasSpacePrefix(I); break;
      case '#': FS.setHasAlternativeForm(I); break;
      case '0': FS.setHasLeadingZeros(I); break;
    }
    if (!hasMore)
      break;
  }

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  // Look for the field width (if any).
  if (ParseFieldWidth(H, FS, Start, I, E,
                      FS.usesPositionalArg() ? nullptr : &argIndex))
    return true;

  if (I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  // Look for the precision (if any).
  if (*I == '.') {
    ++I;
    if (I == E) {
      if (Warn)
        H.HandleIncompleteSpecifier(Start, E - Start);
      return true;
    }

    if (ParsePrecision(H, FS, Start, I, E,
                       FS.usesPositionalArg() ? nullptr : &argIndex))
      return true;

    if (I == E) {
      // No more characters left?
      if (Warn)
        H.HandleIncompleteSpecifier(Start, E - Start);
      return true;
    }
  }

  // Look for the length modifier.
  if (ParseLengthModifier(FS, I, E, LO) && I == E) {
    // No more characters left?
    if (Warn)
      H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  // Look for the Objective-C modifier flags, if any.
  // We parse these here, even if they don't apply to
  // the conversion specifier, and then emit an error
  // later if the conversion specifier isn't '@'.  This
  // enables better recovery, and we don't know if
  // these flags are applicable until later.
  const char *ObjCModifierFlagsStart = nullptr,
             *ObjCModifierFlagsEnd = nullptr;
  if (*I == '[') {
    ObjCModifierFlagsStart = I;
    ++I;
    auto flagStart = I;
    for (;; ++I) {
      ObjCModifierFlagsEnd = I;
      if (I == E) {
        if (Warn)
          H.HandleIncompleteSpecifier(Start, E - Start);
        return true;
      }
      // Did we find the closing ']'?
      if (*I == ']') {
        if (ParseObjCFlags(H, FS, flagStart, I, Warn))
          return true;
        ++I;
        break;
      }
      // There are no separators defined yet for multiple
      // Objective-C modifier flags.  When those are
      // defined, this is the place to check.
    }
  }

  if (*I == '\0') {
    // Detect spurious null characters, which are likely errors.
    H.HandleNullChar(I);
    return true;
  }

  // Finally, look for the conversion specifier.
  const char *conversionPosition = I++;
  ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
  switch (*conversionPosition) {
    default:
      break;
    // C99: 7.19.6.1 (section 8).
    case '%': k = ConversionSpecifier::PercentArg;   break;
    case 'A': k = ConversionSpecifier::AArg; break;
    case 'E': k = ConversionSpecifier::EArg; break;
    case 'F': k = ConversionSpecifier::FArg; break;
    case 'G': k = ConversionSpecifier::GArg; break;
    case 'X': k = ConversionSpecifier::XArg; break;
    case 'a': k = ConversionSpecifier::aArg; break;
    case 'c': k = ConversionSpecifier::cArg; break;
    case 'd': k = ConversionSpecifier::dArg; break;
    case 'e': k = ConversionSpecifier::eArg; break;
    case 'f': k = ConversionSpecifier::fArg; break;
    case 'g': k = ConversionSpecifier::gArg; break;
    case 'i': k = ConversionSpecifier::iArg; break;
    case 'n': k = ConversionSpecifier::nArg; break;
    case 'o': k = ConversionSpecifier::oArg; break;
    case 'p': k = ConversionSpecifier::pArg; break;
    case 's': k = ConversionSpecifier::sArg; break;
    case 'u': k = ConversionSpecifier::uArg; break;
    case 'x': k = ConversionSpecifier::xArg; break;
    // POSIX specific.
    case 'C': k = ConversionSpecifier::CArg; break;
    case 'S': k = ConversionSpecifier::SArg; break;
    // Apple extension for os_log
    case 'P': k = ConversionSpecifier::PArg; break;
    // Objective-C.
    case '@': k = ConversionSpecifier::ObjCObjArg; break;
    // Glibc specific.
    case 'm': k = ConversionSpecifier::PrintErrno; break;
    // FreeBSD kernel specific.
    case 'b':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
      break;
    case 'r':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDrArg; // int
      break;
    case 'y':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDyArg; // int
      break;
    // Apple-specific.
    case 'D':
      if (isFreeBSDKPrintf)
        k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
      else if (Target.getTriple().isOSDarwin())
        k = ConversionSpecifier::DArg;
      break;
    case 'O':
      if (Target.getTriple().isOSDarwin())
        k = ConversionSpecifier::OArg;
      break;
    case 'U':
      if (Target.getTriple().isOSDarwin())
        k = ConversionSpecifier::UArg;
      break;
    // MS specific.
    case 'Z':
      if (Target.getTriple().isOSMSVCRT())
        k = ConversionSpecifier::ZArg;
  }
  
  // Check to see if we used the Objective-C modifier flags with
  // a conversion specifier other than '@'.
  if (k != ConversionSpecifier::ObjCObjArg &&
      k != ConversionSpecifier::InvalidSpecifier &&
      ObjCModifierFlagsStart) {
    H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
                                           ObjCModifierFlagsEnd + 1,
                                           conversionPosition);
    return true;
  }

  PrintfConversionSpecifier CS(conversionPosition, k);
  FS.setConversionSpecifier(CS);
  if (CS.consumesDataArgument() && !FS.usesPositionalArg())
    FS.setArgIndex(argIndex++);
  // FreeBSD kernel specific.
  if (k == ConversionSpecifier::FreeBSDbArg ||
      k == ConversionSpecifier::FreeBSDDArg)
    argIndex++;

  if (k == ConversionSpecifier::InvalidSpecifier) {
    unsigned Len = I - Start;
    if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
      CS.setEndScanList(Start + Len);
      FS.setConversionSpecifier(CS);
    }
    // Assume the conversion takes one argument.
    return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
  }
  return PrintfSpecifierResult(Start, FS);
}

bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
                                                     const char *I,
                                                     const char *E,
                                                     const LangOptions &LO,
                                                     const TargetInfo &Target,
                                                     bool isFreeBSDKPrintf) {

  unsigned argIndex = 0;

  // Keep looking for a format specifier until we have exhausted the string.
  while (I != E) {
    const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
                                                            LO, Target, true,
                                                            isFreeBSDKPrintf);
    // Did a fail-stop error of any kind occur when parsing the specifier?
    // If so, don't do any more processing.
    if (FSR.shouldStop())
      return true;
    // Did we exhaust the string or encounter an error that
    // we can recover from?
    if (!FSR.hasValue())
      continue;
    // We have a format specifier.  Pass it to the callback.
    if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
                                 I - FSR.getStart()))
      return true;
  }
  assert(I == E && "Format string not exhausted");
  return false;
}

bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
                                                            const char *E,
                                                            const LangOptions &LO,
                                                            const TargetInfo &Target) {
  
  unsigned argIndex = 0;
  
  // Keep looking for a %s format specifier until we have exhausted the string.
  FormatStringHandler H;
  while (I != E) {
    const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
                                                            LO, Target, false,
                                                            false);
    // Did a fail-stop error of any kind occur when parsing the specifier?
    // If so, don't do any more processing.
    if (FSR.shouldStop())
      return false;
    // Did we exhaust the string or encounter an error that
    // we can recover from?
    if (!FSR.hasValue())
      continue;
    const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
    // Return true if this a %s format specifier.
    if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
      return true;
  }
  return false;
}

//===----------------------------------------------------------------------===//
// Methods on PrintfSpecifier.
//===----------------------------------------------------------------------===//

ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
                                    bool IsObjCLiteral) const {
  const PrintfConversionSpecifier &CS = getConversionSpecifier();

  if (!CS.consumesDataArgument())
    return ArgType::Invalid();

  if (CS.getKind() == ConversionSpecifier::cArg)
    switch (LM.getKind()) {
      case LengthModifier::None:
        return Ctx.IntTy;
      case LengthModifier::AsLong:
      case LengthModifier::AsWide:
        return ArgType(ArgType::WIntTy, "wint_t");
      case LengthModifier::AsShort:
        if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
          return Ctx.IntTy;
      default:
        return ArgType::Invalid();
    }

  if (CS.isIntArg())
    switch (LM.getKind()) {
      case LengthModifier::AsLongDouble:
        // GNU extension.
        return Ctx.LongLongTy;
      case LengthModifier::None:
        return Ctx.IntTy;
      case LengthModifier::AsInt32:
        return ArgType(Ctx.IntTy, "__int32");
      case LengthModifier::AsChar: return ArgType::AnyCharTy;
      case LengthModifier::AsShort: return Ctx.ShortTy;
      case LengthModifier::AsLong: return Ctx.LongTy;
      case LengthModifier::AsLongLong:
      case LengthModifier::AsQuad:
        return Ctx.LongLongTy;
      case LengthModifier::AsInt64:
        return ArgType(Ctx.LongLongTy, "__int64");
      case LengthModifier::AsIntMax:
        return ArgType(Ctx.getIntMaxType(), "intmax_t");
      case LengthModifier::AsSizeT:
        // FIXME: How to get the corresponding signed version of size_t?
        return ArgType();
      case LengthModifier::AsInt3264:
        return Ctx.getTargetInfo().getTriple().isArch64Bit()
                   ? ArgType(Ctx.LongLongTy, "__int64")
                   : ArgType(Ctx.IntTy, "__int32");
      case LengthModifier::AsPtrDiff:
        return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
      case LengthModifier::AsAllocate:
      case LengthModifier::AsMAllocate:
      case LengthModifier::AsWide:
        return ArgType::Invalid();
    }

  if (CS.isUIntArg())
    switch (LM.getKind()) {
      case LengthModifier::AsLongDouble:
        // GNU extension.
        return Ctx.UnsignedLongLongTy;
      case LengthModifier::None:
        return Ctx.UnsignedIntTy;
      case LengthModifier::AsInt32:
        return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
      case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
      case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
      case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
      case LengthModifier::AsLongLong:
      case LengthModifier::AsQuad:
        return Ctx.UnsignedLongLongTy;
      case LengthModifier::AsInt64:
        return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
      case LengthModifier::AsIntMax:
        return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
      case LengthModifier::AsSizeT:
        return ArgType(Ctx.getSizeType(), "size_t");
      case LengthModifier::AsInt3264:
        return Ctx.getTargetInfo().getTriple().isArch64Bit()
                   ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
                   : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
      case LengthModifier::AsPtrDiff:
        // FIXME: How to get the corresponding unsigned
        // version of ptrdiff_t?
        return ArgType();
      case LengthModifier::AsAllocate:
      case LengthModifier::AsMAllocate:
      case LengthModifier::AsWide:
        return ArgType::Invalid();
    }

  if (CS.isDoubleArg()) {
    if (LM.getKind() == LengthModifier::AsLongDouble)
      return Ctx.LongDoubleTy;
    return Ctx.DoubleTy;
  }

  if (CS.getKind() == ConversionSpecifier::nArg) {
    switch (LM.getKind()) {
      case LengthModifier::None:
        return ArgType::PtrTo(Ctx.IntTy);
      case LengthModifier::AsChar:
        return ArgType::PtrTo(Ctx.SignedCharTy);
      case LengthModifier::AsShort:
        return ArgType::PtrTo(Ctx.ShortTy);
      case LengthModifier::AsLong:
        return ArgType::PtrTo(Ctx.LongTy);
      case LengthModifier::AsLongLong:
      case LengthModifier::AsQuad:
        return ArgType::PtrTo(Ctx.LongLongTy);
      case LengthModifier::AsIntMax:
        return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
      case LengthModifier::AsSizeT:
        return ArgType(); // FIXME: ssize_t
      case LengthModifier::AsPtrDiff:
        return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
      case LengthModifier::AsLongDouble:
        return ArgType(); // FIXME: Is this a known extension?
      case LengthModifier::AsAllocate:
      case LengthModifier::AsMAllocate:
      case LengthModifier::AsInt32:
      case LengthModifier::AsInt3264:
      case LengthModifier::AsInt64:
      case LengthModifier::AsWide:
        return ArgType::Invalid();
    }
  }

  switch (CS.getKind()) {
    case ConversionSpecifier::sArg:
      if (LM.getKind() == LengthModifier::AsWideChar) {
        if (IsObjCLiteral)
          return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
                         "const unichar *");
        return ArgType(ArgType::WCStrTy, "wchar_t *");
      }
      if (LM.getKind() == LengthModifier::AsWide)
        return ArgType(ArgType::WCStrTy, "wchar_t *");
      return ArgType::CStrTy;
    case ConversionSpecifier::SArg:
      if (IsObjCLiteral)
        return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
                       "const unichar *");
      if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
          LM.getKind() == LengthModifier::AsShort)
        return ArgType::CStrTy;
      return ArgType(ArgType::WCStrTy, "wchar_t *");
    case ConversionSpecifier::CArg:
      if (IsObjCLiteral)
        return ArgType(Ctx.UnsignedShortTy, "unichar");
      if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
          LM.getKind() == LengthModifier::AsShort)
        return Ctx.IntTy;
      return ArgType(Ctx.WideCharTy, "wchar_t");
    case ConversionSpecifier::pArg:
    case ConversionSpecifier::PArg:
      return ArgType::CPointerTy;
    case ConversionSpecifier::ObjCObjArg:
      return ArgType::ObjCPointerTy;
    default:
      break;
  }

  // FIXME: Handle other cases.
  return ArgType();
}

bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
                              ASTContext &Ctx, bool IsObjCLiteral) {
  // %n is different from other conversion specifiers; don't try to fix it.
  if (CS.getKind() == ConversionSpecifier::nArg)
    return false;

  // Handle Objective-C objects first. Note that while the '%@' specifier will
  // not warn for structure pointer or void pointer arguments (because that's
  // how CoreFoundation objects are implemented), we only show a fixit for '%@'
  // if we know it's an object (block, id, class, or __attribute__((NSObject))).
  if (QT->isObjCRetainableType()) {
    if (!IsObjCLiteral)
      return false;

    CS.setKind(ConversionSpecifier::ObjCObjArg);

    // Disable irrelevant flags
    HasThousandsGrouping = false;
    HasPlusPrefix = false;
    HasSpacePrefix = false;
    HasAlternativeForm = false;
    HasLeadingZeroes = false;
    Precision.setHowSpecified(OptionalAmount::NotSpecified);
    LM.setKind(LengthModifier::None);

    return true;
  }

  // Handle strings next (char *, wchar_t *)
  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
    CS.setKind(ConversionSpecifier::sArg);

    // Disable irrelevant flags
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;

    // Set the long length modifier for wide characters
    if (QT->getPointeeType()->isWideCharType())
      LM.setKind(LengthModifier::AsWideChar);
    else
      LM.setKind(LengthModifier::None);

    return true;
  }

  // If it's an enum, get its underlying type.
  if (const EnumType *ETy = QT->getAs<EnumType>())
    QT = ETy->getDecl()->getIntegerType();

  // We can only work with builtin types.
  const BuiltinType *BT = QT->getAs<BuiltinType>();
  if (!BT)
    return false;

  // Set length modifier
  switch (BT->getKind()) {
  case BuiltinType::Bool:
  case BuiltinType::WChar_U:
  case BuiltinType::WChar_S:
  case BuiltinType::Char16:
  case BuiltinType::Char32:
  case BuiltinType::UInt128:
  case BuiltinType::Int128:
  case BuiltinType::Half:
  case BuiltinType::Float128:
    // Various types which are non-trivial to correct.
    return false;

#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
  case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
#define SIGNED_TYPE(Id, SingletonId)
#define UNSIGNED_TYPE(Id, SingletonId)
#define FLOATING_TYPE(Id, SingletonId)
#define BUILTIN_TYPE(Id, SingletonId) \
  case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
    // Misc other stuff which doesn't make sense here.
    return false;

  case BuiltinType::UInt:
  case BuiltinType::Int:
  case BuiltinType::Float:
  case BuiltinType::Double:
    LM.setKind(LengthModifier::None);
    break;

  case BuiltinType::Char_U:
  case BuiltinType::UChar:
  case BuiltinType::Char_S:
  case BuiltinType::SChar:
    LM.setKind(LengthModifier::AsChar);
    break;

  case BuiltinType::Short:
  case BuiltinType::UShort:
    LM.setKind(LengthModifier::AsShort);
    break;

  case BuiltinType::Long:
  case BuiltinType::ULong:
    LM.setKind(LengthModifier::AsLong);
    break;

  case BuiltinType::LongLong:
  case BuiltinType::ULongLong:
    LM.setKind(LengthModifier::AsLongLong);
    break;

  case BuiltinType::LongDouble:
    LM.setKind(LengthModifier::AsLongDouble);
    break;
  }

  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
    namedTypeToLengthModifier(QT, LM);

  // If fixing the length modifier was enough, we might be done.
  if (hasValidLengthModifier(Ctx.getTargetInfo())) {
    // If we're going to offer a fix anyway, make sure the sign matches.
    switch (CS.getKind()) {
    case ConversionSpecifier::uArg:
    case ConversionSpecifier::UArg:
      if (QT->isSignedIntegerType())
        CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
      break;
    case ConversionSpecifier::dArg:
    case ConversionSpecifier::DArg:
    case ConversionSpecifier::iArg:
      if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
        CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
      break;
    default:
      // Other specifiers do not have signed/unsigned variants.
      break;
    }

    const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
    if (ATR.isValid() && ATR.matchesType(Ctx, QT))
      return true;
  }

  // Set conversion specifier and disable any flags which do not apply to it.
  // Let typedefs to char fall through to int, as %c is silly for uint8_t.
  if (!isa<TypedefType>(QT) && QT->isCharType()) {
    CS.setKind(ConversionSpecifier::cArg);
    LM.setKind(LengthModifier::None);
    Precision.setHowSpecified(OptionalAmount::NotSpecified);
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;
    HasPlusPrefix = 0;
  }
  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
  else if (QT->isRealFloatingType()) {
    CS.setKind(ConversionSpecifier::fArg);
  }
  else if (QT->isSignedIntegerType()) {
    CS.setKind(ConversionSpecifier::dArg);
    HasAlternativeForm = 0;
  }
  else if (QT->isUnsignedIntegerType()) {
    CS.setKind(ConversionSpecifier::uArg);
    HasAlternativeForm = 0;
    HasPlusPrefix = 0;
  } else {
    llvm_unreachable("Unexpected type");
  }

  return true;
}

void PrintfSpecifier::toString(raw_ostream &os) const {
  // Whilst some features have no defined order, we are using the order
  // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
  os << "%";

  // Positional args
  if (usesPositionalArg()) {
    os << getPositionalArgIndex() << "$";
  }

  // Conversion flags
  if (IsLeftJustified)    os << "-";
  if (HasPlusPrefix)      os << "+";
  if (HasSpacePrefix)     os << " ";
  if (HasAlternativeForm) os << "#";
  if (HasLeadingZeroes)   os << "0";

  // Minimum field width
  FieldWidth.toString(os);
  // Precision
  Precision.toString(os);
  // Length modifier
  os << LM.toString();
  // Conversion specifier
  os << CS.toString();
}

bool PrintfSpecifier::hasValidPlusPrefix() const {
  if (!HasPlusPrefix)
    return true;

  // The plus prefix only makes sense for signed conversions
  switch (CS.getKind()) {
  case ConversionSpecifier::dArg:
  case ConversionSpecifier::DArg:
  case ConversionSpecifier::iArg:
  case ConversionSpecifier::fArg:
  case ConversionSpecifier::FArg:
  case ConversionSpecifier::eArg:
  case ConversionSpecifier::EArg:
  case ConversionSpecifier::gArg:
  case ConversionSpecifier::GArg:
  case ConversionSpecifier::aArg:
  case ConversionSpecifier::AArg:
  case ConversionSpecifier::FreeBSDrArg:
  case ConversionSpecifier::FreeBSDyArg:
    return true;

  default:
    return false;
  }
}

bool PrintfSpecifier::hasValidAlternativeForm() const {
  if (!HasAlternativeForm)
    return true;

  // Alternate form flag only valid with the oxXaAeEfFgG conversions
  switch (CS.getKind()) {
  case ConversionSpecifier::oArg:
  case ConversionSpecifier::OArg:
  case ConversionSpecifier::xArg:
  case ConversionSpecifier::XArg:
  case ConversionSpecifier::aArg:
  case ConversionSpecifier::AArg:
  case ConversionSpecifier::eArg:
  case ConversionSpecifier::EArg:
  case ConversionSpecifier::fArg:
  case ConversionSpecifier::FArg:
  case ConversionSpecifier::gArg:
  case ConversionSpecifier::GArg:
  case ConversionSpecifier::FreeBSDrArg:
  case ConversionSpecifier::FreeBSDyArg:
    return true;

  default:
    return false;
  }
}

bool PrintfSpecifier::hasValidLeadingZeros() const {
  if (!HasLeadingZeroes)
    return true;

  // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
  switch (CS.getKind()) {
  case ConversionSpecifier::dArg:
  case ConversionSpecifier::DArg:
  case ConversionSpecifier::iArg:
  case ConversionSpecifier::oArg:
  case ConversionSpecifier::OArg:
  case ConversionSpecifier::uArg:
  case ConversionSpecifier::UArg:
  case ConversionSpecifier::xArg:
  case ConversionSpecifier::XArg:
  case ConversionSpecifier::aArg:
  case ConversionSpecifier::AArg:
  case ConversionSpecifier::eArg:
  case ConversionSpecifier::EArg:
  case ConversionSpecifier::fArg:
  case ConversionSpecifier::FArg:
  case ConversionSpecifier::gArg:
  case ConversionSpecifier::GArg:
  case ConversionSpecifier::FreeBSDrArg:
  case ConversionSpecifier::FreeBSDyArg:
    return true;

  default:
    return false;
  }
}

bool PrintfSpecifier::hasValidSpacePrefix() const {
  if (!HasSpacePrefix)
    return true;

  // The space prefix only makes sense for signed conversions
  switch (CS.getKind()) {
  case ConversionSpecifier::dArg:
  case ConversionSpecifier::DArg:
  case ConversionSpecifier::iArg:
  case ConversionSpecifier::fArg:
  case ConversionSpecifier::FArg:
  case ConversionSpecifier::eArg:
  case ConversionSpecifier::EArg:
  case ConversionSpecifier::gArg:
  case ConversionSpecifier::GArg:
  case ConversionSpecifier::aArg:
  case ConversionSpecifier::AArg:
  case ConversionSpecifier::FreeBSDrArg:
  case ConversionSpecifier::FreeBSDyArg:
    return true;

  default:
    return false;
  }
}

bool PrintfSpecifier::hasValidLeftJustified() const {
  if (!IsLeftJustified)
    return true;

  // The left justified flag is valid for all conversions except n
  switch (CS.getKind()) {
  case ConversionSpecifier::nArg:
    return false;

  default:
    return true;
  }
}

bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
  if (!HasThousandsGrouping)
    return true;

  switch (CS.getKind()) {
    case ConversionSpecifier::dArg:
    case ConversionSpecifier::DArg:
    case ConversionSpecifier::iArg:
    case ConversionSpecifier::uArg:
    case ConversionSpecifier::UArg:
    case ConversionSpecifier::fArg:
    case ConversionSpecifier::FArg:
    case ConversionSpecifier::gArg:
    case ConversionSpecifier::GArg:
      return true;
    default:
      return false;
  }
}

bool PrintfSpecifier::hasValidPrecision() const {
  if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
    return true;

  // Precision is only valid with the diouxXaAeEfFgGsP conversions
  switch (CS.getKind()) {
  case ConversionSpecifier::dArg:
  case ConversionSpecifier::DArg:
  case ConversionSpecifier::iArg:
  case ConversionSpecifier::oArg:
  case ConversionSpecifier::OArg:
  case ConversionSpecifier::uArg:
  case ConversionSpecifier::UArg:
  case ConversionSpecifier::xArg:
  case ConversionSpecifier::XArg:
  case ConversionSpecifier::aArg:
  case ConversionSpecifier::AArg:
  case ConversionSpecifier::eArg:
  case ConversionSpecifier::EArg:
  case ConversionSpecifier::fArg:
  case ConversionSpecifier::FArg:
  case ConversionSpecifier::gArg:
  case ConversionSpecifier::GArg:
  case ConversionSpecifier::sArg:
  case ConversionSpecifier::FreeBSDrArg:
  case ConversionSpecifier::FreeBSDyArg:
  case ConversionSpecifier::PArg:
    return true;

  default:
    return false;
  }
}
bool PrintfSpecifier::hasValidFieldWidth() const {
  if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
      return true;

  // The field width is valid for all conversions except n
  switch (CS.getKind()) {
  case ConversionSpecifier::nArg:
    return false;

  default:
    return true;
  }
}
