From 71eba7a0c684782ccf5d4befa394639f607a2717 Mon Sep 17 00:00:00 2001 From: Chris Manghane Date: Mon, 16 Dec 2013 19:58:50 +0000 Subject: compiler: Use backend interface for struct field expressions. * go-gcc.cc (Gcc_backend::struct_field_expression): New function. From-SVN: r206029 --- gcc/go/ChangeLog | 4 ++++ gcc/go/go-gcc.cc | 36 ++++++++++++++++++++++++++++++++++++ gcc/go/gofrontend/backend.h | 4 ++++ gcc/go/gofrontend/expressions.cc | 28 ++++++---------------------- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index db0212c..f6e6599 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,7 @@ +2013-12-16 Chris Manghane + + * go-gcc.cc (Gcc_backend::struct_field_expression): New function. + 2013-12-11 Ian Lance Taylor * go-lang.c (go_langhook_post_options): Disable sibling calls by diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 939be20..db8fd5e 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -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* diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h index 8344da4..5580594 100644 --- a/gcc/go/gofrontend/backend.h +++ b/gcc/go/gofrontend/backend.h @@ -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 diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 35bcdbb..81d18ca 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -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. -- cgit v1.1