Commit acbe08d2 by Ian Lance Taylor

compiler: Don't insert promoted methods that conflict with fields.

From-SVN: r215856
parent c6d129b0
...@@ -9387,9 +9387,14 @@ void ...@@ -9387,9 +9387,14 @@ void
Type::finalize_methods(Gogo* gogo, const Type* type, Location location, Type::finalize_methods(Gogo* gogo, const Type* type, Location location,
Methods** all_methods) Methods** all_methods)
{ {
*all_methods = NULL; *all_methods = new Methods();
std::vector<const Named_type*> seen; std::vector<const Named_type*> seen;
Type::add_methods_for_type(type, NULL, 0, false, false, &seen, all_methods); Type::add_methods_for_type(type, NULL, 0, false, false, &seen, *all_methods);
if ((*all_methods)->empty())
{
delete *all_methods;
*all_methods = NULL;
}
Type::build_stub_methods(gogo, type, *all_methods, location); Type::build_stub_methods(gogo, type, *all_methods, location);
} }
...@@ -9408,7 +9413,7 @@ Type::add_methods_for_type(const Type* type, ...@@ -9408,7 +9413,7 @@ Type::add_methods_for_type(const Type* type,
bool is_embedded_pointer, bool is_embedded_pointer,
bool needs_stub_method, bool needs_stub_method,
std::vector<const Named_type*>* seen, std::vector<const Named_type*>* seen,
Methods** methods) Methods* methods)
{ {
// Pointer types may not have methods. // Pointer types may not have methods.
if (type->points_to() != NULL) if (type->points_to() != NULL)
...@@ -9457,15 +9462,12 @@ Type::add_local_methods_for_type(const Named_type* nt, ...@@ -9457,15 +9462,12 @@ Type::add_local_methods_for_type(const Named_type* nt,
unsigned int depth, unsigned int depth,
bool is_embedded_pointer, bool is_embedded_pointer,
bool needs_stub_method, bool needs_stub_method,
Methods** methods) Methods* methods)
{ {
const Bindings* local_methods = nt->local_methods(); const Bindings* local_methods = nt->local_methods();
if (local_methods == NULL) if (local_methods == NULL)
return; return;
if (*methods == NULL)
*methods = new Methods();
for (Bindings::const_declarations_iterator p = for (Bindings::const_declarations_iterator p =
local_methods->begin_declarations(); local_methods->begin_declarations();
p != local_methods->end_declarations(); p != local_methods->end_declarations();
...@@ -9476,7 +9478,7 @@ Type::add_local_methods_for_type(const Named_type* nt, ...@@ -9476,7 +9478,7 @@ Type::add_local_methods_for_type(const Named_type* nt,
|| !Type::method_expects_pointer(no)); || !Type::method_expects_pointer(no));
Method* m = new Named_method(no, field_indexes, depth, is_value_method, Method* m = new Named_method(no, field_indexes, depth, is_value_method,
(needs_stub_method || depth > 0)); (needs_stub_method || depth > 0));
if (!(*methods)->insert(no->name(), m)) if (!methods->insert(no->name(), m))
delete m; delete m;
} }
} }
...@@ -9492,7 +9494,7 @@ Type::add_embedded_methods_for_type(const Type* type, ...@@ -9492,7 +9494,7 @@ Type::add_embedded_methods_for_type(const Type* type,
bool is_embedded_pointer, bool is_embedded_pointer,
bool needs_stub_method, bool needs_stub_method,
std::vector<const Named_type*>* seen, std::vector<const Named_type*>* seen,
Methods** methods) Methods* methods)
{ {
// Look for anonymous fields in TYPE. TYPE has fields if it is a // Look for anonymous fields in TYPE. TYPE has fields if it is a
// struct. // struct.
...@@ -9530,13 +9532,35 @@ Type::add_embedded_methods_for_type(const Type* type, ...@@ -9530,13 +9532,35 @@ Type::add_embedded_methods_for_type(const Type* type,
sub_field_indexes->next = field_indexes; sub_field_indexes->next = field_indexes;
sub_field_indexes->field_index = i; sub_field_indexes->field_index = i;
Methods tmp_methods;
Type::add_methods_for_type(fnt, sub_field_indexes, depth + 1, Type::add_methods_for_type(fnt, sub_field_indexes, depth + 1,
(is_embedded_pointer || is_pointer), (is_embedded_pointer || is_pointer),
(needs_stub_method (needs_stub_method
|| is_pointer || is_pointer
|| i > 0), || i > 0),
seen, seen,
methods); &tmp_methods);
// Check if there are promoted methods that conflict with field names and
// don't add them to the method map.
for (Methods::const_iterator p = tmp_methods.begin();
p != tmp_methods.end();
++p)
{
bool found = false;
for (Struct_field_list::const_iterator fp = fields->begin();
fp != fields->end();
++fp)
{
if (fp->field_name() == p->first)
{
found = true;
break;
}
}
if (!found &&
!methods->insert(p->first, p->second))
delete p->second;
}
} }
} }
...@@ -9548,7 +9572,7 @@ void ...@@ -9548,7 +9572,7 @@ void
Type::add_interface_methods_for_type(const Type* type, Type::add_interface_methods_for_type(const Type* type,
const Method::Field_indexes* field_indexes, const Method::Field_indexes* field_indexes,
unsigned int depth, unsigned int depth,
Methods** methods) Methods* methods)
{ {
const Interface_type* it = type->interface_type(); const Interface_type* it = type->interface_type();
if (it == NULL) if (it == NULL)
...@@ -9558,9 +9582,6 @@ Type::add_interface_methods_for_type(const Type* type, ...@@ -9558,9 +9582,6 @@ Type::add_interface_methods_for_type(const Type* type,
if (imethods == NULL) if (imethods == NULL)
return; return;
if (*methods == NULL)
*methods = new Methods();
for (Typed_identifier_list::const_iterator pm = imethods->begin(); for (Typed_identifier_list::const_iterator pm = imethods->begin();
pm != imethods->end(); pm != imethods->end();
++pm) ++pm)
...@@ -9576,7 +9597,7 @@ Type::add_interface_methods_for_type(const Type* type, ...@@ -9576,7 +9597,7 @@ Type::add_interface_methods_for_type(const Type* type,
fntype = fntype->copy_with_receiver(const_cast<Type*>(type)); fntype = fntype->copy_with_receiver(const_cast<Type*>(type));
Method* m = new Interface_method(pm->name(), pm->location(), fntype, Method* m = new Interface_method(pm->name(), pm->location(), fntype,
field_indexes, depth); field_indexes, depth);
if (!(*methods)->insert(pm->name(), m)) if (!methods->insert(pm->name(), m))
delete m; delete m;
} }
} }
......
...@@ -384,6 +384,10 @@ class Methods ...@@ -384,6 +384,10 @@ class Methods
find(const std::string& name) const find(const std::string& name) const
{ return this->methods_.find(name); } { return this->methods_.find(name); }
bool
empty() const
{ return this->methods_.empty(); }
private: private:
Method_map methods_; Method_map methods_;
}; };
...@@ -1228,24 +1232,24 @@ class Type ...@@ -1228,24 +1232,24 @@ class Type
add_methods_for_type(const Type* type, const Method::Field_indexes*, add_methods_for_type(const Type* type, const Method::Field_indexes*,
unsigned int depth, bool, bool, unsigned int depth, bool, bool,
std::vector<const Named_type*>*, std::vector<const Named_type*>*,
Methods**); Methods*);
static void static void
add_local_methods_for_type(const Named_type* type, add_local_methods_for_type(const Named_type* type,
const Method::Field_indexes*, const Method::Field_indexes*,
unsigned int depth, bool, bool, Methods**); unsigned int depth, bool, bool, Methods*);
static void static void
add_embedded_methods_for_type(const Type* type, add_embedded_methods_for_type(const Type* type,
const Method::Field_indexes*, const Method::Field_indexes*,
unsigned int depth, bool, bool, unsigned int depth, bool, bool,
std::vector<const Named_type*>*, std::vector<const Named_type*>*,
Methods**); Methods*);
static void static void
add_interface_methods_for_type(const Type* type, add_interface_methods_for_type(const Type* type,
const Method::Field_indexes*, const Method::Field_indexes*,
unsigned int depth, Methods**); unsigned int depth, Methods*);
// Build stub methods for a type. // Build stub methods for a type.
static void static void
......
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