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.

llvm-svn: 148979
This commit is contained in:
Kaelyn Uhrain 2012-01-25 21:11:35 +00:00
parent cf705b21e2
commit 9afaf793b3
4 changed files with 38 additions and 7 deletions

View File

@ -1583,7 +1583,8 @@ public:
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc,
Expr *ExecConfig);
Expr *ExecConfig,
bool AllowTypoCorrection=true);
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
unsigned Opc,

View File

@ -9215,6 +9215,21 @@ class RecoveryCallCCC : public CorrectionCandidateCallback {
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 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc,
bool EmptyLookup) {
bool EmptyLookup, bool AllowTypoCorrection) {
CXXScopeSpec SS;
SS.Adopt(ULE->getQualifierLoc());
@ -9241,10 +9256,14 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
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 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
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 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
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 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
// 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;

View File

@ -1286,7 +1286,7 @@ static ExprResult BuildForRangeBeginEndCall(Sema &SemaRef, Scope *S,
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();

View File

@ -149,3 +149,11 @@ void Test3() {
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}}
}