diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-04 15:01:18 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-04 15:01:18 +0000 |
commit | 17330019f05966762bc952840ef1926b9becb145 (patch) | |
tree | fbaf21c970aacbde8a56ad400a2532c66d2fadd0 /lib/Sema/SemaOverload.cpp | |
parent | 20bcd55e1465ae0ee149cf4f92aeeb771791ce71 (diff) |
Fix our semantic analysis of
unqualified-id '('
in C++. The unqualified-id might not refer to any declaration in our
current scope, but declarations by that name might be found via
argument-dependent lookup. We now do so properly.
As part of this change, CXXDependentNameExpr, which was previously
designed to express the unqualified-id in the above constructor within
templates, has become UnresolvedFunctionNameExpr, which does
effectively the same thing but will work for both templates and
non-templates.
Additionally, we cope with all unqualified-ids, since ADL also applies
in cases like
operator+(x, y)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63733 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 293e9c3c24..01b9829c66 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3503,20 +3503,56 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, /// resolution. Otherwise, emits diagnostics, deletes all of the /// arguments and Fn, and returns NULL. FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, + DeclarationName UnqualifiedName, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation *CommaLocs, SourceLocation RParenLoc, - bool ArgumentDependentLookup) { + bool &ArgumentDependentLookup) { OverloadCandidateSet CandidateSet; + + // Add the functions denoted by Callee to the set of candidate + // functions. While we're doing so, track whether argument-dependent + // lookup still applies, per: + // + // C++0x [basic.lookup.argdep]p3: + // Let X be the lookup set produced by unqualified lookup (3.4.1) + // and let Y be the lookup set produced by argument dependent + // lookup (defined as follows). If X contains + // + // -- a declaration of a class member, or + // + // -- a block-scope function declaration that is not a + // using-declaration, or + // + // -- a declaration that is neither a function or a function + // template + // + // then Y is empty. if (OverloadedFunctionDecl *Ovl - = dyn_cast_or_null<OverloadedFunctionDecl>(Callee)) - AddOverloadCandidates(Ovl, Args, NumArgs, CandidateSet); - else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) - AddOverloadCandidate(cast<FunctionDecl>(Func), Args, NumArgs, CandidateSet); - + = dyn_cast_or_null<OverloadedFunctionDecl>(Callee)) { + for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(), + FuncEnd = Ovl->function_end(); + Func != FuncEnd; ++Func) { + AddOverloadCandidate(*Func, Args, NumArgs, CandidateSet); + + if ((*Func)->getDeclContext()->isRecord() || + (*Func)->getDeclContext()->isFunctionOrMethod()) + ArgumentDependentLookup = false; + } + } else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) { + AddOverloadCandidate(Func, Args, NumArgs, CandidateSet); + + if (Func->getDeclContext()->isRecord() || + Func->getDeclContext()->isFunctionOrMethod()) + ArgumentDependentLookup = false; + } + + if (Callee) + UnqualifiedName = Callee->getDeclName(); + if (ArgumentDependentLookup) - AddArgumentDependentLookupCandidates(Callee->getDeclName(), Args, NumArgs, + AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs, CandidateSet); OverloadCandidateSet::iterator Best; @@ -3527,14 +3563,14 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, case OR_No_Viable_Function: Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_no_viable_function_in_call) - << Callee->getDeclName() << (unsigned)CandidateSet.size() + << UnqualifiedName << (unsigned)CandidateSet.size() << Fn->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); break; case OR_Ambiguous: Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call) - << Callee->getDeclName() << Fn->getSourceRange(); + << UnqualifiedName << Fn->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); break; } |