This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Add parameter names to export information


I got a request to add function parameter names to the Go export
information, so that tools that do context-sensitive help, such as some
IDEs, have more information to present to the user.  This patch
implements that request.  This is an incompatible change to the export
format--all existing packages will have to be rebuilt.  That is not so
bad since 4.7 is incompatible with 4.6 anyhow.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2012-02-17  Ian Lance Taylor  <iant@google.com>

	* Make-lang.in (go/import.o): Add dependency on $(GO_LEX_H).


Index: gcc/go/Make-lang.in
===================================================================
--- gcc/go/Make-lang.in	(revision 184221)
+++ gcc/go/Make-lang.in	(working copy)
@@ -295,7 +295,8 @@ go/gogo.o: go/gofrontend/gogo.cc $(GO_SY
 	$(GO_IMPORT_H) $(GO_EXPORT_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/import.o: go/gofrontend/import.cc $(GO_SYSTEM_H) \
 	$(srcdir)/../include/filenames.h $(srcdir)/../include/simple-object.h \
-	$(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) $(GO_EXPORT_H) $(GO_IMPORT_H)
+	$(GO_C_H) $(GO_GOGO_H) $(GO_LEX_H) $(GO_TYPES_H) $(GO_EXPORT_H) \
+	$(GO_IMPORT_H)
 go/import-archive.o: go/gofrontend/import-archive.cc $(GO_SYSTEM_H) \
 	$(GO_IMPORT_H)
 go/lex.o: go/gofrontend/lex.cc $(GO_LEX_H) $(GO_SYSTEM_H)
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 184299)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -3274,7 +3274,10 @@ Function::export_func_with_type(Export* 
   if (fntype->is_method())
     {
       exp->write_c_string("(");
-      exp->write_type(fntype->receiver()->type());
+      const Typed_identifier* receiver = fntype->receiver();
+      exp->write_name(receiver->name());
+      exp->write_c_string(" ");
+      exp->write_type(receiver->type());
       exp->write_c_string(") ");
     }
 
@@ -3294,6 +3297,8 @@ Function::export_func_with_type(Export* 
 	    first = false;
 	  else
 	    exp->write_c_string(", ");
+	  exp->write_name(p->name());
+	  exp->write_c_string(" ");
 	  if (!is_varargs || p + 1 != parameters->end())
 	    exp->write_type(p->type());
 	  else
@@ -3308,7 +3313,7 @@ Function::export_func_with_type(Export* 
   const Typed_identifier_list* results = fntype->results();
   if (results != NULL)
     {
-      if (results->size() == 1)
+      if (results->size() == 1 && results->begin()->name().empty())
 	{
 	  exp->write_c_string(" ");
 	  exp->write_type(results->begin()->type());
@@ -3325,6 +3330,8 @@ Function::export_func_with_type(Export* 
 		first = false;
 	      else
 		exp->write_c_string(", ");
+	      exp->write_name(p->name());
+	      exp->write_c_string(" ");
 	      exp->write_type(p->type());
 	    }
 	  exp->write_c_string(")");
@@ -3348,9 +3355,10 @@ Function::import_func(Import* imp, std::
   if (imp->peek_char() == '(')
     {
       imp->require_c_string("(");
+      std::string name = imp->read_name();
+      imp->require_c_string(" ");
       Type* rtype = imp->read_type();
-      *preceiver = new Typed_identifier(Import::import_marker, rtype,
-					imp->location());
+      *preceiver = new Typed_identifier(name, rtype, imp->location());
       imp->require_c_string(") ");
     }
 
@@ -3366,6 +3374,9 @@ Function::import_func(Import* imp, std::
       parameters = new Typed_identifier_list();
       while (true)
 	{
+	  std::string name = imp->read_name();
+	  imp->require_c_string(" ");
+
 	  if (imp->match_c_string("..."))
 	    {
 	      imp->advance(3);
@@ -3375,8 +3386,8 @@ Function::import_func(Import* imp, std::
 	  Type* ptype = imp->read_type();
 	  if (*is_varargs)
 	    ptype = Type::make_array_type(ptype, NULL);
-	  parameters->push_back(Typed_identifier(Import::import_marker,
-						 ptype, imp->location()));
+	  parameters->push_back(Typed_identifier(name, ptype,
+						 imp->location()));
 	  if (imp->peek_char() != ',')
 	    break;
 	  go_assert(!*is_varargs);
@@ -3396,17 +3407,18 @@ Function::import_func(Import* imp, std::
       if (imp->peek_char() != '(')
 	{
 	  Type* rtype = imp->read_type();
-	  results->push_back(Typed_identifier(Import::import_marker, rtype,
-					      imp->location()));
+	  results->push_back(Typed_identifier("", rtype, imp->location()));
 	}
       else
 	{
 	  imp->require_c_string("(");
 	  while (true)
 	    {
+	      std::string name = imp->read_name();
+	      imp->require_c_string(" ");
 	      Type* rtype = imp->read_type();
-	      results->push_back(Typed_identifier(Import::import_marker,
-						  rtype, imp->location()));
+	      results->push_back(Typed_identifier(name, rtype,
+						  imp->location()));
 	      if (imp->peek_char() != ',')
 		break;
 	      imp->require_c_string(", ");
Index: gcc/go/gofrontend/import.h
===================================================================
--- gcc/go/gofrontend/import.h	(revision 184188)
+++ gcc/go/gofrontend/import.h	(working copy)
@@ -181,14 +181,15 @@ class Import
   std::string
   read_identifier();
 
+  // Read a name.  This is like read_identifier, except that a "?" is
+  // returned as an empty string.  This matches Export::write_name.
+  std::string
+  read_name();
+
   // Read a type.
   Type*
   read_type();
 
-  // The name used for parameters, receivers, and results in imported
-  // function types.
-  static const char* const import_marker;
-
  private:
   static Stream*
   try_package_in_directory(const std::string&, Location);
Index: gcc/go/gofrontend/export.cc
===================================================================
--- gcc/go/gofrontend/export.cc	(revision 184188)
+++ gcc/go/gofrontend/export.cc	(working copy)
@@ -229,6 +229,17 @@ Export::write_imported_init_fns(
   this->write_c_string(";\n");
 }
 
+// Write a name to the export stream.
+
+void
+Export::write_name(const std::string& name)
+{
+  if (name.empty())
+    this->write_c_string("?");
+  else
+    this->write_string(Gogo::message_name(name));
+}
+
 // Export a type.  We have to ensure that on import we create a single
 // Named_type node for each named type.  We do this by keeping a hash
 // table mapping named types to reference numbers.  The first time we
Index: gcc/go/gofrontend/export.h
===================================================================
--- gcc/go/gofrontend/export.h	(revision 184188)
+++ gcc/go/gofrontend/export.h	(working copy)
@@ -145,6 +145,10 @@ class Export : public String_dump
   write_bytes(const char* bytes, size_t length)
   { this->stream_->write_bytes(bytes, length); }
 
+  // Write a name to the export stream.  If NAME is empty, write "?".
+  void
+  write_name(const std::string& name);
+
   // Write out a type.  This handles references back to previous
   // definitions.
   void
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 184348)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -3111,9 +3111,7 @@ Function_type::is_valid_redeclaration(co
   // A redeclaration of a function is required to use the same names
   // for the receiver and parameters.
   if (this->receiver() != NULL
-      && this->receiver()->name() != t->receiver()->name()
-      && this->receiver()->name() != Import::import_marker
-      && t->receiver()->name() != Import::import_marker)
+      && this->receiver()->name() != t->receiver()->name())
     {
       if (reason != NULL)
 	*reason = "receiver name changed";
@@ -3129,9 +3127,7 @@ Function_type::is_valid_redeclaration(co
 	   p2 != parms2->end();
 	   ++p2, ++p1)
 	{
-	  if (p1->name() != p2->name()
-	      && p1->name() != Import::import_marker
-	      && p2->name() != Import::import_marker)
+	  if (p1->name() != p2->name())
 	    {
 	      if (reason != NULL)
 		*reason = "parameter name changed";
@@ -3160,9 +3156,7 @@ Function_type::is_valid_redeclaration(co
 	   res2 != results2->end();
 	   ++res2, ++res1)
 	{
-	  if (res1->name() != res2->name()
-	      && res1->name() != Import::import_marker
-	      && res2->name() != Import::import_marker)
+	  if (res1->name() != res2->name())
 	    {
 	      if (reason != NULL)
 		*reason = "result name changed";
@@ -3609,6 +3603,8 @@ Function_type::do_export(Export* exp) co
 	    first = false;
 	  else
 	    exp->write_c_string(", ");
+	  exp->write_name(p->name());
+	  exp->write_c_string(" ");
 	  if (!is_varargs || p + 1 != this->parameters_->end())
 	    exp->write_type(p->type());
 	  else
@@ -3624,7 +3620,7 @@ Function_type::do_export(Export* exp) co
   if (results != NULL)
     {
       exp->write_c_string(" ");
-      if (results->size() == 1)
+      if (results->size() == 1 && results->begin()->name().empty())
 	exp->write_type(results->begin()->type());
       else
 	{
@@ -3638,6 +3634,8 @@ Function_type::do_export(Export* exp) co
 		first = false;
 	      else
 		exp->write_c_string(", ");
+	      exp->write_name(p->name());
+	      exp->write_c_string(" ");
 	      exp->write_type(p->type());
 	    }
 	  exp->write_c_string(")");
@@ -3660,6 +3658,9 @@ Function_type::do_import(Import* imp)
       parameters = new Typed_identifier_list();
       while (true)
 	{
+	  std::string name = imp->read_name();
+	  imp->require_c_string(" ");
+
 	  if (imp->match_c_string("..."))
 	    {
 	      imp->advance(3);
@@ -3669,8 +3670,8 @@ Function_type::do_import(Import* imp)
 	  Type* ptype = imp->read_type();
 	  if (is_varargs)
 	    ptype = Type::make_array_type(ptype, NULL);
-	  parameters->push_back(Typed_identifier(Import::import_marker,
-						 ptype, imp->location()));
+	  parameters->push_back(Typed_identifier(name, ptype,
+						 imp->location()));
 	  if (imp->peek_char() != ',')
 	    break;
 	  go_assert(!is_varargs);
@@ -3689,17 +3690,18 @@ Function_type::do_import(Import* imp)
       if (imp->peek_char() != '(')
 	{
 	  Type* rtype = imp->read_type();
-	  results->push_back(Typed_identifier(Import::import_marker, rtype,
-					      imp->location()));
+	  results->push_back(Typed_identifier("", rtype, imp->location()));
 	}
       else
 	{
 	  imp->advance(1);
 	  while (true)
 	    {
+	      std::string name = imp->read_name();
+	      imp->require_c_string(" ");
 	      Type* rtype = imp->read_type();
-	      results->push_back(Typed_identifier(Import::import_marker,
-						  rtype, imp->location()));
+	      results->push_back(Typed_identifier(name, rtype,
+						  imp->location()));
 	      if (imp->peek_char() != ',')
 		break;
 	      imp->require_c_string(", ");
@@ -7185,7 +7187,7 @@ Interface_type::do_export(Export* exp) c
 	{
 	  if (pm->name().empty())
 	    {
-	      exp->write_c_string("$ ");
+	      exp->write_c_string("? ");
 	      exp->write_type(pm->type());
 	    }
 	  else
@@ -7209,6 +7211,8 @@ Interface_type::do_export(Export* exp) c
 			first = false;
 		      else
 			exp->write_c_string(", ");
+		      exp->write_name(pp->name());
+		      exp->write_c_string(" ");
 		      if (!is_varargs || pp + 1 != parameters->end())
 			exp->write_type(pp->type());
 		      else
@@ -7226,7 +7230,7 @@ Interface_type::do_export(Export* exp) c
 	      if (results != NULL)
 		{
 		  exp->write_c_string(" ");
-		  if (results->size() == 1)
+		  if (results->size() == 1 && results->begin()->name().empty())
 		    exp->write_type(results->begin()->type());
 		  else
 		    {
@@ -7241,6 +7245,8 @@ Interface_type::do_export(Export* exp) c
 			    first = false;
 			  else
 			    exp->write_c_string(", ");
+			  exp->write_name(p->name());
+			  exp->write_c_string(" ");
 			  exp->write_type(p->type());
 			}
 		      exp->write_c_string(")");
@@ -7267,7 +7273,7 @@ Interface_type::do_import(Import* imp)
     {
       std::string name = imp->read_identifier();
 
-      if (name == "$")
+      if (name == "?")
 	{
 	  imp->require_c_string(" ");
 	  Type* t = imp->read_type();
@@ -7287,6 +7293,9 @@ Interface_type::do_import(Import* imp)
 	  parameters = new Typed_identifier_list;
 	  while (true)
 	    {
+	      std::string name = imp->read_name();
+	      imp->require_c_string(" ");
+
 	      if (imp->match_c_string("..."))
 		{
 		  imp->advance(3);
@@ -7296,8 +7305,8 @@ Interface_type::do_import(Import* imp)
 	      Type* ptype = imp->read_type();
 	      if (is_varargs)
 		ptype = Type::make_array_type(ptype, NULL);
-	      parameters->push_back(Typed_identifier(Import::import_marker,
-						     ptype, imp->location()));
+	      parameters->push_back(Typed_identifier(name, ptype,
+						     imp->location()));
 	      if (imp->peek_char() != ',')
 		break;
 	      go_assert(!is_varargs);
@@ -7316,17 +7325,18 @@ Interface_type::do_import(Import* imp)
 	  if (imp->peek_char() != '(')
 	    {
 	      Type* rtype = imp->read_type();
-	      results->push_back(Typed_identifier(Import::import_marker,
-						  rtype, imp->location()));
+	      results->push_back(Typed_identifier("", rtype, imp->location()));
 	    }
 	  else
 	    {
 	      imp->advance(1);
 	      while (true)
 		{
+		  std::string name = imp->read_name();
+		  imp->require_c_string(" ");
 		  Type* rtype = imp->read_type();
-		  results->push_back(Typed_identifier(Import::import_marker,
-						      rtype, imp->location()));
+		  results->push_back(Typed_identifier(name, rtype,
+						      imp->location()));
 		  if (imp->peek_char() != ',')
 		    break;
 		  imp->require_c_string(", ");
Index: gcc/go/gofrontend/import.cc
===================================================================
--- gcc/go/gofrontend/import.cc	(revision 184188)
+++ gcc/go/gofrontend/import.cc	(working copy)
@@ -11,6 +11,7 @@
 
 #include "go-c.h"
 #include "gogo.h"
+#include "lex.h"
 #include "types.h"
 #include "export.h"
 #include "import.h"
@@ -33,11 +34,6 @@ go_add_search_path(const char* path)
   search_path.push_back(std::string(path));
 }
 
-// The name used for parameters, receivers, and results in imported
-// function types.
-
-const char* const Import::import_marker = "*imported*";
-
 // Find import data.  This searches the file system for FILENAME and
 // returns a pointer to a Stream object to read the data that it
 // exports.  If the file is not found, it returns NULL.
@@ -749,6 +745,21 @@ Import::read_identifier()
   return ret;
 }
 
+// Read a name from the stream.
+
+std::string
+Import::read_name()
+{
+  std::string ret = this->read_identifier();
+  if (ret == "?")
+    ret.clear();
+  else if (!Lex::is_exported_name(ret))
+    ret = ('.' + this->package_->unique_prefix()
+	   + '.' + this->package_->name()
+	   + '.' + ret);
+  return ret;
+}
+
 // Turn a string into a integer with appropriate error handling.
 
 bool
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 184352)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -11783,7 +11783,7 @@ Selector_expression::lower_method_expres
 	   p != method_parameters->end();
 	   ++p, ++i)
 	{
-	  if (!p->name().empty() && p->name() != Import::import_marker)
+	  if (!p->name().empty())
 	    parameters->push_back(*p);
 	  else
 	    {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]