Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse variadic functions #2701

Merged
merged 9 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions gcc/rust/ast/rust-ast-collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 ())
Expand Down
10 changes: 7 additions & 3 deletions gcc/rust/ast/rust-ast-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
25 changes: 7 additions & 18 deletions gcc/rust/ast/rust-ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3036,29 +3036,14 @@ ExternalFunctionItem::as_string () const

// function params
str += "\n Function params: ";
if (function_params.empty () && !has_variadics)
if (function_params.empty ())
{
str += "none";
}
else
{
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
Expand All @@ -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;
}
Expand Down
90 changes: 66 additions & 24 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,19 +528,34 @@ class FunctionParam
location_t locus;
std::unique_ptr<Pattern> param_name;
std::unique_ptr<Type> type;
bool variadic;

public:
FunctionParam (std::unique_ptr<Pattern> param_name,
std::unique_ptr<Type> param_type,
std::vector<Attribute> outer_attrs, location_t locus)
: outer_attrs (std::move (outer_attrs)), locus (locus),
param_name (std::move (param_name)), type (std::move (param_type)),
variadic (false),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}

FunctionParam (std::vector<Attribute> outer_attrs, location_t locus)
: outer_attrs (std::move (outer_attrs)), locus (locus),
param_name (nullptr), type (nullptr), variadic (true),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}

FunctionParam (std::unique_ptr<Pattern> param_name,
std::vector<Attribute> outer_attrs, location_t locus)
: outer_attrs (std::move (outer_attrs)), locus (locus),
param_name (std::move (param_name)), type (nullptr), variadic (true),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}

// Copy constructor uses clone
FunctionParam (FunctionParam const &other)
: locus (other.locus), node_id (other.node_id)
: locus (other.locus), variadic (other.variadic), node_id (other.node_id)
{
// guard to prevent nullptr dereference
if (other.param_name != nullptr)
Expand All @@ -554,6 +569,7 @@ class FunctionParam
{
locus = other.locus;
node_id = other.node_id;
variadic = other.variadic;

// guard to prevent nullptr dereference
if (other.param_name != nullptr)
Expand All @@ -573,7 +589,13 @@ class FunctionParam
FunctionParam &operator= (FunctionParam &&other) = default;

// Returns whether FunctionParam is in an invalid state.
bool is_error () const { return param_name == nullptr || type == nullptr; }
bool is_error () const
{
if (variadic)
return false;
else
return param_name == nullptr || type == nullptr;
}

// Creates an error FunctionParam.
static FunctionParam create_error ()
Expand All @@ -596,12 +618,17 @@ class FunctionParam
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 ()
{
rust_assert (type != nullptr);
return type;
}

bool is_variadic () const { return variadic; }

NodeId get_node_id () const { return node_id; }

protected:
Expand Down Expand Up @@ -1657,6 +1684,12 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem

void accept_vis (ASTVisitor &vis) override;

bool is_variadic () const
{
return function_params.size () != 0
&& function_params.back ().is_variadic ();
}

// Invalid if block is null, so base stripping on that.
void mark_for_strip () override { function_body = nullptr; }
bool is_marked_for_strip () const override
Expand Down Expand Up @@ -4135,21 +4168,24 @@ class NamedFunctionParam

NodeId node_id;
location_t locus;
bool variadic;

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 (); }

// Returns whether the named function parameter is in an error state.
bool is_error () const
{
// also if identifier is "" but that is probably more costly to compute
return param_type == nullptr;
return param_type == nullptr && !variadic;
}

bool is_variadic () const { return variadic; }

std::string get_name () const { return name; }

location_t get_locus () { return locus; }
Expand All @@ -4164,17 +4200,35 @@ class NamedFunctionParam
std::vector<Attribute> outer_attrs, location_t locus)
: name (std::move (name)), param_type (std::move (param_type)),
outer_attrs (std::move (outer_attrs)),
node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus)
node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus),
variadic (false)
{}

NamedFunctionParam (std::string name, std::vector<Attribute> outer_attrs,
location_t locus)
: name (std::move (name)), param_type (nullptr),
outer_attrs (std::move (outer_attrs)),
node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus),
variadic (true)
{}

NamedFunctionParam (std::vector<Attribute> outer_attrs, location_t locus)
: name (""), param_type (nullptr), outer_attrs (std::move (outer_attrs)),
node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus),
variadic (true)
{}

// Copy constructor
NamedFunctionParam (NamedFunctionParam const &other)
: name (other.name), outer_attrs (other.outer_attrs)
: name (other.name), outer_attrs (other.outer_attrs),
variadic (other.variadic)
{
node_id = other.node_id;
// guard to prevent null dereference (only required if error state)
if (other.param_type != nullptr)
param_type = other.param_type->clone_type ();
else
param_type = nullptr;
}

~NamedFunctionParam () = default;
Expand Down Expand Up @@ -4244,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.
Expand All @@ -4264,12 +4316,10 @@ class ExternalFunctionItem : public ExternalItem
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; }
Expand All @@ -4281,17 +4331,14 @@ class ExternalFunctionItem : public ExternalItem
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?
Expand All @@ -4301,10 +4348,7 @@ class ExternalFunctionItem : public ExternalItem
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
Expand All @@ -4325,8 +4369,6 @@ class ExternalFunctionItem : public ExternalItem
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
Expand Down
13 changes: 8 additions & 5 deletions gcc/rust/expand/rust-cfg-strip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 2 additions & 5 deletions gcc/rust/expand/rust-expand-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 ());
Expand Down
Loading
Loading