Refactor the way we handle operator overloading and template
instantiation for binary operators. This change moves most of the
operator-overloading code from the parser action ActOnBinOp to a new,
parser-independent semantic checking routine CreateOverloadedBinOp. 

Of particular importance is the fact that CreateOverloadedBinOp does
*not* perform any name lookup based on the current parsing context (it
doesn't take a Scope*), since it has to be usable during template
instantiation, when there is no scope information. Rather, it takes a
pre-computed set of functions that are visible from the context or via
argument-dependent lookup, and adds to that set any member operators
and built-in operator candidates. The set of functions is computed in
the parser action ActOnBinOp based on the current context (both
operator name lookup and argument-dependent lookup). Within a
template, the set computed by ActOnBinOp is saved within the
type-dependent AST node and is augmented with the results of
argument-dependent name lookup at instantiation time (see
TemplateExprInstantiator::VisitCXXOperatorCallExpr).

Sadly, we can't fully test this yet. I'll follow up with template
instantiation for sizeof so that the real fun can begin.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66923 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 9612f7f..4b99eef 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -227,6 +227,68 @@
   return "";
 }
 
+BinaryOperator::Opcode 
+BinaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO) {
+  switch (OO) {
+  case OO_Plus: return Add;
+  case OO_Minus: return Sub;
+  case OO_Star: return Mul;
+  case OO_Slash: return Div;
+  case OO_Percent: return Rem;
+  case OO_Caret: return Xor;
+  case OO_Amp: return And;
+  case OO_Pipe: return Or;
+  case OO_Equal: return Assign;
+  case OO_Less: return LT;
+  case OO_Greater: return GT;
+  case OO_PlusEqual: return AddAssign;
+  case OO_MinusEqual: return SubAssign;
+  case OO_StarEqual: return MulAssign;
+  case OO_SlashEqual: return DivAssign;
+  case OO_PercentEqual: return RemAssign;
+  case OO_CaretEqual: return XorAssign;
+  case OO_AmpEqual: return AndAssign;
+  case OO_PipeEqual: return OrAssign;
+  case OO_LessLess: return Shl;
+  case OO_GreaterGreater: return Shr;
+  case OO_LessLessEqual: return ShlAssign;
+  case OO_GreaterGreaterEqual: return ShrAssign;
+  case OO_EqualEqual: return EQ;
+  case OO_ExclaimEqual: return NE;
+  case OO_LessEqual: return LE;
+  case OO_GreaterEqual: return GE;
+  case OO_AmpAmp: return LAnd;
+  case OO_PipePipe: return LOr;
+  case OO_Comma: return Comma;
+  case OO_ArrowStar: return PtrMemI;
+  default: assert(false && "Not an overloadable binary operator");
+  }
+}
+
+OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
+  static const OverloadedOperatorKind OverOps[] = {
+    /* .* Cannot be overloaded */OO_None, OO_ArrowStar,
+    OO_Star, OO_Slash, OO_Percent,
+    OO_Plus, OO_Minus,
+    OO_LessLess, OO_GreaterGreater,
+    OO_Less, OO_Greater, OO_LessEqual, OO_GreaterEqual,
+    OO_EqualEqual, OO_ExclaimEqual,
+    OO_Amp,
+    OO_Caret,
+    OO_Pipe,
+    OO_AmpAmp,
+    OO_PipePipe,
+    OO_Equal, OO_StarEqual,
+    OO_SlashEqual, OO_PercentEqual,
+    OO_PlusEqual, OO_MinusEqual,
+    OO_LessLessEqual, OO_GreaterGreaterEqual,
+    OO_AmpEqual, OO_CaretEqual,
+    OO_PipeEqual,
+    OO_Comma
+  };
+  return OverOps[Opc];
+}
+
 InitListExpr::InitListExpr(SourceLocation lbraceloc, 
                            Expr **initExprs, unsigned numInits,
                            SourceLocation rbraceloc)