From patchwork Mon Mar 7 21:22:39 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 85816 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 0B2D3B6EEC for ; Tue, 8 Mar 2011 08:22:54 +1100 (EST) Received: (qmail 19390 invoked by alias); 7 Mar 2011 21:22:52 -0000 Received: (qmail 19381 invoked by uid 22791); 7 Mar 2011 21:22:51 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_BF, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 07 Mar 2011 21:22:46 +0000 Received: from kpbe16.cbf.corp.google.com (kpbe16.cbf.corp.google.com [172.25.105.80]) by smtp-out.google.com with ESMTP id p27LMiNN004860 for ; Mon, 7 Mar 2011 13:22:44 -0800 Received: from gxk21 (gxk21.prod.google.com [10.202.11.21]) by kpbe16.cbf.corp.google.com with ESMTP id p27LLwI3006748 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Mon, 7 Mar 2011 13:22:43 -0800 Received: by gxk21 with SMTP id 21so1938489gxk.36 for ; Mon, 07 Mar 2011 13:22:42 -0800 (PST) Received: by 10.150.160.19 with SMTP id i19mr4937861ybe.398.1299532962719; Mon, 07 Mar 2011 13:22:42 -0800 (PST) Received: from coign.google.com ([216.239.45.130]) by mx.google.com with ESMTPS id f2sm159965ybh.19.2011.03.07.13.22.41 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 07 Mar 2011 13:22:42 -0800 (PST) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Handle predeclared names as field names in literals Date: Mon, 07 Mar 2011 13:22:39 -0800 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch to the Go frontend fixes the case where a struct composite literal uses a field name which happens to be a predeclared name. The problem was that predeclared names aren't packed as hidden names, because the package name is not known when they are declared. The field names in structs are, however, packed when appropriate. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r 6b5a5e74bfb4 go/expressions.cc --- a/go/expressions.cc Wed Mar 02 22:49:50 2011 -0800 +++ b/go/expressions.cc Mon Mar 07 13:18:54 2011 -0800 @@ -936,14 +936,6 @@ return this; } -// Return the name of the variable. - -const std::string& -Var_expression::name() const -{ - return this->variable_->name(); -} - // Return the type of a reference to a variable. Type* @@ -1125,14 +1117,6 @@ // a function seems like it could work, though there might be little // point to it. -// Return the name of the function. - -const std::string& -Func_expression::name() const -{ - return this->function_->name(); -} - // Traversal. int @@ -2359,10 +2343,6 @@ named_object() { return this->constant_; } - const std::string& - name() const - { return this->constant_->name(); } - // Check that the initializer does not refer to the constant itself. void check_for_init_loop(); @@ -11645,7 +11625,7 @@ private: Expression* - lower_struct(Type*); + lower_struct(Gogo*, Type*); Expression* lower_array(Type*); @@ -11706,7 +11686,7 @@ if (type->is_error_type()) return Expression::make_error(this->location()); else if (type->struct_type() != NULL) - return this->lower_struct(type); + return this->lower_struct(gogo, type); else if (type->array_type() != NULL) return this->lower_array(type); else if (type->map_type() != NULL) @@ -11723,7 +11703,7 @@ // Lower a struct composite literal. Expression* -Composite_literal_expression::lower_struct(Type* type) +Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) { source_location location = this->location(); Struct_type* st = type->struct_type(); @@ -11751,6 +11731,7 @@ bool bad_key = false; std::string name; + const Named_object* no = NULL; switch (name_expr->classification()) { case EXPRESSION_UNKNOWN_REFERENCE: @@ -11758,7 +11739,7 @@ break; case EXPRESSION_CONST_REFERENCE: - name = static_cast(name_expr)->name(); + no = static_cast(name_expr)->named_object(); break; case EXPRESSION_TYPE: @@ -11768,16 +11749,16 @@ if (nt == NULL) bad_key = true; else - name = nt->name(); + no = nt->named_object(); } break; case EXPRESSION_VAR_REFERENCE: - name = name_expr->var_expression()->name(); + no = name_expr->var_expression()->named_object(); break; case EXPRESSION_FUNC_REFERENCE: - name = name_expr->func_expression()->name(); + no = name_expr->func_expression()->named_object(); break; case EXPRESSION_UNARY: @@ -11825,6 +11806,23 @@ return Expression::make_error(location); } + if (no != NULL) + { + name = no->name(); + + // 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. + if (!Gogo::is_hidden_name(name) + && name[0] >= 'a' + && name[0] <= 'z') + { + Named_object* gno = gogo->lookup_global(name.c_str()); + if (gno == no) + name = gogo->pack_hidden_name(name, false); + } + } + unsigned int index; const Struct_field* sf = st->find_local_field(name, &index); if (sf == NULL) diff -r 6b5a5e74bfb4 go/expressions.h --- a/go/expressions.h Wed Mar 02 22:49:50 2011 -0800 +++ b/go/expressions.h Mon Mar 07 13:18:54 2011 -0800 @@ -903,10 +903,6 @@ named_object() const { return this->variable_; } - // Return the name of the variable. - const std::string& - name() const; - protected: Expression* do_lower(Gogo*, Named_object*, int); @@ -1314,10 +1310,6 @@ named_object() const { return this->function_; } - // Return the name of the function. - const std::string& - name() const; - // Return the closure for this function. This will return NULL if // the function has no closure, which is the normal case. Expression*