diff options
author | Kaelyn Uhrain <rikka@google.com> | 2014-02-28 18:12:42 +0000 |
---|---|---|
committer | Kaelyn Uhrain <rikka@google.com> | 2014-02-28 18:12:42 +0000 |
commit | b4b1475322bd5bae0ba97cc1dc41e528da76749e (patch) | |
tree | 34169d41f8deeb2e33aebc5dcf1de1cb7950a13d | |
parent | 6fe42c9ea5d63456818e6f3e22ab654546c61fdf (diff) | |
download | bcm5719-llvm-b4b1475322bd5bae0ba97cc1dc41e528da76749e.tar.gz bcm5719-llvm-b4b1475322bd5bae0ba97cc1dc41e528da76749e.zip |
Don't suggest non-static methods as corrections when they obviously
won't work (i.e. when not doing a member lookup and not in a method from
the same class or a descendant class).
llvm-svn: 202520
-rw-r--r-- | clang/include/clang/Sema/TypoCorrection.h | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/typo-correction-pt2.cpp | 9 |
4 files changed, 41 insertions, 7 deletions
diff --git a/clang/include/clang/Sema/TypoCorrection.h b/clang/include/clang/Sema/TypoCorrection.h index f0b77264984..c28720b2b12 100644 --- a/clang/include/clang/Sema/TypoCorrection.h +++ b/clang/include/clang/Sema/TypoCorrection.h @@ -305,13 +305,16 @@ public: class FunctionCallFilterCCC : public CorrectionCandidateCallback { public: FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs, - bool HasExplicitTemplateArgs); + bool HasExplicitTemplateArgs, + bool AllowNonStaticMethods = true); virtual bool ValidateCandidate(const TypoCorrection &candidate); private: unsigned NumArgs; bool HasExplicitTemplateArgs; + bool AllowNonStaticMethods; + DeclContext *CurContext; }; // @brief Callback class that effectively disabled typo correction diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 1a47340d69a..5df0a43621e 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -4546,8 +4546,11 @@ bool CorrectionCandidateCallback::ValidateCandidate(const TypoCorrection &candid } FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs, - bool HasExplicitTemplateArgs) - : NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs) { + bool HasExplicitTemplateArgs, + bool AllowNonStaticMethods) + : NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs), + AllowNonStaticMethods(AllowNonStaticMethods), + CurContext(SemaRef.CurContext) { WantTypeSpecifiers = SemaRef.getLangOpts().CPlusPlus; WantRemainingKeywords = false; } @@ -4576,9 +4579,28 @@ bool FunctionCallFilterCCC::ValidateCandidate(const TypoCorrection &candidate) { return true; } } - if (FD && FD->getNumParams() >= NumArgs && - FD->getMinRequiredArguments() <= NumArgs) - return true; + + // Skip the current candidate if it is not a FunctionDecl or does not accept + // the current number of arguments. + if (!FD || !(FD->getNumParams() >= NumArgs && + 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 (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { + if (!AllowNonStaticMethods && !MD->isStatic()) { + CXXMethodDecl *CurMD = dyn_cast_or_null<CXXMethodDecl>(CurContext); + CXXRecordDecl *CurRD = + CurMD ? CurMD->getParent()->getCanonicalDecl() : 0; + CXXRecordDecl *RD = MD->getParent()->getCanonicalDecl(); + if (!CurRD || (CurRD != RD && !CurRD->isDerivedFrom(RD))) + continue; + } + } + return true; } return false; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index fb77ba616f6..eaf3d35148d 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10385,7 +10385,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), Sema::LookupOrdinaryName); FunctionCallFilterCCC Validator(SemaRef, Args.size(), - ExplicitTemplateArgs != 0); + ExplicitTemplateArgs != 0, false); NoTypoCorrectionCCC RejectAll; CorrectionCandidateCallback *CCC = AllowTypoCorrection ? (CorrectionCandidateCallback*)&Validator : diff --git a/clang/test/SemaCXX/typo-correction-pt2.cpp b/clang/test/SemaCXX/typo-correction-pt2.cpp index e08bef0741e..e39a24bd097 100644 --- a/clang/test/SemaCXX/typo-correction-pt2.cpp +++ b/clang/test/SemaCXX/typo-correction-pt2.cpp @@ -234,3 +234,12 @@ class Baz { // expected-error {{expected member name or ';' after declaration specifiers}} }; } + +namespace PR18852 { +void func() { + struct foo { + void bar() {} + }; + bar(); // expected-error-re {{use of undeclared identifier 'bar'{{$}}}} +} +} |