diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-10 04:12:07 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-10 04:12:07 +0000 |
commit | c91d684458cd7b47b7bde87edb4c80b3c999836c (patch) | |
tree | 7d631d706ffb141704c4da9932b37b9eace43df8 | |
parent | c508885f6538b8ad32e501013aa5b68601d69f03 (diff) | |
download | gcc-c91d684458cd7b47b7bde87edb4c80b3c999836c.tar.gz |
Fix using package name as composite literal struct key.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178747 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 1 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 38 |
2 files changed, 36 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 8957acb0c8a..5529e6c3e6f 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 eeb4f5da347..059d9646f13 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); |