Commit 878b569c by Ian Lance Taylor

compiler: Fix multiple types with same name in function.

From-SVN: r191461
parent 06e28db0
...@@ -994,9 +994,19 @@ Named_object::get_id(Gogo* gogo) ...@@ -994,9 +994,19 @@ Named_object::get_id(Gogo* gogo)
} }
if (this->is_type()) 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) 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); return get_identifier_from_string(decl_name);
} }
......
...@@ -1056,7 +1056,15 @@ Gogo::add_type(const std::string& name, Type* type, Location location) ...@@ -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, Named_object* no = this->current_bindings()->add_type(name, NULL, type,
location); location);
if (!this->in_global_scope() && no->is_type()) 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. // Add a named type.
...@@ -1078,7 +1086,12 @@ Gogo::declare_type(const std::string& name, Location location) ...@@ -1078,7 +1086,12 @@ Gogo::declare_type(const std::string& name, Location location)
if (!this->in_global_scope() && no->is_type_declaration()) if (!this->in_global_scope() && no->is_type_declaration())
{ {
Named_object* f = this->functions_.back().function; 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; return no;
} }
...@@ -3042,9 +3055,10 @@ Gogo::convert_named_types_in_bindings(Bindings* bindings) ...@@ -3042,9 +3055,10 @@ Gogo::convert_named_types_in_bindings(Bindings* bindings)
Function::Function(Function_type* type, Function* enclosing, Block* block, Function::Function(Function_type* type, Function* enclosing, Block* block,
Location location) Location location)
: type_(type), enclosing_(enclosing), results_(NULL), : type_(type), enclosing_(enclosing), results_(NULL),
closure_var_(NULL), block_(block), location_(location), fndecl_(NULL), closure_var_(NULL), block_(block), location_(location), labels_(),
defer_stack_(NULL), results_are_named_(false), calls_recover_(false), local_type_count_(0), fndecl_(NULL), defer_stack_(NULL),
is_recover_thunk_(false), has_recover_thunk_(false) 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) ...@@ -4652,9 +4666,10 @@ Named_object::set_type_value(Named_type* named_type)
go_assert(this->classification_ == NAMED_OBJECT_TYPE_DECLARATION); go_assert(this->classification_ == NAMED_OBJECT_TYPE_DECLARATION);
Type_declaration* td = this->u_.type_declaration; Type_declaration* td = this->u_.type_declaration;
td->define_methods(named_type); 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) if (in_function != NULL)
named_type->set_in_function(in_function); named_type->set_in_function(in_function, index);
delete td; delete td;
this->classification_ = NAMED_OBJECT_TYPE; this->classification_ = NAMED_OBJECT_TYPE;
this->u_.type_value = named_type; this->u_.type_value = named_type;
......
...@@ -963,6 +963,11 @@ class Function ...@@ -963,6 +963,11 @@ class Function
void void
check_labels() const; 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. // Whether this function calls the predeclared recover function.
bool bool
calls_recover() const calls_recover() const
...@@ -1084,6 +1089,8 @@ class Function ...@@ -1084,6 +1089,8 @@ class Function
Location location_; Location location_;
// Labels defined or referenced in the function. // Labels defined or referenced in the function.
Labels labels_; Labels labels_;
// The number of local types defined in this function.
unsigned int local_type_count_;
// The function decl. // The function decl.
tree fndecl_; tree fndecl_;
// The defer stack variable. A pointer to this variable is used to // The defer stack variable. A pointer to this variable is used to
...@@ -1638,8 +1645,8 @@ class Type_declaration ...@@ -1638,8 +1645,8 @@ class Type_declaration
{ {
public: public:
Type_declaration(Location location) Type_declaration(Location location)
: location_(location), in_function_(NULL), methods_(), : location_(location), in_function_(NULL), in_function_index_(0),
issued_warning_(false) methods_(), issued_warning_(false)
{ } { }
// Return the location. // Return the location.
...@@ -1650,13 +1657,19 @@ class Type_declaration ...@@ -1650,13 +1657,19 @@ class Type_declaration
// Return the function in which this type is declared. This will // Return the function in which this type is declared. This will
// return NULL for a type declared in global scope. // return NULL for a type declared in global scope.
Named_object* Named_object*
in_function() in_function(unsigned int* pindex)
{ return this->in_function_; } {
*pindex = this->in_function_index_;
return this->in_function_;
}
// Set the function in which this type is declared. // Set the function in which this type is declared.
void void
set_in_function(Named_object* f) set_in_function(Named_object* f, unsigned int index)
{ this->in_function_ = f; } {
this->in_function_ = f;
this->in_function_index_ = index;
}
// Add a method to this type. This is used when methods are defined // Add a method to this type. This is used when methods are defined
// before the type. // before the type.
...@@ -1689,6 +1702,8 @@ class Type_declaration ...@@ -1689,6 +1702,8 @@ class Type_declaration
// If this type is declared in a function, a pointer back to the // If this type is declared in a function, a pointer back to the
// function in which it is defined. // function in which it is defined.
Named_object* in_function_; 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 defined before the type is defined.
Methods methods_; Methods methods_;
// True if we have issued a warning about a use of this type // True if we have issued a warning about a use of this type
......
...@@ -1286,7 +1286,8 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt) ...@@ -1286,7 +1286,8 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt)
return "__go_td_" + this->mangled_name(gogo); return "__go_td_" + this->mangled_name(gogo);
Named_object* no = nt->named_object(); 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_"; std::string ret = "__go_tdn_";
if (nt->is_builtin()) if (nt->is_builtin())
go_assert(in_function == NULL); go_assert(in_function == NULL);
...@@ -1301,6 +1302,13 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt) ...@@ -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(Gogo::unpack_hidden_name(in_function->name()));
ret.append(1, '.'); 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, ...@@ -1737,9 +1745,19 @@ Type::specific_type_functions(Gogo* gogo, Named_type* name,
{ {
// This name is already hidden or not as appropriate. // This name is already hidden or not as appropriate.
base_name = name->name(); 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) 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 hash_name = base_name + "$hash";
std::string equal_name = base_name + "$equal"; std::string equal_name = base_name + "$equal";
...@@ -1980,10 +1998,19 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type, ...@@ -1980,10 +1998,19 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
? gogo->pkgpath() ? gogo->pkgpath()
: package->pkgpath()); : package->pkgpath());
n.assign(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(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); s = Expression::make_string(n, bloc);
vals->push_back(Expression::make_unary(OPERATOR_AND, s, 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 ...@@ -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->append(Gogo::unpack_hidden_name(this->in_function_->name()));
ret->push_back('$'); 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())); 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 ...@@ -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(Gogo::unpack_hidden_name(this->in_function_->name()));
name.append(1, '$'); 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())); name.append(Gogo::unpack_hidden_name(no->name()));
......
...@@ -2623,8 +2623,8 @@ class Named_type : public Type ...@@ -2623,8 +2623,8 @@ class Named_type : public Type
public: public:
Named_type(Named_object* named_object, Type* type, Location location) Named_type(Named_object* named_object, Type* type, Location location)
: Type(TYPE_NAMED), : Type(TYPE_NAMED),
named_object_(named_object), in_function_(NULL), type_(type), named_object_(named_object), in_function_(NULL), in_function_index_(0),
local_methods_(NULL), all_methods_(NULL), type_(type), local_methods_(NULL), all_methods_(NULL),
interface_method_tables_(NULL), pointer_interface_method_tables_(NULL), interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
location_(location), named_btype_(NULL), dependencies_(), location_(location), named_btype_(NULL), dependencies_(),
is_visible_(true), is_error_(false), is_placeholder_(false), is_visible_(true), is_error_(false), is_placeholder_(false),
...@@ -2651,13 +2651,19 @@ class Named_type : public Type ...@@ -2651,13 +2651,19 @@ class Named_type : public Type
// Return the function in which this type is defined. This will // Return the function in which this type is defined. This will
// return NULL for a type defined in global scope. // return NULL for a type defined in global scope.
const Named_object* const Named_object*
in_function() const in_function(unsigned int *pindex) const
{ return this->in_function_; } {
*pindex = this->in_function_index_;
return this->in_function_;
}
// Set the function in which this type is defined. // Set the function in which this type is defined.
void void
set_in_function(Named_object* f) set_in_function(Named_object* f, unsigned int index)
{ this->in_function_ = f; } {
this->in_function_ = f;
this->in_function_index_ = index;
}
// Return the name of the type. // Return the name of the type.
const std::string& const std::string&
...@@ -2865,6 +2871,8 @@ class Named_type : public Type ...@@ -2865,6 +2871,8 @@ class Named_type : public Type
// If this type is defined in a function, a pointer back to the // If this type is defined in a function, a pointer back to the
// function in which it is defined. // function in which it is defined.
Named_object* in_function_; Named_object* in_function_;
// The index of this type in IN_FUNCTION_.
unsigned int in_function_index_;
// The actual type. // The actual type.
Type* type_; Type* type_;
// The list of methods defined for this type. Any named type can // The list of methods defined for this type. Any named type can
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment