return empty_interface_type;
}
+Interface_type::Bmethods_map Interface_type::bmethods_map;
+
// Return a pointer to the backend representation of the method table.
Btype*
if (this->bmethods_ != NULL && !this->bmethods_is_placeholder_)
return this->bmethods_;
+ std::pair<Interface_type*, Bmethods_map_entry> val;
+ val.first = this;
+ val.second.btype = NULL;
+ val.second.is_placeholder = false;
+ std::pair<Bmethods_map::iterator, bool> ins =
+ Interface_type::bmethods_map.insert(val);
+ if (!ins.second
+ && ins.first->second.btype != NULL
+ && !ins.first->second.is_placeholder)
+ {
+ this->bmethods_ = ins.first->second.btype;
+ this->bmethods_is_placeholder_ = false;
+ return this->bmethods_;
+ }
+
Location loc = this->location();
std::vector<Backend::Btyped_identifier>
Btype* st = gogo->backend()->struct_type(mfields);
Btype* ret = gogo->backend()->pointer_type(st);
- if (this->bmethods_ != NULL && this->bmethods_is_placeholder_)
- gogo->backend()->set_placeholder_pointer_type(this->bmethods_, ret);
+ if (ins.first->second.btype != NULL
+ && ins.first->second.is_placeholder)
+ gogo->backend()->set_placeholder_pointer_type(ins.first->second.btype,
+ ret);
this->bmethods_ = ret;
+ ins.first->second.btype = ret;
this->bmethods_is_placeholder_ = false;
+ ins.first->second.is_placeholder = false;
return ret;
}
{
if (this->bmethods_ == NULL)
{
+ std::pair<Interface_type*, Bmethods_map_entry> val;
+ val.first = this;
+ val.second.btype = NULL;
+ val.second.is_placeholder = false;
+ std::pair<Bmethods_map::iterator, bool> ins =
+ Interface_type::bmethods_map.insert(val);
+ if (!ins.second && ins.first->second.btype != NULL)
+ {
+ this->bmethods_ = ins.first->second.btype;
+ this->bmethods_is_placeholder_ = ins.first->second.is_placeholder;
+ return this->bmethods_;
+ }
+
Location loc = this->location();
- this->bmethods_ = gogo->backend()->placeholder_pointer_type("", loc,
- false);
+ Btype* bt = gogo->backend()->placeholder_pointer_type("", loc, false);
+ this->bmethods_ = bt;
+ ins.first->second.btype = bt;
this->bmethods_is_placeholder_ = true;
+ ins.first->second.is_placeholder = true;
}
return this->bmethods_;
}
bool
assume_identical(const Interface_type*, const Interface_type*) const;
+ struct Bmethods_map_entry
+ {
+ Btype *btype;
+ bool is_placeholder;
+ };
+
+ // A mapping from Interface_type to the backend type of its bmethods_,
+ // used to ensure that the backend representation of identical types
+ // is identical.
+ typedef Unordered_map_hash(const Interface_type*, Bmethods_map_entry,
+ Type_hash_identical, Type_identical) Bmethods_map;
+
+ static Bmethods_map bmethods_map;
+
// The list of methods associated with the interface from the
// parser. This will be NULL for the empty interface. This may
// include unnamed interface types.