diff options
| author | Kaelyn Takata <rikka@google.com> | 2014-04-04 22:16:30 +0000 |
|---|---|---|
| committer | Kaelyn Takata <rikka@google.com> | 2014-04-04 22:16:30 +0000 |
| commit | fb271f0cabbeb2d44772dcd7f07d2df6b9cec772 (patch) | |
| tree | 0badcf3c62017d841b22d72c608044f817201017 /clang/lib | |
| parent | 99ed6dfa00fc1182efef430c53d1eadd519ef5c7 (diff) | |
| download | bcm5719-llvm-fb271f0cabbeb2d44772dcd7f07d2df6b9cec772.tar.gz bcm5719-llvm-fb271f0cabbeb2d44772dcd7f07d2df6b9cec772.zip | |
Try harder about not suggesting methods as corrections when they
obviously won't work. Specifically, don't suggest methods (static or
not) from unrelated classes when the expression is a method call
through a specific object.
llvm-svn: 205653
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 39 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 20 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 3 |
3 files changed, 29 insertions, 33 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7894682efcf..c6e3e23fdd6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3974,8 +3974,8 @@ namespace { class FunctionCallCCC : public FunctionCallFilterCCC { public: FunctionCallCCC(Sema &SemaRef, const IdentifierInfo *FuncName, - unsigned NumArgs, bool HasExplicitTemplateArgs) - : FunctionCallFilterCCC(SemaRef, NumArgs, HasExplicitTemplateArgs), + unsigned NumArgs, MemberExpr *ME) + : FunctionCallFilterCCC(SemaRef, NumArgs, false, ME), FunctionName(FuncName) {} bool ValidateCandidate(const TypoCorrection &candidate) override { @@ -3992,17 +3992,20 @@ private: }; } -static TypoCorrection TryTypoCorrectionForCall(Sema &S, - DeclarationNameInfo FuncName, +static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn, + FunctionDecl *FDecl, ArrayRef<Expr *> Args) { - FunctionCallCCC CCC(S, FuncName.getName().getAsIdentifierInfo(), - Args.size(), false); - if (TypoCorrection Corrected = - S.CorrectTypo(FuncName, Sema::LookupOrdinaryName, - S.getScopeForContext(S.CurContext), NULL, CCC)) { + MemberExpr *ME = dyn_cast<MemberExpr>(Fn); + DeclarationName FuncName = FDecl->getDeclName(); + SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getLocStart(); + FunctionCallCCC CCC(S, FuncName.getAsIdentifierInfo(), Args.size(), ME); + + if (TypoCorrection Corrected = S.CorrectTypo( + DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName, + S.getScopeForContext(S.CurContext), NULL, CCC)) { if (NamedDecl *ND = Corrected.getCorrectionDecl()) { if (Corrected.isOverloaded()) { - OverloadCandidateSet OCS(FuncName.getLoc()); + OverloadCandidateSet OCS(NameLoc); OverloadCandidateSet::iterator Best; for (TypoCorrection::decl_iterator CD = Corrected.begin(), CDEnd = Corrected.end(); @@ -4011,7 +4014,7 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, S.AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), Args, OCS); } - switch (OCS.BestViableFunction(S, FuncName.getLoc(), Best)) { + switch (OCS.BestViableFunction(S, NameLoc, Best)) { case OR_Success: ND = Best->Function; Corrected.setCorrectionDecl(ND); @@ -4062,13 +4065,8 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, // arguments for the remaining parameters), don't make the call. if (Args.size() < NumParams) { if (Args.size() < MinArgs) { - MemberExpr *ME = dyn_cast<MemberExpr>(Fn); TypoCorrection TC; - if (FDecl && (TC = TryTypoCorrectionForCall( - *this, DeclarationNameInfo(FDecl->getDeclName(), - (ME ? ME->getMemberLoc() - : Fn->getLocStart())), - Args))) { + if (FDecl && (TC = TryTypoCorrectionForCall(*this, Fn, FDecl, Args))) { unsigned diag_id = MinArgs == NumParams && !Proto->isVariadic() ? diag::err_typecheck_call_too_few_args_suggest @@ -4103,13 +4101,8 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, // them. if (Args.size() > NumParams) { if (!Proto->isVariadic()) { - MemberExpr *ME = dyn_cast<MemberExpr>(Fn); TypoCorrection TC; - if (FDecl && (TC = TryTypoCorrectionForCall( - *this, DeclarationNameInfo(FDecl->getDeclName(), - (ME ? ME->getMemberLoc() - : Fn->getLocStart())), - Args))) { + if (FDecl && (TC = TryTypoCorrectionForCall(*this, Fn, FDecl, Args))) { unsigned diag_id = MinArgs == NumParams && !Proto->isVariadic() ? diag::err_typecheck_call_too_many_args_suggest diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index ac6fb25caee..39a1ceaa57e 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -4511,10 +4511,9 @@ bool CorrectionCandidateCallback::ValidateCandidate(const TypoCorrection &candid FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs, bool HasExplicitTemplateArgs, - bool AllowNonStaticMethods) + MemberExpr *ME) : NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs), - AllowNonStaticMethods(AllowNonStaticMethods), - CurContext(SemaRef.CurContext) { + CurContext(SemaRef.CurContext), MemberFn(ME) { WantTypeSpecifiers = SemaRef.getLangOpts().CPlusPlus; WantRemainingKeywords = false; } @@ -4550,13 +4549,16 @@ bool FunctionCallFilterCCC::ValidateCandidate(const TypoCorrection &candidate) { FD->getMinRequiredArguments() <= NumArgs)) continue; - // If the current candidate is a non-static C++ method and non-static - // methods are being excluded, then skip the candidate unless the current - // DeclContext is a method in the same class or a descendent class of the - // candidate's parent class. + // If the current candidate is a non-static C++ method, skip the candidate + // unless the method being corrected--or the current DeclContext, if the + // function being corrected is not a method--is a method in the same class + // or a descendent class of the candidate's parent class. if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { - if (!AllowNonStaticMethods && !MD->isStatic()) { - CXXMethodDecl *CurMD = dyn_cast_or_null<CXXMethodDecl>(CurContext); + if (MemberFn || !MD->isStatic()) { + CXXMethodDecl *CurMD = + MemberFn + ? dyn_cast_or_null<CXXMethodDecl>(MemberFn->getMemberDecl()) + : dyn_cast_or_null<CXXMethodDecl>(CurContext); CXXRecordDecl *CurRD = CurMD ? CurMD->getParent()->getCanonicalDecl() : 0; CXXRecordDecl *RD = MD->getParent()->getCanonicalDecl(); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index ee1feb5c823..90710205dbb 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10383,7 +10383,8 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), Sema::LookupOrdinaryName); FunctionCallFilterCCC Validator(SemaRef, Args.size(), - ExplicitTemplateArgs != 0, false); + ExplicitTemplateArgs != 0, + dyn_cast<MemberExpr>(Fn)); NoTypoCorrectionCCC RejectAll; CorrectionCandidateCallback *CCC = AllowTypoCorrection ? (CorrectionCandidateCallback*)&Validator : |

