Allow typo correction to be disabled in BuildOverloadedCallExpr variant.

This suppresses typo correction for auto-generated call expressions such
as to 'begin' or 'end' within a C++0x for-range statement.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148979 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 77ae346..12096f5 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1583,7 +1583,8 @@
                                      SourceLocation LParenLoc,
                                      Expr **Args, unsigned NumArgs,
                                      SourceLocation RParenLoc,
-                                     Expr *ExecConfig);
+                                     Expr *ExecConfig,
+                                     bool AllowTypoCorrection=true);
 
   ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
                                      unsigned Opc,
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 3333b4e..36b6946 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -9215,6 +9215,21 @@
   unsigned NumArgs;
   bool HasExplicitTemplateArgs;
 };
+
+// Callback that effectively disabled typo correction
+class NoTypoCorrectionCCC : public CorrectionCandidateCallback {
+ public:
+  NoTypoCorrectionCCC() {
+    WantTypeSpecifiers = false;
+    WantExpressionKeywords = false;
+    WantCXXNamedCasts = false;
+    WantRemainingKeywords = false;
+  }
+
+  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+    return false;
+  }
+};
 }
 
 /// Attempts to recover from a call where no functions were found.
@@ -9226,7 +9241,7 @@
                       SourceLocation LParenLoc,
                       Expr **Args, unsigned NumArgs,
                       SourceLocation RParenLoc,
-                      bool EmptyLookup) {
+                      bool EmptyLookup, bool AllowTypoCorrection) {
 
   CXXScopeSpec SS;
   SS.Adopt(ULE->getQualifierLoc());
@@ -9241,10 +9256,14 @@
   LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
                  Sema::LookupOrdinaryName);
   RecoveryCallCCC Validator(SemaRef, NumArgs, ExplicitTemplateArgs != 0);
+  NoTypoCorrectionCCC RejectAll;
+  CorrectionCandidateCallback *CCC = AllowTypoCorrection ?
+      (CorrectionCandidateCallback*)&Validator :
+      (CorrectionCandidateCallback*)&RejectAll;
   if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R,
                               ExplicitTemplateArgs, Args, NumArgs) &&
       (!EmptyLookup ||
-       SemaRef.DiagnoseEmptyLookup(S, SS, R, Validator,
+       SemaRef.DiagnoseEmptyLookup(S, SS, R, *CCC,
                                    ExplicitTemplateArgs, Args, NumArgs)))
     return ExprError();
 
@@ -9283,7 +9302,8 @@
                               SourceLocation LParenLoc,
                               Expr **Args, unsigned NumArgs,
                               SourceLocation RParenLoc,
-                              Expr *ExecConfig) {
+                              Expr *ExecConfig,
+                              bool AllowTypoCorrection) {
 #ifndef NDEBUG
   if (ULE->requiresADL()) {
     // To do ADL, we must have found an unqualified name.
@@ -9331,7 +9351,8 @@
       return Owned(CE);
     }
     return BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc, Args, NumArgs,
-                                 RParenLoc, /*EmptyLookup=*/true);
+                                 RParenLoc, /*EmptyLookup=*/true,
+                                 AllowTypoCorrection);
   }
 
   UnbridgedCasts.restore();
@@ -9353,7 +9374,8 @@
     // have meant to call.
     ExprResult Recovery = BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc,
                                                 Args, NumArgs, RParenLoc,
-                                                /*EmptyLookup=*/false);
+                                                /*EmptyLookup=*/false,
+                                                AllowTypoCorrection);
     if (!Recovery.isInvalid())
       return Recovery;
 
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 86bb740..0eb8d28 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1286,7 +1286,7 @@
                                    FoundNames.begin(), FoundNames.end(),
                                    /*LookInStdNamespace=*/true);
     CallExpr = SemaRef.BuildOverloadedCallExpr(S, Fn, Fn, Loc, &Range, 1, Loc,
-                                               0);
+                                               0, /*AllowTypoCorrection=*/false);
     if (CallExpr.isInvalid()) {
       SemaRef.Diag(Range->getLocStart(), diag::note_for_range_type)
         << Range->getType();
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 6a3a297..556e654 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -149,3 +149,11 @@
   Provoke("foo", true); // expected-error{{use of undeclared identifier 'Provoke'; did you mean 'provoke'?}}
   Provoke("foo", 7, 22); // expected-error{{use of undeclared identifier 'Provoke'}}
 }
+
+// PR 11737 - Don't try to typo-correct the implicit 'begin' and 'end' in a
+// C++11 for-range statement.
+struct R {};
+bool begun(R);
+void RangeTest() {
+  for (auto b : R()) {} // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type}}
+}