]> granicus.if.org Git - clang/commitdiff
Remainder of the __builtin_overload feedback
authorNate Begeman <natebegeman@mac.com>
Thu, 31 Jan 2008 05:38:29 +0000 (05:38 +0000)
committerNate Begeman <natebegeman@mac.com>
Thu, 31 Jan 2008 05:38:29 +0000 (05:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46601 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGExprAgg.cpp
Parse/ParseExpr.cpp
Sema/SemaExpr.cpp
include/clang/AST/Expr.h
include/clang/Basic/DiagnosticKinds.def

index d52e8b1a0e5f7d08607170876c6398375deba848..377e90df7028e82de168ae6cd160679b510dc2ef 100644 (file)
@@ -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);
 }
index 00b2899a034e221ea87fe0c4b797fa357cab0a94..09f588aeec3bec2dc45576553031d41c526d5578 100644 (file)
@@ -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;
index 86d6d772ddb7d32f4fac498bf08fac3aef9d0ed4..6228b3cf76b2c0bd34d0c40d8eff648e860bfd88 100644 (file)
@@ -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.
index 6e8c7c6e91d26532c02d53627482296e4e8155f4..370e18d05f1be1583f4a11ab1a28c7bbec497425 100644 (file)
@@ -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 {
index 023b7c439d8962b7c9850ff1d93a058959c58b2f..78f6c61c51200fb76d30ac65df2cf11406cf1d22 100644 (file)
@@ -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,