-565b5cd0f49a00ca20941ea042c07ebe6ddf3553
+946aa5ab2e82d045a2a3b2f18ba2c5b00e957c4b
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
return type->hash_for_method(NULL,
(Type::COMPARE_ERRORS
| Type::COMPARE_TAGS
+ | Type::COMPARE_EMBEDDED_INTERFACES
| Type::COMPARE_ALIASES));
}
};
return Type::are_identical(t1, t2,
(Type::COMPARE_ERRORS
| Type::COMPARE_TAGS
+ | Type::COMPARE_EMBEDDED_INTERFACES
| Type::COMPARE_ALIASES),
NULL);
}
if (type->is_abstract())
return TRAVERSE_SKIP_COMPONENTS;
+ // For interfaces make sure that embedded methods are sorted, since the
+ // comparison function we use for indexing types relies on it (this call has
+ // to happen before the set_type_index call below).
+ if (type->classification() == Type::TYPE_INTERFACE)
+ {
+ Interface_type* it = type->interface_type();
+ if (it != NULL)
+ it->sort_embedded();
+ }
+
if (!this->exp_->set_type_index(type))
{
// We've already seen this type.
{
if (!(*p)->is_type())
continue;
+ Interface_type* it = (*p)->type_value()->interface_type();
+ if (it != NULL)
+ it->sort_embedded();
this->set_type_index((*p)->type_value());
}
if (!this->methods_are_finalized_ || !t->methods_are_finalized_)
return false;
+ // Consult a flag to see whether we need to compare based on
+ // parse methods or all methods.
+ Typed_identifier_list* methods = (((flags & COMPARE_EMBEDDED_INTERFACES) != 0)
+ ? this->parse_methods_
+ : this->all_methods_);
+ Typed_identifier_list* tmethods = (((flags & COMPARE_EMBEDDED_INTERFACES) != 0)
+ ? t->parse_methods_
+ : t->all_methods_);
+
// We require the same methods with the same types. The methods
// have already been sorted.
- if (this->all_methods_ == NULL || t->all_methods_ == NULL)
- return this->all_methods_ == t->all_methods_;
+ if (methods == NULL || tmethods == NULL)
+ return methods == tmethods;
if (this->assume_identical(this, t) || t->assume_identical(t, this))
return true;
ai.next = hold_ai;
this->assume_identical_ = &ai;
- Typed_identifier_list::const_iterator p1 = this->all_methods_->begin();
+ Typed_identifier_list::const_iterator p1 = methods->begin();
Typed_identifier_list::const_iterator p2;
- for (p2 = t->all_methods_->begin(); p2 != t->all_methods_->end(); ++p1, ++p2)
+ for (p2 = tmethods->begin(); p2 != tmethods->end(); ++p1, ++p2)
{
- if (p1 == this->all_methods_->end())
+ if (p1 == methods->end())
break;
if (p1->name() != p2->name()
|| !Type::are_identical(p1->type(), p2->type(), flags, NULL))
this->assume_identical_ = hold_ai;
- return p1 == this->all_methods_->end() && p2 == t->all_methods_->end();
+ return p1 == methods->end() && p2 == tmethods->end();
}
// Return true if T1 and T2 are assumed to be identical during a type
// Compare aliases: treat an alias to T as distinct from T.
static const int COMPARE_ALIASES = 4;
+ // When comparing interface types compare the interface embedding heirarchy,
+ // if any, rather than only comparing method sets. Useful primarily when
+ // exporting types.
+ static const int COMPARE_EMBEDDED_INTERFACES = 8;
+
// Return true if two types are identical. If this returns false,
// and REASON is not NULL, it may set *REASON.
static bool
methods_are_finalized() const
{ return this->methods_are_finalized_; }
+ // Sort embedded interfaces by name. Needed when we are preparing
+ // to emit types into the export data.
+ void
+ sort_embedded()
+ {
+ if (parse_methods_ != NULL)
+ parse_methods_->sort_by_name();
+ }
+
protected:
int
do_traverse(Traverse*);