// 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
// 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.
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
// 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;
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;
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)
|| error_operand_p (fndecl))
{
*pstatement = error_mark_node;
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
}
tree var;
|| TREE_TYPE (init_tree) == void_type_node))
*pstatement = compound_statement (init_tree, *pstatement);
- return new Bvariable (var);
+ return LocalVariable (var);
}
// Make a label.
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