Improve 0-argument -Wvexing-parse diagnostic by adding notes with fix-its:

 - If the declarator is at the start of a line, and the previous line contained
   another declarator and ended with a comma, then that comma was probably a
   typo for a semicolon:

   int n = 0, m = 1, l = 2, // k = 5;
   myImportantFunctionCall(); // oops!

 - If removing the parentheses would correctly initialize the object, then
   produce a note suggesting that fix.

 - Otherwise, if there is a simple initializer we can suggest which performs
   value-initialization, then provide a note suggesting a correction to that
   initializer.

Sema::Declarator now tracks the location of the comma prior to the declarator in
the declaration, if there is one, to facilitate providing the note. The code to
determine an appropriate initializer from the -Wuninitialized warning has been
factored out to allow use in both that and -Wvexing-parse.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148072 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 3567b6b..9b3191b 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -415,42 +415,15 @@
     return false;
 
   // Suggest possible initialization (if any).
-  const char *initialization = 0;
   QualType VariableTy = VD->getType().getCanonicalType();
-
-  if (VariableTy->isObjCObjectPointerType() ||
-      VariableTy->isBlockPointerType()) {
-    // Check if 'nil' is defined.
-    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil")))
-      initialization = " = nil";
-    else
-      initialization = " = 0";
-  }
-  else if (VariableTy->isRealFloatingType())
-    initialization = " = 0.0";
-  else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus)
-    initialization = " = false";
-  else if (VariableTy->isEnumeralType())
+  const char *Init = S.getFixItZeroInitializerForType(VariableTy);
+  if (!Init)
     return false;
-  else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) {
-    if (S.Context.getLangOptions().CPlusPlus0x)
-      initialization = " = nullptr";
-    // Check if 'NULL' is defined.
-    else if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL")))
-      initialization = " = NULL";
-    else
-      initialization = " = 0";
-  }
-  else if (VariableTy->isScalarType())
-    initialization = " = 0";
 
-  if (initialization) {
-    SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
-    S.Diag(loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
-      << FixItHint::CreateInsertion(loc, initialization);
-    return true;
-  }
-  return false;
+  SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
+  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
+    << FixItHint::CreateInsertion(Loc, Init);
+  return true;
 }
 
 /// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an