diff options
author | Chris Manghane <cmang@google.com> | 2013-12-16 19:58:50 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-12-16 19:58:50 +0000 |
commit | 71eba7a0c684782ccf5d4befa394639f607a2717 (patch) | |
tree | d9380cfc26a9af9a9f0f214d08c54d1da389bb26 /gcc/go/go-gcc.cc | |
parent | 74f769b5e02d3d1bfed29c4b74f3c4be17ce30d1 (diff) | |
download | gcc-71eba7a0c684782ccf5d4befa394639f607a2717.zip gcc-71eba7a0c684782ccf5d4befa394639f607a2717.tar.gz gcc-71eba7a0c684782ccf5d4befa394639f607a2717.tar.bz2 |
compiler: Use backend interface for struct field expressions.
* go-gcc.cc (Gcc_backend::struct_field_expression): New function.
From-SVN: r206029
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r-- | gcc/go/go-gcc.cc | 36 |
1 files changed, 36 insertions, 0 deletions
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* |