summaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-19 05:27:19 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-19 05:27:19 +0000
commit9ca8281f597bc7d9f235424b667371280b9a9a18 (patch)
treecb0f3e4c8b179c8a4b73ed69005a7b2e283a36cd /gcc/go/gofrontend
parent2e4c148b20224b76dcec221ae033ce0a0ab38936 (diff)
downloadgcc-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.cc14
-rw-r--r--gcc/go/gofrontend/gogo.cc29
-rw-r--r--gcc/go/gofrontend/gogo.h27
-rw-r--r--gcc/go/gofrontend/types.cc51
-rw-r--r--gcc/go/gofrontend/types.h20
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