Fix a long standard problem with clang retaining "too much" sugar 
information about types.  We often print diagnostics where we say 
"foo_t" is bad, but the user doesn't know how foo_t is declared 
(because it is a typedef).  Fix this by expanding sugar when present
in a diagnostic (and not one of a few special cases, like vectors).

Before:
t.m:5:2: error: invalid operands to binary expression ('typeof(P)' and 'typeof(F)')
 MAX(P, F);
 ^~~~~~~~~
t.m:1:78: note: instantiated from:
#define MAX(A,B)    ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
                                                                             ^

After:
t.m:5:2: error: invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))
 MAX(P, F);
 ^~~~~~~~~
t.m:1:78: note: instantiated from:
#define MAX(A,B)    ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
                                                                             ^




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65081 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 3f94a03..83ccd22 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -648,9 +648,9 @@
     }
     // ---- NAMES and TYPES ----
     case Diagnostic::ak_identifierinfo: {
-      OutStr.push_back('\'');
       const IdentifierInfo *II = getArgIdentifier(ArgNo);
       assert(ModifierLen == 0 && "No modifiers for strings yet");
+      OutStr.push_back('\'');
       OutStr.append(II->getName(), II->getName() + II->getLength());
       OutStr.push_back('\'');
       break;
@@ -658,11 +658,9 @@
     case Diagnostic::ak_qualtype:
     case Diagnostic::ak_declarationname:
     case Diagnostic::ak_nameddecl:
-      OutStr.push_back('\'');
       getDiags()->ConvertArgToString(getArgKind(ArgNo), getRawArg(ArgNo),
                                      Modifier, ModifierLen,
                                      Argument, ArgumentLen, OutStr);
-      OutStr.push_back('\'');
       break;
     }
   }
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 539457f..1ffaf93 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -22,19 +22,39 @@
 /// ConvertQualTypeToStringFn - This function is used to pretty print the 
 /// specified QualType as a string in diagnostics.
 static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val,
-                                      const char *Modifier, unsigned ModLen,
-                                      const char *Argument, unsigned ArgLen,
-                                      llvm::SmallVectorImpl<char> &Output) {
+                                 const char *Modifier, unsigned ModLen,
+                                 const char *Argument, unsigned ArgLen,
+                                 llvm::SmallVectorImpl<char> &Output) {
   
   std::string S;
   if (Kind == Diagnostic::ak_qualtype) {
+    assert(ModLen == 0 && ArgLen == 0 &&
+           "Invalid modifier for QualType argument");
+
     QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
 
     // FIXME: Playing with std::string is really slow.
     S = Ty.getAsString();
+    
+    // If this is a sugared type (like a typedef, typeof, etc), then unwrap one
+    // level of the sugar so that the type is more obvious to the user.
+    QualType DesugaredTy = Ty->getDesugaredType();
+    DesugaredTy.setCVRQualifiers(DesugaredTy.getCVRQualifiers() |
+                                 Ty.getCVRQualifiers());
 
-    assert(ModLen == 0 && ArgLen == 0 &&
-           "Invalid modifier for QualType argument");
+    if (Ty != DesugaredTy &&
+        // If the desugared type is a vector type, we don't want to expand it,
+        // it will turn into an attribute mess. People want their "vec4".
+        !isa<VectorType>(DesugaredTy) &&
+      
+        // Don't desugar objc types.  FIXME: THIS IS A HACK.
+        S != "id" && S != "Class") {
+      S = "'"+S+"' (aka '";
+      S += DesugaredTy.getAsString();
+      S += "')";
+      Output.append(S.begin(), S.end());
+      return;
+    }
     
   } else if (Kind == Diagnostic::ak_declarationname) {
    
@@ -58,7 +78,10 @@
       S = reinterpret_cast<NamedDecl*>(Val)->getNameAsString();
     }
   }
+  
+  Output.push_back('\'');
   Output.append(S.begin(), S.end());
+  Output.push_back('\'');
 }