forked from OSchip/llvm-project
Change FixOverloadedFunctionReference to return a (possibly new) expression. Substitute TemplateIdRefExprs with DeclRefExprs. Doug, plz review :)
llvm-svn: 84763
This commit is contained in:
parent
26b9178a50
commit
fcb4ab4420
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue