Make printf warnings refer to intmax_t et al. by name
in addition to underlying type.

For example, the warning for printf("%zu", 42.0);
changes from "conversion specifies type 'unsigned long'" to "conversion
specifies type 'size_t' (aka 'unsigned long')"

(This is a second attempt after r145697, which got reverted.)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146032 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp
index 6498ded..0853164 100644
--- a/lib/Analysis/FormatString.cpp
+++ b/lib/Analysis/FormatString.cpp
@@ -228,6 +228,7 @@
       return false;
     }
       
+    case TypedefTy:
     case SpecificTy: {
       argTy = C.getCanonicalType(argTy).getUnqualifiedType();
       if (T == argTy)
@@ -331,6 +332,7 @@
     case AnyCharTy:
       return C.CharTy;
     case SpecificTy:
+    case TypedefTy:
       return T;
     case CStrTy:
       return C.getPointerType(C.CharTy);
@@ -351,6 +353,13 @@
   return QualType();
 }
 
+std::string ArgTypeResult::getRepresentativeTypeName(ASTContext &C) const {
+  if (K != TypedefTy)
+    return std::string("'") + getRepresentativeType(C).getAsString() + "'";
+  return std::string("'") + Name + "' (aka '" + T.getAsString() + "')";
+}
+
+
 //===----------------------------------------------------------------------===//
 // Methods on OptionalAmount.
 //===----------------------------------------------------------------------===//
@@ -485,5 +494,3 @@
   }
   return false;
 }
-
-
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index 70dbfd3..e14c952 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -301,11 +301,13 @@
       case LengthModifier::AsShort: return Ctx.ShortTy;
       case LengthModifier::AsLong: return Ctx.LongTy;
       case LengthModifier::AsLongLong: return Ctx.LongLongTy;
-      case LengthModifier::AsIntMax: return Ctx.getIntMaxType();
+      case LengthModifier::AsIntMax:
+        return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t");
       case LengthModifier::AsSizeT:
         // FIXME: How to get the corresponding signed version of size_t?
         return ArgTypeResult();
-      case LengthModifier::AsPtrDiff: return Ctx.getPointerDiffType();
+      case LengthModifier::AsPtrDiff:
+        return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t");
     }
 
   if (CS.isUIntArg())
@@ -317,9 +319,10 @@
       case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
       case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
       case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy;
-      case LengthModifier::AsIntMax: return Ctx.getUIntMaxType();
+      case LengthModifier::AsIntMax:
+        return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t");
       case LengthModifier::AsSizeT:
-        return Ctx.getSizeType();
+        return ArgTypeResult(Ctx.getSizeType(), "size_t");
       case LengthModifier::AsPtrDiff:
         // FIXME: How to get the corresponding unsigned
         // version of ptrdiff_t?