aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2013-02-01 00:23:22 +0000
committerIan Lance Taylor <iant@google.com>2013-02-01 00:23:22 +0000
commit08b124e5350a1c46f9e81815cbac65ea13c54916 (patch)
treebdb7b11102b400b214f9255ea3a43456dc0c1373 /gcc/go
parent5b3810b8b62a5a96b912e45acde4a07717d62c4b (diff)
compiler: Don't emit multiple methods for identical unnamed structs.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@195638 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/types.cc20
-rw-r--r--gcc/go/gofrontend/types.h6
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index c0aeb91acff..76949828229 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -4170,6 +4170,11 @@ Struct_field::is_field_name(const std::string& name) const
// Class Struct_type.
+// A hash table used to find identical unnamed structs so that they
+// share method tables.
+
+Struct_type::Identical_structs Struct_type::identical_structs;
+
// Traversal.
int
@@ -4596,6 +4601,21 @@ Struct_type::finalize_methods(Gogo* gogo)
{
if (this->all_methods_ != NULL)
return;
+
+ // It is possible to have multiple identical structs that have
+ // methods. We want them to share method tables. Otherwise we will
+ // emit identical methods more than once, which is bad since they
+ // will even have the same names.
+ std::pair<Identical_structs::iterator, bool> ins =
+ Struct_type::identical_structs.insert(std::make_pair(this, this));
+ if (!ins.second)
+ {
+ // An identical struct was already entered into the hash table.
+ // Note that finalize_methods is, fortunately, not recursive.
+ this->all_methods_ = ins.first->second->all_methods_;
+ return;
+ }
+
Type::finalize_methods(gogo, this, this->location_, &this->all_methods_);
}
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index ba918c96023..3922a634f59 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -2184,6 +2184,12 @@ class Struct_type : public Type
do_export(Export*) const;
private:
+ // Used to merge method sets of identical unnamed structs.
+ typedef Unordered_map_hash(Struct_type*, Struct_type*, Type_hash_identical,
+ Type_identical) Identical_structs;
+
+ static Identical_structs identical_structs;
+
// Used to avoid infinite loops in field_reference_depth.
struct Saw_named_type
{