aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-01-25 23:13:31 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-25 23:13:31 +0000
commit1bfbe9adbc554930163eb551f9904cf4fe096696 (patch)
tree62d1d4ee4dddd626ab695de3285ec42ac4e5d60f /gcc/go
parenta14e122ae2ecf27a8cace7e0d1dda8606d5e4eca (diff)
downloadgcc-1bfbe9adbc554930163eb551f9904cf4fe096696.zip
gcc-1bfbe9adbc554930163eb551f9904cf4fe096696.tar.gz
gcc-1bfbe9adbc554930163eb551f9904cf4fe096696.tar.bz2
compiler: look through aliases when looking for methods
Add a Type::is_alias method to remove some existing loops and avoid adding a new one. Test case is https://golang.org/cl/89935. Fixes golang/go#23489 Reviewed-on: https://go-review.googlesource.com/89975 From-SVN: r257069
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/types.cc60
-rw-r--r--gcc/go/gofrontend/types.h9
3 files changed, 49 insertions, 22 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 038a8e8c..25801a6 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-203cbe7d3820fa03c965a01f72461f71588fe952
+897ce971b06a39c217d02dce9e1361bc7a240188
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/types.cc b/gcc/go/gofrontend/types.cc
index 28eef8e..3ee9884 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -107,6 +107,34 @@ Type::forwarded() const
return t;
}
+// Skip alias definitions.
+
+Type*
+Type::unalias()
+{
+ Type* t = this->forwarded();
+ Named_type* nt = t->named_type();
+ while (nt != NULL && nt->is_alias())
+ {
+ t = nt->real_type()->forwarded();
+ nt = t->named_type();
+ }
+ return t;
+}
+
+const Type*
+Type::unalias() const
+{
+ const Type* t = this->forwarded();
+ const Named_type* nt = t->named_type();
+ while (nt != NULL && nt->is_alias())
+ {
+ t = nt->real_type()->forwarded();
+ nt = t->named_type();
+ }
+ return t;
+}
+
// If this is a named type, return it. Otherwise, return NULL.
Named_type*
@@ -333,15 +361,9 @@ Type::are_identical_cmp_tags(const Type* t1, const Type* t2, Cmp_tags cmp_tags,
return errors_are_identical ? true : t1 == t2;
}
- // Skip defined forward declarations.
- t1 = t1->forwarded();
- t2 = t2->forwarded();
-
- // Ignore aliases for purposes of type identity.
- while (t1->named_type() != NULL && t1->named_type()->is_alias())
- t1 = t1->named_type()->real_type()->forwarded();
- while (t2->named_type() != NULL && t2->named_type()->is_alias())
- t2 = t2->named_type()->real_type()->forwarded();
+ // Skip defined forward declarations. Ignore aliases.
+ t1 = t1->unalias();
+ t2 = t2->unalias();
if (t1 == t2)
return true;
@@ -1197,9 +1219,7 @@ Type::finish_backend(Gogo* gogo, Btype *placeholder)
Bexpression*
Type::type_descriptor_pointer(Gogo* gogo, Location location)
{
- Type* t = this->forwarded();
- while (t->named_type() != NULL && t->named_type()->is_alias())
- t = t->named_type()->real_type()->forwarded();
+ Type* t = this->unalias();
if (t->type_descriptor_var_ == NULL)
{
t->make_type_descriptor_var(gogo);
@@ -1648,10 +1668,10 @@ Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
Function_type* equal_fntype, Named_object** hash_fn,
Named_object** equal_fn)
{
- // If this loop leaves NAME as NULL, then the type does not have a
- // name after all.
- while (name != NULL && name->is_alias())
- name = name->real_type()->named_type();
+ // If the unaliased type is not a named type, then the type does not
+ // have a name after all.
+ if (name != NULL)
+ name = name->unalias()->named_type();
if (!this->is_comparable())
{
@@ -2370,9 +2390,7 @@ static const int64_t max_ptrmask_bytes = 2048;
Bexpression*
Type::gc_symbol_pointer(Gogo* gogo)
{
- Type* t = this->forwarded();
- while (t->named_type() != NULL && t->named_type()->is_alias())
- t = t->named_type()->real_type()->forwarded();
+ Type* t = this->unalias();
if (!t->has_pointer())
return gogo->backend()->nil_pointer_expression();
@@ -11494,9 +11512,9 @@ Type::find_field_or_method(const Type* type,
std::string* ambig2)
{
// Named types can have locally defined methods.
- const Named_type* nt = type->named_type();
+ const Named_type* nt = type->unalias()->named_type();
if (nt == NULL && type->points_to() != NULL)
- nt = type->points_to()->named_type();
+ nt = type->points_to()->unalias()->named_type();
if (nt != NULL)
{
Named_object* no = nt->find_local_method(name);
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 08e5701..2703319 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -676,6 +676,15 @@ class Type
const Type*
forwarded() const;
+ // Return the type skipping any alias definitions and any defined
+ // forward declarations. This is like forwarded, but also
+ // recursively expands alias definitions to the aliased type.
+ Type*
+ unalias();
+
+ const Type*
+ unalias() const;
+
// Return true if this is a basic type: a type which is not composed
// of other types, and is not void.
bool