aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/export.cc15
-rw-r--r--gcc/go/gofrontend/types.cc21
-rw-r--r--gcc/go/gofrontend/types.h14
4 files changed, 45 insertions, 7 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 5104e7b..f3c52bf 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-565b5cd0f49a00ca20941ea042c07ebe6ddf3553
+946aa5ab2e82d045a2a3b2f18ba2c5b00e957c4b
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc
index d021ac4..963f0bf 100644
--- a/gcc/go/gofrontend/export.cc
+++ b/gcc/go/gofrontend/export.cc
@@ -60,6 +60,7 @@ class Type_hash_alias_identical
return type->hash_for_method(NULL,
(Type::COMPARE_ERRORS
| Type::COMPARE_TAGS
+ | Type::COMPARE_EMBEDDED_INTERFACES
| Type::COMPARE_ALIASES));
}
};
@@ -73,6 +74,7 @@ class Type_alias_identical
return Type::are_identical(t1, t2,
(Type::COMPARE_ERRORS
| Type::COMPARE_TAGS
+ | Type::COMPARE_EMBEDDED_INTERFACES
| Type::COMPARE_ALIASES),
NULL);
}
@@ -295,6 +297,16 @@ Find_types_to_prepare::type(Type* type)
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.
@@ -408,6 +420,9 @@ Export::prepare_types(const std::vector<Named_object*>* exports,
{
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());
}
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index e12e670..e9cbfd8 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -8808,10 +8808,19 @@ Interface_type::is_identical(const Interface_type* t, int flags) const
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;
@@ -8823,11 +8832,11 @@ Interface_type::is_identical(const Interface_type* t, int flags) const
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))
@@ -8836,7 +8845,7 @@ Interface_type::is_identical(const Interface_type* t, int flags) const
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
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 976d41a..07121dd 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -577,6 +577,11 @@ class 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
@@ -3165,6 +3170,15 @@ class Interface_type : public Type
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*);