]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix multiple issues with variadic representation
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Thu, 19 Oct 2023 13:23:26 +0000 (15:23 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 18:13:12 +0000 (19:13 +0100)
The new variadic representation has introduced multiple issues and ICE
into the codebase. Some early passes in the compiler depend on the
parameters all having a type and being an actual parameter.

gcc/rust/ChangeLog:

* ast/rust-ast.cc (ExternalFunctionItem::as_string): Adapt as_string
function to the new ast representation.
(NamedFunctionParam::as_string): Likewise.
* ast/rust-item.h: Add a function to test whether a FunctionParam has
a name pattern.
* expand/rust-cfg-strip.cc (CfgStrip::visit): Adapt cfg strip visitor
for the new variadic arguments.
* hir/rust-ast-lower-extern.h: Adapt lowering to the new variadic
function representation.
* metadata/rust-export-metadata.cc (ExportContext::emit_function):
Change call to constructor.
* parse/rust-parse-impl.h (Parser::parse_named_function_param): Change
NamedFunctionParam parsing to accomodate new variadic representation.
(Parser::parse_external_item): Change external item parsing to use the
new NamedFunctionParam variadics.
* parse/rust-parse.h: Add new parsing function prototypes.
* ast/rust-ast-collector.cc (TokenCollector::visit): Rework token
collection to take into account variadic parameters.
* ast/rust-ast-visitor.cc: Likewise.
* expand/rust-expand-visitor.cc (ExpandVisitor::visit): Change function
bound to avoid getting the type of a variadic parameter.
* resolve/rust-ast-resolve-item.cc (ResolveExternItem::visit):
Likewise.
* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit):
Likewise.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
12 files changed:
gcc/rust/ast/rust-ast-collector.cc
gcc/rust/ast/rust-ast-visitor.cc
gcc/rust/ast/rust-ast.cc
gcc/rust/ast/rust-item.h
gcc/rust/expand/rust-cfg-strip.cc
gcc/rust/expand/rust-expand-visitor.cc
gcc/rust/hir/rust-ast-lower-extern.h
gcc/rust/metadata/rust-export-metadata.cc
gcc/rust/parse/rust-parse-impl.h
gcc/rust/parse/rust-parse.h
gcc/rust/resolve/rust-ast-resolve-item.cc
gcc/rust/resolve/rust-early-name-resolver.cc

index 71cc09835c3a1abd754bc24b8f791b5d0a0c37a6..9997523272164c840abbfe7aa43c13a01d9602fd 100644 (file)
@@ -172,9 +172,22 @@ TokenCollector::visit (Visitable &v)
 void
 TokenCollector::visit (FunctionParam &param)
 {
-  visit (param.get_pattern ());
-  push (Rust::Token::make (COLON, UNDEF_LOCATION));
-  visit (param.get_type ());
+  visit_items_as_lines (param.get_outer_attrs ());
+  if (!param.is_variadic ())
+    {
+      visit (param.get_pattern ());
+      push (Rust::Token::make (COLON, UNDEF_LOCATION));
+      visit (param.get_type ());
+    }
+  else
+    {
+      if (param.has_name ())
+       {
+         visit (param.get_pattern ());
+         push (Rust::Token::make (COLON, UNDEF_LOCATION));
+       }
+      push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
+    }
 }
 
 void
@@ -293,9 +306,23 @@ void
 TokenCollector::visit (NamedFunctionParam &param)
 {
   auto name = param.get_name ();
-  push (Rust::Token::make_identifier (param.get_locus (), std::move (name)));
-  push (Rust::Token::make (COLON, UNDEF_LOCATION));
-  visit (param.get_type ());
+  if (!param.is_variadic ())
+    {
+      push (
+       Rust::Token::make_identifier (param.get_locus (), std::move (name)));
+      push (Rust::Token::make (COLON, UNDEF_LOCATION));
+      visit (param.get_type ());
+    }
+  else
+    {
+      if (name != "")
+       {
+         push (Rust::Token::make_identifier (param.get_locus (),
+                                             std::move (name)));
+         push (Rust::Token::make (COLON, UNDEF_LOCATION));
+       }
+      push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
+    }
 }
 
 void
@@ -2209,13 +2236,6 @@ TokenCollector::visit (ExternalFunctionItem &function)
   push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
 
   visit_items_joined_by_separator (function.get_function_params ());
-  if (function.is_variadic ())
-    {
-      push (Rust::Token::make (COMMA, UNDEF_LOCATION));
-      // TODO: Add variadic outer attributes?
-      // TODO: Add variadic name once implemented.
-      push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
-    }
 
   push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
   if (function.has_return_type ())
index 9fb10997e1fdb620d62a5730a769352910c9de79..4b954fdc99841add7960a64c396374cc84f0c024 100644 (file)
@@ -721,8 +721,11 @@ void
 DefaultASTVisitor::visit (AST::FunctionParam &param)
 {
   visit_outer_attrs (param);
-  visit (param.get_pattern ());
-  visit (param.get_type ());
+  if (param.has_name ())
+    visit (param.get_pattern ());
+
+  if (!param.is_variadic ())
+    visit (param.get_type ());
 }
 
 void
@@ -1054,7 +1057,8 @@ void
 DefaultASTVisitor::visit (AST::NamedFunctionParam &param)
 {
   visit_outer_attrs (param);
-  visit (param.get_type ());
+  if (!param.is_variadic ())
+    visit (param.get_type ());
 }
 
 void
index d9c493debe6e69adc102c03e3237b9d07f55a2a6..3e8d4143e5af7f2df7bf55a840aa8bf2ee86cae8 100644 (file)
@@ -3036,7 +3036,7 @@ ExternalFunctionItem::as_string () const
 
   // function params
   str += "\n Function params: ";
-  if (function_params.empty () && !has_variadics)
+  if (function_params.empty ())
     {
       str += "none";
     }
@@ -3044,21 +3044,6 @@ ExternalFunctionItem::as_string () const
     {
       for (const auto &param : function_params)
        str += "\n  " + param.as_string ();
-
-      if (has_variadics)
-       {
-         str += "\n  variadic outer attrs: ";
-         if (has_variadic_outer_attrs ())
-           {
-             for (const auto &attr : variadic_outer_attrs)
-               str += "\n   " + attr.as_string ();
-           }
-         else
-           {
-             str += "none";
-           }
-         str += "\n  ... (variadic)";
-       }
     }
 
   // add type on new line
@@ -3080,9 +3065,13 @@ NamedFunctionParam::as_string () const
 {
   std::string str = append_attributes (outer_attrs, OUTER);
 
-  str += "\n" + name;
+  if (has_name ())
+    str += "\n" + name;
 
-  str += "\n Type: " + param_type->as_string ();
+  if (is_variadic ())
+    str += "...";
+  else
+    str += "\n Type: " + param_type->as_string ();
 
   return str;
 }
index 7cdbc8baf85f1dcf9162368c44ca39362c65c7e2..70ef93dcc5297c5811e6f65326f7ae5983e2e2e4 100644 (file)
@@ -618,6 +618,8 @@ public:
     return param_name;
   }
 
+  bool has_name () const { return param_name != nullptr; }
+
   // TODO: is this better? Or is a "vis_block" better?
   std::unique_ptr<Type> &get_type ()
   {
@@ -4171,7 +4173,7 @@ class NamedFunctionParam
 public:
   /* Returns whether the named function parameter has a name (i.e. name is not
    * '_'). */
-  bool has_name () const { return name != "_"; }
+  bool has_name () const { return name != "_" && name != ""; }
 
   bool has_outer_attrs () const { return !outer_attrs.empty (); }
 
@@ -4182,6 +4184,8 @@ public:
     return param_type == nullptr && !variadic;
   }
 
+  bool is_variadic () const { return variadic; }
+
   std::string get_name () const { return name; }
 
   location_t get_locus () { return locus; }
@@ -4294,8 +4298,6 @@ class ExternalFunctionItem : public ExternalItem
   WhereClause where_clause;
 
   std::vector<NamedFunctionParam> function_params;
-  bool has_variadics;
-  std::vector<Attribute> variadic_outer_attrs;
 
 public:
   // Returns whether item has generic parameters.
@@ -4314,12 +4316,10 @@ public:
   bool has_visibility () const { return !visibility.is_error (); }
 
   // Returns whether item has variadic parameters.
-  bool is_variadic () const { return has_variadics; }
-
-  // Returns whether item has outer attributes on its variadic parameters.
-  bool has_variadic_outer_attrs () const
+  bool is_variadic () const
   {
-    return !variadic_outer_attrs.empty ();
+    return function_params.size () != 0
+          && function_params.back ().is_variadic ();
   }
 
   location_t get_locus () const { return locus; }
@@ -4331,17 +4331,14 @@ public:
     Identifier item_name,
     std::vector<std::unique_ptr<GenericParam>> generic_params,
     std::unique_ptr<Type> return_type, WhereClause where_clause,
-    std::vector<NamedFunctionParam> function_params, bool has_variadics,
-    std::vector<Attribute> variadic_outer_attrs, Visibility vis,
+    std::vector<NamedFunctionParam> function_params, Visibility vis,
     std::vector<Attribute> outer_attrs, location_t locus)
     : ExternalItem (), outer_attrs (std::move (outer_attrs)),
       visibility (std::move (vis)), item_name (std::move (item_name)),
       locus (locus), generic_params (std::move (generic_params)),
       return_type (std::move (return_type)),
       where_clause (std::move (where_clause)),
-      function_params (std::move (function_params)),
-      has_variadics (has_variadics),
-      variadic_outer_attrs (std::move (variadic_outer_attrs))
+      function_params (std::move (function_params))
   {
     // TODO: assert that if has variadic outer attrs, then has_variadics is
     // true?
@@ -4351,10 +4348,7 @@ public:
   ExternalFunctionItem (ExternalFunctionItem const &other)
     : outer_attrs (other.outer_attrs), visibility (other.visibility),
       item_name (other.item_name), locus (other.locus),
-      where_clause (other.where_clause),
-      function_params (other.function_params),
-      has_variadics (other.has_variadics),
-      variadic_outer_attrs (other.variadic_outer_attrs)
+      where_clause (other.where_clause), function_params (other.function_params)
   {
     node_id = other.node_id;
     // guard to prevent null pointer dereference
@@ -4375,8 +4369,6 @@ public:
     locus = other.locus;
     where_clause = other.where_clause;
     function_params = other.function_params;
-    has_variadics = other.has_variadics;
-    variadic_outer_attrs = other.variadic_outer_attrs;
     node_id = other.node_id;
 
     // guard to prevent null pointer dereference
index 9c5b92c4460c5cbae9ed03379150564aa2177c5f..8976d858e163bf017ffa320a451e6c289cd3704e 100644 (file)
@@ -2603,12 +2603,15 @@ CfgStrip::visit (AST::ExternalFunctionItem &item)
          continue;
        }
 
-      auto &type = param.get_type ();
-      type->accept_vis (*this);
+      if (!param.is_variadic ())
+       {
+         auto &type = param.get_type ();
+         param.get_type ()->accept_vis (*this);
 
-      if (type->is_marked_for_strip ())
-       rust_error_at (type->get_locus (),
-                      "cannot strip type in this position");
+         if (type->is_marked_for_strip ())
+           rust_error_at (type->get_locus (),
+                          "cannot strip type in this position");
+       }
 
       // increment if nothing else happens
       ++it;
index b0fa004fdc34d98eafc12cfc1ad1e1ac5e6c51e4..cb9e8b6568abc27015de51e08fd999a868cf2897 100644 (file)
@@ -1265,12 +1265,9 @@ ExpandVisitor::visit (AST::ExternalFunctionItem &item)
   for (auto &param : item.get_generic_params ())
     visit (param);
 
-  // FIXME: Should this work? What is the difference between NamedFunctionParam
-  // and FunctionParam?
-  // expand_function_params (item.get_function_params ());
-
   for (auto &param : item.get_function_params ())
-    maybe_expand_type (param.get_type ());
+    if (!param.is_variadic ())
+      maybe_expand_type (param.get_type ());
 
   if (item.has_return_type ())
     maybe_expand_type (item.get_return_type ());
index 422e902253ad3580c4be55823597a1d726872b7f..cee480bb9ed84fffbbf3ee4ec9070891a5869212 100644 (file)
@@ -110,7 +110,7 @@ public:
     translated = new HIR::ExternalFunctionItem (
       mapping, function.get_identifier (), std::move (generic_params),
       std::unique_ptr<HIR::Type> (return_type), std::move (where_clause),
-      std::move (function_params), function.is_variadic (), std::move (vis),
+      std::move (function_params), is_variadic, std::move (vis),
       function.get_outer_attrs (), function.get_locus ());
   }
 
index 74c57ea68e1cecdbcb659610dad5121f8b81252b..73c3abfe0a28d62a272bd4fe1da2e4fdda5d2b0d 100644 (file)
@@ -118,11 +118,12 @@ ExportContext::emit_function (const HIR::Function &fn)
          function_params.push_back (std::move (p));
        }
 
-      AST::ExternalItem *external_item = new AST::ExternalFunctionItem (
-       item_name, {} /* generic_params */, std::move (return_type),
-       where_clause, std::move (function_params), false /* has_variadics */,
-       {} /* variadic_outer_attrs */, vis, function.get_outer_attrs (),
-       function.get_locus ());
+      AST::ExternalItem *external_item
+       = new AST::ExternalFunctionItem (item_name, {} /* generic_params */,
+                                        std::move (return_type), where_clause,
+                                        std::move (function_params), vis,
+                                        function.get_outer_attrs (),
+                                        function.get_locus ());
 
       std::vector<std::unique_ptr<AST::ExternalItem>> external_items;
       external_items.push_back (
index 61c915db99723970c0ede5b1e15d7f3f19c51ab5..007b2bfaba04a6ca363adbfbb33ee4d75ed41392 100644 (file)
@@ -5963,6 +5963,161 @@ Parser<ManagedTokenSource>::parse_extern_block (AST::Visibility vis,
                          std::move (outer_attrs), locus));
 }
 
+template <typename ManagedTokenSource>
+AST::NamedFunctionParam
+Parser<ManagedTokenSource>::parse_named_function_param ()
+{
+  AST::AttrVec outer_attrs = parse_outer_attributes ();
+  location_t locus = lexer.peek_token ()->get_locus ();
+
+  if (lexer.peek_token ()->get_id () == ELLIPSIS)
+    {
+      lexer.skip_token (); // Skip ellipsis
+      return AST::NamedFunctionParam (std::move (outer_attrs), locus);
+    }
+
+  // parse identifier/_
+  std::string name;
+
+  const_TokenPtr t = lexer.peek_token ();
+  location_t name_location = t->get_locus ();
+  switch (t->get_id ())
+    {
+    case IDENTIFIER:
+      name = t->get_str ();
+      lexer.skip_token ();
+      break;
+    case UNDERSCORE:
+      name = "_";
+      lexer.skip_token ();
+      break;
+    default:
+      // this is not a function param, but not necessarily an error
+      return AST::NamedFunctionParam::create_error ();
+    }
+
+  if (!skip_token (COLON))
+    {
+      // skip after somewhere?
+      return AST::NamedFunctionParam::create_error ();
+    }
+
+  // parse (required) type
+  std::unique_ptr<AST::Type> param_type = parse_type ();
+  if (param_type == nullptr)
+    {
+      Error error (
+       lexer.peek_token ()->get_locus (),
+       "could not parse param type in extern block function declaration");
+      add_error (std::move (error));
+
+      skip_after_semicolon ();
+      return AST::NamedFunctionParam::create_error ();
+    }
+
+  return AST::NamedFunctionParam (std::move (name), std::move (param_type),
+                                 std::move (outer_attrs), name_location);
+}
+
+template <typename ManagedTokenSource>
+template <typename EndTokenPred>
+std::vector<AST::NamedFunctionParam>
+Parser<ManagedTokenSource>::parse_named_function_params (
+  EndTokenPred is_end_token)
+{
+  std::vector<AST::NamedFunctionParam> params;
+  if (is_end_token (lexer.peek_token ()->get_id ()))
+    return params;
+
+  auto initial_param = parse_named_function_param ();
+  if (initial_param.is_error ())
+    return params;
+
+  params.push_back (std::move (initial_param));
+  auto t = lexer.peek_token ();
+  while (t->get_id () == COMMA)
+    {
+      lexer.skip_token ();
+      if (is_end_token (lexer.peek_token ()->get_id ()))
+       break;
+
+      auto param = parse_named_function_param ();
+      if (param.is_error ())
+       {
+         Error error (lexer.peek_token ()->get_locus (),
+                      "failed to parse param in c function params");
+         add_error (error);
+         return std::vector<AST::NamedFunctionParam> ();
+       }
+      params.push_back (std::move (param));
+      t = lexer.peek_token ();
+    }
+  params.shrink_to_fit ();
+  return params;
+}
+
+template <typename ManagedTokenSource>
+std::unique_ptr<AST::ExternalFunctionItem>
+Parser<ManagedTokenSource>::parse_external_function_item (
+  AST::Visibility vis, AST::AttrVec outer_attrs)
+{
+  location_t locus = lexer.peek_token ()->get_locus ();
+
+  // parse extern function declaration item
+  // skip function token
+  lexer.skip_token ();
+
+  // parse identifier
+  const_TokenPtr ident_tok = expect_token (IDENTIFIER);
+  if (ident_tok == nullptr)
+    {
+      skip_after_semicolon ();
+      return nullptr;
+    }
+  Identifier ident{ident_tok};
+
+  // parse (optional) generic params
+  std::vector<std::unique_ptr<AST::GenericParam>> generic_params
+    = parse_generic_params_in_angles ();
+
+  if (!skip_token (LEFT_PAREN))
+    {
+      skip_after_semicolon ();
+      return nullptr;
+    }
+
+  // parse parameters
+  std::vector<AST::NamedFunctionParam> function_params
+    = parse_named_function_params (
+      [] (TokenId id) { return id == RIGHT_PAREN; });
+
+  if (!skip_token (RIGHT_PAREN))
+    {
+      skip_after_semicolon ();
+      return nullptr;
+    }
+
+  // parse (optional) return type
+  std::unique_ptr<AST::Type> return_type = parse_function_return_type ();
+
+  // parse (optional) where clause
+  AST::WhereClause where_clause = parse_where_clause ();
+
+  if (!skip_token (SEMICOLON))
+    {
+      // skip somewhere?
+      return nullptr;
+    }
+
+  function_params.shrink_to_fit ();
+
+  return std::unique_ptr<AST::ExternalFunctionItem> (
+    new AST::ExternalFunctionItem (
+      std::move (ident), std::move (generic_params), std::move (return_type),
+      std::move (where_clause), std::move (function_params), std::move (vis),
+      std::move (outer_attrs), locus));
+}
+
 // Parses a single extern block item (static or function declaration).
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::ExternalItem>
@@ -6031,112 +6186,9 @@ Parser<ManagedTokenSource>::parse_external_item ()
                                       has_mut, std::move (vis),
                                       std::move (outer_attrs), locus));
       }
-      case FN_TOK: {
-       // parse extern function declaration item
-       // skip function token
-       lexer.skip_token ();
-
-       // parse identifier
-       const_TokenPtr ident_tok = expect_token (IDENTIFIER);
-       if (ident_tok == nullptr)
-         {
-           skip_after_semicolon ();
-           return nullptr;
-         }
-       Identifier ident{ident_tok};
-
-       // parse (optional) generic params
-       std::vector<std::unique_ptr<AST::GenericParam>> generic_params
-         = parse_generic_params_in_angles ();
-
-       if (!skip_token (LEFT_PAREN))
-         {
-           skip_after_semicolon ();
-           return nullptr;
-         }
-
-       // parse parameters
-       std::vector<AST::NamedFunctionParam> function_params;
-       bool is_variadic = false;
-       AST::AttrVec variadic_attrs;
-
-       const_TokenPtr t = lexer.peek_token ();
-       while (t->get_id () != RIGHT_PAREN)
-         {
-           AST::AttrVec maybe_variadic_attrs = parse_outer_attributes ();
-           if (lexer.peek_token ()->get_id () == ELLIPSIS)
-             {
-               // variadic - use attrs for this
-               lexer.skip_token ();
-               is_variadic = true;
-               variadic_attrs = std::move (maybe_variadic_attrs);
-               t = lexer.peek_token ();
-
-               if (t->get_id () != RIGHT_PAREN)
-                 {
-                   Error error (t->get_locus (),
-                                "expected right parentheses after variadic in "
-                                "named function "
-                                "parameters, found %qs",
-                                t->get_token_description ());
-                   add_error (std::move (error));
-
-                   skip_after_semicolon ();
-                   return nullptr;
-                 }
-
-               break;
-             }
-
-           AST::NamedFunctionParam param
-             = parse_named_function_param (std::move (maybe_variadic_attrs));
-           if (param.is_error ())
-             {
-               Error error (t->get_locus (), "could not parse named function "
-                                             "parameter in external function");
-               add_error (std::move (error));
-
-               skip_after_semicolon ();
-               return nullptr;
-             }
-           function_params.push_back (std::move (param));
-
-           if (lexer.peek_token ()->get_id () != COMMA)
-             break;
-
-           // skip comma
-           lexer.skip_token ();
-           t = lexer.peek_token ();
-         }
-
-       if (!skip_token (RIGHT_PAREN))
-         {
-           skip_after_semicolon ();
-           return nullptr;
-         }
-
-       // parse (optional) return type
-       std::unique_ptr<AST::Type> return_type = parse_function_return_type ();
-
-       // parse (optional) where clause
-       AST::WhereClause where_clause = parse_where_clause ();
-
-       if (!skip_token (SEMICOLON))
-         {
-           // skip somewhere?
-           return nullptr;
-         }
-
-       function_params.shrink_to_fit ();
-
-       return std::unique_ptr<AST::ExternalFunctionItem> (
-         new AST::ExternalFunctionItem (
-           std::move (ident), std::move (generic_params),
-           std::move (return_type), std::move (where_clause),
-           std::move (function_params), is_variadic,
-           std::move (variadic_attrs), std::move (vis),
-           std::move (outer_attrs), locus));
-      }
+    case FN_TOK:
+      return parse_external_function_item (std::move (vis),
+                                          std::move (outer_attrs));
     case TYPE:
       return parse_external_type_item (std::move (vis),
                                       std::move (outer_attrs));
@@ -6152,56 +6204,6 @@ Parser<ManagedTokenSource>::parse_external_item ()
     }
 }
 
-/* Parses an extern block function param (with "pattern" being _ or an
- * identifier). */
-template <typename ManagedTokenSource>
-AST::NamedFunctionParam
-Parser<ManagedTokenSource>::parse_named_function_param (
-  AST::AttrVec outer_attrs)
-{
-  // parse identifier/_
-  std::string name;
-
-  const_TokenPtr t = lexer.peek_token ();
-  location_t name_location = t->get_locus ();
-  switch (t->get_id ())
-    {
-    case IDENTIFIER:
-      name = t->get_str ();
-      lexer.skip_token ();
-      break;
-    case UNDERSCORE:
-      name = "_";
-      lexer.skip_token ();
-      break;
-    default:
-      // this is not a function param, but not necessarily an error
-      return AST::NamedFunctionParam::create_error ();
-    }
-
-  if (!skip_token (COLON))
-    {
-      // skip after somewhere?
-      return AST::NamedFunctionParam::create_error ();
-    }
-
-  // parse (required) type
-  std::unique_ptr<AST::Type> param_type = parse_type ();
-  if (param_type == nullptr)
-    {
-      Error error (
-       lexer.peek_token ()->get_locus (),
-       "could not parse param type in extern block function declaration");
-      add_error (std::move (error));
-
-      skip_after_semicolon ();
-      return AST::NamedFunctionParam::create_error ();
-    }
-
-  return AST::NamedFunctionParam (std::move (name), std::move (param_type),
-                                 std::move (outer_attrs), name_location);
-}
-
 // Parses a statement (will further disambiguate any statement).
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::Stmt>
index 6a69533b3f2b3eb2fc6e4e3db69438a27cdccb5d..e4322754c701e5b2197ea5501c12d7b89adca6fc 100644 (file)
@@ -298,6 +298,13 @@ private:
   AST::Lifetime lifetime_from_token (const_TokenPtr tok);
   std::unique_ptr<AST::ExternalTypeItem>
   parse_external_type_item (AST::Visibility vis, AST::AttrVec outer_attrs);
+  std::unique_ptr<AST::ExternalFunctionItem>
+  parse_external_function_item (AST::Visibility vis, AST::AttrVec outer_attrs);
+  AST::NamedFunctionParam parse_named_function_param ();
+  template <typename EndTokenPred>
+  std::vector<AST::NamedFunctionParam>
+  parse_named_function_params (EndTokenPred is_end_token);
+
   std::unique_ptr<AST::TypeAlias> parse_type_alias (AST::Visibility vis,
                                                    AST::AttrVec outer_attrs);
   std::unique_ptr<AST::Struct> parse_struct (AST::Visibility vis,
@@ -338,8 +345,6 @@ private:
                                       AST::AttrVec outer_attrs);
   std::unique_ptr<AST::ExternBlock>
   parse_extern_block (AST::Visibility vis, AST::AttrVec outer_attrs);
-  AST::NamedFunctionParam parse_named_function_param (AST::AttrVec outer_attrs
-                                                     = AST::AttrVec ());
   AST::Method parse_method ();
 
   // Expression-related (Pratt parsed)
index 04fa7216175101b4e6640811d4cf3ae9734b09d0..8126f8370fbce46b5cb7bbe952a43c6ce20bb342 100644 (file)
@@ -1115,9 +1115,8 @@ ResolveExternItem::visit (AST::ExternalFunctionItem &function)
   // we make a new scope so the names of parameters are resolved and shadowed
   // correctly
   for (auto &param : function.get_function_params ())
-    {
+    if (!param.is_variadic ())
       ResolveType::go (param.get_type ().get ());
-    }
 
   // done
   resolver->get_name_scope ().pop ();
index b9307c8612f26046f7f9d72ebf2853b592b4f046..4c78404f037c544032f9a7c2b2335735abb475fa 100644 (file)
@@ -872,7 +872,8 @@ EarlyNameResolver::visit (AST::ExternalFunctionItem &item)
     generic->accept_vis (*this);
 
   for (auto &param : item.get_function_params ())
-    param.get_type ()->accept_vis (*this);
+    if (!param.is_variadic ())
+      param.get_type ()->accept_vis (*this);
 
   if (item.has_return_type ())
     item.get_return_type ()->accept_vis (*this);