diff options
| author | John McCall <rjmccall@apple.com> | 2009-12-16 08:11:27 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2009-12-16 08:11:27 +0000 |
| commit | d681c3959f85b53342a694a6718192c8f52e3833 (patch) | |
| tree | a678d9daf1b1faba65ce7ac073fe23c30866a347 /clang/lib/Sema/SemaOverload.cpp | |
| parent | 2003b908079464ae89b08f7f391269d6f0071b3d (diff) | |
| download | bcm5719-llvm-d681c3959f85b53342a694a6718192c8f52e3833.tar.gz bcm5719-llvm-d681c3959f85b53342a694a6718192c8f52e3833.zip | |
Introduce a centralized routine in Sema for diagnosing failed lookups (when
used as expressions). In dependent contexts, try to recover by doing a lookup
in previously-dependent base classes. We get better diagnostics out, but
unfortunately the recovery fails: we need to turn it into a method call
expression, not a bare call expression. Thus this is still a WIP.
llvm-svn: 91525
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 23598bf605e..d01bca718d0 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2622,7 +2622,14 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, Args, NumArgs, Specialization, Info)) { // FIXME: Record what happened with template argument deduction, so // that we can give the user a beautiful diagnostic. - (void)Result; + (void) Result; + + CandidateSet.push_back(OverloadCandidate()); + OverloadCandidate &Candidate = CandidateSet.back(); + Candidate.Function = FunctionTemplate->getTemplatedDecl(); + Candidate.Viable = false; + Candidate.IsSurrogate = false; + Candidate.IgnoreObjectArgument = false; return; } @@ -4637,6 +4644,34 @@ void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns, CandidateSet, PartialOverloading); } + +/// Attempts to recover from a call where no functions were found. +/// +/// Returns true if new candidates were found. +static bool AddRecoveryCallCandidates(Sema &SemaRef, Expr *Fn, + const TemplateArgumentListInfo *ExplicitTemplateArgs, + Expr **Args, unsigned NumArgs, + OverloadCandidateSet &CandidateSet) { + UnresolvedLookupExpr *ULE + = cast<UnresolvedLookupExpr>(Fn->IgnoreParenCasts()); + + CXXScopeSpec SS; + if (ULE->getQualifier()) { + SS.setScopeRep(ULE->getQualifier()); + SS.setRange(ULE->getQualifierRange()); + } + + LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), + Sema::LookupOrdinaryName); + if (SemaRef.DiagnoseEmptyLookup(SS, R)) + return false; + + for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { + AddOverloadedCallCandidate(SemaRef, *I, ExplicitTemplateArgs, + Args, NumArgs, CandidateSet, false); + } + return true; +} /// ResolveOverloadedCallFn - Given the call expression that calls Fn /// (which eventually refers to the declaration Func) and the call @@ -4661,6 +4696,19 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, AddOverloadedCallCandidates(Fns, UnqualifiedName, ArgumentDependentLookup, ExplicitTemplateArgs, Args, NumArgs, CandidateSet); + + // If we found nothing, try to recover. + // AddRecoveryCallCandidates diagnoses the error itself, so we just + // bailout out if it fails. + if (CandidateSet.empty() && + !AddRecoveryCallCandidates(*this, Fn, ExplicitTemplateArgs, + Args, NumArgs, CandidateSet)) { + Fn->Destroy(Context); + for (unsigned Arg = 0; Arg < NumArgs; ++Arg) + Args[Arg]->Destroy(Context); + return 0; + } + OverloadCandidateSet::iterator Best; switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) { case OR_Success: |

