From 260f587c3a51252440b07eeaa4794bcb98332c72 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 1 Feb 2013 00:23:22 +0000 Subject: [PATCH] compiler: Don't emit multiple methods for identical unnamed structs. From-SVN: r195638 --- gcc/go/gofrontend/types.cc | 20 ++++++++++++++++++++ gcc/go/gofrontend/types.h | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index c0aeb91..7694982 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 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 ba918c9..3922a63 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 { -- 2.7.4