aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-09-10 04:12:07 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-09-10 04:12:07 +0000
commit93d83339d55749adabcb634ebf6ac452bfc495a3 (patch)
tree7d631d706ffb141704c4da9932b37b9eace43df8
parent049d28935129d6c2daa4993899f25a27e7b239af (diff)
downloadgcc-93d83339d55749adabcb634ebf6ac452bfc495a3.zip
gcc-93d83339d55749adabcb634ebf6ac452bfc495a3.tar.gz
gcc-93d83339d55749adabcb634ebf6ac452bfc495a3.tar.bz2
Fix using package name as composite literal struct key.
From-SVN: r178747
-rw-r--r--gcc/go/gofrontend/expressions.cc1
-rw-r--r--gcc/go/gofrontend/parse.cc38
2 files changed, 36 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 8957acb..5529e6c3 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -1436,7 +1436,6 @@ Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
Expression*
Expression::make_unknown_reference(Named_object* no, source_location location)
{
- go_assert(no->resolve()->is_unknown());
return new Unknown_expression(no, location);
}
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index eeb4f5d..059d964 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -2445,7 +2445,9 @@ Parse::enclosing_var_reference(Named_object* in_function, Named_object* var,
// LiteralValue = "{" [ ElementList [ "," ] ] "}" .
// ElementList = Element { "," Element } .
// Element = [ Key ":" ] Value .
-// Key = Expression .
+// Key = FieldName | ElementIndex .
+// FieldName = identifier .
+// ElementIndex = Expression .
// Value = Expression | LiteralValue .
// We have already seen the type if there is one, and we are now
@@ -2478,7 +2480,33 @@ Parse::composite_lit(Type* type, int depth, source_location location)
const Token* token = this->peek_token();
- if (!token->is_op(OPERATOR_LCURLY))
+ if (token->is_identifier())
+ {
+ std::string identifier = token->identifier();
+ bool is_exported = token->is_identifier_exported();
+ source_location location = token->location();
+
+ if (this->advance_token()->is_op(OPERATOR_COLON))
+ {
+ // This may be a field name. We don't know for sure--it
+ // could also be an expression for an array index. We
+ // don't want to parse it as an expression because may
+ // trigger various errors, e.g., if this identifier
+ // happens to be the name of a package.
+ Gogo* gogo = this->gogo_;
+ val = this->id_to_expression(gogo->pack_hidden_name(identifier,
+ is_exported),
+ location);
+ }
+ else
+ {
+ this->unget_token(Token::make_identifier_token(identifier,
+ is_exported,
+ location));
+ val = this->expression(PRECEDENCE_NORMAL, false, true, NULL);
+ }
+ }
+ else if (!token->is_op(OPERATOR_LCURLY))
val = this->expression(PRECEDENCE_NORMAL, false, true, NULL);
else
{
@@ -2922,6 +2950,12 @@ Parse::id_to_expression(const std::string& name, source_location location)
return Expression::make_func_reference(named_object, NULL, location);
case Named_object::NAMED_OBJECT_UNKNOWN:
return Expression::make_unknown_reference(named_object, location);
+ case Named_object::NAMED_OBJECT_PACKAGE:
+ case Named_object::NAMED_OBJECT_TYPE:
+ case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
+ // These cases can arise for a field name in a composite
+ // literal.
+ return Expression::make_unknown_reference(named_object, location);
default:
error_at(this->location(), "unexpected type of identifier");
return Expression::make_error(location);