Commit eb6eb862 by Chris Manghane Committed by Ian Lance Taylor

compiler: Use backend interface for interface info and field expressions.

	* go-gcc.cc (Gcc_backend::compound_expression): New function.
	(Gcc_backend::conditional_expression): New function.

From-SVN: r206615
parent 3f3bd8aa
2014-01-14 Chris Manghane <cmang@google.com>
* go-gcc.cc (Gcc_backend::compound_expression): New function.
(Gcc_backend::conditional_expression): New function.
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com> 2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
Update copyright years Update copyright years
......
...@@ -246,6 +246,12 @@ class Gcc_backend : public Backend ...@@ -246,6 +246,12 @@ class Gcc_backend : public Backend
Bexpression* Bexpression*
struct_field_expression(Bexpression*, size_t, Location); struct_field_expression(Bexpression*, size_t, Location);
Bexpression*
compound_expression(Bstatement*, Bexpression*, Location);
Bexpression*
conditional_expression(Bexpression*, Bexpression*, Bexpression*, Location);
// Statements. // Statements.
Bstatement* Bstatement*
...@@ -1034,6 +1040,41 @@ Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index, ...@@ -1034,6 +1040,41 @@ Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index,
return tree_to_expr(ret); return tree_to_expr(ret);
} }
// Return an expression that executes BSTAT before BEXPR.
Bexpression*
Gcc_backend::compound_expression(Bstatement* bstat, Bexpression* bexpr,
Location location)
{
tree stat = bstat->get_tree();
tree expr = bexpr->get_tree();
if (stat == error_mark_node || expr == error_mark_node)
return this->error_expression();
tree ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
TREE_TYPE(expr), stat, expr);
return this->make_expression(ret);
}
// Return an expression that executes THEN_EXPR if CONDITION is true, or
// ELSE_EXPR otherwise.
Bexpression*
Gcc_backend::conditional_expression(Bexpression* condition,
Bexpression* then_expr,
Bexpression* else_expr, Location location)
{
tree cond_tree = condition->get_tree();
tree then_tree = then_expr->get_tree();
tree else_tree = else_expr == NULL ? NULL_TREE : else_expr->get_tree();
if (cond_tree == error_mark_node
|| then_tree == error_mark_node
|| else_tree == error_mark_node)
return this->error_expression();
tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
cond_tree, then_tree, else_tree);
return this->make_expression(ret);
}
// An expression as a statement. // An expression as a statement.
Bstatement* Bstatement*
......
...@@ -284,6 +284,16 @@ class Backend ...@@ -284,6 +284,16 @@ class Backend
virtual Bexpression* virtual Bexpression*
struct_field_expression(Bexpression* bstruct, size_t index, Location) = 0; struct_field_expression(Bexpression* bstruct, size_t index, Location) = 0;
// Create an expression that executes BSTAT before BEXPR.
virtual Bexpression*
compound_expression(Bstatement* bstat, Bexpression* bexpr, Location) = 0;
// Return an expression that executes THEN_EXPR if CONDITION is true, or
// ELSE_EXPR otherwise. ELSE_EXPR may be NULL.
virtual Bexpression*
conditional_expression(Bexpression* condition, Bexpression* then_expr,
Bexpression* else_expr, Location) = 0;
// Statements. // Statements.
// Create an error statement. This is used for cases which should // Create an error statement. This is used for cases which should
......
...@@ -103,6 +103,7 @@ class Expression ...@@ -103,6 +103,7 @@ class Expression
EXPRESSION_TYPE_DESCRIPTOR, EXPRESSION_TYPE_DESCRIPTOR,
EXPRESSION_TYPE_INFO, EXPRESSION_TYPE_INFO,
EXPRESSION_SLICE_INFO, EXPRESSION_SLICE_INFO,
EXPRESSION_INTERFACE_INFO,
EXPRESSION_STRUCT_FIELD_OFFSET, EXPRESSION_STRUCT_FIELD_OFFSET,
EXPRESSION_MAP_DESCRIPTOR, EXPRESSION_MAP_DESCRIPTOR,
EXPRESSION_LABEL_ADDR EXPRESSION_LABEL_ADDR
...@@ -356,6 +357,21 @@ class Expression ...@@ -356,6 +357,21 @@ class Expression
static Expression* static Expression*
make_slice_info(Expression* slice, Slice_info, Location); make_slice_info(Expression* slice, Slice_info, Location);
// Make an expression that evaluates to some characteristic of a
// interface. For simplicity, the enum values must match the field indexes
// of a non-empty interface in the underlying struct.
enum Interface_info
{
// The methods of an interface.
INTERFACE_INFO_METHODS,
// The first argument to pass to an interface method.
INTERFACE_INFO_OBJECT
};
static Expression*
make_interface_info(Expression* iface, Interface_info, Location);
// Make an expression which evaluates to the offset of a field in a // Make an expression which evaluates to the offset of a field in a
// struct. This is only used for type descriptors, so there is no // struct. This is only used for type descriptors, so there is no
// location parameter. // location parameter.
...@@ -1508,10 +1524,9 @@ class Call_expression : public Expression ...@@ -1508,10 +1524,9 @@ class Call_expression : public Expression
bool bool
check_argument_type(int, const Type*, const Type*, Location, bool); check_argument_type(int, const Type*, const Type*, Location, bool);
tree Expression*
interface_method_function(Translate_context*, interface_method_function(Interface_field_reference_expression*,
Interface_field_reference_expression*, Expression**);
tree*);
tree tree
set_results(Translate_context*, tree); set_results(Translate_context*, tree);
...@@ -2115,16 +2130,14 @@ class Interface_field_reference_expression : public Expression ...@@ -2115,16 +2130,14 @@ class Interface_field_reference_expression : public Expression
static Named_object* static Named_object*
create_thunk(Gogo*, Interface_type* type, const std::string& name); create_thunk(Gogo*, Interface_type* type, const std::string& name);
// Return a tree for the pointer to the function to call, given a // Return an expression for the pointer to the function to call.
// tree for the expression. Expression*
tree get_function();
get_function_tree(Translate_context*, tree);
// Return a tree for the first argument to pass to the interface // Return an expression for the first argument to pass to the interface
// function, given a tree for the expression. This is the real // function. This is the real object associated with the interface object.
// object associated with the interface object. Expression*
tree get_underlying_object();
get_underlying_object_tree(Translate_context*, tree);
protected: protected:
int int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment