compiler: Use backend interface for struct field expressions.
* go-gcc.cc (Gcc_backend::struct_field_expression): New function. From-SVN: r206029
This commit is contained in:
parent
74f769b5e0
commit
71eba7a0c6
4 changed files with 50 additions and 22 deletions
|
@ -1,3 +1,7 @@
|
|||
2013-12-16 Chris Manghane <cmang@google.com>
|
||||
|
||||
* go-gcc.cc (Gcc_backend::struct_field_expression): New function.
|
||||
|
||||
2013-12-11 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* go-lang.c (go_langhook_post_options): Disable sibling calls by
|
||||
|
|
|
@ -243,6 +243,9 @@ class Gcc_backend : public Backend
|
|||
Bexpression*
|
||||
address_expression(Bexpression*, Location);
|
||||
|
||||
Bexpression*
|
||||
struct_field_expression(Bexpression*, size_t, Location);
|
||||
|
||||
// Statements.
|
||||
|
||||
Bstatement*
|
||||
|
@ -998,6 +1001,39 @@ Gcc_backend::address_expression(Bexpression* bexpr, Location location)
|
|||
return this->make_expression(ret);
|
||||
}
|
||||
|
||||
// Return an expression for the field at INDEX in BSTRUCT.
|
||||
|
||||
Bexpression*
|
||||
Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index,
|
||||
Location location)
|
||||
{
|
||||
tree struct_tree = bstruct->get_tree();
|
||||
if (struct_tree == error_mark_node
|
||||
|| TREE_TYPE(struct_tree) == error_mark_node)
|
||||
return this->error_expression();
|
||||
gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
|
||||
tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
|
||||
if (field == NULL_TREE)
|
||||
{
|
||||
// This can happen for a type which refers to itself indirectly
|
||||
// and then turns out to be erroneous.
|
||||
return this->error_expression();
|
||||
}
|
||||
for (unsigned int i = index; i > 0; --i)
|
||||
{
|
||||
field = DECL_CHAIN(field);
|
||||
gcc_assert(field != NULL_TREE);
|
||||
}
|
||||
if (TREE_TYPE(field) == error_mark_node)
|
||||
return this->error_expression();
|
||||
tree ret = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
|
||||
TREE_TYPE(field), struct_tree, field,
|
||||
NULL_TREE);
|
||||
if (TREE_CONSTANT(struct_tree))
|
||||
TREE_CONSTANT(ret) = 1;
|
||||
return tree_to_expr(ret);
|
||||
}
|
||||
|
||||
// An expression as a statement.
|
||||
|
||||
Bstatement*
|
||||
|
|
|
@ -280,6 +280,10 @@ class Backend
|
|||
virtual Bexpression*
|
||||
address_expression(Bexpression*, Location) = 0;
|
||||
|
||||
// Return an expression for the field at INDEX in BSTRUCT.
|
||||
virtual Bexpression*
|
||||
struct_field_expression(Bexpression* bstruct, size_t index, Location) = 0;
|
||||
|
||||
// Statements.
|
||||
|
||||
// Create an error statement. This is used for cases which should
|
||||
|
|
|
@ -11539,28 +11539,12 @@ Field_reference_expression::do_check_types(Gogo*)
|
|||
tree
|
||||
Field_reference_expression::do_get_tree(Translate_context* context)
|
||||
{
|
||||
tree struct_tree = this->expr_->get_tree(context);
|
||||
if (struct_tree == error_mark_node
|
||||
|| TREE_TYPE(struct_tree) == error_mark_node)
|
||||
return error_mark_node;
|
||||
go_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
|
||||
tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
|
||||
if (field == NULL_TREE)
|
||||
{
|
||||
// This can happen for a type which refers to itself indirectly
|
||||
// and then turns out to be erroneous.
|
||||
go_assert(saw_errors());
|
||||
return error_mark_node;
|
||||
}
|
||||
for (unsigned int i = this->field_index_; i > 0; --i)
|
||||
{
|
||||
field = DECL_CHAIN(field);
|
||||
go_assert(field != NULL_TREE);
|
||||
}
|
||||
if (TREE_TYPE(field) == error_mark_node)
|
||||
return error_mark_node;
|
||||
return build3(COMPONENT_REF, TREE_TYPE(field), struct_tree, field,
|
||||
NULL_TREE);
|
||||
Bexpression* bstruct = tree_to_expr(this->expr_->get_tree(context));
|
||||
Bexpression* ret =
|
||||
context->gogo()->backend()->struct_field_expression(bstruct,
|
||||
this->field_index_,
|
||||
this->location());
|
||||
return expr_to_tree(ret);
|
||||
}
|
||||
|
||||
// Dump ast representation for a field reference expression.
|
||||
|
|
Loading…
Add table
Reference in a new issue