aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/types.cc74
-rw-r--r--gcc/go/gofrontend/types.h13
2 files changed, 50 insertions, 37 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index c13bfea438d..59247d6fb05 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -4209,7 +4209,8 @@ Struct_field::is_field_name(const std::string& name) const
// This is a horrible hack caused by the fact that we don't pack
// the names of builtin types. FIXME.
- if (nt != NULL
+ if (!this->is_imported_
+ && nt != NULL
&& nt->is_builtin()
&& nt->name() == Gogo::unpack_hidden_name(name))
return true;
@@ -4218,6 +4219,36 @@ Struct_field::is_field_name(const std::string& name) const
}
}
+// Return whether this field is an unexported field named NAME.
+
+bool
+Struct_field::is_unexported_field_name(Gogo* gogo,
+ const std::string& name) const
+{
+ const std::string& field_name(this->field_name());
+ if (Gogo::is_hidden_name(field_name)
+ && name == Gogo::unpack_hidden_name(field_name)
+ && gogo->pack_hidden_name(name, false) != field_name)
+ return true;
+
+ // Check for the name of a builtin type. This is like the test in
+ // is_field_name, only there we return false if this->is_imported_,
+ // and here we return true.
+ if (this->is_imported_ && this->is_anonymous())
+ {
+ Type* t = this->typed_identifier_.type();
+ if (t->points_to() != NULL)
+ t = t->points_to();
+ Named_type* nt = t->named_type();
+ if (nt != NULL
+ && nt->is_builtin()
+ && nt->name() == Gogo::unpack_hidden_name(name))
+ return true;
+ }
+
+ return false;
+}
+
// Return whether this field is an embedded built-in type.
bool
@@ -4650,13 +4681,8 @@ Struct_type::is_unexported_local_field(Gogo* gogo,
for (Struct_field_list::const_iterator pf = fields->begin();
pf != fields->end();
++pf)
- {
- const std::string& field_name(pf->field_name());
- if (Gogo::is_hidden_name(field_name)
- && name == Gogo::unpack_hidden_name(field_name)
- && gogo->pack_hidden_name(name, false) != field_name)
- return true;
- }
+ if (pf->is_unexported_field_name(gogo, name))
+ return true;
}
return false;
}
@@ -5258,34 +5284,8 @@ Struct_type::do_import(Import* imp)
}
Type* ftype = imp->read_type();
- // We don't pack the names of builtin types. In
- // Struct_field::is_field_name we cope with a hack. Now we
- // need another hack so that we don't accidentally think
- // that an embedded builtin type is accessible from another
- // package (we know that all the builtin types are not
- // exported).
- // This is called during parsing, before anything is
- // lowered, so we have to be careful to avoid dereferencing
- // an unknown type name.
- if (name.empty())
- {
- Type *t = ftype;
- if (t->classification() == Type::TYPE_POINTER)
- {
- // Very ugly.
- Pointer_type* ptype = static_cast<Pointer_type*>(t);
- t = ptype->points_to();
- }
- std::string tname;
- if (t->forward_declaration_type() != NULL)
- tname = t->forward_declaration_type()->name();
- else if (t->named_type() != NULL)
- tname = t->named_type()->name();
- if (!tname.empty() && tname[0] >= 'a' && tname[0] <= 'z')
- name = '.' + imp->package()->pkgpath() + '.' + tname;
- }
-
Struct_field sf(Typed_identifier(name, ftype, imp->location()));
+ sf.set_is_imported();
if (imp->peek_char() == ' ')
{
@@ -9327,7 +9327,9 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
else
{
bool is_unexported;
- if (!Gogo::is_hidden_name(name))
+ // The test for 'a' and 'z' is to handle builtin names,
+ // which are not hidden.
+ if (!Gogo::is_hidden_name(name) && (name[0] < 'a' || name[0] > 'z'))
is_unexported = false;
else
{
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 928c593a919..ed01d9cdc38 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -1924,7 +1924,7 @@ class Struct_field
{
public:
explicit Struct_field(const Typed_identifier& typed_identifier)
- : typed_identifier_(typed_identifier), tag_(NULL)
+ : typed_identifier_(typed_identifier), tag_(NULL), is_imported_(false)
{ }
// The field name.
@@ -1935,6 +1935,10 @@ class Struct_field
bool
is_field_name(const std::string& name) const;
+ // Return whether this struct field is an unexported field named NAME.
+ bool
+ is_unexported_field_name(Gogo*, const std::string& name) const;
+
// Return whether this struct field is an embedded built-in type.
bool
is_embedded_builtin(Gogo*) const;
@@ -1972,6 +1976,11 @@ class Struct_field
set_tag(const std::string& tag)
{ this->tag_ = new std::string(tag); }
+ // Record that this field is defined in an imported struct.
+ void
+ set_is_imported()
+ { this->is_imported_ = true; }
+
// Set the type. This is only used in error cases.
void
set_type(Type* type)
@@ -1982,6 +1991,8 @@ class Struct_field
Typed_identifier typed_identifier_;
// The field tag. This is NULL if the field has no tag.
std::string* tag_;
+ // Whether this field is defined in an imported struct.
+ bool is_imported_;
};
// A list of struct fields.