diff mbox

Go patch committed: Add conditional expressions to Go IR

Message ID mcrr47olxop.fsf@iant-glaptop.roam.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor Jan. 31, 2014, 1:58 a.m. UTC
This patch from Chris Manghane adds a conditional expression construct
to the Go frontend IR, for use in future conversion to the backend
interface.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r cc4de9df6d88 go/expressions.cc
--- a/go/expressions.cc	Tue Jan 28 13:43:27 2014 -0800
+++ b/go/expressions.cc	Thu Jan 30 17:55:18 2014 -0800
@@ -15040,6 +15040,103 @@ 
   return new Label_addr_expression(label, location);
 }
 
+// Conditional expressions.
+
+class Conditional_expression : public Expression
+{
+ public:
+  Conditional_expression(Expression* cond, Expression* then_expr,
+                         Expression* else_expr, Location location)
+      : Expression(EXPRESSION_CONDITIONAL, location),
+        cond_(cond), then_(then_expr), else_(else_expr)
+  {}
+
+ protected:
+  Type*
+  do_type();
+
+  void
+  do_determine_type(const Type_context*)
+  { }
+
+  Expression*
+  do_copy()
+  {
+    return new Conditional_expression(this->cond_->copy(), this->then_->copy(),
+                                      this->else_->copy(), this->location());
+  }
+
+  tree
+  do_get_tree(Translate_context* context);
+
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
+ private:
+  // The condition to be checked.
+  Expression* cond_;
+  // The expression to execute if the condition is true.
+  Expression* then_;
+  // The expression to execute if the condition is false.
+  Expression* else_;
+};
+
+// Return the type of the conditional expression.
+
+Type*
+Conditional_expression::do_type()
+{
+  Type* result_type = Type::make_void_type();
+  if (this->then_->type() == this->else_->type())
+    result_type = this->then_->type();
+  else if (this->then_->is_nil_expression()
+           || this->else_->is_nil_expression())
+    result_type = (!this->then_->is_nil_expression()
+                   ? this->then_->type()
+                   : this->else_->type());
+  return result_type;
+}
+
+// Get the backend representation of a conditional expression.
+
+tree
+Conditional_expression::do_get_tree(Translate_context* context)
+{
+  Gogo* gogo = context->gogo();
+  Btype* result_btype = this->type()->get_backend(gogo);
+  Bexpression* cond = tree_to_expr(this->cond_->get_tree(context));
+  Bexpression* then = tree_to_expr(this->then_->get_tree(context));
+  Bexpression* belse = tree_to_expr(this->else_->get_tree(context));
+  Bexpression* ret =
+      gogo->backend()->conditional_expression(result_btype, cond, then, belse,
+                                              this->location());
+  return expr_to_tree(ret);
+}
+
+// Dump ast representation of a conditional expression.
+
+void
+Conditional_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "(";
+  ast_dump_context->dump_expression(this->cond_);
+  ast_dump_context->ostream() << " ? ";
+  ast_dump_context->dump_expression(this->then_);
+  ast_dump_context->ostream() << " : ";
+  ast_dump_context->dump_expression(this->else_);
+  ast_dump_context->ostream() << ") ";
+}
+
+// Make a conditional expression.
+
+Expression*
+Expression::make_conditional(Expression* cond, Expression* then,
+                             Expression* else_expr, Location location)
+{
+  return new Conditional_expression(cond, then, else_expr, location);
+}
+
 // Import an expression.  This comes at the end in order to see the
 // various class definitions.
 
diff -r cc4de9df6d88 go/expressions.h
--- a/go/expressions.h	Tue Jan 28 13:43:27 2014 -0800
+++ b/go/expressions.h	Thu Jan 30 17:55:18 2014 -0800
@@ -106,7 +106,8 @@ 
     EXPRESSION_INTERFACE_INFO,
     EXPRESSION_STRUCT_FIELD_OFFSET,
     EXPRESSION_MAP_DESCRIPTOR,
-    EXPRESSION_LABEL_ADDR
+    EXPRESSION_LABEL_ADDR,
+    EXPRESSION_CONDITIONAL
   };
 
   Expression(Expression_classification, Location);
@@ -388,6 +389,10 @@ 
   static Expression*
   make_label_addr(Label*, Location);
 
+  // Make a conditional expression.
+  static Expression*
+  make_conditional(Expression*, Expression*, Expression*, Location);
+
   // Return the expression classification.
   Expression_classification
   classification() const