[cfe-commits] r46572 - in /cfe/trunk: AST/Expr.cpp AST/StmtPrinter.cpp CodeGen/CGExprComplex.cpp CodeGen/CGExprScalar.cpp Sema/SemaExpr.cpp include/clang/AST/Expr.h include/clang/Basic/DiagnosticKinds.def
Nate Begeman
natebegeman at mac.com
Wed Jan 30 12:50:20 PST 2008
Author: sampo
Date: Wed Jan 30 14:50:20 2008
New Revision: 46572
URL: http://llvm.org/viewvc/llvm-project?rev=46572&view=rev
Log:
Implement first round of feedback on __builtin_overload
Modified:
cfe/trunk/AST/Expr.cpp
cfe/trunk/AST/StmtPrinter.cpp
cfe/trunk/CodeGen/CGExprComplex.cpp
cfe/trunk/CodeGen/CGExprScalar.cpp
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=46572&r1=46571&r2=46572&view=diff
==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Wed Jan 30 14:50:20 2008
@@ -1291,7 +1291,7 @@
return reinterpret_cast<Stmt**>(&SubExprs[0]);
}
Stmt::child_iterator OverloadExpr::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs[NumArgs]);
+ return reinterpret_cast<Stmt**>(&SubExprs[NumExprs]);
}
// VAArgExpr
Modified: cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtPrinter.cpp?rev=46572&r1=46571&r2=46572&view=diff
==============================================================================
--- cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/AST/StmtPrinter.cpp Wed Jan 30 14:50:20 2008
@@ -743,9 +743,9 @@
void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
OS << "__builtin_overload(";
- for (unsigned i = 0, e = Node->getNumArgs(); i != e; ++i) {
+ for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
if (i) OS << ", ";
- PrintExpr(Node->getArg(i));
+ PrintExpr(Node->getExpr(i));
}
OS << ")";
}
Modified: cfe/trunk/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprComplex.cpp?rev=46572&r1=46571&r2=46572&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/CodeGen/CGExprComplex.cpp Wed Jan 30 14:50:20 2008
@@ -93,6 +93,7 @@
}
ComplexPairTy VisitCallExpr(const CallExpr *E);
ComplexPairTy VisitStmtExpr(const StmtExpr *E);
+ ComplexPairTy VisitOverloadExpr(const OverloadExpr *OE);
// Operators.
ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
@@ -250,6 +251,11 @@
return CGF.EmitCallExpr(E).getComplexVal();
}
+ComplexPairTy ComplexExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
+ return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
+ E->getNumArgs(CGF.getContext())).getComplexVal();
+}
+
ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
}
Modified: cfe/trunk/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprScalar.cpp?rev=46572&r1=46571&r2=46572&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/CodeGen/CGExprScalar.cpp Wed Jan 30 14:50:20 2008
@@ -1012,7 +1012,8 @@
}
Value *ScalarExprEmitter::VisitOverloadExpr(OverloadExpr *E) {
- return CGF.EmitCallExpr(E->getFn(), E->arg_begin(), E->getNumArgs()).getScalarVal();
+ return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
+ E->getNumArgs(CGF.getContext())).getScalarVal();
}
Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=46572&r1=46571&r2=46572&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Wed Jan 30 14:50:20 2008
@@ -2086,12 +2086,15 @@
return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc);
}
-/// ExprsCompatibleWithFnType - return true if the Exprs in array Args have
+/// ExprsMatchFnType - return true if the Exprs in array Args have
/// QualTypes that match the QualTypes of the arguments of the FnType.
-static bool ExprsCompatibleWithFnType(Expr **Args, FunctionTypeProto *FnType) {
+/// The number of arguments has already been validated to match the number of
+/// arguments in FnType.
+static bool ExprsMatchFnType(Expr **Args, const FunctionTypeProto *FnType) {
unsigned NumParams = FnType->getNumArgs();
for (unsigned i = 0; i != NumParams; ++i)
- if (Args[i]->getType() != FnType->getArgType(i))
+ if (Args[i]->getType().getCanonicalType() !=
+ FnType->getArgType(i).getCanonicalType())
return false;
return true;
}
@@ -2123,25 +2126,28 @@
SourceRange(BuiltinLoc, RParenLoc));
// Figure out the return type, by matching the args to one of the functions
- // listed after the paramters.
+ // listed after the parameters.
for (unsigned i = NumParams + 1; i < NumArgs; ++i) {
// UsualUnaryConversions will convert the function DeclRefExpr into a
// pointer to function.
Expr *Fn = UsualUnaryConversions(Args[i]);
FunctionTypeProto *FnType = 0;
- if (const PointerType *PT = Fn->getType()->getAsPointerType())
- FnType = dyn_cast<FunctionTypeProto>(PT->getPointeeType());
+ if (const PointerType *PT = Fn->getType()->getAsPointerType()) {
+ QualType PointeeType = PT->getPointeeType().getCanonicalType();
+ FnType = dyn_cast<FunctionTypeProto>(PointeeType);
+ }
// The Expr type must be FunctionTypeProto, since FunctionTypeProto has no
// parameters, and the number of parameters must match the value passed to
// the builtin.
if (!FnType || (FnType->getNumArgs() != NumParams))
- continue;
+ return Diag(Fn->getExprLoc(), diag::err_overload_incorrect_fntype,
+ Fn->getSourceRange());
// Scan the parameter list for the FunctionType, checking the QualType of
- // each paramter against the QualTypes of the arguments to the builtin.
+ // each parameter against the QualTypes of the arguments to the builtin.
// If they match, return a new OverloadExpr.
- if (ExprsCompatibleWithFnType(Args+1, FnType))
+ if (ExprsMatchFnType(Args+1, FnType))
return new OverloadExpr(Args, NumArgs, i, FnType->getResultType(),
BuiltinLoc, RParenLoc);
}
@@ -2149,8 +2155,10 @@
// If we didn't find a matching function Expr in the __builtin_overload list
// the return an error.
std::string typeNames;
- for (unsigned i = 0; i != NumParams; ++i)
- typeNames += Args[i+1]->getType().getAsString() + " ";
+ for (unsigned i = 0; i != NumParams; ++i) {
+ if (i != 0) typeNames += ", ";
+ typeNames += Args[i+1]->getType().getAsString();
+ }
return Diag(BuiltinLoc, diag::err_overload_no_match, typeNames,
SourceRange(BuiltinLoc, RParenLoc));
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=46572&r1=46571&r2=46572&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Wed Jan 30 14:50:20 2008
@@ -1128,21 +1128,45 @@
};
/// OverloadExpr - Clang builtin-in function __builtin_overload.
-/// This AST node provides a way to overload functions in C
-/// i.e. float Z = __builtin_overload(2, X, Y, modf, mod, modl);
-/// would pick whichever of the functions modf, mod, and modl that took two
-/// arguments of the same type as X and Y.
+/// This AST node provides a way to overload functions in C.
+///
+/// The first argument is required to be a constant expression, for the number
+/// of arguments passed to each candidate function.
+///
+/// The next N arguments, where N is the value of the constant expression,
+/// are the values to be passed as arguments.
+///
+/// The rest of the arguments are values of pointer to function type, which
+/// are the candidate functions for overloading.
+///
+/// The result is a equivalent to a CallExpr taking N arguments to the
+/// candidate function whose parameter types match the types of the N arguments.
+///
+/// example: float Z = __builtin_overload(2, X, Y, modf, mod, modl);
+/// If X and Y are long doubles, Z will assigned the result of modl(X, Y);
+/// If X and Y are floats, Z will be assigned the result of modf(X, Y);
class OverloadExpr : public Expr {
+ // SubExprs - the list of values passed to the __builtin_overload function.
+ // SubExpr[0] is a constant expression
+ // SubExpr[1-N] are the parameters to pass to the matching function call
+ // SubExpr[N-...] are the candidate functions, of type pointer to function.
Expr **SubExprs;
- unsigned NumArgs;
+
+ // 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,
SourceLocation bloc, SourceLocation rploc)
- : Expr(OverloadExprClass, t), NumArgs(narg), FnIndex(idx), BuiltinLoc(bloc),
- RParenLoc(rploc) {
+ : Expr(OverloadExprClass, t), NumExprs(narg), FnIndex(idx),
+ BuiltinLoc(bloc), RParenLoc(rploc) {
SubExprs = new Expr*[narg];
for (unsigned i = 0; i != narg; ++i)
SubExprs[i] = args[i];
@@ -1151,19 +1175,31 @@
delete [] SubExprs;
}
+ /// arg_begin - Return a pointer to the list of arguments that will be passed
+ /// to the matching candidate function, skipping over the initial constant
+ /// expression.
typedef Expr * const *arg_const_iterator;
arg_const_iterator arg_begin() const { return SubExprs+1; }
- /// getNumArgs - Return the number of actual arguments to this call.
- ///
- unsigned getNumArgs() const { return NumArgs; }
+ /// getNumArgs - Return the number of arguments to pass to the candidate
+ /// functions.
+ unsigned getNumArgs(ASTContext &Ctx) const {
+ llvm::APSInt constEval(32);
+ (void) SubExprs[0]->isIntegerConstantExpr(constEval, Ctx);
+ return constEval.getZExtValue();
+ }
+
+ /// getNumSubExprs - Return the size of the SubExprs array
+ unsigned getNumSubExprs() const { return NumExprs; }
/// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return SubExprs[Arg];
+ Expr *getExpr(unsigned Expr) {
+ assert((Expr < NumExprs) && "Arg access out of range!");
+ return SubExprs[Expr];
}
- Expr *getFn() { return SubExprs[FnIndex]; }
+
+ /// getFn - Return the matching candidate function for this OverloadExpr
+ Expr *getFn() const { return SubExprs[FnIndex]; }
virtual SourceRange getSourceRange() const {
return SourceRange(BuiltinLoc, RParenLoc);
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=46572&r1=46571&r2=46572&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jan 30 14:50:20 2008
@@ -844,6 +844,8 @@
"invalid conversion between vector type '%0' and scalar type '%1'")
DIAG(err_overload_expr_requires_non_zero_constant, ERROR,
"overload requires a non-zero constant expression as first argument")
+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'")
More information about the cfe-commits
mailing list