Skip to content

Create LocalVariable #3862

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
}

auto receiver_tmp = NULL_TREE;
auto receiver
Bvariable *receiver
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
TREE_TYPE (lhs), lhs, true,
expr.get_locus (), &receiver_tmp);
Expand Down Expand Up @@ -210,7 +210,7 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
if (ctx->in_fn () && !ctx->const_context_p ())
{
auto tmp = NULL_TREE;
auto receiver
Bvariable *receiver
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
TREE_TYPE (lhs), lhs, true,
expr.get_locus (), &tmp);
Expand Down
18 changes: 9 additions & 9 deletions gcc/rust/rust-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,18 +342,18 @@ void global_variable_set_init (Bvariable *, tree);
// the function, as otherwise the variable would be on the heap).
// LOCATION is where the variable is defined. For each local variable
// the frontend will call init_statement to set the initial value.
Bvariable *local_variable (tree function, GGC::Ident name, tree type,
Bvariable *decl_var, location_t location);
LocalVariable local_variable (tree function, GGC::Ident name, tree type,
Bvariable *decl_var, location_t location);

// Create a function parameter. This is an incoming parameter, not
// a result parameter (result parameters are treated as local
// variables). The arguments are as for local_variable.
Bvariable *parameter_variable (tree function, GGC::Ident name, tree type,
location_t location);
LocalVariable parameter_variable (tree function, GGC::Ident name, tree type,
location_t location);

// Create a static chain parameter. This is the closure parameter.
Bvariable *static_chain_variable (tree function, GGC::Ident name, tree type,
location_t location);
LocalVariable static_chain_variable (tree function, GGC::Ident name, tree type,
location_t location);

// Create a temporary variable. A temporary variable has no name,
// just a type. We pass in FUNCTION and BLOCK in case they are
Expand All @@ -366,9 +366,9 @@ Bvariable *static_chain_variable (tree function, GGC::Ident name, tree type,
// variable, and may not be very useful. This function should
// return a variable which can be referenced later and should set
// *PSTATEMENT to a statement which initializes the variable.
Bvariable *temporary_variable (tree fndecl, tree bind_tree, tree type,
tree init, bool address_is_taken,
location_t location, tree *pstatement);
LocalVariable temporary_variable (tree fndecl, tree bind_tree, tree type,
tree init, bool address_is_taken,
location_t location, tree *pstatement);

// Labels.

Expand Down
41 changes: 29 additions & 12 deletions gcc/rust/rust-gcc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,23 @@ Bvariable::error_variable ()
return new Bvariable (error_mark_node);
}

// Get the tree of a variable for use as an expression
tree
LocalVariable::get_tree (location_t location) const
{
if (error_operand_p (t))
return error_mark_node;

TREE_USED (t) = 1;
return t;
}

LocalVariable
LocalVariable::error_variable ()
{
return LocalVariable (error_mark_node);
}

// This file implements the interface between the Rust frontend proper
// and the gcc IR. This implements specific instantiations of
// abstract classes defined by the Rust frontend proper. The Rust
Expand Down Expand Up @@ -1980,12 +1997,12 @@ global_variable_set_init (Bvariable *var, tree expr_tree)

// Make a local variable.

Bvariable *
LocalVariable
local_variable (tree function, GGC::Ident name, tree type_tree,
Bvariable *decl_var, location_t location)
{
if (error_operand_p (type_tree))
return Bvariable::error_variable ();
return LocalVariable::error_variable ();
tree decl = build_decl (location, VAR_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = function;

Expand All @@ -1995,33 +2012,33 @@ local_variable (tree function, GGC::Ident name, tree type_tree,
SET_DECL_VALUE_EXPR (decl, decl_var->get_decl ());
}
rust_preserve_from_gc (decl);
return new Bvariable (decl);
return LocalVariable (decl);
}

// Make a function parameter variable.

Bvariable *
LocalVariable
parameter_variable (tree function, GGC::Ident name, tree type_tree,
location_t location)
{
if (error_operand_p (type_tree))
return Bvariable::error_variable ();
return LocalVariable::error_variable ();
tree decl = build_decl (location, PARM_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = function;
DECL_ARG_TYPE (decl) = type_tree;

rust_preserve_from_gc (decl);
return new Bvariable (decl);
return LocalVariable (decl);
}

// Make a static chain variable.

Bvariable *
LocalVariable
static_chain_variable (tree fndecl, GGC::Ident name, tree type_tree,
location_t location)
{
if (error_operand_p (type_tree))
return Bvariable::error_variable ();
return LocalVariable::error_variable ();
tree decl = build_decl (location, PARM_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = fndecl;
DECL_ARG_TYPE (decl) = type_tree;
Expand All @@ -2042,12 +2059,12 @@ static_chain_variable (tree fndecl, GGC::Ident name, tree type_tree,
DECL_STATIC_CHAIN (fndecl) = 1;

rust_preserve_from_gc (decl);
return new Bvariable (decl);
return LocalVariable (decl);
}

// Make a temporary variable.

Bvariable *
LocalVariable
temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
bool is_address_taken, location_t location,
tree *pstatement)
Expand All @@ -2057,7 +2074,7 @@ temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
|| error_operand_p (fndecl))
{
*pstatement = error_mark_node;
return Bvariable::error_variable ();
return LocalVariable::error_variable ();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of error state hidden within a single class. Couldn't we return an Expected<LocalVariable> ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, though I'd like to leave that for another PR

}

tree var;
Expand Down Expand Up @@ -2107,7 +2124,7 @@ temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
|| TREE_TYPE (init_tree) == void_type_node))
*pstatement = compound_statement (init_tree, *pstatement);

return new Bvariable (var);
return LocalVariable (var);
}

// Make a label.
Expand Down
24 changes: 24 additions & 0 deletions gcc/rust/rust-gcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,28 @@ class Bvariable
tree orig_type_;
};

// like Bvariable, but orig_type_ == nullptr always holds
// could be any variable which isn't a zero-sized global
class LocalVariable
{
public:
LocalVariable (tree t) : t (t) {}

// Get the tree for use as an expression.
tree get_tree (location_t) const;

// Get the actual decl;
tree get_decl () const { return t; }

// Create an error variable. This is used for cases which should
// not occur in a correct program, in order to keep the compilation
// going without crashing.
static LocalVariable error_variable ();

operator Bvariable * () const { return new Bvariable (t); }

private:
tree t;
};

#endif // RUST_GCC
Loading