From: Anders Carlsson Date: Wed, 21 Oct 2009 17:16:23 +0000 (+0000) Subject: Change FixOverloadedFunctionReference to return a (possibly new) expression. Substitu... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=96ad5337a4949523ce9df617dad8ca10d3ab9788;p=clang Change FixOverloadedFunctionReference to return a (possibly new) expression. Substitute TemplateIdRefExprs with DeclRefExprs. Doug, plz review :) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84763 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 0b55ecd770..3f31405426 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -929,7 +929,7 @@ public: FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, bool Complain); - bool FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn); + Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn); void AddOverloadedCallCandidates(NamedDecl *Callee, DeclarationName &UnqualifiedName, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d2ef113b30..ba2a93d65c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3569,7 +3569,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, if (DiagnoseUseOfDecl(Fn, DeclLoc)) return true; - FixOverloadedFunctionReference(Init, Fn); + Init = FixOverloadedFunctionReference(Init, Fn); } T2 = Fn->getType(); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 181c1349bd..567111223a 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1226,12 +1226,13 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin())) return true; - bool WasAddrOf = FixOverloadedFunctionReference(From, Fn); + From = FixOverloadedFunctionReference(From, Fn); FromType = From->getType(); + // 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 // invalid additional pointer level. - if (WasAddrOf) + if (FromType->isPointerType() || FromType->isMemberFunctionPointerType()) break; } FromType = Context.getPointerType(FromType); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 5c3e131eb4..f5a7d18980 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5368,13 +5368,12 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) { /// a C++ overloaded function (possibly with some parentheses and /// perhaps a '&' around it). We have resolved the overloaded function /// to the function declaration Fn, so patch up the expression E to -/// refer (possibly indirectly) to Fn. -/// Returns true if the function reference used an explicit address-of operator. -bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { +/// refer (possibly indirectly) to Fn. Returns the new expr. +Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { if (ParenExpr *PE = dyn_cast(E)) { - bool ret = FixOverloadedFunctionReference(PE->getSubExpr(), Fn); - E->setType(PE->getSubExpr()->getType()); - return ret; + Expr *NewExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Fn); + NewExpr->setType(PE->getSubExpr()->getType()); + return NewExpr; } else if (UnaryOperator *UnOp = dyn_cast(E)) { assert(UnOp->getOpcode() == UnaryOperator::AddrOf && "Can only take the address of an overloaded function"); @@ -5393,12 +5392,14 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { = Context.getTypeDeclType(cast(Method->getDeclContext())); E->setType(Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr())); - return true; + return E; } } - FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); - E->setType(Context.getPointerType(UnOp->getSubExpr()->getType())); - return true; + Expr *NewExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); + UnOp->setSubExpr(NewExpr); + UnOp->setType(Context.getPointerType(NewExpr->getType())); + + return UnOp; } else if (DeclRefExpr *DR = dyn_cast(E)) { assert((isa(DR->getDecl()) || isa(DR->getDecl())) && @@ -5408,10 +5409,17 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { } else if (MemberExpr *MemExpr = dyn_cast(E)) { MemExpr->setMemberDecl(Fn); E->setType(Fn->getType()); + } else if (TemplateIdRefExpr *TID = dyn_cast(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 { assert(false && "Invalid reference to overloaded function"); } - return false; + + return E; } } // end namespace clang diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index da7545c02d..d9c53ebec6 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2037,7 +2037,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) return true; - FixOverloadedFunctionReference(Arg, Fn); + Arg = FixOverloadedFunctionReference(Arg, Fn); ArgType = Arg->getType(); if (ArgType->isFunctionType() && ParamType->isPointerType()) { ArgType = Context.getPointerType(Arg->getType()); diff --git a/test/CodeGenCXX/address-of-fntemplate.cpp b/test/CodeGenCXX/address-of-fntemplate.cpp index 9a1364325f..1f0c8f3863 100644 --- a/test/CodeGenCXX/address-of-fntemplate.cpp +++ b/test/CodeGenCXX/address-of-fntemplate.cpp @@ -1,8 +1,13 @@ // RUN: clang-cc %s -emit-llvm -o - | FileCheck %s template void f(T) {} +template void f() { } void test() { // CHECK: @_Z1fIiEvT_ void (*p)(int) = &f; + + // CHECK: @_Z1fIiEvv + void (*p2)() = f; } // CHECK: define linkonce_odr void @_Z1fIiEvT_ +// CHECK: define linkonce_odr void @_Z1fIiEvv