[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
Chris Lattner
clattner at apple.com
Wed Jan 30 20:28:29 PST 2008
On Jan 30, 2008, at 12:50 PM, Nate Begeman wrote:
> URL: http://llvm.org/viewvc/llvm-project?rev=46572&view=rev
> Log:
> Implement first round of feedback on __builtin_overload
Nice!
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- 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.
> +///
> +/// 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);
Very nice!
>
> 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
> +
I think the NumArgs comment is dead?
>
> + // The index of the matching candidate function
> unsigned FnIndex;
> +
> SourceLocation BuiltinLoc;
> SourceLocation RParenLoc;
> public:
> OverloadExpr(Expr **args, unsigned narg, unsigned idx, QualType t,
Please rename narg -> nexprs for consistency.
>
> SourceLocation bloc, SourceLocation 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; }
Nice. Much more clear.
> + /// 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();
> + }
Lazy is good.
>
> +
> + /// getNumSubExprs - Return the size of the SubExprs array
> + unsigned getNumSubExprs() const { return NumExprs; }
Sentence needs to end with a period. How about also adding "this
includes the constant expression, the actual arguments passed in, and
the function pointers."
>
>
> /// getArg - Return the specified argument.
> + Expr *getExpr(unsigned Expr) {
Comment needs updating.
>
> + 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]; }
Sentence needs to end with a period. :)
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- 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);
> }
>
> // 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);
> }
This is great, but it stops checking the functions as soon as it gets
a match. For example, it would allow craziness like:
__builtin_overload(1, (double)x, sin, 42)
I think it should scan the whole list and then create the overload
expr outside the loop. This would also let you emit an error if
multiple things match like:
__builtin_overload(1, (double)x, sin, sin)
Thanks Nate!
-Chris
More information about the cfe-commits
mailing list