From 024d76ae7ed2b7fd2b2b2bfe41926d550bf932e0 Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 18 Sep 2013 21:53:44 +0000 Subject: compiler: Correctly handle identical unnamed structs with methods. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202723 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/go/gofrontend/types.cc | 24 ++++++++++++++++++++++-- gcc/go/gofrontend/types.h | 20 +++++++++++--------- 2 files changed, 33 insertions(+), 11 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 9ce329d5503..0e8f479db70 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -4229,6 +4229,11 @@ Struct_field::is_embedded_builtin(Gogo* gogo) const Struct_type::Identical_structs Struct_type::identical_structs; +// A hash table used to merge method sets for identical unnamed +// structs. + +Struct_type::Struct_method_tables Struct_type::struct_method_tables; + // Traversal. int @@ -4693,9 +4698,24 @@ Struct_type::interface_method_table(Gogo* gogo, const Interface_type* interface, bool is_pointer) { + std::pair + val(this, NULL); + std::pair ins = + Struct_type::struct_method_tables.insert(val); + + Struct_method_table_pair* smtp; + if (!ins.second) + smtp = ins.first->second; + else + { + smtp = new Struct_method_table_pair(); + smtp->first = NULL; + smtp->second = NULL; + ins.first->second = smtp; + } + return Type::interface_method_table(gogo, this, interface, is_pointer, - &this->interface_method_tables_, - &this->pointer_interface_method_tables_); + &smtp->first, &smtp->second); } // Convert struct fields to the backend representation. This is not diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index d207fe5a375..d8a3080f586 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2041,8 +2041,7 @@ class Struct_type : public Type public: Struct_type(Struct_field_list* fields, Location location) : Type(TYPE_STRUCT), - fields_(fields), location_(location), all_methods_(NULL), - interface_method_tables_(NULL), pointer_interface_method_tables_(NULL) + fields_(fields), location_(location), all_methods_(NULL) { } // Return the field NAME. This only looks at local fields, not at @@ -2200,6 +2199,16 @@ class Struct_type : public Type static Identical_structs identical_structs; + // Used to manage method tables for identical unnamed structs. + typedef std::pair + Struct_method_table_pair; + + typedef Unordered_map_hash(Struct_type*, Struct_method_table_pair*, + Type_hash_identical, Type_identical) + Struct_method_tables; + + static Struct_method_tables struct_method_tables; + // Used to avoid infinite loops in field_reference_depth. struct Saw_named_type { @@ -2218,13 +2227,6 @@ class Struct_type : public Type Location location_; // If this struct is unnamed, a list of methods. Methods* all_methods_; - // A mapping from interfaces to the associated interface method - // tables for this type. Only used if this struct is unnamed. - Interface_method_tables* interface_method_tables_; - // A mapping from interfaces to the associated interface method - // tables for pointers to this type. Only used if this struct is - // unnamed. - Interface_method_tables* pointer_interface_method_tables_; }; // The type of an array. -- cgit v1.2.1