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/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index bbd53d0..cf6d4c0 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -811,6 +811,49 @@
 }
 
 // C++
+void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
+  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
+    "",
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+    Spelling,
+#include "clang/Basic/OperatorKinds.def"
+  };
+
+  OverloadedOperatorKind Kind = Node->getOperator();
+  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
+    if (Node->getNumArgs() == 1) {
+      OS << OpStrings[Kind] << ' ';
+      PrintExpr(Node->getArg(0));
+    } else {
+      PrintExpr(Node->getArg(0));
+      OS << ' ' << OpStrings[Kind];
+    }
+  } else if (Kind == OO_Call) {
+    PrintExpr(Node->getArg(0));
+    OS << '(';
+    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
+      if (ArgIdx > 1)
+        OS << ", ";
+      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
+        PrintExpr(Node->getArg(ArgIdx));
+    }
+    OS << ')';
+  } else if (Kind == OO_Subscript) {
+    PrintExpr(Node->getArg(0));
+    OS << '[';
+    PrintExpr(Node->getArg(1));
+    OS << ']';
+  } else if (Node->getNumArgs() == 1) {
+    OS << OpStrings[Kind] << ' ';
+    PrintExpr(Node->getArg(0));
+  } else if (Node->getNumArgs() == 2) {
+    PrintExpr(Node->getArg(0));
+    OS << ' ' << OpStrings[Kind] << ' ';
+    PrintExpr(Node->getArg(1));
+  } else {
+    assert(false && "unknown overloaded operator");
+  }
+}
 
 void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
   OS << Node->getCastName() << '<';