void
ASTLoweringBlock::visit (AST::BlockExpr &expr)
{
+ auto label = lower_loop_label (expr.get_label ());
+
std::vector<std::unique_ptr<HIR::Stmt>> block_stmts;
bool block_did_terminate = false;
= new HIR::BlockExpr (mapping, std::move (block_stmts),
std::unique_ptr<HIR::ExprWithoutBlock> (tail_expr),
tail_reachable, expr.get_inner_attrs (),
- expr.get_outer_attrs (), expr.get_start_locus (),
- expr.get_end_locus ());
+ expr.get_outer_attrs (), label,
+ expr.get_start_locus (), expr.get_end_locus ());
terminated = block_did_terminate;
}
namespace Rust {
namespace HIR {
+// Loop label expression HIR node used with break and continue expressions
+// TODO: inline?
+class LoopLabel /*: public Node*/
+{
+ Lifetime label; // or type LIFETIME_OR_LABEL
+
+ location_t locus;
+
+ Analysis::NodeMapping mappings;
+
+public:
+ std::string as_string () const;
+
+ LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label,
+ location_t locus)
+ : label (std::move (loop_label)), locus (locus), mappings (mapping)
+ {}
+
+ // Returns whether the LoopLabel is in an error state.
+ bool is_error () const { return label.is_error (); }
+
+ location_t get_locus () const { return locus; }
+
+ Analysis::NodeMapping &get_mappings () { return mappings; }
+
+ Lifetime &get_lifetime () { return label; }
+};
+
// HIR node for an expression with an accompanying block - abstract
class ExprWithBlock : public Expr
{
std::vector<std::unique_ptr<Stmt> > statements;
std::unique_ptr<Expr> expr;
bool tail_reachable;
+ LoopLabel label;
location_t start_locus;
location_t end_locus;
std::vector<std::unique_ptr<Stmt> > block_statements,
std::unique_ptr<Expr> block_expr, bool tail_reachable,
AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
- location_t start_locus, location_t end_locus)
+ LoopLabel label, location_t start_locus, location_t end_locus)
: ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
WithInnerAttrs (std::move (inner_attribs)),
statements (std::move (block_statements)), expr (std::move (block_expr)),
- tail_reachable (tail_reachable), start_locus (start_locus),
- end_locus (end_locus)
+ tail_reachable (tail_reachable), label (std::move (label)),
+ start_locus (start_locus), end_locus (end_locus)
{}
// Copy constructor with clone
BlockExpr (BlockExpr const &other)
: ExprWithBlock (other), /*statements(other.statements),*/
- WithInnerAttrs (other.inner_attrs), start_locus (other.start_locus),
- end_locus (other.end_locus)
+ WithInnerAttrs (other.inner_attrs), label (other.label),
+ start_locus (other.start_locus), end_locus (other.end_locus)
{
// guard to protect from null pointer dereference
if (other.expr != nullptr)
return ExprType::Block;
}
+ bool has_label () const { return !label.is_error (); }
+ LoopLabel &get_label () { return label; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
}
};
-// Loop label expression HIR node used with break and continue expressions
-// TODO: inline?
-class LoopLabel /*: public Node*/
-{
- Lifetime label; // or type LIFETIME_OR_LABEL
-
- location_t locus;
-
- Analysis::NodeMapping mappings;
-
-public:
- std::string as_string () const;
-
- LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label,
- location_t locus)
- : label (std::move (loop_label)), locus (locus), mappings (mapping)
- {}
-
- // Returns whether the LoopLabel is in an error state.
- bool is_error () const { return label.is_error (); }
-
- location_t get_locus () const { return locus; }
-
- Analysis::NodeMapping &get_mappings () { return mappings; }
-
- Lifetime &get_lifetime () { return label; }
-};
-
// Base loop expression HIR node - aka LoopExpr
class BaseLoopExpr : public ExprWithBlock
{