summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-18 21:53:44 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-18 21:53:44 +0000
commit024d76ae7ed2b7fd2b2b2bfe41926d550bf932e0 (patch)
tree7d70c1bcdccfab6efcf01ddcba289deec3251b38 /gcc
parent9bb02a7e317598da9183c861725fb1077ea95d6d (diff)
downloadgcc-024d76ae7ed2b7fd2b2b2bfe41926d550bf932e0.tar.gz
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/types.cc24
-rw-r--r--gcc/go/gofrontend/types.h20
2 files changed, 33 insertions, 11 deletions
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<Struct_type*, Struct_type::Struct_method_table_pair*>
+ val(this, NULL);
+ std::pair<Struct_type::Struct_method_tables::iterator, bool> 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<Interface_method_tables*, Interface_method_tables*>
+ 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.