@@ -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.
@@ -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