[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