compiler: refactoring in Export class to encapsulate type refs map

Convert the Export::type_refs map from a static object to a field
contained (indirectly, via an impl class) in Export itself, for better
encapsulation and to be able to reclaim its memory when exporting is
done. No change in compiler functionality.

Change-Id: I2cd2647aee8dc704053f165b5508011f86479f60
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/184170
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/go/export.cc b/go/export.cc
index a48ca07..a1bd8cc 100644
--- a/go/export.cc
+++ b/go/export.cc
@@ -41,14 +41,6 @@
 
 const int Export::checksum_len;
 
-// Constructor.
-
-Export::Export(Stream* stream)
-  : stream_(stream), type_index_(1), packages_()
-{
-  go_assert(Export::checksum_len == Go_sha1_helper::checksum_len);
-}
-
 // Type hash table operations, treating aliases as distinct.
 
 class Type_hash_alias_identical
@@ -80,14 +72,31 @@
   }
 };
 
-// Mapping from Type objects to a constant index.  This would be nicer
-// as a field in Export, but then export.h would have to #include
-// types.h.
-
+// Mapping from Type objects to a constant index.
 typedef Unordered_map_hash(const Type*, int, Type_hash_alias_identical,
-			   Type_alias_identical) Type_refs;
+                           Type_alias_identical) Type_refs;
 
-static Type_refs type_refs;
+// Implementation object for class Export.  Hidden implementation avoids
+// having to #include types.h in export.h, or use a static map.
+
+struct Export_impl {
+  Type_refs type_refs;
+};
+
+// Constructor.
+
+Export::Export(Stream* stream)
+    : stream_(stream), type_index_(1), packages_(), impl_(new Export_impl)
+{
+  go_assert(Export::checksum_len == Go_sha1_helper::checksum_len);
+}
+
+// Destructor.
+
+Export::~Export()
+{
+  delete this->impl_;
+}
 
 // A traversal class to collect functions and global variables
 // referenced by inlined functions.
@@ -635,7 +644,7 @@
   type = type->forwarded();
 
   std::pair<Type_refs::iterator, bool> ins =
-    type_refs.insert(std::make_pair(type, 0));
+    this->impl_->type_refs.insert(std::make_pair(type, 0));
   if (!ins.second)
     {
       // We've already seen this type.
@@ -1011,8 +1020,8 @@
 {
   // Map from type index to type.
   std::vector<const Type*> types(static_cast<size_t>(this->type_index_));
-  for (Type_refs::const_iterator p = type_refs.begin();
-       p != type_refs.end();
+  for (Type_refs::const_iterator p = this->impl_->type_refs.begin();
+       p != this->impl_->type_refs.end();
        ++p)
     {
       if (p->second >= 0)
@@ -1152,8 +1161,8 @@
 Export::type_index(const Type* type)
 {
   type = type->forwarded();
-  Type_refs::const_iterator p = type_refs.find(type);
-  go_assert(p != type_refs.end());
+  Type_refs::const_iterator p = this->impl_->type_refs.find(type);
+  go_assert(p != this->impl_->type_refs.end());
   int index = p->second;
   go_assert(index != 0);
   return index;
@@ -1231,7 +1240,7 @@
   Named_object* named_object = gogo->lookup_global(name);
   go_assert(named_object != NULL && named_object->is_type());
   std::pair<Type_refs::iterator, bool> ins =
-    type_refs.insert(std::make_pair(named_object->type_value(), code));
+    this->impl_->type_refs.insert(std::make_pair(named_object->type_value(), code));
   go_assert(ins.second);
 
   // We also insert the underlying type.  We can see the underlying
@@ -1239,7 +1248,7 @@
   // fails--we expect duplications here, and it doesn't matter when
   // they occur.
   Type* real_type = named_object->type_value()->real_type();
-  type_refs.insert(std::make_pair(real_type, code));
+  this->impl_->type_refs.insert(std::make_pair(real_type, code));
 }
 
 // Class Export::Stream.
diff --git a/go/export.h b/go/export.h
index 910b1db..74bdd94 100644
--- a/go/export.h
+++ b/go/export.h
@@ -22,6 +22,7 @@
 class Backend;
 class Temporary_statement;
 class Unnamed_label;
+struct Export_impl;
 
 // Codes used for the builtin types.  These are all negative to make
 // them easily distinct from the codes assigned by Export::write_type.
@@ -121,6 +122,7 @@
   };
 
   Export(Stream*);
+  ~Export();
 
   // Size of export data magic string (which includes version number).
   static const int magic_len = 4;
@@ -262,6 +264,8 @@
   int type_index_;
   // Packages we have written out.
   Unordered_map(const Package*, int) packages_;
+  // Hidden implementation-specific state.
+  Export_impl* impl_;
 };
 
 // An export streamer that puts the export stream in a named section.