summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-14 22:28:10 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-14 22:28:10 +0000
commit2d29d278b82acc8bb48565b565b3683a5fb7a56d (patch)
tree8cfeff8cbb8f4589275ca984068b5ddb92b8a76a
parent9f608b2741e61ee37d354034824e3f8f992dc14d (diff)
downloadgcc-2d29d278b82acc8bb48565b565b3683a5fb7a56d.tar.gz
Fix handling of structs with embedded global types.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178870 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/go/gofrontend/expressions.cc17
-rw-r--r--gcc/go/gofrontend/types.cc157
-rw-r--r--gcc/go/gofrontend/types.h4
3 files changed, 112 insertions, 66 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index b0be4834e50..32f0612a1b0 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -12640,6 +12640,16 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
{
const Struct_field* sf = st->field(fre->field_index());
name = sf->field_name();
+
+ // See below. FIXME.
+ if (!Gogo::is_hidden_name(name)
+ && name[0] >= 'a'
+ && name[0] <= 'z')
+ {
+ if (gogo->lookup_global(name.c_str()) != NULL)
+ name = gogo->pack_hidden_name(name, false);
+ }
+
char buf[20];
snprintf(buf, sizeof buf, "%u", fre->field_index());
size_t buflen = strlen(buf);
@@ -12671,7 +12681,7 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
// A predefined name won't be packed. If it starts with a
// lower case letter we need to check for that case, because
- // the field name will be packed.
+ // the field name will be packed. FIXME.
if (!Gogo::is_hidden_name(name)
&& name[0] >= 'a'
&& name[0] <= 'z')
@@ -13505,7 +13515,10 @@ Struct_field_offset_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "unsafe.Offsetof(";
- ast_dump_context->ostream() << this->field_->field_name();
+ ast_dump_context->dump_type(this->type_);
+ ast_dump_context->ostream() << '.';
+ ast_dump_context->ostream() <<
+ Gogo::message_name(this->field_->field_name());
ast_dump_context->ostream() << ")";
}
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 453e741e2cf..21c5ba20030 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -1297,28 +1297,28 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
if (!this->has_pointer())
runtime_type_kind |= RUNTIME_TYPE_KIND_NO_POINTERS;
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "Kind");
+ go_assert(p->is_field_name("Kind"));
mpz_t iv;
mpz_init_set_ui(iv, runtime_type_kind);
vals->push_back(Expression::make_integer(&iv, p->type(), bloc));
++p;
- go_assert(p->field_name() == "align");
+ go_assert(p->is_field_name("align"));
Expression::Type_info type_info = Expression::TYPE_INFO_ALIGNMENT;
vals->push_back(Expression::make_type_info(this, type_info));
++p;
- go_assert(p->field_name() == "fieldAlign");
+ go_assert(p->is_field_name("fieldAlign"));
type_info = Expression::TYPE_INFO_FIELD_ALIGNMENT;
vals->push_back(Expression::make_type_info(this, type_info));
++p;
- go_assert(p->field_name() == "size");
+ go_assert(p->is_field_name("size"));
type_info = Expression::TYPE_INFO_SIZE;
vals->push_back(Expression::make_type_info(this, type_info));
++p;
- go_assert(p->field_name() == "hash");
+ go_assert(p->is_field_name("hash"));
mpz_set_ui(iv, this->hash_for_method(gogo));
vals->push_back(Expression::make_integer(&iv, p->type(), bloc));
@@ -1327,7 +1327,7 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
this->type_functions(&hash_fn, &equal_fn);
++p;
- go_assert(p->field_name() == "hashfn");
+ go_assert(p->is_field_name("hashfn"));
Function_type* fntype = p->type()->function_type();
Named_object* no = Named_object::make_function_declaration(hash_fn, NULL,
fntype,
@@ -1336,14 +1336,14 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
vals->push_back(Expression::make_func_reference(no, NULL, bloc));
++p;
- go_assert(p->field_name() == "equalfn");
+ go_assert(p->is_field_name("equalfn"));
fntype = p->type()->function_type();
no = Named_object::make_function_declaration(equal_fn, NULL, fntype, bloc);
no->func_declaration_value()->set_asm_name(equal_fn);
vals->push_back(Expression::make_func_reference(no, NULL, bloc));
++p;
- go_assert(p->field_name() == "string");
+ go_assert(p->is_field_name("string"));
Expression* s = Expression::make_string((name != NULL
? name->reflection(gogo)
: this->reflection(gogo)),
@@ -1351,7 +1351,7 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
++p;
- go_assert(p->field_name() == "uncommonType");
+ go_assert(p->is_field_name("uncommonType"));
if (name == NULL && methods == NULL)
vals->push_back(Expression::make_nil(bloc));
else
@@ -1365,7 +1365,7 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
}
++p;
- go_assert(p->field_name() == "ptrToThis");
+ go_assert(p->is_field_name("ptrToThis"));
if (name == NULL)
vals->push_back(Expression::make_nil(bloc));
else
@@ -1402,10 +1402,10 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
vals->reserve(3);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "name");
+ go_assert(p->is_field_name("name"));
++p;
- go_assert(p->field_name() == "pkgPath");
+ go_assert(p->is_field_name("pkgPath"));
if (name == NULL)
{
@@ -1444,7 +1444,7 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
}
++p;
- go_assert(p->field_name() == "methods");
+ go_assert(p->is_field_name("methods"));
vals->push_back(this->methods_constructor(gogo, p->type(), methods,
only_value_methods));
@@ -1532,13 +1532,13 @@ Type::method_constructor(Gogo*, Type* method_type,
vals->reserve(5);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "name");
+ go_assert(p->is_field_name("name"));
const std::string n = Gogo::unpack_hidden_name(method_name);
Expression* s = Expression::make_string(n, bloc);
vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
++p;
- go_assert(p->field_name() == "pkgPath");
+ go_assert(p->is_field_name("pkgPath"));
if (!Gogo::is_hidden_name(method_name))
vals->push_back(Expression::make_nil(bloc));
else
@@ -1560,11 +1560,11 @@ Type::method_constructor(Gogo*, Type* method_type,
Type* nonmethod_type = mtype->copy_without_receiver();
++p;
- go_assert(p->field_name() == "mtyp");
+ go_assert(p->is_field_name("mtyp"));
vals->push_back(Expression::make_type_descriptor(nonmethod_type, bloc));
++p;
- go_assert(p->field_name() == "typ");
+ go_assert(p->is_field_name("typ"));
if (!only_value_methods && m->is_value_method())
{
// This is a value method on a pointer type. Change the type of
@@ -1587,7 +1587,7 @@ Type::method_constructor(Gogo*, Type* method_type,
vals->push_back(Expression::make_type_descriptor(mtype, bloc));
++p;
- go_assert(p->field_name() == "tfn");
+ go_assert(p->is_field_name("tfn"));
vals->push_back(Expression::make_func_reference(no, NULL, bloc));
++p;
@@ -2752,22 +2752,22 @@ Function_type::do_type_descriptor(Gogo* gogo, Named_type* name)
vals->reserve(4);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "commonType");
+ go_assert(p->is_field_name("commonType"));
vals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_FUNC,
name, NULL, true));
++p;
- go_assert(p->field_name() == "dotdotdot");
+ go_assert(p->is_field_name("dotdotdot"));
vals->push_back(Expression::make_boolean(this->is_varargs(), bloc));
++p;
- go_assert(p->field_name() == "in");
+ go_assert(p->is_field_name("in"));
vals->push_back(this->type_descriptor_params(p->type(), this->receiver(),
this->parameters()));
++p;
- go_assert(p->field_name() == "out");
+ go_assert(p->is_field_name("out"));
vals->push_back(this->type_descriptor_params(p->type(), NULL,
this->results()));
@@ -3159,13 +3159,13 @@ Pointer_type::do_type_descriptor(Gogo* gogo, Named_type* name)
vals->reserve(2);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "commonType");
+ go_assert(p->is_field_name("commonType"));
vals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_PTR,
name, methods, false));
++p;
- go_assert(p->field_name() == "elem");
+ go_assert(p->is_field_name("elem"));
vals->push_back(Expression::make_type_descriptor(deref, bloc));
return Expression::make_struct_composite_literal(ptr_tdt, vals, bloc);
@@ -3373,6 +3373,34 @@ Struct_field::field_name() const
}
}
+// Return whether this field is named NAME.
+
+bool
+Struct_field::is_field_name(const std::string& name) const
+{
+ const std::string& me(this->typed_identifier_.name());
+ if (!me.empty())
+ return me == name;
+ else
+ {
+ 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->name() == name)
+ return true;
+
+ // This is a horrible hack caused by the fact that we don't pack
+ // the names of builtin types. FIXME.
+ if (nt != NULL
+ && nt->is_builtin()
+ && nt->name() == Gogo::unpack_hidden_name(name))
+ return true;
+
+ return false;
+ }
+}
+
// Class Struct_type.
// Traversal.
@@ -3567,7 +3595,7 @@ Struct_type::find_local_field(const std::string& name,
pf != fields->end();
++pf, ++i)
{
- if (pf->field_name() == name)
+ if (pf->is_field_name(name))
{
if (pindex != NULL)
*pindex = i;
@@ -3608,7 +3636,7 @@ Struct_type::field_reference_depth(Expression* struct_expr,
pf != fields->end();
++pf, ++i)
{
- if (pf->field_name() == name)
+ if (pf->is_field_name(name))
{
*depth = 0;
return Expression::make_field_reference(struct_expr, i, location);
@@ -3854,13 +3882,13 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
go_assert(methods == NULL || name == NULL);
Struct_field_list::const_iterator ps = fields->begin();
- go_assert(ps->field_name() == "commonType");
+ go_assert(ps->is_field_name("commonType"));
vals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_STRUCT,
name, methods, true));
++ps;
- go_assert(ps->field_name() == "fields");
+ go_assert(ps->is_field_name("fields"));
Expression_list* elements = new Expression_list();
elements->reserve(this->fields_->size());
@@ -3875,7 +3903,7 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
fvals->reserve(5);
Struct_field_list::const_iterator q = f->begin();
- go_assert(q->field_name() == "name");
+ go_assert(q->is_field_name("name"));
if (pf->is_anonymous())
fvals->push_back(Expression::make_nil(bloc));
else
@@ -3886,7 +3914,7 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
}
++q;
- go_assert(q->field_name() == "pkgPath");
+ go_assert(q->is_field_name("pkgPath"));
if (!Gogo::is_hidden_name(pf->field_name()))
fvals->push_back(Expression::make_nil(bloc));
else
@@ -3897,11 +3925,11 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
}
++q;
- go_assert(q->field_name() == "typ");
+ go_assert(q->is_field_name("typ"));
fvals->push_back(Expression::make_type_descriptor(pf->type(), bloc));
++q;
- go_assert(q->field_name() == "tag");
+ go_assert(q->is_field_name("tag"));
if (!pf->has_tag())
fvals->push_back(Expression::make_nil(bloc));
else
@@ -3911,7 +3939,7 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
}
++q;
- go_assert(q->field_name() == "offset");
+ go_assert(q->is_field_name("offset"));
fvals->push_back(Expression::make_struct_field_offset(this, &*pf));
Expression* v = Expression::make_struct_composite_literal(element_type,
@@ -4561,22 +4589,22 @@ Array_type::array_type_descriptor(Gogo* gogo, Named_type* name)
vals->reserve(3);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "commonType");
+ go_assert(p->is_field_name("commonType"));
vals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_ARRAY,
name, NULL, true));
++p;
- go_assert(p->field_name() == "elem");
+ go_assert(p->is_field_name("elem"));
vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));
++p;
- go_assert(p->field_name() == "slice");
+ go_assert(p->is_field_name("slice"));
Type* slice_type = Type::make_array_type(this->element_type_, NULL);
vals->push_back(Expression::make_type_descriptor(slice_type, bloc));
++p;
- go_assert(p->field_name() == "len");
+ go_assert(p->is_field_name("len"));
vals->push_back(Expression::make_cast(p->type(), this->length_, bloc));
++p;
@@ -4600,13 +4628,13 @@ Array_type::slice_type_descriptor(Gogo* gogo, Named_type* name)
vals->reserve(2);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "commonType");
+ go_assert(p->is_field_name("commonType"));
vals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_SLICE,
name, NULL, true));
++p;
- go_assert(p->field_name() == "elem");
+ go_assert(p->is_field_name("elem"));
vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));
++p;
@@ -4810,17 +4838,17 @@ Map_type::do_type_descriptor(Gogo* gogo, Named_type* name)
vals->reserve(3);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "commonType");
+ go_assert(p->is_field_name("commonType"));
vals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_MAP,
name, NULL, true));
++p;
- go_assert(p->field_name() == "key");
+ go_assert(p->is_field_name("key"));
vals->push_back(Expression::make_type_descriptor(this->key_type_, bloc));
++p;
- go_assert(p->field_name() == "elem");
+ go_assert(p->is_field_name("elem"));
vals->push_back(Expression::make_type_descriptor(this->val_type_, bloc));
++p;
@@ -4883,27 +4911,27 @@ Map_type::map_descriptor(Gogo* gogo)
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "__map_descriptor");
+ go_assert(p->is_field_name("__map_descriptor"));
vals->push_back(Expression::make_type_descriptor(this, bloc));
++p;
- go_assert(p->field_name() == "__entry_size");
+ go_assert(p->is_field_name("__entry_size"));
Expression::Type_info type_info = Expression::TYPE_INFO_SIZE;
vals->push_back(Expression::make_type_info(map_entry_type, type_info));
Struct_field_list::const_iterator pf = map_entry_type->fields()->begin();
++pf;
- go_assert(pf->field_name() == "__key");
+ go_assert(pf->is_field_name("__key"));
++p;
- go_assert(p->field_name() == "__key_offset");
+ go_assert(p->is_field_name("__key_offset"));
vals->push_back(Expression::make_struct_field_offset(map_entry_type, &*pf));
++pf;
- go_assert(pf->field_name() == "__val");
+ go_assert(pf->is_field_name("__val"));
++p;
- go_assert(p->field_name() == "__val_offset");
+ go_assert(p->is_field_name("__val_offset"));
vals->push_back(Expression::make_struct_field_offset(map_entry_type, &*pf));
++p;
@@ -5093,17 +5121,17 @@ Channel_type::do_type_descriptor(Gogo* gogo, Named_type* name)
vals->reserve(3);
Struct_field_list::const_iterator p = fields->begin();
- go_assert(p->field_name() == "commonType");
+ go_assert(p->is_field_name("commonType"));
vals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_CHAN,
name, NULL, true));
++p;
- go_assert(p->field_name() == "elem");
+ go_assert(p->is_field_name("elem"));
vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));
++p;
- go_assert(p->field_name() == "dir");
+ go_assert(p->is_field_name("dir"));
// These bits must match the ones in libgo/runtime/go-type.h.
int val = 0;
if (this->may_receive_)
@@ -5771,13 +5799,13 @@ Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
ivals->reserve(2);
Struct_field_list::const_iterator pif = ifields->begin();
- go_assert(pif->field_name() == "commonType");
+ go_assert(pif->is_field_name("commonType"));
ivals->push_back(this->type_descriptor_constructor(gogo,
RUNTIME_TYPE_KIND_INTERFACE,
name, NULL, true));
++pif;
- go_assert(pif->field_name() == "methods");
+ go_assert(pif->is_field_name("methods"));
Expression_list* methods = new Expression_list();
if (this->methods_ != NULL && !this->methods_->empty())
@@ -5795,13 +5823,13 @@ Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
mvals->reserve(3);
Struct_field_list::const_iterator pmf = mfields->begin();
- go_assert(pmf->field_name() == "name");
+ go_assert(pmf->is_field_name("name"));
std::string s = Gogo::unpack_hidden_name(pm->name());
Expression* e = Expression::make_string(s, bloc);
mvals->push_back(Expression::make_unary(OPERATOR_AND, e, bloc));
++pmf;
- go_assert(pmf->field_name() == "pkgPath");
+ go_assert(pmf->is_field_name("pkgPath"));
if (!Gogo::is_hidden_name(pm->name()))
mvals->push_back(Expression::make_nil(bloc));
else
@@ -5812,7 +5840,7 @@ Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
}
++pmf;
- go_assert(pmf->field_name() == "typ");
+ go_assert(pmf->is_field_name("typ"));
mvals->push_back(Expression::make_type_descriptor(pm->type(), bloc));
++pmf;
@@ -7571,9 +7599,8 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
{
if (!ambig1.empty())
error_at(location, "%qs is ambiguous via %qs and %qs",
- Gogo::message_name(name).c_str(),
- Gogo::message_name(ambig1).c_str(),
- Gogo::message_name(ambig2).c_str());
+ Gogo::message_name(name).c_str(), ambig1.c_str(),
+ ambig2.c_str());
else if (found_pointer_method)
error_at(location, "method requires a pointer");
else if (nt == NULL && st == NULL && it == NULL)
@@ -7701,7 +7728,7 @@ Type::find_field_or_method(const Type* type,
pf != fields->end();
++pf)
{
- if (pf->field_name() == name)
+ if (pf->is_field_name(name))
{
*is_method = false;
if (nt != NULL)
@@ -7744,8 +7771,10 @@ Type::find_field_or_method(const Type* type,
// pass the ambiguity back to the caller.
if (found_level == 0 || sublevel <= found_level)
{
- found_ambig1 = pf->field_name() + '.' + subambig1;
- found_ambig2 = pf->field_name() + '.' + subambig2;
+ found_ambig1 = (Gogo::message_name(pf->field_name())
+ + '.' + subambig1);
+ found_ambig2 = (Gogo::message_name(pf->field_name())
+ + '.' + subambig2);
found_level = sublevel;
}
}
@@ -7769,8 +7798,8 @@ Type::find_field_or_method(const Type* type,
{
// We found an ambiguity.
go_assert(found_parent != NULL);
- found_ambig1 = found_parent->field_name();
- found_ambig2 = pf->field_name();
+ found_ambig1 = Gogo::message_name(found_parent->field_name());
+ found_ambig2 = Gogo::message_name(pf->field_name());
}
else
{
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 9947a2ca749..f6c8642c86d 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -1732,6 +1732,10 @@ class Struct_field
const std::string&
field_name() const;
+ // Return whether this struct field is named NAME.
+ bool
+ is_field_name(const std::string& name) const;
+
// The field type.
Type*
type() const