Commit 4500f676 by Ian Lance Taylor

compiler: don't export embedded builtins.

The panic in test/fixedbugs/bug461.go was caused by the fact that
reflect expects unexported fields in a struct to have a valid
package path. If a struct field is an embedded built-in type, it is
now given the package name of the currently compiling package, so it
remains unexported for purposes of reflect.

Fixed Issue 25.

From-SVN: r201951
parent 009e5353
...@@ -4221,6 +4221,22 @@ Struct_field::is_field_name(const std::string& name) const ...@@ -4221,6 +4221,22 @@ Struct_field::is_field_name(const std::string& name) const
} }
} }
// Return whether this field is an embedded built-in type.
bool
Struct_field::is_embedded_builtin(Gogo* gogo) const
{
const std::string& name(this->field_name());
// We know that a field is an embedded type if it is anonymous.
// We can decide if it is a built-in type by checking to see if it is
// registered globally under the field's name.
// This allows us to distinguish between embedded built-in types and
// embedded types that are aliases to built-in types.
return (this->is_anonymous()
&& !Gogo::is_hidden_name(name)
&& gogo->lookup_global(name.c_str()) != NULL);
}
// Class Struct_type. // Class Struct_type.
// A hash table used to find identical unnamed structs so that they // A hash table used to find identical unnamed structs so that they
...@@ -4835,11 +4851,16 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name) ...@@ -4835,11 +4851,16 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
++q; ++q;
go_assert(q->is_field_name("pkgPath")); go_assert(q->is_field_name("pkgPath"));
if (!Gogo::is_hidden_name(pf->field_name())) bool is_embedded_builtin = pf->is_embedded_builtin(gogo);
fvals->push_back(Expression::make_nil(bloc)); if (!Gogo::is_hidden_name(pf->field_name()) && !is_embedded_builtin)
fvals->push_back(Expression::make_nil(bloc));
else else
{ {
std::string n = Gogo::hidden_name_pkgpath(pf->field_name()); std::string n;
if (is_embedded_builtin)
n = gogo->package_name();
else
n = Gogo::hidden_name_pkgpath(pf->field_name());
Expression* s = Expression::make_string(n, bloc); Expression* s = Expression::make_string(n, bloc);
fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc)); fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
} }
......
...@@ -1926,6 +1926,10 @@ class Struct_field ...@@ -1926,6 +1926,10 @@ class Struct_field
bool bool
is_field_name(const std::string& name) const; is_field_name(const std::string& name) const;
// Return whether this struct field is an embedded built-in type.
bool
is_embedded_builtin(Gogo*) const;
// The field type. // The field type.
Type* Type*
type() const type() const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment