Type::finalize_methods(Gogo* gogo, const Type* type, Location location,
Methods** all_methods)
{
- *all_methods = NULL;
+ *all_methods = new Methods();
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);
}
bool is_embedded_pointer,
bool needs_stub_method,
std::vector<const Named_type*>* seen,
- Methods** methods)
+ Methods* methods)
{
// Pointer types may not have methods.
if (type->points_to() != NULL)
unsigned int depth,
bool is_embedded_pointer,
bool needs_stub_method,
- Methods** methods)
+ Methods* methods)
{
const Bindings* local_methods = nt->local_methods();
if (local_methods == NULL)
return;
- if (*methods == NULL)
- *methods = new Methods();
-
for (Bindings::const_declarations_iterator p =
local_methods->begin_declarations();
p != local_methods->end_declarations();
|| !Type::method_expects_pointer(no));
Method* m = new Named_method(no, field_indexes, depth, is_value_method,
(needs_stub_method || depth > 0));
- if (!(*methods)->insert(no->name(), m))
+ if (!methods->insert(no->name(), m))
delete m;
}
}
bool is_embedded_pointer,
bool needs_stub_method,
std::vector<const Named_type*>* seen,
- Methods** methods)
+ Methods* methods)
{
// Look for anonymous fields in TYPE. TYPE has fields if it is a
// struct.
sub_field_indexes->next = field_indexes;
sub_field_indexes->field_index = i;
+ Methods tmp_methods;
Type::add_methods_for_type(fnt, sub_field_indexes, depth + 1,
(is_embedded_pointer || is_pointer),
(needs_stub_method
|| is_pointer
|| i > 0),
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;
+ }
}
}
Type::add_interface_methods_for_type(const Type* type,
const Method::Field_indexes* field_indexes,
unsigned int depth,
- Methods** methods)
+ Methods* methods)
{
const Interface_type* it = type->interface_type();
if (it == NULL)
if (imethods == NULL)
return;
- if (*methods == NULL)
- *methods = new Methods();
-
for (Typed_identifier_list::const_iterator pm = imethods->begin();
pm != imethods->end();
++pm)
fntype = fntype->copy_with_receiver(const_cast<Type*>(type));
Method* m = new Interface_method(pm->name(), pm->location(), fntype,
field_indexes, depth);
- if (!(*methods)->insert(pm->name(), m))
+ if (!methods->insert(pm->name(), m))
delete m;
}
}
find(const std::string& name) const
{ return this->methods_.find(name); }
+ bool
+ empty() const
+ { return this->methods_.empty(); }
+
private:
Method_map methods_;
};
add_methods_for_type(const Type* type, const Method::Field_indexes*,
unsigned int depth, bool, bool,
std::vector<const Named_type*>*,
- Methods**);
+ Methods*);
static void
add_local_methods_for_type(const Named_type* type,
const Method::Field_indexes*,
- unsigned int depth, bool, bool, Methods**);
+ unsigned int depth, bool, bool, Methods*);
static void
add_embedded_methods_for_type(const Type* type,
const Method::Field_indexes*,
unsigned int depth, bool, bool,
std::vector<const Named_type*>*,
- Methods**);
+ Methods*);
static void
add_interface_methods_for_type(const Type* type,
const Method::Field_indexes*,
- unsigned int depth, Methods**);
+ unsigned int depth, Methods*);
// Build stub methods for a type.
static void