diff options
author | Kaelyn Uhrain <rikka@google.com> | 2011-08-03 20:36:05 +0000 |
---|---|---|
committer | Kaelyn Uhrain <rikka@google.com> | 2011-08-03 20:36:05 +0000 |
commit | acbdc5748e70fef350d7974106c7886451b53801 (patch) | |
tree | 7e36e71a496eaf62ff398282fd820a3df99d90d9 /clang/lib/Sema | |
parent | d855d82a160c66215551b41a2533f406b7ba27ac (diff) | |
download | bcm5719-llvm-acbdc5748e70fef350d7974106c7886451b53801.tar.gz bcm5719-llvm-acbdc5748e70fef350d7974106c7886451b53801.zip |
Improve overloaded function handling in the typo correction code.
Change TypoCorrection to store a set of NamedDecls instead of a single
NamedDecl. Also add initial support for performing function overload
resolution to Sema::DiagnoseEmptyLookup.
llvm-svn: 136807
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 48 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 3 |
3 files changed, 64 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 55e04b79de0..6ace3e92e60 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1364,7 +1364,8 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id, /// /// \return false if new lookup candidates were found bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - CorrectTypoContext CTC) { + CorrectTypoContext CTC, Expr **Args, + unsigned NumArgs) { DeclarationName Name = R.getLookupName(); unsigned diagnostic = diag::err_undeclared_var_use; @@ -1450,6 +1451,27 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, R.setLookupName(Corrected.getCorrection()); if (NamedDecl *ND = Corrected.getCorrectionDecl()) { + if (Corrected.isOverloaded()) { + OverloadCandidateSet OCS(R.getNameLoc()); + OverloadCandidateSet::iterator Best; + for (TypoCorrection::decl_iterator CD = Corrected.begin(), + CDEnd = Corrected.end(); + CD != CDEnd; ++CD) { + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*CD)) + AddOverloadCandidate(FD, DeclAccessPair::make(*CD, AS_none), + Args, NumArgs, OCS); + // TODO: Handle FunctionTemplateDecl and other Decl types that + // support overloading and could be corrected by CorrectTypo. + } + switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) { + case OR_Success: + ND = Best->Function; + break; + default: + // Don't try to recover; it won't work. + return true; + } + } R.addDecl(ND); if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { if (SS.isEmpty()) diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index c5ba95a1f4e..240eb5f1bf7 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3020,7 +3020,7 @@ public: void FoundName(StringRef Name); void addKeywordResult(StringRef Keyword); void addName(StringRef Name, NamedDecl *ND, unsigned Distance, - NestedNameSpecifier *NNS=NULL); + NestedNameSpecifier *NNS=NULL, bool isKeyword=false); void addCorrection(TypoCorrection Correction); typedef TypoResultsMap::iterator result_iterator; @@ -3099,15 +3099,17 @@ void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) { return; } - addName(Keyword, TypoCorrection::KeywordDecl(), ED); + addName(Keyword, NULL, ED, NULL, true); } void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND, unsigned Distance, - NestedNameSpecifier *NNS) { - addCorrection(TypoCorrection(&SemaRef.Context.Idents.get(Name), - ND, NNS, Distance)); + NestedNameSpecifier *NNS, + bool isKeyword) { + TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, Distance); + if (isKeyword) TC.makeKeyword(); + addCorrection(TC); } void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) { @@ -3677,12 +3679,19 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, // We don't deal with ambiguities. return TypoCorrection(); + case LookupResult::FoundOverloaded: { + // Store all of the Decls for overloaded symbols + for (LookupResult::iterator TRD = TmpRes.begin(), + TRDEnd = TmpRes.end(); + TRD != TRDEnd; ++TRD) + I->second.addCorrectionDecl(*TRD); + ++I; + break; + } + case LookupResult::Found: - case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: I->second.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>()); - // FIXME: This sets the CorrectionDecl to NULL for overloaded functions. - // It would be nice to find the right one with overload resolution. ++I; break; } @@ -3718,11 +3727,20 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, switch (TmpRes.getResultKind()) { case LookupResult::Found: - case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: Consumer.addName((*QRI)->getName(), TmpRes.getAsSingle<NamedDecl>(), QualifiedED, NI->NameSpecifier); break; + case LookupResult::FoundOverloaded: { + TypoCorrection corr(&Context.Idents.get((*QRI)->getName()), NULL, + NI->NameSpecifier, QualifiedED); + for (LookupResult::iterator TRD = TmpRes.begin(), + TRDEnd = TmpRes.end(); + TRD != TRDEnd; ++TRD) + corr.addCorrectionDecl(*TRD); + Consumer.addCorrection(corr); + break; + } case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: case LookupResult::Ambiguous: @@ -3802,6 +3820,18 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, return TypoCorrection(); } +void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) { + if (!CDecl) return; + + if (isKeyword()) + CorrectionDecls.clear(); + + CorrectionDecls.push_back(CDecl); + + if (!CorrectionName) + CorrectionName = CDecl->getDeclName(); +} + std::string TypoCorrection::getAsString(const LangOptions &LO) const { if (CorrectionNameSpec) { std::string tmpBuffer; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 79aa305b86f..712720bf9e8 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -8220,7 +8220,8 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R, ExplicitTemplateArgs, Args, NumArgs) && (!EmptyLookup || - SemaRef.DiagnoseEmptyLookup(S, SS, R, Sema::CTC_Expression))) + SemaRef.DiagnoseEmptyLookup(S, SS, R, Sema::CTC_Expression, + Args, NumArgs))) return ExprError(); assert(!R.empty() && "lookup results empty despite recovery"); |