Implement template instantiation for builtin binary operators

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66835 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 6252e29..4b98d30 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -576,9 +576,13 @@
     Sema::OwningExprResult VisitIntegerLiteral(IntegerLiteral *E);
     Sema::OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
     Sema::OwningExprResult VisitParenExpr(ParenExpr *E);
+    Sema::OwningExprResult VisitBinaryOperator(BinaryOperator *E);
 
     // Base case. I'm supposed to ignore this.
-    Sema::OwningExprResult VisitStmt(Stmt *) { return SemaRef.ExprError(); }
+    Sema::OwningExprResult VisitStmt(Stmt *) { 
+      assert(false && "Cannot instantiate this kind of expression");
+      return SemaRef.ExprError(); 
+    }
   };
 }
 
@@ -619,6 +623,29 @@
 }
 
 Sema::OwningExprResult 
+TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
+  Sema::OwningExprResult LHS = Visit(E->getLHS());
+  if (LHS.isInvalid())
+    return SemaRef.ExprError();
+
+  Sema::OwningExprResult RHS = Visit(E->getRHS());
+  if (RHS.isInvalid())
+    return SemaRef.ExprError();
+
+  Sema::OwningExprResult Result
+    = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), 
+                                 E->getOpcode(),
+                                 (Expr *)LHS.get(),
+                                 (Expr *)RHS.get());
+  if (Result.isInvalid())
+    return SemaRef.ExprError();
+
+  LHS.release();
+  RHS.release();
+  return move(Result);
+}
+
+Sema::OwningExprResult 
 Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs,
                       unsigned NumTemplateArgs) {
   TemplateExprInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs);