compiler: Fix multiple types with same name in function.
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 19 Sep 2012 05:27:19 +0000 (05:27 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 19 Sep 2012 05:27:19 +0000 (05:27 +0000)
From-SVN: r191461

gcc/go/gofrontend/gogo-tree.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h

index 9a181a3..b1313ab 100644 (file)
@@ -994,9 +994,19 @@ Named_object::get_id(Gogo* gogo)
     }
   if (this->is_type())
     {
-      const Named_object* in_function = this->type_value()->in_function();
+      unsigned int index;
+      const Named_object* in_function = this->type_value()->in_function(&index);
       if (in_function != NULL)
-       decl_name += '$' + Gogo::unpack_hidden_name(in_function->name());
+       {
+         decl_name += '$' + Gogo::unpack_hidden_name(in_function->name());
+         if (index > 0)
+           {
+             char buf[30];
+             snprintf(buf, sizeof buf, "%u", index);
+             decl_name += '$';
+             decl_name += buf;
+           }
+       }
     }
   return get_identifier_from_string(decl_name);
 }
index a434c4d..06f0369 100644 (file)
@@ -1056,7 +1056,15 @@ Gogo::add_type(const std::string& name, Type* type, Location location)
   Named_object* no = this->current_bindings()->add_type(name, NULL, type,
                                                        location);
   if (!this->in_global_scope() && no->is_type())
-    no->type_value()->set_in_function(this->functions_.back().function);
+    {
+      Named_object* f = this->functions_.back().function;
+      unsigned int index;
+      if (f->is_function())
+       index = f->func_value()->new_local_type_index();
+      else
+       index = 0;
+      no->type_value()->set_in_function(f, index);
+    }
 }
 
 // Add a named type.
@@ -1078,7 +1086,12 @@ Gogo::declare_type(const std::string& name, Location location)
   if (!this->in_global_scope() && no->is_type_declaration())
     {
       Named_object* f = this->functions_.back().function;
-      no->type_declaration_value()->set_in_function(f);
+      unsigned int index;
+      if (f->is_function())
+       index = f->func_value()->new_local_type_index();
+      else
+       index = 0;
+      no->type_declaration_value()->set_in_function(f, index);
     }
   return no;
 }
@@ -3042,9 +3055,10 @@ Gogo::convert_named_types_in_bindings(Bindings* bindings)
 Function::Function(Function_type* type, Function* enclosing, Block* block,
                   Location location)
   : type_(type), enclosing_(enclosing), results_(NULL),
-    closure_var_(NULL), block_(block), location_(location), fndecl_(NULL),
-    defer_stack_(NULL), results_are_named_(false), calls_recover_(false),
-    is_recover_thunk_(false), has_recover_thunk_(false)
+    closure_var_(NULL), block_(block), location_(location), labels_(),
+    local_type_count_(0), fndecl_(NULL), defer_stack_(NULL),
+    results_are_named_(false), calls_recover_(false), is_recover_thunk_(false),
+    has_recover_thunk_(false)
 {
 }
 
@@ -4652,9 +4666,10 @@ Named_object::set_type_value(Named_type* named_type)
   go_assert(this->classification_ == NAMED_OBJECT_TYPE_DECLARATION);
   Type_declaration* td = this->u_.type_declaration;
   td->define_methods(named_type);
-  Named_object* in_function = td->in_function();
+  unsigned int index;
+  Named_object* in_function = td->in_function(&index);
   if (in_function != NULL)
-    named_type->set_in_function(in_function);
+    named_type->set_in_function(in_function, index);
   delete td;
   this->classification_ = NAMED_OBJECT_TYPE;
   this->u_.type_value = named_type;
index deb9968..efd31f1 100644 (file)
@@ -963,6 +963,11 @@ class Function
   void
   check_labels() const;
 
+  // Note that a new local type has been added.  Return its index.
+  unsigned int
+  new_local_type_index()
+  { return this->local_type_count_++; }
+
   // Whether this function calls the predeclared recover function.
   bool
   calls_recover() const
@@ -1084,6 +1089,8 @@ class Function
   Location location_;
   // Labels defined or referenced in the function.
   Labels labels_;
+  // The number of local types defined in this function.
+  unsigned int local_type_count_;
   // The function decl.
   tree fndecl_;
   // The defer stack variable.  A pointer to this variable is used to
@@ -1638,8 +1645,8 @@ class Type_declaration
 {
  public:
   Type_declaration(Location location)
-    : location_(location), in_function_(NULL), methods_(),
-      issued_warning_(false)
+    : location_(location), in_function_(NULL), in_function_index_(0),
+      methods_(), issued_warning_(false)
   { }
 
   // Return the location.
@@ -1650,13 +1657,19 @@ class Type_declaration
   // Return the function in which this type is declared.  This will
   // return NULL for a type declared in global scope.
   Named_object*
-  in_function()
-  { return this->in_function_; }
+  in_function(unsigned int* pindex)
+  {
+    *pindex = this->in_function_index_;
+    return this->in_function_;
+  }
 
   // Set the function in which this type is declared.
   void
-  set_in_function(Named_object* f)
-  { this->in_function_ = f; }
+  set_in_function(Named_object* f, unsigned int index)
+  {
+    this->in_function_ = f;
+    this->in_function_index_ = index;
+  }
 
   // Add a method to this type.  This is used when methods are defined
   // before the type.
@@ -1689,6 +1702,8 @@ class Type_declaration
   // If this type is declared in a function, a pointer back to the
   // function in which it is defined.
   Named_object* in_function_;
+  // The index of this type in IN_FUNCTION_.
+  unsigned int in_function_index_;
   // Methods defined before the type is defined.
   Methods methods_;
   // True if we have issued a warning about a use of this type
index c52f41b..d527787 100644 (file)
@@ -1286,7 +1286,8 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt)
     return "__go_td_" + this->mangled_name(gogo);
 
   Named_object* no = nt->named_object();
-  const Named_object* in_function = nt->in_function();
+  unsigned int index;
+  const Named_object* in_function = nt->in_function(&index);
   std::string ret = "__go_tdn_";
   if (nt->is_builtin())
     go_assert(in_function == NULL);
@@ -1301,6 +1302,13 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt)
        {
          ret.append(Gogo::unpack_hidden_name(in_function->name()));
          ret.append(1, '.');
+         if (index > 0)
+           {
+             char buf[30];
+             snprintf(buf, sizeof buf, "%u", index);
+             ret.append(buf);
+             ret.append(1, '.');
+           }
        }
     }
 
@@ -1737,9 +1745,19 @@ Type::specific_type_functions(Gogo* gogo, Named_type* name,
     {
       // This name is already hidden or not as appropriate.
       base_name = name->name();
-      const Named_object* in_function = name->in_function();
+      unsigned int index;
+      const Named_object* in_function = name->in_function(&index);
       if (in_function != NULL)
-       base_name += '$' + Gogo::unpack_hidden_name(in_function->name());
+       {
+         base_name += '$' + Gogo::unpack_hidden_name(in_function->name());
+         if (index > 0)
+           {
+             char buf[30];
+             snprintf(buf, sizeof buf, "%u", index);
+             base_name += '$';
+             base_name += buf;
+           }
+       }
     }
   std::string hash_name = base_name + "$hash";
   std::string equal_name = base_name + "$equal";
@@ -1980,10 +1998,19 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
                                     ? gogo->pkgpath()
                                     : package->pkgpath());
          n.assign(pkgpath);
-         if (name->in_function() != NULL)
+         unsigned int index;
+         const Named_object* in_function = name->in_function(&index);
+         if (in_function != NULL)
            {
              n.append(1, '.');
-             n.append(Gogo::unpack_hidden_name(name->in_function()->name()));
+             n.append(Gogo::unpack_hidden_name(in_function->name()));
+             if (index > 0)
+               {
+                 char buf[30];
+                 snprintf(buf, sizeof buf, "%u", index);
+                 n.append(1, '.');
+                 n.append(buf);
+               }
            }
          s = Expression::make_string(n, bloc);
          vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
@@ -8351,6 +8378,13 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const
     {
       ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
       ret->push_back('$');
+      if (this->in_function_index_ > 0)
+       {
+         char buf[30];
+         snprintf(buf, sizeof buf, "%u", this->in_function_index_);
+         ret->append(buf);
+         ret->push_back('$');
+       }
     }
   ret->append(Gogo::unpack_hidden_name(this->named_object_->name()));
 }
@@ -8380,6 +8414,13 @@ Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
        {
          name.append(Gogo::unpack_hidden_name(this->in_function_->name()));
          name.append(1, '$');
+         if (this->in_function_index_ > 0)
+           {
+             char buf[30];
+             snprintf(buf, sizeof buf, "%u", this->in_function_index_);
+             name.append(buf);
+             name.append(1, '$');
+           }
        }
     }
   name.append(Gogo::unpack_hidden_name(no->name()));
index a542bf7..7b87924 100644 (file)
@@ -2623,8 +2623,8 @@ class Named_type : public Type
  public:
   Named_type(Named_object* named_object, Type* type, Location location)
     : Type(TYPE_NAMED),
-      named_object_(named_object), in_function_(NULL), type_(type),
-      local_methods_(NULL), all_methods_(NULL),
+      named_object_(named_object), in_function_(NULL), in_function_index_(0),
+      type_(type), local_methods_(NULL), all_methods_(NULL),
       interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
       location_(location), named_btype_(NULL), dependencies_(),
       is_visible_(true), is_error_(false), is_placeholder_(false),
@@ -2651,13 +2651,19 @@ class Named_type : public Type
   // Return the function in which this type is defined.  This will
   // return NULL for a type defined in global scope.
   const Named_object*
-  in_function() const
-  { return this->in_function_; }
+  in_function(unsigned int *pindex) const
+  {
+    *pindex = this->in_function_index_;
+    return this->in_function_;
+  }
 
   // Set the function in which this type is defined.
   void
-  set_in_function(Named_object* f)
-  { this->in_function_ = f; }
+  set_in_function(Named_object* f, unsigned int index)
+  {
+    this->in_function_ = f;
+    this->in_function_index_ = index;
+  }
 
   // Return the name of the type.
   const std::string&
@@ -2865,6 +2871,8 @@ class Named_type : public Type
   // If this type is defined in a function, a pointer back to the
   // function in which it is defined.
   Named_object* in_function_;
+  // The index of this type in IN_FUNCTION_.
+  unsigned int in_function_index_;
   // The actual type.
   Type* type_;
   // The list of methods defined for this type.  Any named type can