Add a new expression node, CXXOperatorCallExpr, which expresses a
function call created in response to the use of operator syntax that
resolves to an overloaded operator in C++, e.g., "str1 +
str2" that resolves to std::operator+(str1, str2)". We now build a
CXXOperatorCallExpr in C++ when we pick an overloaded operator. (But
only for binary operators, where we actually implement overloading)

I decided *not* to refactor the current CallExpr to make it abstract
(with FunctionCallExpr and CXXOperatorCallExpr as derived
classes). Doing so would allow us to make CXXOperatorCallExpr a little
bit smaller, at the cost of making the argument and callee accessors
virtual. We won't know if this is going to be a win until we can parse
lots of C++ code to determine how much memory we'll save by making
this change vs. the performance penalty due to the extra virtual
calls.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59306 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 249bebc..871dc4b 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -101,6 +101,15 @@
 // Postfix Operators.
 //===----------------------------------------------------------------------===//
 
+CallExpr::CallExpr(StmtClass SC, Expr *fn, Expr **args, unsigned numargs, 
+                   QualType t, SourceLocation rparenloc)
+  : Expr(SC, t), NumArgs(numargs) {
+  SubExprs = new Stmt*[numargs+1];
+  SubExprs[FN] = fn;
+  for (unsigned i = 0; i != numargs; ++i)
+    SubExprs[i+ARGS_START] = args[i];
+  RParenLoc = rparenloc;
+}
 
 CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
                    SourceLocation rparenloc)
@@ -285,6 +294,7 @@
     return getType().isVolatileQualified();
 
   case CallExprClass:
+  case CXXOperatorCallExprClass:
     // TODO: check attributes for pure/const.   "void foo() { strlen("bar"); }"
     // should warn.
     return true;
@@ -410,7 +420,8 @@
     //   An assignment expression [...] is not an lvalue.
     return LV_InvalidExpression;
   }
-  case CallExprClass: {
+  case CallExprClass: 
+  case CXXOperatorCallExprClass: {
     // C++ [expr.call]p10:
     //   A function call is an lvalue if and only if the result type
     //   is a reference.
@@ -586,7 +597,8 @@
   case CXXBoolLiteralExprClass:
   case AddrLabelExprClass:
     return true;
-  case CallExprClass: {
+  case CallExprClass: 
+  case CXXOperatorCallExprClass: {
     const CallExpr *CE = cast<CallExpr>(this);
 
     // Allow any constant foldable calls to builtins.
@@ -777,7 +789,8 @@
                                     T1.getUnqualifiedType());
     break;
   }
-  case CallExprClass: {
+  case CallExprClass: 
+  case CXXOperatorCallExprClass: {
     const CallExpr *CE = cast<CallExpr>(this);
     Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));