Change FixOverloadedFunctionReference to return a (possibly new) expression. Substitute TemplateIdRefExprs with DeclRefExprs. Doug, plz review :)

llvm-svn: 84763
This commit is contained in:
Anders Carlsson 2009-10-21 17:16:23 +00:00
parent 26b9178a50
commit fcb4ab4420
6 changed files with 30 additions and 16 deletions

View File

@ -929,7 +929,7 @@ public:
FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
bool Complain); bool Complain);
bool FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn); Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
void AddOverloadedCallCandidates(NamedDecl *Callee, void AddOverloadedCallCandidates(NamedDecl *Callee,
DeclarationName &UnqualifiedName, DeclarationName &UnqualifiedName,

View File

@ -3569,7 +3569,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
if (DiagnoseUseOfDecl(Fn, DeclLoc)) if (DiagnoseUseOfDecl(Fn, DeclLoc))
return true; return true;
FixOverloadedFunctionReference(Init, Fn); Init = FixOverloadedFunctionReference(Init, Fn);
} }
T2 = Fn->getType(); T2 = Fn->getType();

View File

@ -1226,12 +1226,13 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin())) if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin()))
return true; return true;
bool WasAddrOf = FixOverloadedFunctionReference(From, Fn); From = FixOverloadedFunctionReference(From, Fn);
FromType = From->getType(); FromType = From->getType();
// If there's already an address-of operator in the expression, we have // If there's already an address-of operator in the expression, we have
// the right type already, and the code below would just introduce an // the right type already, and the code below would just introduce an
// invalid additional pointer level. // invalid additional pointer level.
if (WasAddrOf) if (FromType->isPointerType() || FromType->isMemberFunctionPointerType())
break; break;
} }
FromType = Context.getPointerType(FromType); FromType = Context.getPointerType(FromType);

View File

@ -5368,13 +5368,12 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
/// a C++ overloaded function (possibly with some parentheses and /// a C++ overloaded function (possibly with some parentheses and
/// perhaps a '&' around it). We have resolved the overloaded function /// perhaps a '&' around it). We have resolved the overloaded function
/// to the function declaration Fn, so patch up the expression E to /// to the function declaration Fn, so patch up the expression E to
/// refer (possibly indirectly) to Fn. /// refer (possibly indirectly) to Fn. Returns the new expr.
/// Returns true if the function reference used an explicit address-of operator. Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) { if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
bool ret = FixOverloadedFunctionReference(PE->getSubExpr(), Fn); Expr *NewExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
E->setType(PE->getSubExpr()->getType()); NewExpr->setType(PE->getSubExpr()->getType());
return ret; return NewExpr;
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) { } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
assert(UnOp->getOpcode() == UnaryOperator::AddrOf && assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
"Can only take the address of an overloaded function"); "Can only take the address of an overloaded function");
@ -5393,12 +5392,14 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
= Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext())); = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
E->setType(Context.getMemberPointerType(Fn->getType(), E->setType(Context.getMemberPointerType(Fn->getType(),
ClassType.getTypePtr())); ClassType.getTypePtr()));
return true; return E;
} }
} }
FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); Expr *NewExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn);
E->setType(Context.getPointerType(UnOp->getSubExpr()->getType())); UnOp->setSubExpr(NewExpr);
return true; UnOp->setType(Context.getPointerType(NewExpr->getType()));
return UnOp;
} else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) { } else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
assert((isa<OverloadedFunctionDecl>(DR->getDecl()) || assert((isa<OverloadedFunctionDecl>(DR->getDecl()) ||
isa<FunctionTemplateDecl>(DR->getDecl())) && isa<FunctionTemplateDecl>(DR->getDecl())) &&
@ -5408,10 +5409,17 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
} else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) { } else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) {
MemExpr->setMemberDecl(Fn); MemExpr->setMemberDecl(Fn);
E->setType(Fn->getType()); E->setType(Fn->getType());
} else if (TemplateIdRefExpr *TID = dyn_cast<TemplateIdRefExpr>(E)) {
// FIXME: Should we create QualifiedDeclRefExprs here too?
// FIXME: We should capture the template arguments here.
E = new (Context) DeclRefExpr(Fn, Fn->getType(),
TID->getSourceRange().getBegin());
TID->Destroy(Context);
} else { } else {
assert(false && "Invalid reference to overloaded function"); assert(false && "Invalid reference to overloaded function");
} }
return false;
return E;
} }
} // end namespace clang } // end namespace clang

View File

@ -2037,7 +2037,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
return true; return true;
FixOverloadedFunctionReference(Arg, Fn); Arg = FixOverloadedFunctionReference(Arg, Fn);
ArgType = Arg->getType(); ArgType = Arg->getType();
if (ArgType->isFunctionType() && ParamType->isPointerType()) { if (ArgType->isFunctionType() && ParamType->isPointerType()) {
ArgType = Context.getPointerType(Arg->getType()); ArgType = Context.getPointerType(Arg->getType());

View File

@ -1,8 +1,13 @@
// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s // RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
template <typename T> void f(T) {} template <typename T> void f(T) {}
template <typename T> void f() { }
void test() { void test() {
// CHECK: @_Z1fIiEvT_ // CHECK: @_Z1fIiEvT_
void (*p)(int) = &f; void (*p)(int) = &f;
// CHECK: @_Z1fIiEvv
void (*p2)() = f<int>;
} }
// CHECK: define linkonce_odr void @_Z1fIiEvT_ // CHECK: define linkonce_odr void @_Z1fIiEvT_
// CHECK: define linkonce_odr void @_Z1fIiEvv