[cfe-commits] r46132 - in /cfe/trunk: AST/Expr.cpp AST/StmtPrinter.cpp CodeGen/CGBuiltin.cpp CodeGen/CGExpr.cpp CodeGen/CGExprScalar.cpp CodeGen/CodeGenFunction.h Parse/ParseExpr.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/Expr.h include/clang/AST/StmtNodes.def include/clang/Basic/DiagnosticKinds.def include/clang/Basic/TokenKinds.def include/clang/Parse/Action.h

Nate Begeman natebegeman at mac.com
Thu Jan 17 09:46:28 PST 2008


Author: sampo
Date: Thu Jan 17 11:46:27 2008
New Revision: 46132

URL: http://llvm.org/viewvc/llvm-project?rev=46132&view=rev
Log:
Implement basic overload support via a new builtin, __builtin_overload.

__builtin_overload takes 2 or more arguments:
0) a non-zero constant-expr for the number of arguments the overloaded 
   functions will take
1) the arguments to pass to the matching overloaded function
2) a list of functions to match.

The return type of __builtin_overload is inferred from the function whose args
match the types of the arguments passed to the builtin.  For example:

float a;
float sinf(float);
int   sini(int);

float b = __builtin_overload(1, a, sini, sinf);

Says that we are overloading functions that take one argument, and trying to 
pass an argument of the same type as 'a'.  sini() does not match since it takes
and argument of type int.  sinf does match, so at codegen time this will turn
into float b = sinf(a);

Modified:
    cfe/trunk/AST/Expr.cpp
    cfe/trunk/AST/StmtPrinter.cpp
    cfe/trunk/CodeGen/CGBuiltin.cpp
    cfe/trunk/CodeGen/CGExpr.cpp
    cfe/trunk/CodeGen/CGExprScalar.cpp
    cfe/trunk/CodeGen/CodeGenFunction.h
    cfe/trunk/Parse/ParseExpr.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Basic/TokenKinds.def
    cfe/trunk/include/clang/Parse/Action.h

Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Thu Jan 17 11:46:27 2008
@@ -78,6 +78,7 @@
 // Postfix Operators.
 //===----------------------------------------------------------------------===//
 
+
 CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
                    SourceLocation rparenloc)
   : Expr(CallExprClass, t), NumArgs(numargs) {
@@ -1238,6 +1239,14 @@
   return reinterpret_cast<Stmt**>(&SubExprs)+END_EXPR;
 }
 
+// OverloadExpr
+Stmt::child_iterator OverloadExpr::child_begin() {
+  return reinterpret_cast<Stmt**>(&SubExprs[0]);
+}
+Stmt::child_iterator OverloadExpr::child_end() {
+  return reinterpret_cast<Stmt**>(&SubExprs[NumArgs]);
+}
+
 // VAArgExpr
 Stmt::child_iterator VAArgExpr::child_begin() {
   return reinterpret_cast<Stmt**>(&Val);

Modified: cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtPrinter.cpp?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/AST/StmtPrinter.cpp Thu Jan 17 11:46:27 2008
@@ -733,6 +733,15 @@
   OS << ")";
 }
 
+void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
+  OS << "__builtin_overload(";
+  for (unsigned i = 0, e = Node->getNumArgs(); i != e; ++i) {
+    if (i) OS << ", ";
+    PrintExpr(Node->getArg(i));
+  }
+  OS << ")";
+}
+
 void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
   OS << "{ ";
   for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {

Modified: cfe/trunk/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGBuiltin.cpp?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/CodeGen/CGBuiltin.cpp Thu Jan 17 11:46:27 2008
@@ -29,7 +29,8 @@
   switch (BuiltinID) {
   default: {
     if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
-      return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), E);
+      return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), E->getType(),
+                          E->arg_begin());
   
     // See if we have a target specific intrinsic.
     Intrinsic::ID IntrinsicID;

Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Thu Jan 17 11:46:27 2008
@@ -450,7 +450,12 @@
           return EmitBuiltinExpr(builtinID, E);
         
   llvm::Value *Callee = EmitScalarExpr(E->getCallee());
-  return EmitCallExpr(Callee, E);
+  return EmitCallExpr(Callee, E->getType(), E->arg_begin());
+}
+
+RValue CodeGenFunction::EmitCallExpr(Expr *FnExpr, Expr *const *Args) {
+  llvm::Value *Callee = EmitScalarExpr(FnExpr);
+  return EmitCallExpr(Callee, FnExpr->getType(), Args);
 }
 
 LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
@@ -459,45 +464,42 @@
   return LValue::MakeAddr(RV.getAggregateAddr());
 }
 
-RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, const CallExpr *E) {
+RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, 
+                                     Expr *const *ArgExprs) {
   // The callee type will always be a pointer to function type, get the function
   // type.
-  QualType CalleeTy = E->getCallee()->getType();
-  CalleeTy = cast<PointerType>(CalleeTy.getCanonicalType())->getPointeeType();
-  
-  // Get information about the argument types.
-  FunctionTypeProto::arg_type_iterator ArgTyIt = 0, ArgTyEnd = 0;
+  FnType = cast<PointerType>(FnType.getCanonicalType())->getPointeeType();
+  QualType ResultType = cast<FunctionType>(FnType)->getResultType();
   
   // Calling unprototyped functions provides no argument info.
-  if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(CalleeTy)) {
-    ArgTyIt  = FTP->arg_type_begin();
-    ArgTyEnd = FTP->arg_type_end();
-  }
+  unsigned NumArgs = 0;
+  if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FnType))
+    NumArgs = FTP->getNumArgs();
   
   llvm::SmallVector<llvm::Value*, 16> Args;
   
   // Handle struct-return functions by passing a pointer to the location that
   // we would like to return into.
-  if (hasAggregateLLVMType(E->getType())) {
+  if (hasAggregateLLVMType(ResultType)) {
     // Create a temporary alloca to hold the result of the call. :(
-    Args.push_back(CreateTempAlloca(ConvertType(E->getType())));
+    Args.push_back(CreateTempAlloca(ConvertType(ResultType)));
     // FIXME: set the stret attribute on the argument.
   }
   
-  for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
-    QualType ArgTy = E->getArg(i)->getType();
+  for (unsigned i = 0, e = NumArgs; i != e; ++i) {
+    QualType ArgTy = ArgExprs[i]->getType();
     
     if (!hasAggregateLLVMType(ArgTy)) {
       // Scalar argument is passed by-value.
-      Args.push_back(EmitScalarExpr(E->getArg(i)));
+      Args.push_back(EmitScalarExpr(ArgExprs[i]));
     } else if (ArgTy->isComplexType()) {
       // Make a temporary alloca to pass the argument.
       llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
-      EmitComplexExprIntoAddr(E->getArg(i), DestMem, false);
+      EmitComplexExprIntoAddr(ArgExprs[i], DestMem, false);
       Args.push_back(DestMem);
     } else {
       llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
-      EmitAggExpr(E->getArg(i), DestMem, false);
+      EmitAggExpr(ArgExprs[i], DestMem, false);
       Args.push_back(DestMem);
     }
   }
@@ -505,14 +507,14 @@
   llvm::Value *V = Builder.CreateCall(Callee, &Args[0], &Args[0]+Args.size());
   if (V->getType() != llvm::Type::VoidTy)
     V->setName("call");
-  else if (E->getType()->isComplexType())
+  else if (ResultType->isComplexType())
     return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
-  else if (hasAggregateLLVMType(E->getType()))
+  else if (hasAggregateLLVMType(ResultType))
     // Struct return.
     return RValue::getAggregate(Args[0]);
   else {
     // void return.
-    assert(E->getType()->isVoidType() && "Should only have a void expr here");
+    assert(ResultType->isVoidType() && "Should only have a void expr here");
     V = 0;
   }
       

Modified: cfe/trunk/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprScalar.cpp?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/CodeGen/CGExprScalar.cpp Thu Jan 17 11:46:27 2008
@@ -282,6 +282,7 @@
   // Other Operators.
   Value *VisitConditionalOperator(const ConditionalOperator *CO);
   Value *VisitChooseExpr(ChooseExpr *CE);
+  Value *VisitOverloadExpr(OverloadExpr *OE);
   Value *VisitVAArgExpr(VAArgExpr *VE);
   Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
     return CGF.EmitObjCStringLiteral(E);
@@ -991,6 +992,10 @@
     Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() : E->getRHS());
 }
 
+Value *ScalarExprEmitter::VisitOverloadExpr(OverloadExpr *E) {
+  return CGF.EmitCallExpr(E->getFn(), E->arg_begin()).getScalarVal();
+}
+
 Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
   llvm::Value *ArgValue = EmitLValue(VE->getSubExpr()).getAddress();
 

Modified: cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenFunction.h?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/CodeGen/CodeGenFunction.h Thu Jan 17 11:46:27 2008
@@ -388,7 +388,8 @@
   //===--------------------------------------------------------------------===//
 
   RValue EmitCallExpr(const CallExpr *E);
-  RValue EmitCallExpr(llvm::Value *Callee, const CallExpr *E);
+  RValue EmitCallExpr(Expr *FnExpr, Expr *const *Args);
+  RValue EmitCallExpr(llvm::Value *Callee, QualType FnType, Expr *const *Args);
   RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
 
   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);

Modified: cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseExpr.cpp?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/Parse/ParseExpr.cpp Thu Jan 17 11:46:27 2008
@@ -550,6 +550,7 @@
   case tok::kw___builtin_va_arg:
   case tok::kw___builtin_offsetof:
   case tok::kw___builtin_choose_expr:
+  case tok::kw___builtin_overload:
   case tok::kw___builtin_types_compatible_p:
     return ParseBuiltinPrimaryExpression();
   case tok::plusplus:      // unary-expression: '++' unary-expression
@@ -774,6 +775,7 @@
 /// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
 ///                                     assign-expr ')'
 /// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+/// [CLANG] '__builtin_overload' '(' expr (',' expr)* ')'
 /// 
 /// [GNU] offsetof-member-designator:
 /// [GNU]   identifier
@@ -909,6 +911,44 @@
                                   ConsumeParen());
     break;
   }
+  case tok::kw___builtin_overload: {
+    llvm::SmallVector<ExprTy*, 8> ArgExprs;
+    llvm::SmallVector<SourceLocation, 8> CommaLocs;
+
+    // For each iteration through the loop look for assign-expr followed by a
+    // comma.  If there is no comma, break and attempt to match r-paren.
+    if (Tok.isNot(tok::r_paren)) {
+      while (1) {
+        ExprResult ArgExpr = ParseAssignmentExpression();
+        if (ArgExpr.isInvalid) {
+          SkipUntil(tok::r_paren);
+          return ExprResult(true);
+        } else
+          ArgExprs.push_back(ArgExpr.Val);
+        
+        if (Tok.isNot(tok::comma))
+          break;
+        // Move to the next argument, remember where the comma was.
+        CommaLocs.push_back(ConsumeToken());
+      }
+    }
+    
+    // Attempt to consume the r-paren
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok, diag::err_expected_rparen);
+      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;
+  }
   case tok::kw___builtin_types_compatible_p:
     TypeTy *Ty1 = ParseTypeName();
     

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Jan 17 11:46:27 2008
@@ -465,6 +465,12 @@
                                      ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
                                      SourceLocation RPLoc);
   
+  // __builtin_overload(...)
+  virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
+                                       SourceLocation *CommaLocs,
+                                       SourceLocation BuiltinLoc, 
+                                       SourceLocation RParenLoc);
+  
   // __builtin_va_arg(expr, type)
   virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
                                 ExprTy *expr, TypeTy *type,

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Thu Jan 17 11:46:27 2008
@@ -892,7 +892,7 @@
     ImpCastExprToType(e, Context.getPointerType(ary->getElementType()));
 }
 
-/// UsualUnaryConversion - Performs various conversions that are common to most
+/// UsualUnaryConversions - Performs various conversions that are common to most
 /// operators (C99 6.3). The conversions of array and function types are 
 /// sometimes surpressed. For example, the array->pointer conversion doesn't
 /// apply if the array is an argument to the sizeof or address (&) operators.
@@ -2074,6 +2074,76 @@
   return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc);
 }
 
+/// ExprsCompatibleWithFnType - 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) {
+  unsigned NumParams = FnType->getNumArgs();
+  for (unsigned i = 0; i != NumParams; ++i)
+    if (Args[i]->getType() != FnType->getArgType(i))
+      return false;
+  return true;
+}
+
+Sema::ExprResult Sema::ActOnOverloadExpr(ExprTy **args, unsigned NumArgs,
+                                         SourceLocation *CommaLocs,
+                                         SourceLocation BuiltinLoc,
+                                         SourceLocation RParenLoc) {
+  assert((NumArgs > 1) && "Too few arguments for OverloadExpr!");
+
+  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 *NParamsExpr = Args[0];
+  llvm::APSInt constEval(32);
+  SourceLocation ExpLoc;
+  if (!NParamsExpr->isIntegerConstantExpr(constEval, Context, &ExpLoc))
+    return Diag(ExpLoc, diag::err_overload_expr_requires_non_zero_constant,
+                NParamsExpr->getSourceRange());
+  
+  // Verify that the number of parameters is > 0
+  unsigned NumParams = constEval.getZExtValue();
+  if (NumParams == 0)
+    return Diag(ExpLoc, diag::err_overload_expr_requires_non_zero_constant,
+                NParamsExpr->getSourceRange());
+  // Verify that we have at least 1 + NumParams arguments to the builtin.
+  if ((NumParams + 1) > NumArgs)
+    return Diag(RParenLoc, diag::err_typecheck_call_too_few_args,
+                SourceRange(BuiltinLoc, RParenLoc));
+
+  // Figure out the return type, by matching the args to one of the functions
+  // listed after the paramters.
+  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());
+ 
+    // 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;
+
+    // Scan the parameter list for the FunctionType, checking the QualType of
+    // each paramter against the QualTypes of the arguments to the builtin.
+    // If they match, return a new OverloadExpr.
+    if (ExprsCompatibleWithFnType(Args+1, FnType))
+      return new OverloadExpr(Args, NumArgs, i, FnType->getResultType(),
+                              BuiltinLoc, RParenLoc);
+  }
+
+  // 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() + " ";
+
+  return Diag(BuiltinLoc, diag::err_overload_no_match, typeNames,
+              SourceRange(BuiltinLoc, RParenLoc));
+}
+
 Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
                                   ExprTy *expr, TypeTy *type,
                                   SourceLocation RPLoc) {

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Jan 17 11:46:27 2008
@@ -1124,6 +1124,57 @@
   virtual child_iterator child_end();
 };
 
+/// 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.  
+class OverloadExpr : public Expr {
+  Expr **SubExprs;
+  unsigned NumArgs;
+  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) {
+    SubExprs = new Expr*[narg];
+    for (unsigned i = 0; i != narg; ++i)
+      SubExprs[i] = args[i];
+  }
+  ~OverloadExpr() {
+    delete [] SubExprs;
+  }
+
+  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; }
+  
+  /// getArg - Return the specified argument.
+  Expr *getArg(unsigned Arg) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return SubExprs[Arg];
+  }
+  Expr *getFn() { return SubExprs[FnIndex]; }
+  
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(BuiltinLoc, RParenLoc);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OverloadExprClass; 
+  }
+  static bool classof(const OverloadExpr *) { return true; }
+  
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
 /// VAArgExpr, used for the builtin function __builtin_va_start.
 class VAArgExpr : public Expr {
   Expr *Val;

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Thu Jan 17 11:46:27 2008
@@ -98,7 +98,10 @@
 STMT(74, ObjCProtocolExpr     , Expr)
 STMT(75, ObjCIvarRefExpr      , Expr)
 
-LAST_EXPR(75)
+// Clang Extensions.
+STMT(76, OverloadExpr         , Expr)
+
+LAST_EXPR(76)
 
 #undef STMT
 #undef FIRST_STMT

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Jan 17 11:46:27 2008
@@ -834,6 +834,10 @@
     "of different size")
 DIAG(err_invalid_conversion_between_vector_and_scalar, ERROR,
     "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_no_match, ERROR,
+     "no matching overload found for arguments of type '%0'")
 
 // CHECK: printf format string errors
 DIAG(warn_printf_not_string_constant, WARNING,

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Thu Jan 17 11:46:27 2008
@@ -289,6 +289,7 @@
 KEYWORD(__alignof                   , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
 KEYWORD(__attribute                 , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
 KEYWORD(__builtin_choose_expr       , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
+KEYWORD(__builtin_overload          , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
 KEYWORD(__builtin_offsetof          , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
 KEYWORD(__builtin_types_compatible_p, EXTC90|EXTC99|EXTCPP|EXTCPP0x)
 KEYWORD(__builtin_va_arg            , EXTC90|EXTC99|EXTCPP|EXTCPP0x)

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=46132&r1=46131&r2=46132&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Jan 17 11:46:27 2008
@@ -476,6 +476,14 @@
                                      SourceLocation RPLoc) {
     return 0;
   }
+  // __builtin_overload(...)
+  virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
+                                       SourceLocation *CommaLocs,
+                                       SourceLocation BuiltinLoc, 
+                                       SourceLocation RPLoc) {
+    return 0;
+  }
+  
 
   // __builtin_va_arg(expr, type)
   virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,





More information about the cfe-commits mailing list