Suggest typo corrections for implicit function declarations.

A mistyped function call becomes an inmplicit function declaration in C.
Suggest typo correction when one can be found.

llvm-svn: 145930
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c90b749..cc8ec87 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7262,14 +7262,38 @@
     return Pos->second;
   }
 
+  // See if we can find a typo correction.
+  TypoCorrection Corrected;
+  FunctionDecl *Func = 0;
+  std::string CorrectedStr;
+  std::string CorrectedQuotedStr;
+  if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc),
+                                    LookupOrdinaryName, S, 0))) {
+    // Since this is an implicit function declaration, we are only
+    // interested in a potential typo for a function name.
+    if ((Func = dyn_cast_or_null<FunctionDecl>(
+            Corrected.getCorrectionDecl()))) {
+      CorrectedStr = Corrected.getAsString(getLangOptions());
+      CorrectedQuotedStr = Corrected.getQuoted(getLangOptions());
+    }
+  }
+
   // Extension in C99.  Legal in C90, but warn about it.
   if (II.getName().startswith("__builtin_"))
-    Diag(Loc, diag::warn_builtin_unknown) << &II;
+    Diag(Loc, diag::err_builtin_unknown) << &II;
   else if (getLangOptions().C99)
     Diag(Loc, diag::ext_implicit_function_decl) << &II;
   else
     Diag(Loc, diag::warn_implicit_function_decl) << &II;
 
+  if (Func) {
+    // If we found a typo correction, then suggest that.
+    Diag(Loc, diag::note_function_suggestion) << CorrectedQuotedStr
+        << FixItHint::CreateReplacement(Loc, CorrectedStr);
+    if (Func->getLocation().isValid() && !II.getName().startswith("__builtin_"))
+      Diag(Func->getLocation(), diag::note_previous_decl) << CorrectedQuotedStr;
+  }
+
   // Set a Declarator for the implicit definition: int foo();
   const char *Dummy;
   AttributeFactory attrFactory;