aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-10-23 22:18:25 +0000
committerDouglas Gregor <dgregor@apple.com>2009-10-23 22:18:25 +0000
commit097bfb11759be2187732329ecf4c0849609cdf57 (patch)
tree9cafc65d553197a03de4fb7294d30d96d55b9445 /lib/Sema/SemaOverload.cpp
parent06a59bb8260ce3d52de761865dee90f90054a5cc (diff)
Migrate Sema::ActOnCallExpr to Sema::FixOverloadedFunctionReference,
so that we maintain better source information after template argument deduction and overloading resolves down to a specific declaration. Found and dealt with a few more cases that FixOverloadedFunctionReference didn't cope with. (Finally) added a test case that puts together this change with the DeclRefExpr change to (optionally) include nested-name-specifiers and explicit template argument lists. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 5e946eb762..7ed79f3073 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5361,8 +5361,14 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
Expr *NewExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
- NewExpr->setType(PE->getSubExpr()->getType());
- return NewExpr;
+ PE->setSubExpr(NewExpr);
+ PE->setType(NewExpr->getType());
+ } else if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ Expr *NewExpr = FixOverloadedFunctionReference(ICE->getSubExpr(), Fn);
+ assert(Context.hasSameType(ICE->getSubExpr()->getType(),
+ NewExpr->getType()) &&
+ "Implicit cast type cannot be determined from overload");
+ ICE->setSubExpr(NewExpr);
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
"Can only take the address of an overloaded function");
@@ -5394,8 +5400,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
return UnOp;
} else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
assert((isa<OverloadedFunctionDecl>(DR->getDecl()) ||
- isa<FunctionTemplateDecl>(DR->getDecl())) &&
- "Expected overloaded function or function template");
+ isa<FunctionTemplateDecl>(DR->getDecl()) ||
+ isa<FunctionDecl>(DR->getDecl())) &&
+ "Expected function or function template");
DR->setDecl(Fn);
E->setType(Fn->getType());
} else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) {
@@ -5416,6 +5423,12 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
// FIXME: Don't destroy TID here, since we need its template arguments
// to survive.
// TID->Destroy(Context);
+ } else if (isa<UnresolvedFunctionNameExpr>(E)) {
+ return DeclRefExpr::Create(Context,
+ /*Qualifier=*/0,
+ /*QualifierRange=*/SourceRange(),
+ Fn, E->getLocStart(),
+ Fn->getType(), false, false);
} else {
assert(false && "Invalid reference to overloaded function");
}