From 36c49e3f258dced101949edabd72e9bc3f1dedc4 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Fri, 17 Sep 2010 15:54:40 +0000
Subject: Vendor import of clang r114020 (from the release_28 branch):
 http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020

Approved by:	rpaulo (mentor)
---
 lib/Analysis/PrintfFormatString.cpp | 572 +++++-------------------------------
 1 file changed, 77 insertions(+), 495 deletions(-)

(limited to 'lib/Analysis/PrintfFormatString.cpp')

diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index 558d38a..b8c327c 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -1,4 +1,4 @@
-//= PrintfFormatStrings.cpp - Analysis of printf format strings --*- C++ -*-==//
+//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -12,141 +12,28 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Analysis/Analyses/PrintfFormatString.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Type.h"
-#include "llvm/Support/raw_ostream.h"
+#include "clang/Analysis/Analyses/FormatString.h"
+#include "FormatStringParsing.h"
 
-using clang::analyze_printf::ArgTypeResult;
-using clang::analyze_printf::FormatSpecifier;
-using clang::analyze_printf::FormatStringHandler;
-using clang::analyze_printf::OptionalAmount;
-using clang::analyze_printf::PositionContext;
-using clang::analyze_printf::ConversionSpecifier;
-using clang::analyze_printf::LengthModifier;
+using clang::analyze_format_string::ArgTypeResult;
+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;
 
-namespace {
-class FormatSpecifierResult {
-  FormatSpecifier FS;
-  const char *Start;
-  bool Stop;
-public:
-  FormatSpecifierResult(bool stop = false)
-    : Start(0), Stop(stop) {}
-  FormatSpecifierResult(const char *start,
-                        const FormatSpecifier &fs)
-    : FS(fs), Start(start), Stop(false) {}
-
-  const char *getStart() const { return Start; }
-  bool shouldStop() const { return Stop; }
-  bool hasValue() const { return Start != 0; }
-  const FormatSpecifier &getValue() const {
-    assert(hasValue());
-    return FS;
-  }
-  const FormatSpecifier &getValue() { return FS; }
-};
-} // end anonymous namespace
-
-template <typename T>
-class UpdateOnReturn {
-  T &ValueToUpdate;
-  const T &ValueToCopy;
-public:
-  UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
-    : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
-
-  ~UpdateOnReturn() {
-    ValueToUpdate = ValueToCopy;
-  }
-};
+typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
+        PrintfSpecifierResult;
 
 //===----------------------------------------------------------------------===//
 // Methods for parsing format strings.
 //===----------------------------------------------------------------------===//
 
-static OptionalAmount ParseAmount(const char *&Beg, const char *E) {
-  const char *I = Beg;
-  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
-
-  unsigned accumulator = 0;
-  bool hasDigits = false;
-
-  for ( ; I != E; ++I) {
-    char c = *I;
-    if (c >= '0' && c <= '9') {
-      hasDigits = true;
-      accumulator = (accumulator * 10) + (c - '0');
-      continue;
-    }
-
-    if (hasDigits)
-      return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
-          false);
-
-    break;
-  }
-
-  return OptionalAmount();
-}
-
-static OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
-                                             unsigned &argIndex) {
-  if (*Beg == '*') {
-    ++Beg;
-    return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
-  }
-
-  return ParseAmount(Beg, E);
-}
-
-static OptionalAmount ParsePositionAmount(FormatStringHandler &H,
-                                          const char *Start,
-                                          const char *&Beg, const char *E,
-                                          PositionContext p) {
-  if (*Beg == '*') {
-    const char *I = Beg + 1;
-    const OptionalAmount &Amt = ParseAmount(I, E);
-
-    if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
-      H.HandleInvalidPosition(Beg, I - Beg, p);
-      return OptionalAmount(false);
-    }
-
-    if (I== E) {
-      // No more characters left?
-      H.HandleIncompleteFormatSpecifier(Start, E - Start);
-      return OptionalAmount(false);
-    }
-
-    assert(Amt.getHowSpecified() == OptionalAmount::Constant);
-
-    if (*I == '$') {
-      // Handle positional arguments
-
-      // Special case: '*0$', since this is an easy mistake.
-      if (Amt.getConstantAmount() == 0) {
-        H.HandleZeroPosition(Beg, I - Beg + 1);
-        return OptionalAmount(false);
-      }
-
-      const char *Tmp = Beg;
-      Beg = ++I;
-
-      return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
-                            Tmp, 0, true);
-    }
-
-    H.HandleInvalidPosition(Beg, I - Beg, p);
-    return OptionalAmount(false);
-  }
-
-  return ParseAmount(Beg, E);
-}
+using analyze_format_string::ParseNonPositionAmount;
 
-static bool ParsePrecision(FormatStringHandler &H, FormatSpecifier &FS,
+static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
                            const char *Start, const char *&Beg, const char *E,
                            unsigned *argIndex) {
   if (argIndex) {
@@ -154,7 +41,7 @@ static bool ParsePrecision(FormatStringHandler &H, FormatSpecifier &FS,
   }
   else {
     const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
-                                                  analyze_printf::PrecisionPos);
+                                           analyze_format_string::PrecisionPos);
     if (Amt.isInvalid())
       return true;
     FS.setPrecision(Amt);
@@ -162,61 +49,12 @@ static bool ParsePrecision(FormatStringHandler &H, FormatSpecifier &FS,
   return false;
 }
 
-static bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &FS,
-                            const char *Start, const char *&Beg, const char *E,
-                            unsigned *argIndex) {
-  // FIXME: Support negative field widths.
-  if (argIndex) {
-    FS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
-  }
-  else {
-    const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
-                                                 analyze_printf::FieldWidthPos);
-    if (Amt.isInvalid())
-      return true;
-    FS.setFieldWidth(Amt);
-  }
-  return false;
-}
-
-static bool ParseArgPosition(FormatStringHandler &H,
-                             FormatSpecifier &FS, const char *Start,
-                             const char *&Beg, const char *E) {
-
-  using namespace clang::analyze_printf;
-  const char *I = Beg;
-
-  const OptionalAmount &Amt = ParseAmount(I, E);
-
-  if (I == E) {
-    // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
-    return true;
-  }
-
-  if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
-    // Special case: '%0$', since this is an easy mistake.
-    if (Amt.getConstantAmount() == 0) {
-      H.HandleZeroPosition(Start, I - Start);
-      return true;
-    }
-
-    FS.setArgIndex(Amt.getConstantAmount() - 1);
-    FS.setUsesPositionalArg();
-    // Update the caller's pointer if we decided to consume
-    // these characters.
-    Beg = I;
-    return false;
-  }
-
-  return false;
-}
-
-static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
+static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
                                                   const char *&Beg,
                                                   const char *E,
                                                   unsigned &argIndex) {
 
+  using namespace clang::analyze_format_string;
   using namespace clang::analyze_printf;
 
   const char *I = Beg;
@@ -243,17 +81,17 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
-  FormatSpecifier FS;
+  PrintfSpecifier FS;
   if (ParseArgPosition(H, FS, Start, I, E))
     return true;
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -274,7 +112,7 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -285,7 +123,7 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -293,7 +131,7 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
   if (*I == '.') {
     ++I;
     if (I == E) {
-      H.HandleIncompleteFormatSpecifier(Start, E - Start);
+      H.HandleIncompleteSpecifier(Start, E - Start);
       return true;
     }
 
@@ -303,39 +141,15 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
 
     if (I == E) {
       // No more characters left?
-      H.HandleIncompleteFormatSpecifier(Start, E - Start);
+      H.HandleIncompleteSpecifier(Start, E - Start);
       return true;
     }
   }
 
   // Look for the length modifier.
-  LengthModifier::Kind lmKind = LengthModifier::None;
-  const char *lmPosition = I;
-  switch (*I) {
-    default:
-      break;
-    case 'h':
-      ++I;
-      lmKind = (I != E && *I == 'h') ?
-          ++I, LengthModifier::AsChar : LengthModifier::AsShort;
-      break;
-    case 'l':
-      ++I;
-      lmKind = (I != E && *I == 'l') ?
-          ++I, LengthModifier::AsLongLong : LengthModifier::AsLong;
-      break;
-    case 'j': lmKind = LengthModifier::AsIntMax;     ++I; break;
-    case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
-    case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
-    case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
-    case 'q': lmKind = LengthModifier::AsLongLong;   ++I; break;
-  }
-  LengthModifier lm(lmPosition, lmKind);
-  FS.setLengthModifier(lm);
-
-  if (I == E) {
+  if (ParseLengthModifier(FS, I, E) && I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -359,46 +173,47 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
     case 'G': k = ConversionSpecifier::GArg; break;
     case 'X': k = ConversionSpecifier::XArg; break;
     case 'a': k = ConversionSpecifier::aArg; break;
-    case 'c': k = ConversionSpecifier::IntAsCharArg; 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::OutIntPtrArg; break;
+    case 'n': k = ConversionSpecifier::nArg; break;
     case 'o': k = ConversionSpecifier::oArg; break;
-    case 'p': k = ConversionSpecifier::VoidPtrArg;   break;
-    case 's': k = ConversionSpecifier::CStrArg;      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;
     // Mac OS X (unicode) specific
     case 'C': k = ConversionSpecifier::CArg; break;
-    case 'S': k = ConversionSpecifier::UnicodeStrArg; break;
+    case 'S': k = ConversionSpecifier::SArg; break;
     // Objective-C.
     case '@': k = ConversionSpecifier::ObjCObjArg; break;
     // Glibc specific.
     case 'm': k = ConversionSpecifier::PrintErrno; break;
   }
-  ConversionSpecifier CS(conversionPosition, k);
+  PrintfConversionSpecifier CS(conversionPosition, k);
   FS.setConversionSpecifier(CS);
   if (CS.consumesDataArgument() && !FS.usesPositionalArg())
     FS.setArgIndex(argIndex++);
 
   if (k == ConversionSpecifier::InvalidSpecifier) {
     // Assume the conversion takes one argument.
-    return !H.HandleInvalidConversionSpecifier(FS, Beg, I - Beg);
+    return !H.HandleInvalidPrintfConversionSpecifier(FS, Beg, I - Beg);
   }
-  return FormatSpecifierResult(Start, FS);
+  return PrintfSpecifierResult(Start, FS);
 }
 
-bool clang::analyze_printf::ParseFormatString(FormatStringHandler &H,
-                       const char *I, const char *E) {
+bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
+                                                     const char *I,
+                                                     const char *E) {
 
   unsigned argIndex = 0;
 
   // Keep looking for a format specifier until we have exhausted the string.
   while (I != E) {
-    const FormatSpecifierResult &FSR = ParseFormatSpecifier(H, I, E, argIndex);
+    const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex);
     // Did a fail-stop error of any kind occur when parsing the specifier?
     // If so, don't do any more processing.
     if (FSR.shouldStop())
@@ -408,7 +223,7 @@ bool clang::analyze_printf::ParseFormatString(FormatStringHandler &H,
     if (!FSR.hasValue())
       continue;
     // We have a format specifier.  Pass it to the callback.
-    if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(),
+    if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
                                  I - FSR.getStart()))
       return true;
   }
@@ -416,129 +231,6 @@ bool clang::analyze_printf::ParseFormatString(FormatStringHandler &H,
   return false;
 }
 
-FormatStringHandler::~FormatStringHandler() {}
-
-//===----------------------------------------------------------------------===//
-// Methods on ArgTypeResult.
-//===----------------------------------------------------------------------===//
-
-bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
-  switch (K) {
-    case InvalidTy:
-      assert(false && "ArgTypeResult must be valid");
-      return true;
-
-    case UnknownTy:
-      return true;
-
-    case SpecificTy: {
-      argTy = C.getCanonicalType(argTy).getUnqualifiedType();
-      if (T == argTy)
-        return true;
-      if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
-        switch (BT->getKind()) {
-          default:
-            break;
-          case BuiltinType::Char_S:
-          case BuiltinType::SChar:
-            return T == C.UnsignedCharTy;
-          case BuiltinType::Char_U:
-          case BuiltinType::UChar:
-            return T == C.SignedCharTy;
-          case BuiltinType::Short:
-            return T == C.UnsignedShortTy;
-          case BuiltinType::UShort:
-            return T == C.ShortTy;
-          case BuiltinType::Int:
-            return T == C.UnsignedIntTy;
-          case BuiltinType::UInt:
-            return T == C.IntTy;
-          case BuiltinType::Long:
-            return T == C.UnsignedLongTy;
-          case BuiltinType::ULong:
-            return T == C.LongTy;
-          case BuiltinType::LongLong:
-            return T == C.UnsignedLongLongTy;
-          case BuiltinType::ULongLong:
-            return T == C.LongLongTy;
-        }
-      return false;
-    }
-
-    case CStrTy: {
-      const PointerType *PT = argTy->getAs<PointerType>();
-      if (!PT)
-        return false;
-      QualType pointeeTy = PT->getPointeeType();
-      if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
-        switch (BT->getKind()) {
-          case BuiltinType::Void:
-          case BuiltinType::Char_U:
-          case BuiltinType::UChar:
-          case BuiltinType::Char_S:
-          case BuiltinType::SChar:
-            return true;
-          default:
-            break;
-        }
-
-      return false;
-    }
-
-    case WCStrTy: {
-      const PointerType *PT = argTy->getAs<PointerType>();
-      if (!PT)
-        return false;
-      QualType pointeeTy =
-        C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
-      return pointeeTy == C.getWCharType();
-    }
-
-    case CPointerTy:
-      return argTy->getAs<PointerType>() != NULL ||
-      	     argTy->getAs<ObjCObjectPointerType>() != NULL;
-
-    case ObjCPointerTy:
-      return argTy->getAs<ObjCObjectPointerType>() != NULL;
-  }
-
-  // FIXME: Should be unreachable, but Clang is currently emitting
-  // a warning.
-  return false;
-}
-
-QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const {
-  switch (K) {
-    case InvalidTy:
-      assert(false && "No representative type for Invalid ArgTypeResult");
-      // Fall-through.
-    case UnknownTy:
-      return QualType();
-    case SpecificTy:
-      return T;
-    case CStrTy:
-      return C.getPointerType(C.CharTy);
-    case WCStrTy:
-      return C.getPointerType(C.getWCharType());
-    case ObjCPointerTy:
-      return C.ObjCBuiltinIdTy;
-    case CPointerTy:
-      return C.VoidPtrTy;
-  }
-
-  // FIXME: Should be unreachable, but Clang is currently emitting
-  // a warning.
-  return QualType();
-}
-
-//===----------------------------------------------------------------------===//
-// Methods on OptionalAmount.
-//===----------------------------------------------------------------------===//
-
-ArgTypeResult OptionalAmount::getArgType(ASTContext &Ctx) const {
-  return Ctx.IntTy;
-}
-
 //===----------------------------------------------------------------------===//
 // Methods on ConversionSpecifier.
 //===----------------------------------------------------------------------===//
@@ -558,16 +250,17 @@ const char *ConversionSpecifier::toString() const {
   case GArg: return "G";
   case aArg: return "a";
   case AArg: return "A";
-  case IntAsCharArg:     return "c";
-  case CStrArg:          return "s";
-  case VoidPtrArg:       return "p";
-  case OutIntPtrArg:     return "n";
-  case PercentArg:       return "%";
+  case cArg: return "c";
+  case sArg: return "s";
+  case pArg: return "p";
+  case nArg: return "n";
+  case PercentArg:  return "%";
+  case ScanListArg: return "[";
   case InvalidSpecifier: return NULL;
 
   // MacOS X unicode extensions.
-  case CArg:          return "C";
-  case UnicodeStrArg: return "S";
+  case CArg: return "C";
+  case SArg: return "S";
 
   // Objective-C specific specifiers.
   case ObjCObjArg: return "@";
@@ -579,66 +272,23 @@ const char *ConversionSpecifier::toString() const {
 }
 
 //===----------------------------------------------------------------------===//
-// Methods on LengthModifier.
-//===----------------------------------------------------------------------===//
-
-const char *LengthModifier::toString() const {
-  switch (kind) {
-  case AsChar:
-    return "hh";
-  case AsShort:
-    return "h";
-  case AsLong: // or AsWideChar
-    return "l";
-  case AsLongLong:
-    return "ll";
-  case AsIntMax:
-    return "j";
-  case AsSizeT:
-    return "z";
-  case AsPtrDiff:
-    return "t";
-  case AsLongDouble:
-    return "L";
-  case None:
-    return "";
-  }
-  return NULL;
-}
-
-//===----------------------------------------------------------------------===//
-// Methods on OptionalAmount.
+// Methods on PrintfSpecifier.
 //===----------------------------------------------------------------------===//
 
-void OptionalAmount::toString(llvm::raw_ostream &os) const {
-  switch (hs) {
-  case Invalid:
-  case NotSpecified:
-    return;
-  case Arg:
-    if (UsesDotPrefix)
-        os << ".";
-    if (usesPositionalArg())
-      os << "*" << getPositionalArgIndex() << "$";
-    else
-      os << "*";
-    break;
-  case Constant:
-    if (UsesDotPrefix)
-        os << ".";
-    os << amt;
-    break;
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// Methods on FormatSpecifier.
-//===----------------------------------------------------------------------===//
-
-ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const {
+ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
+  const PrintfConversionSpecifier &CS = getConversionSpecifier();
+  
   if (!CS.consumesDataArgument())
     return ArgTypeResult::Invalid();
 
+  if (CS.getKind() == ConversionSpecifier::cArg)
+    switch (LM.getKind()) {
+      case LengthModifier::None: return Ctx.IntTy;
+      case LengthModifier::AsLong: return ArgTypeResult::WIntTy;
+      default:
+        return ArgTypeResult::Invalid();
+    }
+  
   if (CS.isIntArg())
     switch (LM.getKind()) {
       case LengthModifier::AsLongDouble:
@@ -684,15 +334,15 @@ ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const {
   }
 
   switch (CS.getKind()) {
-    case ConversionSpecifier::CStrArg:
+    case ConversionSpecifier::sArg:
       return ArgTypeResult(LM.getKind() == LengthModifier::AsWideChar ?
           ArgTypeResult::WCStrTy : ArgTypeResult::CStrTy);
-    case ConversionSpecifier::UnicodeStrArg:
+    case ConversionSpecifier::SArg:
       // FIXME: This appears to be Mac OS X specific.
       return ArgTypeResult::WCStrTy;
     case ConversionSpecifier::CArg:
       return Ctx.WCharTy;
-    case ConversionSpecifier::VoidPtrArg:
+    case ConversionSpecifier::pArg:
       return ArgTypeResult::CPointerTy;
     default:
       break;
@@ -702,10 +352,10 @@ ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const {
   return ArgTypeResult();
 }
 
-bool FormatSpecifier::fixType(QualType QT) {
+bool PrintfSpecifier::fixType(QualType QT) {
   // Handle strings first (char *, wchar_t *)
   if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
-    CS.setKind(ConversionSpecifier::CStrArg);
+    CS.setKind(ConversionSpecifier::sArg);
 
     // Disable irrelevant flags
     HasAlternativeForm = 0;
@@ -750,7 +400,7 @@ bool FormatSpecifier::fixType(QualType QT) {
 
   // Set conversion specifier and disable any flags which do not apply to it.
   if (QT->isAnyCharacterType()) {
-    CS.setKind(ConversionSpecifier::IntAsCharArg);
+    CS.setKind(ConversionSpecifier::cArg);
     Precision.setHowSpecified(OptionalAmount::NotSpecified);
     HasAlternativeForm = 0;
     HasLeadingZeroes = 0;
@@ -761,7 +411,7 @@ bool FormatSpecifier::fixType(QualType QT) {
     CS.setKind(ConversionSpecifier::fArg);
   }
   else if (QT->isPointerType()) {
-    CS.setKind(ConversionSpecifier::VoidPtrArg);
+    CS.setKind(ConversionSpecifier::pArg);
     Precision.setHowSpecified(OptionalAmount::NotSpecified);
     HasAlternativeForm = 0;
     HasLeadingZeroes = 0;
@@ -783,9 +433,9 @@ bool FormatSpecifier::fixType(QualType QT) {
   return true;
 }
 
-void FormatSpecifier::toString(llvm::raw_ostream &os) const {
+void PrintfSpecifier::toString(llvm::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)
+  // appearing in the C99 standard (ISO/IEC 9899:1999 (E) ¤7.19.6.1)
   os << "%";
 
   // Positional args
@@ -810,7 +460,7 @@ void FormatSpecifier::toString(llvm::raw_ostream &os) const {
   os << CS.toString();
 }
 
-bool FormatSpecifier::hasValidPlusPrefix() const {
+bool PrintfSpecifier::hasValidPlusPrefix() const {
   if (!HasPlusPrefix)
     return true;
 
@@ -833,7 +483,7 @@ bool FormatSpecifier::hasValidPlusPrefix() const {
   }
 }
 
-bool FormatSpecifier::hasValidAlternativeForm() const {
+bool PrintfSpecifier::hasValidAlternativeForm() const {
   if (!HasAlternativeForm)
     return true;
 
@@ -856,7 +506,7 @@ bool FormatSpecifier::hasValidAlternativeForm() const {
   }
 }
 
-bool FormatSpecifier::hasValidLeadingZeros() const {
+bool PrintfSpecifier::hasValidLeadingZeros() const {
   if (!HasLeadingZeroes)
     return true;
 
@@ -883,7 +533,7 @@ bool FormatSpecifier::hasValidLeadingZeros() const {
   }
 }
 
-bool FormatSpecifier::hasValidSpacePrefix() const {
+bool PrintfSpecifier::hasValidSpacePrefix() const {
   if (!HasSpacePrefix)
     return true;
 
@@ -906,13 +556,13 @@ bool FormatSpecifier::hasValidSpacePrefix() const {
   }
 }
 
-bool FormatSpecifier::hasValidLeftJustified() const {
+bool PrintfSpecifier::hasValidLeftJustified() const {
   if (!IsLeftJustified)
     return true;
 
   // The left justified flag is valid for all conversions except n
   switch (CS.getKind()) {
-  case ConversionSpecifier::OutIntPtrArg:
+  case ConversionSpecifier::nArg:
     return false;
 
   default:
@@ -920,75 +570,7 @@ bool FormatSpecifier::hasValidLeftJustified() const {
   }
 }
 
-bool FormatSpecifier::hasValidLengthModifier() const {
-  switch (LM.getKind()) {
-  case LengthModifier::None:
-    return true;
-
-  // Handle most integer flags
-  case LengthModifier::AsChar:
-  case LengthModifier::AsShort:
-  case LengthModifier::AsLongLong:
-  case LengthModifier::AsIntMax:
-  case LengthModifier::AsSizeT:
-  case LengthModifier::AsPtrDiff:
-    switch (CS.getKind()) {
-    case ConversionSpecifier::dArg:
-    case ConversionSpecifier::iArg:
-    case ConversionSpecifier::oArg:
-    case ConversionSpecifier::uArg:
-    case ConversionSpecifier::xArg:
-    case ConversionSpecifier::XArg:
-    case ConversionSpecifier::OutIntPtrArg:
-      return true;
-    default:
-      return false;
-    }
-
-  // Handle 'l' flag
-  case LengthModifier::AsLong:
-    switch (CS.getKind()) {
-    case ConversionSpecifier::dArg:
-    case ConversionSpecifier::iArg:
-    case ConversionSpecifier::oArg:
-    case ConversionSpecifier::uArg:
-    case ConversionSpecifier::xArg:
-    case ConversionSpecifier::XArg:
-    case ConversionSpecifier::aArg:
-    case ConversionSpecifier::AArg:
-    case ConversionSpecifier::fArg:
-    case ConversionSpecifier::FArg:
-    case ConversionSpecifier::eArg:
-    case ConversionSpecifier::EArg:
-    case ConversionSpecifier::gArg:
-    case ConversionSpecifier::GArg:
-    case ConversionSpecifier::OutIntPtrArg:
-    case ConversionSpecifier::IntAsCharArg:
-    case ConversionSpecifier::CStrArg:
-      return true;
-    default:
-      return false;
-    }
-
-  case LengthModifier::AsLongDouble:
-    switch (CS.getKind()) {
-    case ConversionSpecifier::aArg:
-    case ConversionSpecifier::AArg:
-    case ConversionSpecifier::fArg:
-    case ConversionSpecifier::FArg:
-    case ConversionSpecifier::eArg:
-    case ConversionSpecifier::EArg:
-    case ConversionSpecifier::gArg:
-    case ConversionSpecifier::GArg:
-      return true;
-    default:
-      return false;
-    }
-  }
-  return false;
-}
-
-bool FormatSpecifier::hasValidPrecision() const {
+bool PrintfSpecifier::hasValidPrecision() const {
   if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
     return true;
 
@@ -1008,20 +590,20 @@ bool FormatSpecifier::hasValidPrecision() const {
   case ConversionSpecifier::FArg:
   case ConversionSpecifier::gArg:
   case ConversionSpecifier::GArg:
-  case ConversionSpecifier::CStrArg:
+  case ConversionSpecifier::sArg:
     return true;
 
   default:
     return false;
   }
 }
-bool FormatSpecifier::hasValidFieldWidth() const {
+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::OutIntPtrArg:
+  case ConversionSpecifier::nArg:
     return false;
 
   default:
-- 
cgit v1.1