diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-19 05:27:19 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-19 05:27:19 +0000 |
commit | 9ca8281f597bc7d9f235424b667371280b9a9a18 (patch) | |
tree | cb0f3e4c8b179c8a4b73ed69005a7b2e283a36cd /gcc/go/gofrontend | |
parent | 2e4c148b20224b76dcec221ae033ce0a0ab38936 (diff) | |
download | gcc-9ca8281f597bc7d9f235424b667371280b9a9a18.tar.gz |
compiler: Fix multiple types with same name in function.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191461 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go/gofrontend')
-rw-r--r-- | gcc/go/gofrontend/gogo-tree.cc | 14 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 29 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 27 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 51 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 20 |
5 files changed, 115 insertions, 26 deletions
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index 9a181a344ad..b1313ab8979 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -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); } diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index a434c4df6bb..06f0369b2eb 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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; diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index deb9968e84f..efd31f1d727 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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 diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index c52f41b76ec..d527787ca5a 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -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())); diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index a542bf71738..7b879240e3a 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -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 |