public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Go patch committed: Track //go:nointerface in export data
@ 2018-02-09 19:39 Ian Lance Taylor
  0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2018-02-09 19:39 UTC (permalink / raw)
  To: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 362 bytes --]

In the Go frontend, the magic //go:nointerface comment, used for field
tracking, was only implemented for conversions to interface types in
the same package.  This patch records it in the export data, so that
it works as expected for types imported from a different package.
Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 6155 bytes --]

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 257527)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@
-7e94bac5676afc8188677c98ecb263c78c1a7f8d
+89105404f94005ffa8e2b08df78015dc9ac91362
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 257527)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -5189,17 +5189,24 @@ Function::defer_stack(Location location)
 void
 Function::export_func(Export* exp, const std::string& name) const
 {
-  Function::export_func_with_type(exp, name, this->type_);
+  Function::export_func_with_type(exp, name, this->type_,
+				  this->is_method() && this->nointerface());
 }
 
 // Export a function with a type.
 
 void
 Function::export_func_with_type(Export* exp, const std::string& name,
-				const Function_type* fntype)
+				const Function_type* fntype, bool nointerface)
 {
   exp->write_c_string("func ");
 
+  if (nointerface)
+    {
+      go_assert(fntype->is_method());
+      exp->write_c_string("/*nointerface*/ ");
+    }
+
   if (fntype->is_method())
     {
       exp->write_c_string("(");
@@ -5280,10 +5287,21 @@ Function::import_func(Import* imp, std::
 		      Typed_identifier** preceiver,
 		      Typed_identifier_list** pparameters,
 		      Typed_identifier_list** presults,
-		      bool* is_varargs)
+		      bool* is_varargs,
+		      bool* nointerface)
 {
   imp->require_c_string("func ");
 
+  *nointerface = false;
+  if (imp->match_c_string("/*"))
+    {
+      imp->require_c_string("/*nointerface*/ ");
+      *nointerface = true;
+
+      // Only a method can be nointerface.
+      go_assert(imp->peek_char() == '(');
+    }
+
   *preceiver = NULL;
   if (imp->peek_char() == '(')
     {
@@ -6213,6 +6231,32 @@ Bindings_snapshot::check_goto_defs(Locat
 
 // Class Function_declaration.
 
+// Whether this declares a method.
+
+bool
+Function_declaration::is_method() const
+{
+  return this->fntype_->is_method();
+}
+
+// Whether this method should not be included in the type descriptor.
+
+bool
+Function_declaration::nointerface() const
+{
+  go_assert(this->is_method());
+  return (this->pragmas_ & GOPRAGMA_NOINTERFACE) != 0;
+}
+
+// Record that this method should not be included in the type
+// descriptor.
+
+void
+Function_declaration::set_nointerface()
+{
+  this->pragmas_ |= GOPRAGMA_NOINTERFACE;
+}
+
 // Return the function descriptor.
 
 Expression*
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 257527)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -1476,13 +1476,14 @@ class Function
   // Export a function with a type.
   static void
   export_func_with_type(Export*, const std::string& name,
-			const Function_type*);
+			const Function_type*, bool nointerface);
 
   // Import a function.
   static void
   import_func(Import*, std::string* pname, Typed_identifier** receiver,
 	      Typed_identifier_list** pparameters,
-	      Typed_identifier_list** presults, bool* is_varargs);
+	      Typed_identifier_list** presults, bool* is_varargs,
+	      bool* nointerface);
 
  private:
   // Type for mapping from label names to Label objects.
@@ -1607,6 +1608,10 @@ class Function_declaration
   location() const
   { return this->location_; }
 
+  // Return whether this function declaration is a method.
+  bool
+  is_method() const;
+
   const std::string&
   asm_name() const
   { return this->asm_name_; }
@@ -1628,6 +1633,16 @@ class Function_declaration
     this->pragmas_ = pragmas;
   }
 
+  // Whether this method should not be included in the type
+  // descriptor.
+  bool
+  nointerface() const;
+
+  // Record that this method should not be included in the type
+  // descriptor.
+  void
+  set_nointerface();
+
   // Return an expression for the function descriptor, given the named
   // object for this function.  This may only be called for functions
   // without a closure.  This will be an immutable struct with one
@@ -1652,7 +1667,10 @@ class Function_declaration
   // Export a function declaration.
   void
   export_func(Export* exp, const std::string& name) const
-  { Function::export_func_with_type(exp, name, this->fntype_); }
+  {
+    Function::export_func_with_type(exp, name, this->fntype_,
+				    this->is_method() && this->nointerface());
+  }
 
   // Check that the types used in this declaration's signature are defined.
   void
Index: gcc/go/gofrontend/import.cc
===================================================================
--- gcc/go/gofrontend/import.cc	(revision 257527)
+++ gcc/go/gofrontend/import.cc	(working copy)
@@ -607,8 +607,9 @@ Import::import_func(Package* package)
   Typed_identifier_list* parameters;
   Typed_identifier_list* results;
   bool is_varargs;
+  bool nointerface;
   Function::import_func(this, &name, &receiver,
-			&parameters, &results, &is_varargs);
+			&parameters, &results, &is_varargs, &nointerface);
   Function_type *fntype = Type::make_function_type(receiver, parameters,
 						   results, this->location_);
   if (is_varargs)
@@ -648,6 +649,10 @@ Import::import_func(Package* package)
       if (this->add_to_globals_)
 	this->gogo_->add_dot_import_object(no);
     }
+
+  if (nointerface)
+    no->func_declaration_value()->set_nointerface();
+
   return no;
 }
 
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 257527)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -9742,7 +9742,12 @@ bool
 Named_method::do_nointerface() const
 {
   Named_object* no = this->named_object_;
-  return no->is_function() && no->func_value()->nointerface();
+  if (no->is_function())
+    return no->func_value()->nointerface();
+  else if (no->is_function_declaration())
+    return no->func_declaration_value()->nointerface();
+  else
+    go_unreachable();
 }
 
 // Class Interface_method.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-02-09 19:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-09 19:39 Go patch committed: Track //go:nointerface in export data Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).