diff options
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 29 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 26 |
3 files changed, 50 insertions, 9 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 9ed4e47..f9eccd5 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,7 @@ +2011-04-26 Ian Lance Taylor <iant@google.com> + + * go-gcc.cc (Gcc_backend::struct_type): Implement. + 2011-04-25 Ian Lance Taylor <iant@google.com> * go-gcc.cc (Gcc_backend::error_type): Implement. diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index d250646..7751fb8 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -158,8 +158,7 @@ class Gcc_backend : public Backend source_location); Btype* - struct_type(const std::vector<Btyped_identifier>&) - { gcc_unreachable(); } + struct_type(const std::vector<Btyped_identifier>&); Btype* array_type(const Btype* /* element_type */, const Bexpression* /* length */) @@ -449,6 +448,32 @@ Gcc_backend::function_type(const Btyped_identifier& receiver, return this->make_type(build_pointer_type(fntype)); } +// Make a struct type. + +Btype* +Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields) +{ + tree ret = make_node(RECORD_TYPE); + tree field_trees = NULL_TREE; + tree* pp = &field_trees; + for (std::vector<Btyped_identifier>::const_iterator p = fields.begin(); + p != fields.end(); + ++p) + { + tree name_tree = get_identifier_from_string(p->name); + tree type_tree = p->btype->get_tree(); + if (type_tree == error_mark_node) + return this->error_type(); + tree field = build_decl(p->location, FIELD_DECL, name_tree, type_tree); + DECL_CONTEXT(field) = ret; + *pp = field; + pp = &DECL_CHAIN(field); + } + TYPE_FIELDS(ret) = field_trees; + layout_type(ret); + return this->make_type(ret); +} + // An expression as a statement. Bstatement* diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 6c344cef..09f80c0 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -2593,7 +2593,7 @@ Function_type::do_get_tree(Gogo* gogo) Backend::Btyped_identifier breceiver; if (this->receiver_ != NULL) { - breceiver.name = this->receiver_->name(); + breceiver.name = Gogo::unpack_hidden_name(this->receiver_->name()); // We always pass the address of the receiver parameter, in // order to make interface calls work with unknown types. @@ -2613,11 +2613,11 @@ Function_type::do_get_tree(Gogo* gogo) p != this->parameters_->end(); ++p, ++i) { - bparameters[i].name = p->name(); + bparameters[i].name = Gogo::unpack_hidden_name(p->name()); bparameters[i].btype = tree_to_type(p->type()->get_tree(gogo)); bparameters[i].location = p->location(); } - gcc_assert(i == bparameters.size()); + go_assert(i == bparameters.size()); } std::vector<Backend::Btyped_identifier> bresults; @@ -2629,11 +2629,11 @@ Function_type::do_get_tree(Gogo* gogo) p != this->results_->end(); ++p, ++i) { - bresults[i].name = p->name(); + bresults[i].name = Gogo::unpack_hidden_name(p->name()); bresults[i].btype = tree_to_type(p->type()->get_tree(gogo)); bresults[i].location = p->location(); } - gcc_assert(i == bresults.size()); + go_assert(i == bresults.size()); } Btype* fntype = gogo->backend()->function_type(breceiver, bparameters, @@ -3753,8 +3753,20 @@ Struct_type::method_function(const std::string& name, bool* is_ambiguous) const tree Struct_type::do_get_tree(Gogo* gogo) { - tree type = make_node(RECORD_TYPE); - return this->fill_in_tree(gogo, type); + std::vector<Backend::Btyped_identifier> fields; + fields.resize(this->fields_->size()); + size_t i = 0; + for (Struct_field_list::const_iterator p = this->fields_->begin(); + p != this->fields_->end(); + ++p, ++i) + { + fields[i].name = Gogo::unpack_hidden_name(p->field_name()); + fields[i].btype = tree_to_type(p->type()->get_tree(gogo)); + fields[i].location = p->location(); + } + go_assert(i == this->fields_->size()); + Btype* btype = gogo->backend()->struct_type(fields); + return type_to_tree(btype); } // Fill in the fields for a struct type. |