Patchwork [gccgo] Remove old ... syntax

login
register
mail settings
Submitter Ian Taylor
Date Oct. 22, 2010, 10:11 p.m.
Message ID <mcrd3r1x4ho.fsf@google.com>
Download mbox | patch
Permalink /patch/68982/
State New
Headers show

Comments

Ian Taylor - Oct. 22, 2010, 10:11 p.m.
Go used to permit this syntax for varargs:
  func f1(...)
You are now required to provide the type of the argument.
  func f2(... int)
  func f3(... interface{})

This patch implements that change in gccgo.  Committed to gccgo branch.

Ian

Patch

diff -r 8b1ab1ceabf1 go/expressions.cc
--- a/go/expressions.cc	Fri Oct 22 15:00:44 2010 -0700
+++ b/go/expressions.cc	Fri Oct 22 15:06:26 2010 -0700
@@ -7779,79 +7779,26 @@ 
 	push_empty_arg = true;
       else
 	{
-	  Type* element_type;
-	  Struct_field_list* fields;
-	  if (varargs_type->interface_type() != NULL)
-	    {
-	      element_type = NULL;
-	      fields = new Struct_field_list();
-	    }
-	  else
-	    {
-	      element_type = varargs_type->array_type()->element_type();
-	      fields = NULL;
-	    }
-
+	  Type* element_type = varargs_type->array_type()->element_type();
 	  Expression_list* vals = new Expression_list;
 	  for (; pa != old_args->end(); ++pa, ++i)
 	    {
 	      // Check types here so that we get a better message.
 	      Type* patype = (*pa)->type();
 	      source_location paloc = (*pa)->location();
-	      if (element_type != NULL)
-		{
-		  if (!this->check_argument_type(i, element_type, patype,
-						 paloc, issued_error))
-		    continue;
-		}
-	      else
-		{
-		  if (patype->is_nil_type())
-		    {
-		      if (!issued_error)
-			error_at((*pa)->location(),
-				 "invalid use of %<nil%> for %<...%> argument");
-		      continue;
-		    }
-		  if (patype->is_abstract())
-		    patype = patype->make_non_abstract_type();
-		  fields->push_back(Struct_field(Typed_identifier("UNNAMED",
-								  patype,
-								  paloc)));
-		}
-
+	      if (!this->check_argument_type(i, element_type, patype,
+					     paloc, issued_error))
+		continue;
 	      vals->push_back(*pa);
 	    }
-
-	  Expression* val;
-	  if (element_type == NULL)
-	    {
-	      Type* ctype = Type::make_struct_type(fields, loc);
-	      val = Expression::make_struct_composite_literal(ctype, vals, loc);
-	    }
-	  else
-	    {
-	      Type* ctype = Type::make_array_type(element_type, NULL);
-	      val = Expression::make_slice_composite_literal(ctype, vals, loc);
-	    }
-
+	  Expression* val =
+	    Expression::make_slice_composite_literal(varargs_type, vals, loc);
 	  new_args->push_back(val);
 	}
     }
 
   if (push_empty_arg)
-    {
-      if (varargs_type->interface_type() == NULL)
-	new_args->push_back(Expression::make_nil(loc));
-      else
-	{
-	  Struct_field_list* fields = new Struct_field_list();
-	  Type* param_type = Type::make_struct_type(fields, loc);
-	  Expression* v = Expression::make_struct_composite_literal(param_type,
-								    NULL, loc);
-	  new_args->push_back(v);
-	}
-    }
+    new_args->push_back(Expression::make_nil(loc));
 
   // We can't return a new call expression here, because this one may
   // be referenced by Call_result expressions.  FIXME.
@@ -7931,31 +7878,18 @@ 
   if (var_type == NULL)
     return false;
 
-  if (var_type->interface_type() != NULL)
-    {
-      // The argument is ... with no type.  We only match if the
-      // parameter is too.
-      if (param_type->interface_type() != NULL)
-	return true;
-      error_at(arg->location(), "... mismatch: passing ... as ...T");
-      *issued_error = true;
-      return false;
-    }
-  else
-    {
-      // The argument is ... T with a type.  We only match if the
-      // parameter is the same, with an identical type.
-      Array_type* var_at = var_type->array_type();
-      gcc_assert(var_at != NULL);
-      Array_type* param_at = param_type->array_type();
-      if (param_at != NULL
-	  && Type::are_identical(var_at->element_type(),
-				 param_at->element_type(), NULL))
-	return true;
-      error_at(arg->location(), "... mismatch: passing ...T as ...");
-      *issued_error = true;
-      return false;
-    }
+  // We only match if the parameter is the same, with an identical
+  // type.
+  Array_type* var_at = var_type->array_type();
+  gcc_assert(var_at != NULL);
+  Array_type* param_at = param_type->array_type();
+  if (param_at != NULL
+      && Type::are_identical(var_at->element_type(),
+			     param_at->element_type(), NULL))
+    return true;
+  error_at(arg->location(), "... mismatch: passing ...T as ...");
+  *issued_error = true;
+  return false;
 }
 
 // Get the function type.  Returns NULL if we don't know the type.  If
diff -r 8b1ab1ceabf1 go/gogo.cc
--- a/go/gogo.cc	Fri Oct 22 15:00:44 2010 -0700
+++ b/go/gogo.cc	Fri Oct 22 15:06:26 2010 -0700
@@ -2663,8 +2663,7 @@ 
 	  else
 	    {
 	      exp->write_c_string("...");
-	      if (p->type()->array_type() != NULL)
-		exp->write_type(p->type()->array_type()->element_type());
+	      exp->write_type(p->type()->array_type()->element_type());
 	    }
 	}
     }
@@ -2735,15 +2734,6 @@ 
 	    {
 	      imp->advance(3);
 	      *is_varargs = true;
-	      if (imp->peek_char() == ')')
-		{
-		  Type* empty = Type::make_interface_type(NULL,
-							  imp->location());
-		  parameters->push_back(Typed_identifier(Import::import_marker,
-							 empty,
-							 imp->location()));
-		  break;
-		}
 	    }
 
 	  Type* ptype = imp->read_type();
diff -r 8b1ab1ceabf1 go/parse.cc
--- a/go/parse.cc	Fri Oct 22 15:00:44 2010 -0700
+++ b/go/parse.cc	Fri Oct 22 15:06:26 2010 -0700
@@ -894,7 +894,7 @@ 
   return ret;
 }
 
-// ParameterDecl  = [ IdentifierList ] ( Type | "..." [ Type ] ) .
+// ParameterDecl  = [ IdentifierList ] [ "..." ] Type .
 
 void
 Parse::parameter_decl(bool parameters_have_names,
@@ -916,8 +916,10 @@ 
 		this->error("invalid use of %<...%>");
 	      else
 		*is_varargs = true;
-	      if (this->advance_token()->is_op(OPERATOR_RPAREN))
-		type = Type::make_interface_type(NULL, location);
+	      this->advance_token();
+	      if (is_varargs == NULL
+		  && this->peek_token()->is_op(OPERATOR_RPAREN))
+		type = Type::make_error_type();
 	      else
 		{
 		  Type* element_type = this->type();
@@ -961,15 +963,9 @@ 
 	    this->error("%<...%> only permits one name");
 	  else
 	    *is_varargs = true;
-	  source_location location = this->location();
 	  this->advance_token();
-	  if (!this->type_may_start_here())
-	    type = Type::make_interface_type(NULL, location);
-	  else
-	    {
-	      Type* element_type = this->type();
-	      type = Type::make_array_type(element_type, NULL);
-	    }
+	  Type* element_type = this->type();
+	  type = Type::make_array_type(element_type, NULL);
 	}
       for (size_t i = orig_count; i < new_count; ++i)
 	til->set_type(i, type);
diff -r 8b1ab1ceabf1 go/types.cc
--- a/go/types.cc	Fri Oct 22 15:00:44 2010 -0700
+++ b/go/types.cc	Fri Oct 22 15:06:26 2010 -0700
@@ -2716,9 +2716,8 @@ 
 	  else
 	    {
 	      ret->append("...");
-	      if (p->type()->array_type() != NULL)
-		this->append_reflection(p->type()->array_type()->element_type(),
-					gogo, ret);
+	      this->append_reflection(p->type()->array_type()->element_type(),
+				      gogo, ret);
 	    }
 	}
     }
@@ -2813,8 +2812,7 @@ 
 	  else
 	    {
 	      exp->write_c_string("...");
-	      if (p->type()->array_type() != NULL)
-		exp->write_type(p->type()->array_type()->element_type());
+	      exp->write_type(p->type()->array_type()->element_type());
 	    }
 	}
     }
@@ -2864,15 +2862,6 @@ 
 	    {
 	      imp->advance(3);
 	      is_varargs = true;
-	      if (imp->peek_char() == ')')
-		{
-		  Type* empty = Type::make_interface_type(NULL,
-							  imp->location());
-		  parameters->push_back(Typed_identifier(Import::import_marker,
-							 empty,
-							 imp->location()));
-		  break;
-		}
 	    }
 
 	  Type* ptype = imp->read_type();
@@ -6137,8 +6126,7 @@ 
 		    {
 		      exp->write_c_string("...");
 		      Type *pptype = pp->type();
-		      if (pptype->array_type() != NULL)
-			exp->write_type(pptype->array_type()->element_type());
+		      exp->write_type(pptype->array_type()->element_type());
 		    }
 		}
 	    }
@@ -6203,15 +6191,6 @@ 
 		{
 		  imp->advance(3);
 		  is_varargs = true;
-		  if (imp->peek_char() == ')')
-		    {
-		      Type* empty = Type::make_interface_type(NULL,
-							      imp->location());
-		      Typed_identifier tid(Import::import_marker, empty,
-					   imp->location());
-		      parameters->push_back(tid);
-		      break;
-		    }
 		}
 
 	      Type* ptype = imp->read_type();