forked from OSchip/llvm-project
Remainder of the __builtin_overload feedback
llvm-svn: 46601
This commit is contained in:
parent
a779d69029
commit
4cd6689d1f
|
@ -76,6 +76,7 @@ public:
|
|||
void VisitStmtExpr(const StmtExpr *E);
|
||||
void VisitBinaryOperator(const BinaryOperator *BO);
|
||||
void VisitBinAssign(const BinaryOperator *E);
|
||||
void VisitOverloadExpr(const OverloadExpr *E);
|
||||
|
||||
|
||||
void VisitConditionalOperator(const ConditionalOperator *CO);
|
||||
|
@ -160,6 +161,20 @@ void AggExprEmitter::VisitCallExpr(const CallExpr *E)
|
|||
EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E)
|
||||
{
|
||||
RValue RV = CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
|
||||
E->getNumArgs(CGF.getContext()));
|
||||
assert(RV.isAggregate() && "Return value must be aggregate value!");
|
||||
|
||||
// If the result is ignored, don't copy from the value.
|
||||
if (DestPtr == 0)
|
||||
// FIXME: If the source is volatile, we must read from it.
|
||||
return;
|
||||
|
||||
EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
|
||||
CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
|
||||
}
|
||||
|
|
|
@ -938,12 +938,6 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
|||
SkipUntil(tok::r_paren);
|
||||
return ExprResult(true);
|
||||
}
|
||||
|
||||
// __builtin_overload requires at least 2 arguments
|
||||
if (ArgExprs.size() < 2) {
|
||||
Diag(Tok, diag::err_typecheck_call_too_few_args);
|
||||
return ExprResult(true);
|
||||
}
|
||||
Res = Actions.ActOnOverloadExpr(&ArgExprs[0], ArgExprs.size(),
|
||||
&CommaLocs[0], StartLoc, ConsumeParen());
|
||||
break;
|
||||
|
|
|
@ -2103,11 +2103,14 @@ Sema::ExprResult Sema::ActOnOverloadExpr(ExprTy **args, unsigned NumArgs,
|
|||
SourceLocation *CommaLocs,
|
||||
SourceLocation BuiltinLoc,
|
||||
SourceLocation RParenLoc) {
|
||||
assert((NumArgs > 1) && "Too few arguments for OverloadExpr!");
|
||||
// __builtin_overload requires at least 2 arguments
|
||||
if (NumArgs < 2)
|
||||
return Diag(RParenLoc, diag::err_typecheck_call_too_few_args,
|
||||
SourceRange(BuiltinLoc, RParenLoc));
|
||||
|
||||
Expr **Args = reinterpret_cast<Expr**>(args);
|
||||
// The first argument is required to be a constant expression. It tells us
|
||||
// the number of arguments to pass to each of the functions to be overloaded.
|
||||
Expr **Args = reinterpret_cast<Expr**>(args);
|
||||
Expr *NParamsExpr = Args[0];
|
||||
llvm::APSInt constEval(32);
|
||||
SourceLocation ExpLoc;
|
||||
|
@ -2127,6 +2130,7 @@ Sema::ExprResult Sema::ActOnOverloadExpr(ExprTy **args, unsigned NumArgs,
|
|||
|
||||
// Figure out the return type, by matching the args to one of the functions
|
||||
// listed after the parameters.
|
||||
OverloadExpr *OE = 0;
|
||||
for (unsigned i = NumParams + 1; i < NumArgs; ++i) {
|
||||
// UsualUnaryConversions will convert the function DeclRefExpr into a
|
||||
// pointer to function.
|
||||
|
@ -2147,10 +2151,20 @@ Sema::ExprResult Sema::ActOnOverloadExpr(ExprTy **args, unsigned NumArgs,
|
|||
// Scan the parameter list for the FunctionType, checking the QualType of
|
||||
// each parameter against the QualTypes of the arguments to the builtin.
|
||||
// If they match, return a new OverloadExpr.
|
||||
if (ExprsMatchFnType(Args+1, FnType))
|
||||
return new OverloadExpr(Args, NumArgs, i, FnType->getResultType(),
|
||||
BuiltinLoc, RParenLoc);
|
||||
if (ExprsMatchFnType(Args+1, FnType)) {
|
||||
if (OE)
|
||||
return Diag(Fn->getExprLoc(), diag::err_overload_multiple_match,
|
||||
OE->getFn()->getSourceRange());
|
||||
// Remember our match, and continue processing the remaining arguments
|
||||
// to catch any errors.
|
||||
OE = new OverloadExpr(Args, NumArgs, i, FnType->getResultType(),
|
||||
BuiltinLoc, RParenLoc);
|
||||
}
|
||||
}
|
||||
// Return the newly created OverloadExpr node, if we succeded in matching
|
||||
// exactly one of the candidate functions.
|
||||
if (OE)
|
||||
return OE;
|
||||
|
||||
// If we didn't find a matching function Expr in the __builtin_overload list
|
||||
// the return an error.
|
||||
|
|
|
@ -1158,20 +1158,18 @@ class OverloadExpr : public Expr {
|
|||
// NumExprs - the size of the SubExprs array
|
||||
unsigned NumExprs;
|
||||
|
||||
// NumArgs - the number of arguments
|
||||
|
||||
// The index of the matching candidate function
|
||||
unsigned FnIndex;
|
||||
|
||||
SourceLocation BuiltinLoc;
|
||||
SourceLocation RParenLoc;
|
||||
public:
|
||||
OverloadExpr(Expr **args, unsigned narg, unsigned idx, QualType t,
|
||||
OverloadExpr(Expr **args, unsigned nexprs, unsigned idx, QualType t,
|
||||
SourceLocation bloc, SourceLocation rploc)
|
||||
: Expr(OverloadExprClass, t), NumExprs(narg), FnIndex(idx),
|
||||
: Expr(OverloadExprClass, t), NumExprs(nexprs), FnIndex(idx),
|
||||
BuiltinLoc(bloc), RParenLoc(rploc) {
|
||||
SubExprs = new Expr*[narg];
|
||||
for (unsigned i = 0; i != narg; ++i)
|
||||
SubExprs = new Expr*[nexprs];
|
||||
for (unsigned i = 0; i != nexprs; ++i)
|
||||
SubExprs[i] = args[i];
|
||||
}
|
||||
~OverloadExpr() {
|
||||
|
@ -1192,16 +1190,18 @@ public:
|
|||
return constEval.getZExtValue();
|
||||
}
|
||||
|
||||
/// getNumSubExprs - Return the size of the SubExprs array
|
||||
/// getNumSubExprs - Return the size of the SubExprs array. This includes the
|
||||
/// constant expression, the actual arguments passed in, and the function
|
||||
/// pointers.
|
||||
unsigned getNumSubExprs() const { return NumExprs; }
|
||||
|
||||
/// getArg - Return the specified argument.
|
||||
Expr *getExpr(unsigned Expr) {
|
||||
assert((Expr < NumExprs) && "Arg access out of range!");
|
||||
return SubExprs[Expr];
|
||||
/// getExpr - Return the Expr at the specified index.
|
||||
Expr *getExpr(unsigned Index) {
|
||||
assert((Index < NumExprs) && "Arg access out of range!");
|
||||
return SubExprs[Index];
|
||||
}
|
||||
|
||||
/// getFn - Return the matching candidate function for this OverloadExpr
|
||||
/// getFn - Return the matching candidate function for this OverloadExpr.
|
||||
Expr *getFn() const { return SubExprs[FnIndex]; }
|
||||
|
||||
virtual SourceRange getSourceRange() const {
|
||||
|
|
|
@ -848,6 +848,8 @@ DIAG(err_overload_incorrect_fntype, ERROR,
|
|||
"argument is not a function, or has wrong number of parameters")
|
||||
DIAG(err_overload_no_match, ERROR,
|
||||
"no matching overload found for arguments of type '%0'")
|
||||
DIAG(err_overload_multiple_match, ERROR,
|
||||
"more than one matching function found in __builtin_overload")
|
||||
|
||||
// CHECK: printf format string errors
|
||||
DIAG(warn_printf_not_string_constant, WARNING,
|
||||
|
|
Loading…
Reference in New Issue