aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSimplyTheOther <simplytheother@gmail.com>2020-10-25 17:04:55 +0800
committerSimplyTheOther <simplytheother@gmail.com>2020-12-08 21:10:16 +0800
commit98d429466bf783ff1a7ac59bf800061d3e67061a (patch)
treedfd9923f42bc77371b7e379a70978d0618a4e0ed /gcc
parenteb644945a4f1bcac234a099f904812dcbbafcc93 (diff)
downloadgcc-98d429466bf783ff1a7ac59bf800061d3e67061a.zip
gcc-98d429466bf783ff1a7ac59bf800061d3e67061a.tar.gz
gcc-98d429466bf783ff1a7ac59bf800061d3e67061a.tar.bz2
Added strip-marking to statements, items and expressions (to allow them to be stripped from their parents)
Fixed compile errors and added more stripping behaviour for extern blocks
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc41
-rw-r--r--gcc/rust/ast/rust-ast.h98
-rw-r--r--gcc/rust/ast/rust-expr.h1000
-rw-r--r--gcc/rust/ast/rust-item.h319
-rw-r--r--gcc/rust/ast/rust-macro.h44
-rw-r--r--gcc/rust/ast/rust-path.h77
-rw-r--r--gcc/rust/ast/rust-pattern.h21
-rw-r--r--gcc/rust/ast/rust-stmt.h85
-rw-r--r--gcc/rust/ast/rust-type.h98
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc219
-rw-r--r--gcc/rust/rust-session-manager.cc3
11 files changed, 1153 insertions, 852 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index e269645..cbeb7d4 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -192,6 +192,8 @@ Attribute &Attribute::operator= (Attribute const &other)
// guard to protect from null pointer dereference
if (other.attr_input != nullptr)
attr_input = other.attr_input->clone_attr_input ();
+ else
+ attr_input = nullptr;
return *this;
}
@@ -323,7 +325,13 @@ std::string
VisItem::as_string () const
{
// FIXME: can't do formatting on string to make identation occur.
- std::string str = Item::as_string ();
+ std::string str;
+
+ if (!outer_attrs.empty ())
+ {
+ for (const auto &attr : outer_attrs)
+ str += attr.as_string () + "\n";
+ }
if (has_visibility ())
{
@@ -334,7 +342,7 @@ VisItem::as_string () const
}
// Creates a string that reflects the outer attributes stored.
-std::string
+/*std::string
Item::as_string () const
{
std::string str;
@@ -348,7 +356,7 @@ Item::as_string () const
}
return str;
-}
+}*/
std::string
Module::as_string () const
@@ -1400,8 +1408,14 @@ TypeAlias::as_string () const
std::string
MacroInvocationSemi::as_string () const
{
+ std::string str;
+
// get outer attrs
- std::string str = MacroItem::as_string ();
+ if (!outer_attrs.empty ())
+ {
+ for (const auto &attr : outer_attrs)
+ str += attr.as_string () + "\n";
+ }
str += "\n" + path.as_string () + "!";
@@ -1498,7 +1512,16 @@ MacroRule::as_string () const
std::string
MacroRulesDefinition::as_string () const
{
- std::string str ("macro_rules!");
+ std::string str;
+
+ // get outer attrs
+ if (!outer_attrs.empty ())
+ {
+ for (const auto &attr : outer_attrs)
+ str += attr.as_string () + "\n";
+ }
+
+ str += "macro_rules!";
str += rule_name;
@@ -1510,9 +1533,7 @@ MacroRulesDefinition::as_string () const
else
{
for (const auto &rule : rules)
- {
str += "\n " + rule.as_string ();
- }
}
str += "\n Delim type: ";
@@ -5403,9 +5424,9 @@ std::vector<Attribute> Attribute::separate_cfg_attrs () {
if (!has_attr_input () || path.as_string () != "cfg_attr")
return {};
- // TODO: maybe replace with storing a "has been parsed" variable?
- parse_attr_to_meta_item ();
- // can't be const because of this anyway
+ // TODO: maybe replace with storing a "has been parsed" variable?
+ parse_attr_to_meta_item ();
+ // can't be const because of this anyway
return attr_input->separate_cfg_attrs ();
}
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 90e3504..31c547a 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -591,7 +591,7 @@ public:
void accept_vis (ASTVisitor &vis) override;
bool
- check_cfg_predicate (const Session &session ATTRIBUTE_UNUSED) const override
+ check_cfg_predicate (const Session&) const override
{
// this should never be called - should be converted first
return false;
@@ -764,6 +764,9 @@ public:
* methods. */
virtual Location get_locus_slow () const { return Location (); }
+ virtual void mark_for_strip () = 0;
+ virtual bool is_marked_for_strip () const = 0;
+
protected:
// Clone function implementation as pure virtual method
virtual Stmt *clone_stmt_impl () const = 0;
@@ -772,10 +775,6 @@ protected:
// Rust "item" AST node (declaration of top-level/module-level allowed stuff)
class Item : public Stmt
{
- std::vector<Attribute> outer_attrs;
-
- // TODO: should outer attrs be defined here or in each derived class?
-
public:
// Unique pointer custom clone function
std::unique_ptr<Item> clone_item () const
@@ -783,29 +782,22 @@ public:
return std::unique_ptr<Item> (clone_item_impl ());
}
- std::string as_string () const;
+ std::string as_string () const = 0;
/* Adds crate names to the vector passed by reference, if it can
- * (polymorphism). */
+ * (polymorphism). TODO: remove, unused. */
virtual void
add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
{}
- virtual void accept_vis (ASTVisitor &vis ATTRIBUTE_UNUSED) {}
-
protected:
- // Constructor
- Item (std::vector<Attribute> outer_attribs = std::vector<Attribute> ())
- : outer_attrs (std::move (outer_attribs))
- {}
-
// Clone function implementation as pure virtual method
virtual Item *clone_item_impl () const = 0;
/* Save having to specify two clone methods in derived classes by making
* statement clone return item clone. Hopefully won't affect performance too
* much. */
- Item *clone_stmt_impl () const override { return clone_item_impl (); }
+ Item *clone_stmt_impl () const final override { return clone_item_impl (); }
};
// forward decl of ExprWithoutBlock
@@ -849,6 +841,9 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
+ virtual void mark_for_strip () = 0;
+ virtual bool is_marked_for_strip () const = 0;
+
protected:
// Constructor
Expr (std::vector<Attribute> outer_attribs = std::vector<Attribute> ())
@@ -882,7 +877,7 @@ protected:
/* Save having to specify two clone methods in derived classes by making expr
* clone return exprwithoutblock clone. Hopefully won't affect performance too
* much. */
- ExprWithoutBlock *clone_expr_impl () const override
+ ExprWithoutBlock *clone_expr_impl () const final override
{
return clone_expr_without_block_impl ();
}
@@ -935,6 +930,10 @@ public:
return std::unique_ptr<IdentifierExpr> (clone_identifier_expr_impl ());
}
+ // "Error state" if ident is empty, so base stripping on this.
+ void mark_for_strip () override { ident = {}; }
+ bool is_marked_for_strip () const override { return ident.empty (); }
+
protected:
// Clone method implementation
IdentifierExpr *clone_expr_without_block_impl () const override
@@ -946,9 +945,6 @@ protected:
{
return new IdentifierExpr (*this);
}
-
- IdentifierExpr (IdentifierExpr const &other) = default;
- IdentifierExpr &operator= (IdentifierExpr const &other) = default;
};
// Pattern base AST node
@@ -994,7 +990,7 @@ public:
/* HACK: convert to trait bound. Virtual method overriden by classes that
* enable this. */
- virtual TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const
+ virtual TraitBound *to_trait_bound (bool) const
{
return nullptr;
}
@@ -1025,7 +1021,7 @@ protected:
/* Save having to specify two clone methods in derived classes by making type
* clone return typenobounds clone. Hopefully won't affect performance too
* much. */
- TypeNoBounds *clone_type_impl () const override
+ TypeNoBounds *clone_type_impl () const final override
{
return clone_type_no_bounds_impl ();
}
@@ -1207,10 +1203,12 @@ class MacroItem : public Item
{
/*public:
std::string as_string() const;*/
+ //std::vector<Attribute> outer_attrs;
+
protected:
- MacroItem (std::vector<Attribute> outer_attribs)
- : Item (std::move (outer_attribs))
- {}
+ /*MacroItem (std::vector<Attribute> outer_attribs)
+ : outer_attrs (std::move (outer_attribs))
+ {}*/
};
// Item used in trait declarations - abstract base class
@@ -1298,6 +1296,7 @@ class MacroInvocationSemi : public MacroItem,
public InherentImplItem,
public TraitImplItem
{
+ std::vector<Attribute> outer_attrs;
SimplePath path;
// all delim types except curly must have invocation end with a semicolon
DelimType delim_type;
@@ -1310,36 +1309,15 @@ public:
MacroInvocationSemi (SimplePath macro_path, DelimType delim_type,
std::vector<std::unique_ptr<TokenTree>> token_trees,
std::vector<Attribute> outer_attribs, Location locus)
- : MacroItem (std::move (outer_attribs)), path (std::move (macro_path)),
+ : outer_attrs (std::move (outer_attribs)), path (std::move (macro_path)),
delim_type (delim_type), token_trees (std::move (token_trees)),
locus (locus)
{}
- /* TODO: possible issue with Item and TraitItem hierarchies both having outer
- * attributes
- * - storage inefficiency at least.
- * Best current idea is to make Item preferred and have TraitItem get virtual
- * functions for attributes or something. Or just redo the "composition"
- * approach, but then this prevents polymorphism and would entail redoing
- * quite a bit of the parser. */
-
- // Move constructors
- MacroInvocationSemi (MacroInvocationSemi &&other) = default;
- MacroInvocationSemi &operator= (MacroInvocationSemi &&other) = default;
-
- void accept_vis (ASTVisitor &vis) override;
-
- // Clones this macro invocation semi.
- std::unique_ptr<MacroInvocationSemi> clone_macro_invocation_semi () const
- {
- return std::unique_ptr<MacroInvocationSemi> (
- clone_macro_invocation_semi_impl ());
- }
-protected:
// Copy constructor with vector clone
MacroInvocationSemi (MacroInvocationSemi const &other)
: MacroItem (other), TraitItem (other), InherentImplItem (other),
- TraitImplItem (other), path (other.path), delim_type (other.delim_type),
+ TraitImplItem (other), outer_attrs(other.outer_attrs), path (other.path), delim_type (other.delim_type),
locus (other.locus)
{
token_trees.reserve (other.token_trees.size ());
@@ -1354,6 +1332,7 @@ protected:
TraitItem::operator= (other);
InherentImplItem::operator= (other);
TraitImplItem::operator= (other);
+ outer_attrs = other.outer_attrs;
path = other.path;
delim_type = other.delim_type;
locus = other.locus;
@@ -1365,6 +1344,24 @@ protected:
return *this;
}
+ // Move constructors
+ MacroInvocationSemi (MacroInvocationSemi &&other) = default;
+ MacroInvocationSemi &operator= (MacroInvocationSemi &&other) = default;
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ // Clones this macro invocation semi.
+ std::unique_ptr<MacroInvocationSemi> clone_macro_invocation_semi () const
+ {
+ return std::unique_ptr<MacroInvocationSemi> (
+ clone_macro_invocation_semi_impl ());
+ }
+
+ // Invalid if path is empty, so base stripping on that.
+ void mark_for_strip () override { path = SimplePath::create_empty (); }
+ bool is_marked_for_strip () const override { return path.is_empty (); }
+
+protected:
MacroInvocationSemi *clone_macro_invocation_semi_impl () const
{
return new MacroInvocationSemi (*this);
@@ -1391,13 +1388,6 @@ protected:
return clone_macro_invocation_semi_impl ();
}
- // FIXME: remove if item impl virtual override works properly
- // Use covariance to implement clone function as returning this object rather
- // than base
- /*MacroInvocationSemi* clone_statement_impl() const override {
- return clone_macro_invocation_semi_impl ();
- }*/
-
/* Use covariance to implement clone function as returning this object rather
* than base */
MacroInvocationSemi *clone_trait_item_impl () const override
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index fd6913f..4647829 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -23,7 +23,7 @@ protected:
virtual ExprWithBlock *clone_expr_with_block_impl () const = 0;
// prevent having to define multiple clone expressions
- ExprWithBlock *clone_expr_impl () const override
+ ExprWithBlock *clone_expr_impl () const final override
{
return clone_expr_with_block_impl ();
}
@@ -73,19 +73,16 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- LiteralExpr *clone_expr_impl () const override
- {
- return new LiteralExpr (*this);
- }
+ // Invalid if literal is in error state, so base stripping on that.
+ void mark_for_strip () override { literal = Literal::create_error (); }
+ bool is_marked_for_strip () const override { return literal.is_error (); }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
LiteralExpr *clone_expr_without_block_impl () const override
{
- return new LiteralExpr (*this);
+ return clone_literal_expr_impl ();
}
/* not virtual as currently no subclasses of LiteralExpr, but could be in
@@ -121,7 +118,7 @@ public:
/* this can never be a cfg predicate - cfg and cfg_attr require a token-tree
* cfg */
bool
- check_cfg_predicate (const Session &session ATTRIBUTE_UNUSED) const override
+ check_cfg_predicate (const Session&) const override
{
return false;
}
@@ -212,18 +209,26 @@ protected:
// Copy constructor (only for initialisation of expr purposes)
OperatorExpr (OperatorExpr const &other)
- : ExprWithoutBlock (other), locus (other.locus),
- main_or_left_expr (other.main_or_left_expr->clone_expr ())
- {}
+ : ExprWithoutBlock (other), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.main_or_left_expr != nullptr)
+ main_or_left_expr = other.main_or_left_expr->clone_expr ();
+ }
// Overload assignment operator to deep copy expr
OperatorExpr &operator= (OperatorExpr const &other)
{
ExprWithoutBlock::operator= (other);
- main_or_left_expr = other.main_or_left_expr->clone_expr ();
locus = other.locus;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.main_or_left_expr != nullptr)
+ main_or_left_expr = other.main_or_left_expr->clone_expr ();
+ else
+ main_or_left_expr = nullptr;
+
return *this;
}
@@ -234,6 +239,10 @@ protected:
public:
Location get_locus () const { return locus; }
Location get_locus_slow () const override { return get_locus (); }
+
+ // Invalid if expr is null, so base stripping on that.
+ void mark_for_strip () override { main_or_left_expr = nullptr; }
+ bool is_marked_for_strip () const override { return main_or_left_expr == nullptr; }
};
/* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be
@@ -249,9 +258,8 @@ public:
BorrowExpr (std::unique_ptr<Expr> borrow_lvalue, bool is_mut_borrow,
bool is_double_borrow, std::vector<Attribute> outer_attribs,
Location locus)
- : OperatorExpr (std::move (borrow_lvalue), std::move (outer_attribs),
- locus),
- is_mut (is_mut_borrow), double_borrow (is_double_borrow)
+ : OperatorExpr (std::move (borrow_lvalue), std::move (outer_attribs),
+ locus), is_mut (is_mut_borrow), double_borrow (is_double_borrow)
{}
void accept_vis (ASTVisitor &vis) override;
@@ -259,13 +267,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- BorrowExpr *clone_expr_impl () const override
- {
- return new BorrowExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
BorrowExpr *clone_expr_without_block_impl () const override
{
return new BorrowExpr (*this);
@@ -289,13 +290,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- DereferenceExpr *clone_expr_impl () const override
- {
- return new DereferenceExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
DereferenceExpr *clone_expr_without_block_impl () const override
{
return new DereferenceExpr (*this);
@@ -320,13 +314,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ErrorPropagationExpr *clone_expr_impl () const override
- {
- return new ErrorPropagationExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ErrorPropagationExpr *clone_expr_without_block_impl () const override
{
return new ErrorPropagationExpr (*this);
@@ -368,13 +355,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- NegationExpr *clone_expr_impl () const override
- {
- return new NegationExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
NegationExpr *clone_expr_without_block_impl () const override
{
return new NegationExpr (*this);
@@ -450,13 +430,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ArithmeticOrLogicalExpr *clone_expr_impl () const override
- {
- return new ArithmeticOrLogicalExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ArithmeticOrLogicalExpr *clone_expr_without_block_impl () const override
{
return new ArithmeticOrLogicalExpr (*this);
@@ -527,13 +500,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ComparisonExpr *clone_expr_impl () const override
- {
- return new ComparisonExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ComparisonExpr *clone_expr_without_block_impl () const override
{
return new ComparisonExpr (*this);
@@ -597,13 +563,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- LazyBooleanExpr *clone_expr_impl () const override
- {
- return new LazyBooleanExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
LazyBooleanExpr *clone_expr_without_block_impl () const override
{
return new LazyBooleanExpr (*this);
@@ -652,13 +611,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TypeCastExpr *clone_expr_impl () const override
- {
- return new TypeCastExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
TypeCastExpr *clone_expr_without_block_impl () const override
{
return new TypeCastExpr (*this);
@@ -712,13 +664,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- AssignmentExpr *clone_expr_impl () const override
- {
- return new AssignmentExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
AssignmentExpr *clone_expr_without_block_impl () const override
{
return new AssignmentExpr (*this);
@@ -791,13 +736,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- CompoundAssignmentExpr *clone_expr_impl () const override
- {
- return new CompoundAssignmentExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
CompoundAssignmentExpr *clone_expr_without_block_impl () const override
{
return new CompoundAssignmentExpr (*this);
@@ -828,18 +766,27 @@ public:
// Copy constructor includes clone for expr_in_parens
GroupedExpr (GroupedExpr const &other)
: ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
- expr_in_parens (other.expr_in_parens->clone_expr ()), locus (other.locus)
- {}
+ locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr_in_parens != nullptr)
+ expr_in_parens = other.expr_in_parens->clone_expr ();
+ }
// Overloaded assignment operator to clone expr_in_parens
GroupedExpr &operator= (GroupedExpr const &other)
{
ExprWithoutBlock::operator= (other);
inner_attrs = other.inner_attrs;
- expr_in_parens = other.expr_in_parens->clone_expr ();
locus = other.locus;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr_in_parens != nullptr)
+ expr_in_parens = other.expr_in_parens->clone_expr ();
+ else
+ expr_in_parens = nullptr;
+
return *this;
}
@@ -852,14 +799,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- GroupedExpr *clone_expr_impl () const override
- {
- return new GroupedExpr (*this);
- }
+ // Invalid if inner expr is null, so base stripping on that.
+ void mark_for_strip () override { expr_in_parens = nullptr; }
+ bool is_marked_for_strip () const override { return expr_in_parens == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
GroupedExpr *clone_expr_without_block_impl () const override
@@ -988,6 +932,9 @@ class ArrayExpr : public ExprWithoutBlock
std::unique_ptr<ArrayElems> internal_elements;
Location locus;
+
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
public:
std::string as_string () const override;
@@ -1009,7 +956,7 @@ public:
// Copy constructor requires cloning ArrayElems for polymorphism to hold
ArrayExpr (ArrayExpr const &other)
: ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
- locus (other.locus)
+ locus (other.locus), marked_for_strip (other.marked_for_strip)
{
if (other.has_array_elems ())
internal_elements = other.internal_elements->clone_array_elems ();
@@ -1020,11 +967,15 @@ public:
{
ExprWithoutBlock::operator= (other);
inner_attrs = other.inner_attrs;
- if (other.has_array_elems ())
- internal_elements = other.internal_elements->clone_array_elems ();
locus = other.locus;
+ marked_for_strip = other.marked_for_strip;
// outer_attrs = other.outer_attrs;
+ if (other.has_array_elems ())
+ internal_elements = other.internal_elements->clone_array_elems ();
+ else
+ internal_elements = nullptr;
+
return *this;
}
@@ -1037,11 +988,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ArrayExpr *clone_expr_impl () const override { return new ArrayExpr (*this); }
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
ArrayExpr *clone_expr_without_block_impl () const override
@@ -1075,19 +1026,32 @@ public:
// Copy constructor requires special cloning due to unique_ptr
ArrayIndexExpr (ArrayIndexExpr const &other)
- : ExprWithoutBlock (other), array_expr (other.array_expr->clone_expr ()),
- index_expr (other.index_expr->clone_expr ()), locus (other.locus)
- {}
+ : ExprWithoutBlock (other), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.array_expr != nullptr)
+ array_expr = other.array_expr->clone_expr ();
+ if (other.index_expr != nullptr)
+ index_expr = other.index_expr->clone_expr ();
+ }
// Overload assignment operator to clone unique_ptrs
ArrayIndexExpr &operator= (ArrayIndexExpr const &other)
{
ExprWithoutBlock::operator= (other);
- array_expr = other.array_expr->clone_expr ();
- index_expr = other.index_expr->clone_expr ();
// outer_attrs = other.outer_attrs;
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.array_expr != nullptr)
+ array_expr = other.array_expr->clone_expr ();
+ else
+ array_expr = nullptr;
+ if (other.index_expr != nullptr)
+ index_expr = other.index_expr->clone_expr ();
+ else
+ index_expr = nullptr;
+
return *this;
}
@@ -1100,14 +1064,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ArrayIndexExpr *clone_expr_impl () const override
- {
- return new ArrayIndexExpr (*this);
- }
+ // Invalid if either expr is null, so base stripping on that.
+ void mark_for_strip () override { array_expr = nullptr; index_expr = nullptr; }
+ bool is_marked_for_strip () const override { return array_expr == nullptr && index_expr == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
ArrayIndexExpr *clone_expr_without_block_impl () const override
@@ -1126,6 +1087,9 @@ class TupleExpr : public ExprWithoutBlock
Location locus;
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
+
public:
std::string as_string () const override;
@@ -1142,7 +1106,7 @@ public:
// copy constructor with vector clone
TupleExpr (TupleExpr const &other)
: ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
- locus (other.locus)
+ locus (other.locus), marked_for_strip (other.marked_for_strip)
{
tuple_elems.reserve (other.tuple_elems.size ());
for (const auto &e : other.tuple_elems)
@@ -1155,6 +1119,7 @@ public:
ExprWithoutBlock::operator= (other);
inner_attrs = other.inner_attrs;
locus = other.locus;
+ marked_for_strip = other.marked_for_strip;
tuple_elems.reserve (other.tuple_elems.size ());
for (const auto &e : other.tuple_elems)
@@ -1175,11 +1140,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- TupleExpr *clone_expr_impl () const override { return new TupleExpr (*this); }
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
TupleExpr *clone_expr_without_block_impl () const override
@@ -1213,19 +1178,27 @@ public:
// Copy constructor requires a clone for tuple_expr
TupleIndexExpr (TupleIndexExpr const &other)
- : ExprWithoutBlock (other), tuple_expr (other.tuple_expr->clone_expr ()),
- tuple_index (other.tuple_index), locus (other.locus)
- {}
+ : ExprWithoutBlock (other), tuple_index (other.tuple_index), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.tuple_expr != nullptr)
+ tuple_expr = other.tuple_expr->clone_expr ();
+ }
// Overload assignment operator in order to clone
TupleIndexExpr &operator= (TupleIndexExpr const &other)
{
ExprWithoutBlock::operator= (other);
- tuple_expr = other.tuple_expr->clone_expr ();
tuple_index = other.tuple_index;
locus = other.locus;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.tuple_expr != nullptr)
+ tuple_expr = other.tuple_expr->clone_expr ();
+ else
+ tuple_expr = nullptr;
+
return *this;
}
@@ -1238,14 +1211,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- TupleIndexExpr *clone_expr_impl () const override
- {
- return new TupleIndexExpr (*this);
- }
+ // Invalid if tuple expr is null, so base stripping on that.
+ void mark_for_strip () override { tuple_expr = nullptr; }
+ bool is_marked_for_strip () const override { return tuple_expr == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
TupleIndexExpr *clone_expr_without_block_impl () const override
@@ -1271,6 +1241,10 @@ public:
const PathInExpression &get_struct_name () const { return struct_name; }
std::string as_string () const override;
+
+ // Invalid if path is empty, so base stripping on that.
+ void mark_for_strip () override { struct_name = PathInExpression::create_error (); }
+ bool is_marked_for_strip () const override { return struct_name.is_error (); }
};
// Actual AST node of the struct creator (with no fields). Not abstract!
@@ -1301,13 +1275,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- StructExprStruct *clone_expr_impl () const override
- {
- return new StructExprStruct (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
StructExprStruct *clone_expr_without_block_impl () const override
{
return new StructExprStruct (*this);
@@ -1332,7 +1299,7 @@ public:
/* HACK: gets around base_struct pointer being null (e.g. if no struct base
* exists) */
if (other.base_struct != nullptr)
- other.base_struct->clone_expr ();
+ base_struct = other.base_struct->clone_expr ();
}
// Destructor
@@ -1341,7 +1308,11 @@ public:
// Overload assignment operator to clone base_struct
StructBase &operator= (StructBase const &other)
{
- base_struct = other.base_struct->clone_expr ();
+ // prevent null pointer dereference
+ if (other.base_struct != nullptr)
+ base_struct = other.base_struct->clone_expr ();
+ else
+ base_struct = nullptr;
return *this;
}
@@ -1557,13 +1528,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- StructExprStructFields *clone_expr_impl () const override
- {
- return new StructExprStructFields (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
StructExprStructFields *clone_expr_without_block_impl () const override
{
return new StructExprStructFields (*this);
@@ -1595,13 +1559,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- StructExprStructBase *clone_expr_impl () const override
- {
- return new StructExprStructBase (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
StructExprStructBase *clone_expr_without_block_impl () const override
{
return new StructExprStructBase (*this);
@@ -1669,13 +1626,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- StructExprTuple *clone_expr_impl () const override
- {
- return new StructExprTuple (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
StructExprTuple *clone_expr_without_block_impl () const override
{
return new StructExprTuple (*this);
@@ -1708,13 +1658,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- StructExprUnit *clone_expr_impl () const override
- {
- return new StructExprUnit (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
StructExprUnit *clone_expr_without_block_impl () const override
{
return new StructExprUnit (*this);
@@ -1738,6 +1681,10 @@ protected:
public:
// TODO: maybe remove and have string version gotten here directly
PathInExpression get_enum_variant_path () const { return enum_variant_path; }
+
+ // Invalid if path is in error state, so base stripping on that.
+ void mark_for_strip () override { enum_variant_path = PathInExpression::create_error (); }
+ bool is_marked_for_strip () const override { return enum_variant_path.is_error (); }
};
/* Base AST node for a single enum expression field (in enum instance creation)
@@ -1828,9 +1775,6 @@ public:
field_name (std::move (field_name))
{}
- // copy constructor, destructor, and assignment operator should not need
- // defining
-
void accept_vis (ASTVisitor &vis) override;
protected:
@@ -1924,13 +1868,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- EnumExprStruct *clone_expr_impl () const override
- {
- return new EnumExprStruct (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
EnumExprStruct *clone_expr_without_block_impl () const override
{
return new EnumExprStruct (*this);
@@ -1993,13 +1930,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- EnumExprTuple *clone_expr_impl () const override
- {
- return new EnumExprTuple (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
EnumExprTuple *clone_expr_without_block_impl () const override
{
return new EnumExprTuple (*this);
@@ -2033,13 +1963,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- EnumExprFieldless *clone_expr_impl () const override
- {
- return new EnumExprFieldless (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
EnumExprFieldless *clone_expr_without_block_impl () const override
{
return new EnumExprFieldless (*this);
@@ -2077,9 +2000,11 @@ public:
// copy constructor requires clone
CallExpr (CallExpr const &other)
- : ExprWithoutBlock (other), function (other.function->clone_expr ()),
- locus (other.locus)
- /*, params(other.params),*/ {
+ : ExprWithoutBlock (other), locus (other.locus) {
+ // guard to prevent null dereference (only required if error state)
+ if (other.function != nullptr)
+ function = other.function->clone_expr ();
+
params.reserve (other.params.size ());
for (const auto &e : other.params)
params.push_back (e->clone_expr ());
@@ -2089,11 +2014,15 @@ public:
CallExpr &operator= (CallExpr const &other)
{
ExprWithoutBlock::operator= (other);
- function = other.function->clone_expr ();
locus = other.locus;
- // params = other.params;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.function != nullptr)
+ function = other.function->clone_expr ();
+ else
+ function = nullptr;
+
params.reserve (other.params.size ());
for (const auto &e : other.params)
params.push_back (e->clone_expr ());
@@ -2113,11 +2042,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- CallExpr *clone_expr_impl () const override { return new CallExpr (*this); }
+ // Invalid if function expr is null, so base stripping on that.
+ void mark_for_strip () override { function = nullptr; }
+ bool is_marked_for_strip () const override { return function == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
CallExpr *clone_expr_without_block_impl () const override
@@ -2155,9 +2084,11 @@ public:
// copy constructor required due to cloning
MethodCallExpr (MethodCallExpr const &other)
- : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
- method_name (other.method_name), locus (other.locus)
- /*, params(other.params),*/ {
+ : ExprWithoutBlock (other), method_name (other.method_name), locus (other.locus) {
+ // guard to prevent null dereference (only required if error state)
+ if (other.receiver != nullptr)
+ receiver = other.receiver->clone_expr ();
+
params.reserve (other.params.size ());
for (const auto &e : other.params)
params.push_back (e->clone_expr ());
@@ -2167,12 +2098,16 @@ public:
MethodCallExpr &operator= (MethodCallExpr const &other)
{
ExprWithoutBlock::operator= (other);
- receiver = other.receiver->clone_expr ();
method_name = other.method_name;
locus = other.locus;
- // params = other.params;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.receiver != nullptr)
+ receiver = other.receiver->clone_expr ();
+ else
+ receiver = nullptr;
+
params.reserve (other.params.size ());
for (const auto &e : other.params)
params.push_back (e->clone_expr ());
@@ -2189,14 +2124,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- MethodCallExpr *clone_expr_impl () const override
- {
- return new MethodCallExpr (*this);
- }
+ // Invalid if receiver expr is null, so base stripping on that.
+ void mark_for_strip () override { receiver = nullptr; }
+ bool is_marked_for_strip () const override { return receiver == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
MethodCallExpr *clone_expr_without_block_impl () const override
@@ -2227,19 +2159,27 @@ public:
// Copy constructor required due to unique_ptr cloning
FieldAccessExpr (FieldAccessExpr const &other)
- : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
- field (other.field), locus (other.locus)
- {}
+ : ExprWithoutBlock (other), field (other.field), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.receiver != nullptr)
+ receiver = other.receiver->clone_expr ();
+ }
// Overload assignment operator to clone unique_ptr
FieldAccessExpr &operator= (FieldAccessExpr const &other)
{
ExprWithoutBlock::operator= (other);
- receiver = other.receiver->clone_expr ();
field = other.field;
locus = other.locus;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.receiver != nullptr)
+ receiver = other.receiver->clone_expr ();
+ else
+ receiver = nullptr;
+
return *this;
}
@@ -2252,14 +2192,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- FieldAccessExpr *clone_expr_impl () const override
- {
- return new FieldAccessExpr (*this);
- }
+ // Invalid if receiver expr is null, so base stripping on that.
+ void mark_for_strip () override { receiver = nullptr; }
+ bool is_marked_for_strip () const override { return receiver == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
FieldAccessExpr *clone_expr_without_block_impl () const override
@@ -2294,6 +2231,8 @@ public:
: pattern (other.pattern->clone_pattern ())
{
// guard to protect from null pointer dereference
+ if (other.pattern != nullptr)
+ pattern = other.pattern->clone_pattern ();
if (other.type != nullptr)
type = other.type->clone_type ();
}
@@ -2303,8 +2242,15 @@ public:
// Assignment operator must be overloaded to clone as well
ClosureParam &operator= (ClosureParam const &other)
{
- pattern = other.pattern->clone_pattern ();
- type = other.type->clone_type ();
+ // guard to protect from null pointer dereference
+ if (other.pattern != nullptr)
+ pattern = other.pattern->clone_pattern ();
+ else
+ pattern = nullptr;
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ else
+ type = nullptr;
return *this;
}
@@ -2367,18 +2313,27 @@ public:
// Copy constructor must be defined to allow copying via cloning of unique_ptr
ClosureExprInner (ClosureExprInner const &other)
- : ClosureExpr (other), closure_inner (other.closure_inner->clone_expr ())
- {}
+ : ClosureExpr (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.closure_inner != nullptr)
+ closure_inner = other.closure_inner->clone_expr ();
+ }
// Overload assignment operator to clone closure_inner
ClosureExprInner &operator= (ClosureExprInner const &other)
{
ClosureExpr::operator= (other);
- closure_inner = other.closure_inner->clone_expr ();
// params = other.params;
// has_move = other.has_move;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.closure_inner != nullptr)
+ closure_inner = other.closure_inner->clone_expr ();
+ else
+ closure_inner = nullptr;
+
return *this;
}
@@ -2388,14 +2343,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ClosureExprInner *clone_expr_impl () const override
- {
- return new ClosureExprInner (*this);
- }
+ // Invalid if inner expr is null, so base stripping on that.
+ void mark_for_strip () override { closure_inner = nullptr; }
+ bool is_marked_for_strip () const override { return closure_inner == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
ClosureExprInner *clone_expr_without_block_impl () const override
@@ -2437,8 +2389,7 @@ public:
// Copy constructor with clone
BlockExpr (BlockExpr const &other)
- : ExprWithBlock (other), /*statements(other.statements),*/
- inner_attrs (other.inner_attrs), locus (other.locus)
+ : ExprWithBlock (other), inner_attrs (other.inner_attrs), locus (other.locus)
{
// guard to protect from null pointer dereference
if (other.expr != nullptr)
@@ -2453,12 +2404,16 @@ public:
BlockExpr &operator= (BlockExpr const &other)
{
ExprWithBlock::operator= (other);
- // statements = other.statements;
- expr = other.expr->clone_expr_without_block ();
inner_attrs = other.inner_attrs;
locus = other.locus;
// outer_attrs = other.outer_attrs;
+ // guard to protect from null pointer dereference
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr_without_block ();
+ else
+ expr = nullptr;
+
statements.reserve (other.statements.size ());
for (const auto &e : other.statements)
statements.push_back (e->clone_stmt ());
@@ -2481,14 +2436,16 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- BlockExpr *clone_expr_impl () const override
- {
- return clone_block_expr_impl ();
+ // Invalid if has no statements or final expr, so base stripping on that.
+ void mark_for_strip () override
+ {
+ expr = nullptr;
+ statements.clear ();
+ statements.shrink_to_fit ();
}
+ bool is_marked_for_strip () const override { return expr == nullptr && statements.empty (); }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
BlockExpr *clone_expr_with_block_impl () const override
@@ -2507,6 +2464,7 @@ protected:
// Represents a type-specified closure expression AST node
class ClosureExprInnerTyped : public ClosureExpr
{
+ // TODO: spec says typenobounds
std::unique_ptr<Type> return_type;
std::unique_ptr<BlockExpr>
expr; // only used because may be polymorphic in future
@@ -2529,20 +2487,33 @@ public:
// Copy constructor requires cloning
ClosureExprInnerTyped (ClosureExprInnerTyped const &other)
- : ClosureExpr (other), return_type (other.return_type->clone_type ()),
- expr (other.expr->clone_block_expr ())
- {}
+ : ClosureExpr (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_block_expr ();
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+ }
// Overload assignment operator to clone unique_ptrs
ClosureExprInnerTyped &operator= (ClosureExprInnerTyped const &other)
{
ClosureExpr::operator= (other);
- return_type = other.return_type->clone_type ();
- expr = other.expr->clone_block_expr ();
// params = other.params;
// has_move = other.has_move;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_block_expr ();
+ else
+ expr = nullptr;
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+ else
+ return_type = nullptr;
+
return *this;
}
@@ -2552,14 +2523,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ClosureExprInnerTyped *clone_expr_impl () const override
- {
- return new ClosureExprInnerTyped (*this);
- }
+ /* Invalid if inner expr is null, so base stripping on that. Technically, type should also not be null. */
+ void mark_for_strip () override { expr = nullptr; }
+ bool is_marked_for_strip () const override { return expr == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
ClosureExprInnerTyped *clone_expr_without_block_impl () const override
@@ -2575,6 +2543,9 @@ class ContinueExpr : public ExprWithoutBlock
Lifetime label;
Location locus;
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
+
public:
std::string as_string () const override;
@@ -2594,14 +2565,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ContinueExpr *clone_expr_impl () const override
- {
- return new ContinueExpr (*this);
- }
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
ContinueExpr *clone_expr_without_block_impl () const override
@@ -2622,6 +2590,9 @@ class BreakExpr : public ExprWithoutBlock
Location locus;
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
+
public:
std::string as_string () const override;
@@ -2643,7 +2614,7 @@ public:
// Copy constructor defined to use clone for unique pointer
BreakExpr (BreakExpr const &other)
- : ExprWithoutBlock (other), label (other.label), locus (other.locus)
+ : ExprWithoutBlock (other), label (other.label), locus (other.locus), marked_for_strip (other.marked_for_strip)
{
// guard to protect from null pointer dereference
if (other.break_expr != nullptr)
@@ -2655,10 +2626,16 @@ public:
{
ExprWithoutBlock::operator= (other);
label = other.label;
- break_expr = other.break_expr->clone_expr ();
locus = other.locus;
+ marked_for_strip = other.marked_for_strip;
// outer_attrs = other.outer_attrs;
+ // guard to protect from null pointer dereference
+ if (other.break_expr != nullptr)
+ break_expr = other.break_expr->clone_expr ();
+ else
+ break_expr = nullptr;
+
return *this;
}
@@ -2671,11 +2648,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- BreakExpr *clone_expr_impl () const override { return new BreakExpr (*this); }
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
BreakExpr *clone_expr_without_block_impl () const override
@@ -2718,16 +2695,29 @@ public:
// Copy constructor with cloning
RangeFromToExpr (RangeFromToExpr const &other)
- : RangeExpr (other), from (other.from->clone_expr ()),
- to (other.to->clone_expr ())
- {}
+ : RangeExpr (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.from != nullptr)
+ from = other.from->clone_expr ();
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ }
// Overload assignment operator to clone unique pointers
RangeFromToExpr &operator= (RangeFromToExpr const &other)
{
RangeExpr::operator= (other);
- from = other.from->clone_expr ();
- to = other.to->clone_expr ();
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.from != nullptr)
+ from = other.from->clone_expr ();
+ else
+ from = nullptr;
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ else
+ to = nullptr;
return *this;
}
@@ -2738,14 +2728,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- RangeFromToExpr *clone_expr_impl () const override
- {
- return new RangeFromToExpr (*this);
- }
+ // Invalid if either expr is null, so base stripping on that.
+ void mark_for_strip () override { from = nullptr; to = nullptr; }
+ bool is_marked_for_strip () const override { return from == nullptr && to == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
RangeFromToExpr *clone_expr_without_block_impl () const override
@@ -2769,14 +2756,23 @@ public:
// Copy constructor with clone
RangeFromExpr (RangeFromExpr const &other)
- : RangeExpr (other), from (other.from->clone_expr ())
- {}
+ : RangeExpr (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.from != nullptr)
+ from = other.from->clone_expr ();
+ }
// Overload assignment operator to clone unique_ptr
RangeFromExpr &operator= (RangeFromExpr const &other)
{
RangeExpr::operator= (other);
- from = other.from->clone_expr ();
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.from != nullptr)
+ from = other.from->clone_expr ();
+ else
+ from = nullptr;
return *this;
}
@@ -2787,14 +2783,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- RangeFromExpr *clone_expr_impl () const override
- {
- return new RangeFromExpr (*this);
- }
+ // Invalid if expr is null, so base stripping on that.
+ void mark_for_strip () override { from = nullptr; }
+ bool is_marked_for_strip () const override { return from == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
RangeFromExpr *clone_expr_without_block_impl () const override
@@ -2819,14 +2812,23 @@ public:
// Copy constructor with clone
RangeToExpr (RangeToExpr const &other)
- : RangeExpr (other), to (other.to->clone_expr ())
- {}
+ : RangeExpr (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ }
// Overload assignment operator to clone unique_ptr
RangeToExpr &operator= (RangeToExpr const &other)
{
RangeExpr::operator= (other);
- to = other.to->clone_expr ();
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ else
+ to = nullptr;
return *this;
}
@@ -2837,14 +2839,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- RangeToExpr *clone_expr_impl () const override
- {
- return new RangeToExpr (*this);
- }
+ // Invalid if expr is null, so base stripping on that.
+ void mark_for_strip () override { to = nullptr; }
+ bool is_marked_for_strip () const override { return to == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
RangeToExpr *clone_expr_without_block_impl () const override
@@ -2857,6 +2856,9 @@ protected:
// constructs a std::ops::RangeFull object
class RangeFullExpr : public RangeExpr
{
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
+
public:
std::string as_string () const override;
@@ -2865,14 +2867,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- RangeFullExpr *clone_expr_impl () const override
- {
- return new RangeFullExpr (*this);
- }
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
RangeFullExpr *clone_expr_without_block_impl () const override
@@ -2900,16 +2899,29 @@ public:
// Copy constructor with clone
RangeFromToInclExpr (RangeFromToInclExpr const &other)
- : RangeExpr (other), from (other.from->clone_expr ()),
- to (other.to->clone_expr ())
- {}
+ : RangeExpr (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.from != nullptr)
+ from = other.from->clone_expr ();
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ }
// Overload assignment operator to use clone
RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other)
{
RangeExpr::operator= (other);
- from = other.from->clone_expr ();
- to = other.to->clone_expr ();
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.from != nullptr)
+ from = other.from->clone_expr ();
+ else
+ from = nullptr;
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ else
+ to = nullptr;
return *this;
}
@@ -2920,14 +2932,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- RangeFromToInclExpr *clone_expr_impl () const override
- {
- return new RangeFromToInclExpr (*this);
- }
+ // Invalid if either expr is null, so base stripping on that.
+ void mark_for_strip () override { from = nullptr; to = nullptr; }
+ bool is_marked_for_strip () const override { return from == nullptr && to == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
RangeFromToInclExpr *clone_expr_without_block_impl () const override
@@ -2952,14 +2961,23 @@ public:
// Copy constructor with clone
RangeToInclExpr (RangeToInclExpr const &other)
- : RangeExpr (other), to (other.to->clone_expr ())
- {}
+ : RangeExpr (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ }
// Overload assignment operator to clone pointer
RangeToInclExpr &operator= (RangeToInclExpr const &other)
{
RangeExpr::operator= (other);
- to = other.to->clone_expr ();
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.to != nullptr)
+ to = other.to->clone_expr ();
+ else
+ to = nullptr;
return *this;
}
@@ -2970,14 +2988,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- RangeToInclExpr *clone_expr_impl () const override
- {
- return new RangeToInclExpr (*this);
- }
+ // Invalid if expr is null, so base stripping on that.
+ void mark_for_strip () override { to = nullptr; }
+ bool is_marked_for_strip () const override { return to == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
RangeToInclExpr *clone_expr_without_block_impl () const override
@@ -2994,6 +3009,9 @@ public:
Location locus;
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
+
std::string as_string () const override;
/* Returns whether the object has an expression returned (i.e. not void return
@@ -3009,7 +3027,7 @@ public:
// Copy constructor with clone
ReturnExpr (ReturnExpr const &other)
- : ExprWithoutBlock (other), locus (other.locus)
+ : ExprWithoutBlock (other), locus (other.locus), marked_for_strip (other.marked_for_strip)
{
// guard to protect from null pointer dereference
if (other.return_expr != nullptr)
@@ -3020,10 +3038,16 @@ public:
ReturnExpr &operator= (ReturnExpr const &other)
{
ExprWithoutBlock::operator= (other);
- return_expr = other.return_expr->clone_expr ();
locus = other.locus;
+ marked_for_strip = other.marked_for_strip;
// outer_attrs = other.outer_attrs;
+ // guard to protect from null pointer dereference
+ if (other.return_expr != nullptr)
+ return_expr = other.return_expr->clone_expr ();
+ else
+ return_expr = nullptr;
+
return *this;
}
@@ -3036,14 +3060,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ReturnExpr *clone_expr_impl () const override
- {
- return new ReturnExpr (*this);
- }
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
ReturnExpr *clone_expr_without_block_impl () const override
@@ -3074,18 +3095,26 @@ public:
// Copy constructor with clone
UnsafeBlockExpr (UnsafeBlockExpr const &other)
- : ExprWithBlock (other), expr (other.expr->clone_block_expr ()),
- locus (other.locus)
- {}
+ : ExprWithBlock (other), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_block_expr ();
+ }
// Overloaded assignment operator to clone
UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other)
{
ExprWithBlock::operator= (other);
- expr = other.expr->clone_block_expr ();
locus = other.locus;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_block_expr ();
+ else
+ expr = nullptr;
+
return *this;
}
@@ -3098,14 +3127,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- UnsafeBlockExpr *clone_expr_impl () const override
- {
- return new UnsafeBlockExpr (*this);
- }
+ // Invalid if block is null, so base stripping on that.
+ void mark_for_strip () override { expr = nullptr; }
+ bool is_marked_for_strip () const override { return expr == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
UnsafeBlockExpr *clone_expr_with_block_impl () const override
@@ -3164,19 +3190,27 @@ protected:
// Copy constructor for BaseLoopExpr with clone
BaseLoopExpr (BaseLoopExpr const &other)
- : ExprWithBlock (other), loop_label (other.loop_label),
- loop_block (other.loop_block->clone_block_expr ()), locus (other.locus)
- {}
+ : ExprWithBlock (other), loop_label (other.loop_label), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.loop_block != nullptr)
+ loop_block = other.loop_block->clone_block_expr ();
+ }
// Overloaded assignment operator to clone
BaseLoopExpr &operator= (BaseLoopExpr const &other)
{
ExprWithBlock::operator= (other);
- loop_block = other.loop_block->clone_block_expr ();
loop_label = other.loop_label;
locus = other.locus;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.loop_block != nullptr)
+ loop_block = other.loop_block->clone_block_expr ();
+ else
+ loop_block = nullptr;
+
return *this;
}
@@ -3189,6 +3223,10 @@ public:
Location get_locus () const { return locus; }
Location get_locus_slow () const override { return get_locus (); }
+
+ // Invalid if loop block is null, so base stripping on that.
+ void mark_for_strip () override { loop_block = nullptr; }
+ bool is_marked_for_strip () const override { return loop_block == nullptr; }
};
// 'Loop' expression (i.e. the infinite loop) AST node
@@ -3210,10 +3248,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- LoopExpr *clone_expr_impl () const override { return new LoopExpr (*this); }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
LoopExpr *clone_expr_with_block_impl () const override
{
return new LoopExpr (*this);
@@ -3265,13 +3299,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- WhileLoopExpr *clone_expr_impl () const override
- {
- return new WhileLoopExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
WhileLoopExpr *clone_expr_with_block_impl () const override
{
return new WhileLoopExpr (*this);
@@ -3338,13 +3365,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- WhileLetLoopExpr *clone_expr_impl () const override
- {
- return new WhileLetLoopExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
WhileLetLoopExpr *clone_expr_with_block_impl () const override
{
return new WhileLetLoopExpr (*this);
@@ -3400,13 +3420,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ForLoopExpr *clone_expr_impl () const override
- {
- return new ForLoopExpr (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ForLoopExpr *clone_expr_with_block_impl () const override
{
return new ForLoopExpr (*this);
@@ -3437,18 +3450,31 @@ public:
// Copy constructor with clone
IfExpr (IfExpr const &other)
- : ExprWithBlock (other), condition (other.condition->clone_expr ()),
- if_block (other.if_block->clone_block_expr ()), locus (other.locus)
- {}
+ : ExprWithBlock (other), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.condition != nullptr)
+ condition = other.condition->clone_expr ();
+ if (other.if_block != nullptr)
+ if_block = other.if_block->clone_block_expr ();
+ }
// Overloaded assignment operator to clone expressions
IfExpr &operator= (IfExpr const &other)
{
ExprWithBlock::operator= (other);
- condition = other.condition->clone_expr ();
- if_block = other.if_block->clone_block_expr ();
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.condition != nullptr)
+ condition = other.condition->clone_expr ();
+ else
+ condition = nullptr;
+ if (other.if_block != nullptr)
+ if_block = other.if_block->clone_block_expr ();
+ else
+ if_block = nullptr;
+
return *this;
}
@@ -3477,19 +3503,19 @@ public:
Expr *get_if_condition () { return condition.get (); }
BlockExpr *get_if_block () { return if_block.get (); }
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfExpr *clone_expr_impl () const override { return new IfExpr (*this); }
+ // Invalid if if block or condition is null, so base stripping on that.
+ void mark_for_strip () override { if_block = nullptr; condition = nullptr; }
+ bool is_marked_for_strip () const override { return if_block == nullptr && condition == nullptr; }
+protected:
// Base clone function but still concrete as concrete base class
virtual IfExpr *clone_if_expr_impl () const { return new IfExpr (*this); }
/* Use covariance to implement clone function as returning this object rather
* than base */
- IfExpr *clone_expr_with_block_impl () const override
+ IfExpr *clone_expr_with_block_impl () const final override
{
- return new IfExpr (*this);
+ return clone_if_expr_impl ();
}
};
@@ -3536,20 +3562,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- IfExprConseqElse *clone_expr_impl () const override
- {
- return new IfExprConseqElse (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfExprConseqElse *clone_expr_with_block_impl () const override
- {
- return new IfExprConseqElse (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
IfExprConseqElse *clone_if_expr_impl () const override
{
return new IfExprConseqElse (*this);
@@ -3602,20 +3614,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- IfExprConseqIf *clone_expr_impl () const override
- {
- return new IfExprConseqIf (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfExprConseqIf *clone_expr_with_block_impl () const override
- {
- return new IfExprConseqIf (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
IfExprConseqIf *clone_if_expr_impl () const override
{
return new IfExprConseqIf (*this);
@@ -3646,11 +3644,14 @@ public:
// copy constructor with clone
IfLetExpr (IfLetExpr const &other)
- : ExprWithBlock (other),
- /*match_arm_patterns(other.match_arm_patterns),*/ value (
- other.value->clone_expr ()),
- if_block (other.if_block->clone_block_expr ()), locus (other.locus)
+ : ExprWithBlock (other), locus (other.locus)
{
+ // guard to prevent null dereference (only required if error state)
+ if (other.value != nullptr)
+ value = other.value->clone_expr ();
+ if (other.if_block != nullptr)
+ if_block = other.if_block->clone_block_expr ();
+
match_arm_patterns.reserve (other.match_arm_patterns.size ());
for (const auto &e : other.match_arm_patterns)
match_arm_patterns.push_back (e->clone_pattern ());
@@ -3660,11 +3661,18 @@ public:
IfLetExpr &operator= (IfLetExpr const &other)
{
ExprWithBlock::operator= (other);
- // match_arm_patterns = other.match_arm_patterns;
- value = other.value->clone_expr ();
- if_block = other.if_block->clone_block_expr ();
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.value != nullptr)
+ value = other.value->clone_expr ();
+ else
+ value = nullptr;
+ if (other.if_block != nullptr)
+ if_block = other.if_block->clone_block_expr ();
+ else
+ if_block = nullptr;
+
match_arm_patterns.reserve (other.match_arm_patterns.size ());
for (const auto &e : other.match_arm_patterns)
match_arm_patterns.push_back (e->clone_pattern ());
@@ -3687,16 +3695,16 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExpr *clone_expr_impl () const override { return new IfLetExpr (*this); }
+ // Invalid if block or value is null, so base stripping on that.
+ void mark_for_strip () override { if_block = nullptr; value = nullptr; }
+ bool is_marked_for_strip () const override { return if_block == nullptr && value == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExpr *clone_expr_with_block_impl () const override
+ * than base (or rather this or any derived object) */
+ IfLetExpr *clone_expr_with_block_impl () const final override
{
- return new IfLetExpr (*this);
+ return clone_if_let_expr_impl ();
}
// Base clone function but still concrete as concrete base class
@@ -3748,20 +3756,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- IfExprConseqIfLet *clone_expr_impl () const override
- {
- return new IfExprConseqIfLet (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfExprConseqIfLet *clone_expr_with_block_impl () const override
- {
- return new IfExprConseqIfLet (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
IfExprConseqIfLet *clone_if_expr_impl () const override
{
return new IfExprConseqIfLet (*this);
@@ -3814,20 +3808,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- IfLetExprConseqElse *clone_expr_impl () const override
- {
- return new IfLetExprConseqElse (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExprConseqElse *clone_expr_with_block_impl () const override
- {
- return new IfLetExprConseqElse (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
IfLetExprConseqElse *clone_if_let_expr_impl () const override
{
return new IfLetExprConseqElse (*this);
@@ -3879,20 +3859,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- IfLetExprConseqIf *clone_expr_impl () const override
- {
- return new IfLetExprConseqIf (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExprConseqIf *clone_expr_with_block_impl () const override
- {
- return new IfLetExprConseqIf (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
IfLetExprConseqIf *clone_if_let_expr_impl () const override
{
return new IfLetExprConseqIf (*this);
@@ -3944,20 +3910,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- IfLetExprConseqIfLet *clone_expr_impl () const override
- {
- return new IfLetExprConseqIfLet (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- IfLetExprConseqIfLet *clone_expr_with_block_impl () const override
- {
- return new IfLetExprConseqIfLet (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
IfLetExprConseqIfLet *clone_if_let_expr_impl () const override
{
return new IfLetExprConseqIfLet (*this);
@@ -4012,6 +3964,8 @@ public:
if (other.guard_expr != nullptr)
guard_expr = other.guard_expr->clone_expr ();
+ else
+ guard_expr = nullptr;
match_arm_patterns.reserve (other.match_arm_patterns.size ());
for (const auto &e : other.match_arm_patterns)
@@ -4224,10 +4178,13 @@ public:
// Copy constructor requires clone due to unique_ptr
MatchExpr (MatchExpr const &other)
- : ExprWithBlock (other), branch_value (other.branch_value->clone_expr ()),
- inner_attrs (other.inner_attrs), match_arms (other.match_arms),
- locus (other.locus)
+ : ExprWithBlock (other), inner_attrs (other.inner_attrs),
+ match_arms (other.match_arms), locus (other.locus)
{
+ // guard to prevent null dereference (only required if error state)
+ if (other.branch_value != nullptr)
+ branch_value = other.branch_value->clone_expr ();
+
/*match_arms.reserve (other.match_arms.size ());
for (const auto &e : other.match_arms)
match_arms.push_back (e->clone_match_case ());*/
@@ -4237,12 +4194,17 @@ public:
MatchExpr &operator= (MatchExpr const &other)
{
ExprWithBlock::operator= (other);
- branch_value = other.branch_value->clone_expr ();
inner_attrs = other.inner_attrs;
match_arms = other.match_arms;
// outer_attrs = other.outer_attrs;
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.branch_value != nullptr)
+ branch_value = other.branch_value->clone_expr ();
+ else
+ branch_value = nullptr;
+
/*match_arms.reserve (other.match_arms.size ());
for (const auto &e : other.match_arms)
match_arms.push_back (e->clone_match_case ());*/
@@ -4259,11 +4221,11 @@ public:
void accept_vis (ASTVisitor &vis) override;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- MatchExpr *clone_expr_impl () const override { return new MatchExpr (*this); }
+ // Invalid if branch value is null, so base stripping on that.
+ void mark_for_strip () override { branch_value = nullptr; }
+ bool is_marked_for_strip () const override { return branch_value == nullptr; }
+protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
MatchExpr *clone_expr_with_block_impl () const override
@@ -4289,17 +4251,25 @@ public:
// copy constructor with clone
AwaitExpr (AwaitExpr const &other)
- : ExprWithoutBlock (other),
- awaited_expr (other.awaited_expr->clone_expr ()), locus (other.locus)
- {}
+ : ExprWithoutBlock (other), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.awaited_expr != nullptr)
+ awaited_expr = other.awaited_expr->clone_expr ();
+ }
// overloaded assignment operator with clone
AwaitExpr &operator= (AwaitExpr const &other)
{
ExprWithoutBlock::operator= (other);
- awaited_expr = other.awaited_expr->clone_expr ();
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.awaited_expr != nullptr)
+ awaited_expr = other.awaited_expr->clone_expr ();
+ else
+ awaited_expr = nullptr;
+
return *this;
}
@@ -4314,6 +4284,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if awaited expr is null, so base stripping on that.
+ void mark_for_strip () override { awaited_expr = nullptr; }
+ bool is_marked_for_strip () const override { return awaited_expr == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -4341,18 +4315,26 @@ public:
// copy constructor with clone
AsyncBlockExpr (AsyncBlockExpr const &other)
- : ExprWithBlock (other), has_move (other.has_move),
- block_expr (other.block_expr->clone_block_expr ()), locus (other.locus)
- {}
+ : ExprWithBlock (other), has_move (other.has_move), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+ }
// overloaded assignment operator to clone
AsyncBlockExpr &operator= (AsyncBlockExpr const &other)
{
ExprWithBlock::operator= (other);
has_move = other.has_move;
- block_expr = other.block_expr->clone_block_expr ();
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+ else
+ block_expr = nullptr;
+
return *this;
}
@@ -4367,6 +4349,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if block is null, so base stripping on that.
+ void mark_for_strip () override { block_expr = nullptr; }
+ bool is_marked_for_strip () const override { return block_expr == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index b5d9247..c35e65f 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -715,24 +715,24 @@ protected:
class VisItem : public Item
{
Visibility visibility;
+ std::vector<Attribute> outer_attrs;
protected:
// Visibility constructor
VisItem (Visibility visibility,
std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
- : Item (std::move (outer_attrs)), visibility (std::move (visibility))
+ : visibility (std::move (visibility)), outer_attrs(std::move (outer_attrs))
{}
// Visibility copy constructor
- VisItem (VisItem const &other) : Item (other), visibility (other.visibility)
+ VisItem (VisItem const &other) : visibility (other.visibility), outer_attrs(other.outer_attrs)
{}
// Overload assignment operator to clone
VisItem &operator= (VisItem const &other)
{
- Item::operator= (other);
visibility = other.visibility;
- // outer_attrs = other.outer_attrs;
+ outer_attrs = other.outer_attrs;
return *this;
}
@@ -747,6 +747,13 @@ public:
bool has_visibility () const { return !visibility.is_error (); }
std::string as_string () const override;
+
+ // TODO: this mutable getter seems really dodgy. Think up better way.
+ Visibility &get_vis () { return visibility; }
+ const Visibility &get_vis () const { return visibility; }
+
+ std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
+ const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
};
// Rust module item - abstract base class
@@ -767,6 +774,10 @@ public:
std::string as_string () const override;
Location get_locus () const { return locus; }
+
+ // Invalid if name is empty, so base stripping on that.
+ void mark_for_strip () override { module_name = ""; }
+ bool is_marked_for_strip () const override { return module_name.empty (); }
};
// Module with a body, defined in file
@@ -837,17 +848,14 @@ protected:
{
return new ModuleBodied (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual ModuleBodied* clone_statement_impl() const override {
- return new ModuleBodied(*this);
- }*/
};
// Module without a body, loaded from external file
class ModuleNoBody : public Module
{
+ /* TODO: are modules loaded from file unique? As in, can you load the same file into two different
+ * other files? Because this may make the difference between simply replacing this with the module
+ * "definition" (as loaded from another file) vs this having to "reference" a module with body. */
public:
std::string as_string () const override;
@@ -867,12 +875,6 @@ protected:
{
return new ModuleNoBody (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual ModuleNoBody* clone_statement_impl() const override {
- return new ModuleNoBody(*this);
- }*/
};
// Rust extern crate declaration AST node
@@ -920,6 +922,10 @@ public:
names.push_back (referenced_crate);
}
+ // Invalid if crate name is empty, so base stripping on that.
+ void mark_for_strip () override { referenced_crate = ""; }
+ bool is_marked_for_strip () const override { return referenced_crate.empty (); }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -927,12 +933,6 @@ protected:
{
return new ExternCrate (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual ExternCrate* clone_statement_impl() const override {
- return new ExternCrate(*this);
- }*/
};
// The path-ish thing referred to in a use declaration - abstract base class
@@ -1153,19 +1153,27 @@ public:
// Copy constructor with clone
UseDeclaration (UseDeclaration const &other)
- : VisItem (other), use_tree (other.use_tree->clone_use_tree ()),
- locus (other.locus)
- {}
+ : VisItem (other), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.use_tree != nullptr)
+ use_tree = other.use_tree->clone_use_tree ();
+ }
// Overloaded assignment operator to clone
UseDeclaration &operator= (UseDeclaration const &other)
{
VisItem::operator= (other);
- use_tree = other.use_tree->clone_use_tree ();
// visibility = other.visibility->clone_visibility();
// outer_attrs = other.outer_attrs;
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.use_tree != nullptr)
+ use_tree = other.use_tree->clone_use_tree ();
+ else
+ use_tree = nullptr;
+
return *this;
}
@@ -1177,6 +1185,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if use tree is null, so base stripping on that.
+ void mark_for_strip () override { use_tree = nullptr; }
+ bool is_marked_for_strip () const override { return use_tree == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1184,12 +1196,6 @@ protected:
{
return new UseDeclaration (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual UseDeclaration* clone_statement_impl() const override {
- return new UseDeclaration(*this);
- }*/
};
// Parameters used in a function - TODO inline?
@@ -1264,11 +1270,16 @@ public:
: VisItem (other), qualifiers (other.qualifiers),
function_name (other.function_name),
function_params (other.function_params),
- return_type (other.return_type->clone_type ()),
- where_clause (other.where_clause),
- function_body (other.function_body->clone_block_expr ()),
- locus (other.locus)
+ where_clause (other.where_clause), locus (other.locus)
{
+ // guard to prevent null dereference (always required)
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.function_body != nullptr)
+ function_body = other.function_body->clone_block_expr ();
+
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
@@ -1280,15 +1291,24 @@ public:
VisItem::operator= (other);
function_name = other.function_name;
qualifiers = other.qualifiers;
- // generic_params = other.generic_params;
function_params = other.function_params;
- return_type = other.return_type->clone_type ();
where_clause = other.where_clause;
- function_body = other.function_body->clone_block_expr ();
// visibility = other.visibility->clone_visibility();
// outer_attrs = other.outer_attrs;
locus = other.locus;
+ // guard to prevent null dereference (always required)
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+ else
+ return_type = nullptr;
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.function_body != nullptr)
+ function_body = other.function_body->clone_block_expr ();
+ else
+ function_body = nullptr;
+
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
@@ -1304,6 +1324,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // 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 { return function_body == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1322,12 +1346,6 @@ protected:
{
return new Function (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual Function* clone_statement_impl() const override {
- return new Function(*this);
- }*/
};
// Rust type alias (i.e. typedef) AST node
@@ -1370,9 +1388,12 @@ public:
// Copy constructor
TypeAlias (TypeAlias const &other)
: VisItem (other), new_type_name (other.new_type_name),
- where_clause (other.where_clause),
- existing_type (other.existing_type->clone_type ()), locus (other.locus)
+ where_clause (other.where_clause), locus (other.locus)
{
+ // guard to prevent null dereference (only required if error state)
+ if (other.existing_type != nullptr)
+ existing_type = other.existing_type->clone_type ();
+
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
@@ -1383,13 +1404,17 @@ public:
{
VisItem::operator= (other);
new_type_name = other.new_type_name;
- // generic_params = other.generic_params;
where_clause = other.where_clause;
- existing_type = other.existing_type->clone_type ();
// visibility = other.visibility->clone_visibility();
// outer_attrs = other.outer_attrs;
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.existing_type != nullptr)
+ existing_type = other.existing_type->clone_type ();
+ else
+ existing_type = nullptr;
+
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
@@ -1405,6 +1430,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if existing type is null, so base stripping on that.
+ void mark_for_strip () override { existing_type = nullptr; }
+ bool is_marked_for_strip () const override { return existing_type == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1416,12 +1445,6 @@ protected:
{
return new TypeAlias (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual TypeAlias* clone_statement_impl() const override {
- return new TypeAlias(*this);
- }*/
};
// Rust base struct declaration AST node - abstract base class
@@ -1448,6 +1471,10 @@ public:
Location get_locus () const { return locus; }
+ // Invalid if name is empty, so base stripping on that.
+ void mark_for_strip () override { struct_name = ""; }
+ bool is_marked_for_strip () const override { return struct_name.empty (); }
+
protected:
Struct (Identifier struct_name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -1584,8 +1611,7 @@ public:
std::vector<Attribute> outer_attrs, Location locus)
: Struct (std::move (struct_name), std::move (generic_params),
std::move (where_clause), std::move (vis), locus,
- std::move (outer_attrs)),
- is_unit (true)
+ std::move (outer_attrs)), is_unit (true)
{}
// TODO: can a unit struct have generic fields? assuming yes for now.
@@ -1603,12 +1629,6 @@ protected:
{
return new StructStruct (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual StructStruct* clone_statement_impl() const override {
- return new StructStruct(*this);
- }*/
};
// A single field in a tuple
@@ -1702,12 +1722,6 @@ protected:
{
return new TupleStruct (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual TupleStruct* clone_statement_impl() const override {
- return new TupleStruct(*this);
- }*/
};
/* An item used in an "enum" tagged union - not abstract: base represents a
@@ -1937,16 +1951,14 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if name is empty, so base stripping on that.
+ void mark_for_strip () override { enum_name = ""; }
+ bool is_marked_for_strip () const override { return enum_name.empty (); }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Enum *clone_item_impl () const override { return new Enum (*this); }
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual Enum* clone_statement_impl() const override {
- return new Enum(*this);
- }*/
};
// Rust untagged union used for C compat AST node
@@ -2020,16 +2032,14 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if name is empty, so base stripping on that.
+ void mark_for_strip () override { union_name = ""; }
+ bool is_marked_for_strip () const override { return union_name.empty (); }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Union *clone_item_impl () const override { return new Union (*this); }
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual Union* clone_statement_impl() const override {
- return new Union(*this);
- }*/
};
/* "Constant item" AST node - used for constant, compile-time expressions
@@ -2041,7 +2051,7 @@ class ConstantItem : public VisItem,
// either has an identifier or "_" - maybe handle in identifier?
// bool identifier_is_underscore;
// if no identifier declared, identifier will be "_"
- Identifier identifier;
+ std::string identifier;
std::unique_ptr<Type> type;
std::unique_ptr<Expr> const_expr;
@@ -2051,7 +2061,7 @@ class ConstantItem : public VisItem,
public:
std::string as_string () const override;
- ConstantItem (Identifier ident, Visibility vis, std::unique_ptr<Type> type,
+ ConstantItem (std::string ident, Visibility vis, std::unique_ptr<Type> type,
std::unique_ptr<Expr> const_expr,
std::vector<Attribute> outer_attrs, Location locus)
: VisItem (std::move (vis), std::move (outer_attrs)),
@@ -2060,20 +2070,32 @@ public:
{}
ConstantItem (ConstantItem const &other)
- : VisItem (other), identifier (other.identifier),
- type (other.type->clone_type ()),
- const_expr (other.const_expr->clone_expr ()), locus (other.locus)
- {}
+ : VisItem (other), identifier (other.identifier), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ if (other.const_expr != nullptr)
+ const_expr = other.const_expr->clone_expr ();
+ }
// Overload assignment operator to clone
ConstantItem &operator= (ConstantItem const &other)
{
VisItem::operator= (other);
identifier = other.identifier;
- type = other.type->clone_type ();
- const_expr = other.const_expr->clone_expr ();
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ else
+ type = nullptr;
+ if (other.const_expr != nullptr)
+ const_expr = other.const_expr->clone_expr ();
+ else
+ const_expr = nullptr;
+
return *this;
}
@@ -2083,12 +2105,16 @@ public:
/* Returns whether constant item is an "unnamed" (wildcard underscore used
* as identifier) constant. */
- bool is_unnamed () const { return identifier == std::string ("_"); }
+ bool is_unnamed () const { return identifier == "_"; }
Location get_locus () const { return locus; }
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if type or expression are null, so base stripping on that.
+ void mark_for_strip () override { type = nullptr; const_expr = nullptr; }
+ bool is_marked_for_strip () const override { return type == nullptr && const_expr == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2110,12 +2136,6 @@ protected:
{
return new ConstantItem (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual ConstantItem* clone_statement_impl() const override {
- return new ConstantItem(*this);
- }*/
};
/* Static item AST node - items within module scope with fixed storage
@@ -2142,9 +2162,14 @@ public:
// Copy constructor with clone
StaticItem (StaticItem const &other)
: VisItem (other), has_mut (other.has_mut), name (other.name),
- type (other.type->clone_type ()), expr (other.expr->clone_expr ()),
locus (other.locus)
- {}
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr ();
+ }
// Overloaded assignment operator to clone
StaticItem &operator= (StaticItem const &other)
@@ -2152,10 +2177,18 @@ public:
VisItem::operator= (other);
name = other.name;
has_mut = other.has_mut;
- type = other.type->clone_type ();
- expr = other.expr->clone_expr ();
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ else
+ type = nullptr;
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr ();
+ else
+ expr = nullptr;
+
return *this;
}
@@ -2167,6 +2200,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if type or expression are null, so base stripping on that.
+ void mark_for_strip () override { type = nullptr; expr = nullptr; }
+ bool is_marked_for_strip () const override { return type == nullptr && expr == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2174,12 +2211,6 @@ protected:
{
return new StaticItem (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual StaticItem* clone_statement_impl() const override {
- return new StaticItem(*this);
- }*/
};
// Function declaration in traits
@@ -2606,7 +2637,6 @@ protected:
class Trait : public VisItem
{
bool has_unsafe;
-
Identifier name;
// bool has_generics;
@@ -2706,16 +2736,14 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if trait name is empty, so base stripping on that.
+ void mark_for_strip () override { name = ""; }
+ bool is_marked_for_strip () const override { return name.empty (); }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Trait *clone_item_impl () const override { return new Trait (*this); }
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual Trait* clone_statement_impl() const override {
- return new Trait(*this);
- }*/
};
// Implementation item declaration AST node - abstract base class
@@ -2751,6 +2779,10 @@ public:
Location get_locus () const { return locus; }
+ // Invalid if trait type is null, so base stripping on that.
+ void mark_for_strip () override { trait_type = nullptr; }
+ bool is_marked_for_strip () const override { return trait_type == nullptr; }
+
protected:
// Mega-constructor
Impl (std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -2766,10 +2798,13 @@ protected:
// Copy constructor
Impl (Impl const &other)
- : VisItem (other), trait_type (other.trait_type->clone_type ()),
- where_clause (other.where_clause), inner_attrs (other.inner_attrs),
- locus (other.locus)
+ : VisItem (other), where_clause (other.where_clause),
+ inner_attrs (other.inner_attrs), locus (other.locus)
{
+ // guard to prevent null dereference (only required if error state)
+ if (other.trait_type != nullptr)
+ trait_type = other.trait_type->clone_type ();
+
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
@@ -2779,11 +2814,16 @@ protected:
Impl &operator= (Impl const &other)
{
VisItem::operator= (other);
- trait_type = other.trait_type->clone_type ();
where_clause = other.where_clause;
inner_attrs = other.inner_attrs;
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.trait_type != nullptr)
+ trait_type = other.trait_type->clone_type ();
+ else
+ trait_type = nullptr;
+
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
@@ -2853,12 +2893,6 @@ protected:
{
return new InherentImpl (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual InherentImpl* clone_statement_impl() const override {
- return new InherentImpl(*this);
- }*/
};
// The "impl footrait for foo" impl block declaration AST node
@@ -2928,12 +2962,6 @@ protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
TraitImpl *clone_item_impl () const override { return new TraitImpl (*this); }
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual TraitImpl* clone_statement_impl() const override {
- return new TraitImpl(*this);
- }*/
};
// Abstract base class for an item used inside an extern block
@@ -2951,6 +2979,10 @@ class ExternalItem
public:
virtual ~ExternalItem () {}
+ /* TODO: spec syntax rules state that "MacroInvocationSemi" can be used as
+ * ExternalItem, but text body isn't so clear. Adding MacroInvocationSemi
+ * support would require a lot of refactoring. */
+
// Returns whether item has outer attributes.
bool has_outer_attrs () const { return !outer_attrs.empty (); }
@@ -2969,6 +3001,11 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
+ // TODO: make virtual? Would be more flexible.
+ // Based on idea that name should never be empty.
+ void mark_for_strip () { item_name = ""; };
+ bool is_marked_for_strip () const { return item_name.empty (); };
+
protected:
ExternalItem (Identifier item_name, Visibility vis,
std::vector<Attribute> outer_attrs, Location locus)
@@ -3209,6 +3246,9 @@ class ExternBlock : public VisItem
std::vector<std::unique_ptr<ExternalItem>> extern_items;
Location locus;
+
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
public:
std::string as_string () const override;
@@ -3234,7 +3274,7 @@ public:
// Copy constructor with vector clone
ExternBlock (ExternBlock const &other)
: VisItem (other), abi (other.abi), inner_attrs (other.inner_attrs),
- locus (other.locus)
+ locus (other.locus), marked_for_strip (other.marked_for_strip)
{
extern_items.reserve (other.extern_items.size ());
for (const auto &e : other.extern_items)
@@ -3248,6 +3288,7 @@ public:
abi = other.abi;
inner_attrs = other.inner_attrs;
locus = other.locus;
+ marked_for_strip = other.marked_for_strip;
extern_items.reserve (other.extern_items.size ());
for (const auto &e : other.extern_items)
@@ -3264,6 +3305,18 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+
+ // TODO: think of better way to do this
+ const std::vector<std::unique_ptr<ExternalItem>>& get_extern_items () const { return extern_items; }
+ std::vector<std::unique_ptr<ExternalItem>>& get_extern_items () { return extern_items; }
+
+ // TODO: think of better way to do this
+ const std::vector<Attribute>& get_inner_attrs () const { return inner_attrs; }
+ std::vector<Attribute>& get_inner_attrs () { return inner_attrs; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -3271,12 +3324,6 @@ protected:
{
return new ExternBlock (*this);
}
-
- /* Use covariance to implement clone function as returning this object
- * rather than base */
- /*virtual ExternBlock* clone_statement_impl() const override {
- return new ExternBlock(*this);
- }*/
};
// Replaced with forward decls - defined in "rust-macro.h"
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 9ecbb51..8d50b88 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -124,7 +124,7 @@ private:
public:
// Returns whether macro match repetition has separator token.
- bool has_sep () const { return sep != NULL; }
+ bool has_sep () const { return sep != nullptr; }
MacroMatchRepetition (std::vector<std::unique_ptr<MacroMatch> > matches,
MacroRepOp op, std::unique_ptr<MacroRepSep> sep)
@@ -133,8 +133,12 @@ public:
// Copy constructor with clone
MacroMatchRepetition (MacroMatchRepetition const &other)
- : op (other.op), sep (other.sep->clone_token ())
+ : op (other.op)
{
+ // guard to protect from null pointer dereference
+ if (other.sep != nullptr)
+ sep = other.sep->clone_token ();
+
matches.reserve (other.matches.size ());
for (const auto &e : other.matches)
matches.push_back (e->clone_macro_match ());
@@ -144,7 +148,12 @@ public:
MacroMatchRepetition &operator= (MacroMatchRepetition const &other)
{
op = other.op;
- sep = other.sep->clone_token ();
+
+ // guard to protect from null pointer dereference
+ if (other.sep != nullptr)
+ sep = other.sep->clone_token ();
+ else
+ sep = nullptr;
matches.reserve (other.matches.size ());
for (const auto &e : other.matches)
@@ -280,8 +289,9 @@ public:
// A macro rules definition item AST node
class MacroRulesDefinition : public MacroItem
{
+ std::vector<Attribute> outer_attrs;
Identifier rule_name;
- // MacroRulesDef rules_def; // TODO: inline
+ // MacroRulesDef rules_def;
// only curly without required semicolon at end
DelimType delim_type;
// MacroRules rules;
@@ -295,12 +305,16 @@ public:
MacroRulesDefinition (Identifier rule_name, DelimType delim_type,
std::vector<MacroRule> rules,
std::vector<Attribute> outer_attrs, Location locus)
- : MacroItem (std::move (outer_attrs)), rule_name (std::move (rule_name)),
+ : outer_attrs (std::move (outer_attrs)), rule_name (std::move (rule_name)),
delim_type (delim_type), rules (std::move (rules)), locus (locus)
{}
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if rule name is empty, so base stripping on that.
+ void mark_for_strip () override { rule_name = ""; }
+ bool is_marked_for_strip () const override { return rule_name.empty (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -334,6 +348,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if path is empty, so base stripping on that.
+ void mark_for_strip () override { path = SimplePath::create_empty (); }
+ bool is_marked_for_strip () const override { return path.is_empty (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -341,14 +359,7 @@ protected:
{
return new MacroInvocation (*this);
}
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- MacroInvocation *clone_expr_impl () const override
- {
- return new MacroInvocation (*this);
- }
-
+
/* Use covariance to implement clone function as returning this object rather
* than base */
MacroInvocation *clone_expr_without_block_impl () const override
@@ -358,13 +369,6 @@ protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- MacroInvocation *clone_type_impl () const override
- {
- return new MacroInvocation (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
MacroInvocation *clone_type_no_bounds_impl () const override
{
return new MacroInvocation (*this);
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 3006780..32147d3 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -70,9 +70,12 @@ public:
// Copy constructor has to deep copy the type as it is a unique pointer
GenericArgsBinding (GenericArgsBinding const &other)
- : identifier (other.identifier), type (other.type->clone_type ()),
- locus (other.locus)
- {}
+ : identifier (other.identifier), locus (other.locus)
+ {
+ // guard to protect from null pointer dereference
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ }
// default destructor
~GenericArgsBinding () = default;
@@ -81,8 +84,14 @@ public:
GenericArgsBinding &operator= (GenericArgsBinding const &other)
{
identifier = other.identifier;
- type = other.type->clone_type ();
locus = other.locus;
+
+ // guard to protect from null pointer dereference
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ else
+ type = nullptr;
+
return *this;
}
@@ -231,6 +240,9 @@ protected:
* and creates a SimplePath from them. */
SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const;
+ // Removes all segments of the path.
+ void remove_all_segments () { segments.clear (); segments.shrink_to_fit (); }
+
public:
/* Returns whether the path is a single segment (excluding qualified path
* initial as segment). */
@@ -286,6 +298,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if path is empty (error state), so base stripping on that.
+ void mark_for_strip () override { remove_all_segments (); }
+ bool is_marked_for_strip () const override { return is_error (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -446,13 +462,6 @@ public:
// Constructor
TypePathFunction (std::vector<std::unique_ptr<Type>> inputs,
- Type *type = nullptr)
- : inputs (std::move (inputs)), return_type (type), is_invalid (false)
- {}
- // FIXME: deprecated
-
- // Constructor
- TypePathFunction (std::vector<std::unique_ptr<Type>> inputs,
std::unique_ptr<Type> type = nullptr)
: inputs (std::move (inputs)), return_type (std::move (type)),
is_invalid (false)
@@ -460,9 +469,12 @@ public:
// Copy constructor with clone
TypePathFunction (TypePathFunction const &other)
- : return_type (other.return_type->clone_type ()),
- is_invalid (other.is_invalid)
+ : is_invalid (other.is_invalid)
{
+ // guard to protect from null pointer dereference
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+
inputs.reserve (other.inputs.size ());
for (const auto &e : other.inputs)
inputs.push_back (e->clone_type ());
@@ -473,9 +485,14 @@ public:
// Overloaded assignment operator to clone type
TypePathFunction &operator= (TypePathFunction const &other)
{
- return_type = other.return_type->clone_type ();
is_invalid = other.is_invalid;
+ // guard to protect from null pointer dereference
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type ();
+ else
+ return_type = nullptr;
+
inputs.reserve (other.inputs.size ());
for (const auto &e : other.inputs)
inputs.push_back (e->clone_type ());
@@ -539,10 +556,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TypePath *clone_type_impl () const override { return new TypePath (*this); }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
TypePath *clone_type_no_bounds_impl () const override
{
return new TypePath (*this);
@@ -635,9 +648,12 @@ public:
// Copy constructor uses custom deep copy for Type to preserve polymorphism
QualifiedPathType (QualifiedPathType const &other)
- : type_to_invoke_on (other.type_to_invoke_on->clone_type ()),
- trait_path (other.trait_path), locus (other.locus)
- {}
+ : trait_path (other.trait_path), locus (other.locus)
+ {
+ // guard to prevent null dereference
+ if (other.type_to_invoke_on != nullptr)
+ type_to_invoke_on = other.type_to_invoke_on->clone_type ();
+ }
// default destructor
~QualifiedPathType () = default;
@@ -645,9 +661,15 @@ public:
// overload assignment operator to use custom clone method
QualifiedPathType &operator= (QualifiedPathType const &other)
{
- type_to_invoke_on = other.type_to_invoke_on->clone_type ();
trait_path = other.trait_path;
locus = other.locus;
+
+ // guard to prevent null dereference
+ if (other.type_to_invoke_on != nullptr)
+ type_to_invoke_on = other.type_to_invoke_on->clone_type ();
+ else
+ type_to_invoke_on = nullptr;
+
return *this;
}
@@ -710,6 +732,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if path_type is error, so base stripping on that.
+ void mark_for_strip () override { path_type = QualifiedPathType::create_error (); }
+ bool is_marked_for_strip () const override { return is_error (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -737,13 +763,6 @@ class QualifiedPathInType : public TypeNoBounds
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- QualifiedPathInType *clone_type_impl () const override
- {
- return new QualifiedPathInType (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
QualifiedPathInType *clone_type_no_bounds_impl () const override
{
return new QualifiedPathInType (*this);
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 4e639a5..63abe7a 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -77,7 +77,7 @@ public:
: variable_ident (other.variable_ident), is_ref (other.is_ref),
is_mut (other.is_mut), locus (other.locus)
{
- // fix to get prevent null pointer dereference
+ // fix to prevent null pointer dereference
if (other.to_bind != nullptr)
to_bind = other.to_bind->clone_pattern ();
}
@@ -90,9 +90,11 @@ public:
is_mut = other.is_mut;
locus = other.locus;
- // fix to get prevent null pointer dereference
+ // fix to prevent null pointer dereference
if (other.to_bind != nullptr)
to_bind = other.to_bind->clone_pattern ();
+ else
+ to_bind = nullptr;
return *this;
}
@@ -1006,15 +1008,24 @@ public:
// Copy constructor requires clone
TuplePattern (TuplePattern const &other)
- : items (other.items->clone_tuple_pattern_items ()), locus (other.locus)
- {}
+ : locus (other.locus)
+ {
+ // guard to prevent null dereference
+ if (other.items != nullptr)
+ items = other.items->clone_tuple_pattern_items ();
+ }
// Overload assignment operator to clone
TuplePattern &operator= (TuplePattern const &other)
{
- items = other.items->clone_tuple_pattern_items ();
locus = other.locus;
+ // guard to prevent null dereference
+ if (other.items != nullptr)
+ items = other.items->clone_tuple_pattern_items ();
+ else
+ items = nullptr;
+
return *this;
}
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index ce7a37a..127ea21 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -12,6 +12,9 @@ class EmptyStmt : public Stmt
{
Location locus;
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
+
public:
std::string as_string () const override { return std::string (1, ';'); }
@@ -21,6 +24,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -68,21 +75,41 @@ public:
// Copy constructor with clone
LetStmt (LetStmt const &other)
- : outer_attrs (other.outer_attrs),
- variables_pattern (other.variables_pattern->clone_pattern ()),
- type (other.type->clone_type ()),
- init_expr (other.init_expr->clone_expr ()), locus (other.locus)
- {}
+ : outer_attrs (other.outer_attrs), locus (other.locus)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.variables_pattern != nullptr)
+ variables_pattern = other.variables_pattern->clone_pattern ();
+
+ // guard to prevent null dereference (always required)
+ if (other.init_expr != nullptr)
+ init_expr = other.init_expr->clone_expr ();
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ }
// Overloaded assignment operator to clone
LetStmt &operator= (LetStmt const &other)
{
- variables_pattern = other.variables_pattern->clone_pattern ();
- init_expr = other.init_expr->clone_expr ();
- type = other.type->clone_type ();
outer_attrs = other.outer_attrs;
locus = other.locus;
+ // guard to prevent null dereference (only required if error state)
+ if (other.variables_pattern != nullptr)
+ variables_pattern = other.variables_pattern->clone_pattern ();
+ else
+ variables_pattern = nullptr;
+
+ // guard to prevent null dereference (always required)
+ if (other.init_expr != nullptr)
+ init_expr = other.init_expr->clone_expr ();
+ else
+ init_expr = nullptr;
+ if (other.type != nullptr)
+ type = other.type->clone_type ();
+ else
+ type = nullptr;
+
return *this;
}
@@ -94,6 +121,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if pattern is null, so base stripping on that.
+ void mark_for_strip () override { variables_pattern = nullptr; }
+ bool is_marked_for_strip () const override { return variables_pattern == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -138,8 +169,12 @@ public:
// Copy constructor with clone
ExprStmtWithoutBlock (ExprStmtWithoutBlock const &other)
- : ExprStmt (other), expr (other.expr->clone_expr_without_block ())
- {}
+ : ExprStmt (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr_without_block ();
+ }
/*ExprStmtWithoutBlock (ExprStmtWithoutBlock const &other)
: ExprStmt (other), expr (other.expr->clone_expr ())
{}*/
@@ -148,9 +183,14 @@ public:
ExprStmtWithoutBlock &operator= (ExprStmtWithoutBlock const &other)
{
ExprStmt::operator= (other);
- expr = other.expr->clone_expr_without_block ();
//expr = other.expr->clone_expr ();
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr_without_block ();
+ else
+ expr = nullptr;
+
return *this;
}
@@ -160,6 +200,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if expr is null, so base stripping on that.
+ void mark_for_strip () override { expr = nullptr; }
+ bool is_marked_for_strip () const override { return expr == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -185,14 +229,23 @@ public:
// Copy constructor with clone
ExprStmtWithBlock (ExprStmtWithBlock const &other)
- : ExprStmt (other), expr (other.expr->clone_expr_with_block ())
- {}
+ : ExprStmt (other)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr_with_block ();
+ }
// Overloaded assignment operator to clone
ExprStmtWithBlock &operator= (ExprStmtWithBlock const &other)
{
ExprStmt::operator= (other);
- expr = other.expr->clone_expr_with_block ();
+
+ // guard to prevent null dereference (only required if error state)
+ if (other.expr != nullptr)
+ expr = other.expr->clone_expr_with_block ();
+ else
+ expr = nullptr;
return *this;
}
@@ -203,6 +256,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // Invalid if expr is null, so base stripping on that.
+ void mark_for_strip () override { expr = nullptr; }
+ bool is_marked_for_strip () const override { return expr == nullptr; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index b396a44..78b57eb 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -177,13 +177,6 @@ class ParenthesisedType : public TypeNoBounds
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ParenthesisedType *clone_type_impl () const override
- {
- return new ParenthesisedType (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ParenthesisedType *clone_type_no_bounds_impl () const override
{
return new ParenthesisedType (*this);
@@ -242,13 +235,6 @@ class ImplTraitTypeOneBound : public TypeNoBounds
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ImplTraitTypeOneBound *clone_type_impl () const override
- {
- return new ImplTraitTypeOneBound (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ImplTraitTypeOneBound *clone_type_no_bounds_impl () const override
{
return new ImplTraitTypeOneBound (*this);
@@ -278,13 +264,6 @@ class TraitObjectTypeOneBound : public TypeNoBounds
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TraitObjectTypeOneBound *clone_type_impl () const override
- {
- return new TraitObjectTypeOneBound (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
TraitObjectTypeOneBound *clone_type_no_bounds_impl () const override
{
return new TraitObjectTypeOneBound (*this);
@@ -362,10 +341,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- TupleType *clone_type_impl () const override { return new TupleType (*this); }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
TupleType *clone_type_no_bounds_impl () const override
{
return new TupleType (*this);
@@ -382,10 +357,6 @@ class NeverType : public TypeNoBounds
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- NeverType *clone_type_impl () const override { return new NeverType (*this); }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
NeverType *clone_type_no_bounds_impl () const override
{
return new NeverType (*this);
@@ -455,13 +426,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- RawPointerType *clone_type_impl () const override
- {
- return new RawPointerType (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
RawPointerType *clone_type_no_bounds_impl () const override
{
return new RawPointerType (*this);
@@ -522,13 +486,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ReferenceType *clone_type_impl () const override
- {
- return new ReferenceType (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ReferenceType *clone_type_no_bounds_impl () const override
{
return new ReferenceType (*this);
@@ -577,10 +534,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- ArrayType *clone_type_impl () const override { return new ArrayType (*this); }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
ArrayType *clone_type_no_bounds_impl () const override
{
return new ArrayType (*this);
@@ -627,10 +580,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- SliceType *clone_type_impl () const override { return new SliceType (*this); }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
SliceType *clone_type_no_bounds_impl () const override
{
return new SliceType (*this);
@@ -647,13 +596,6 @@ class InferredType : public TypeNoBounds
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- InferredType *clone_type_impl () const override
- {
- return new InferredType (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
InferredType *clone_type_no_bounds_impl () const override
{
return new InferredType (*this);
@@ -699,9 +641,12 @@ public:
// Copy constructor with clone
MaybeNamedParam (MaybeNamedParam const &other)
- : param_type (other.param_type->clone_type ()),
- param_kind (other.param_kind), name (other.name), locus (other.locus)
- {}
+ : param_kind (other.param_kind), name (other.name), locus (other.locus)
+ {
+ // guard to prevent null dereference
+ if (other.param_type != nullptr)
+ param_type = other.param_type->clone_type ();
+ }
~MaybeNamedParam () = default;
@@ -710,9 +655,14 @@ public:
{
name = other.name;
param_kind = other.param_kind;
- param_type = other.param_type->clone_type ();
locus = other.locus;
+ // guard to prevent null dereference
+ if (other.param_type != nullptr)
+ param_type = other.param_type->clone_type ();
+ else
+ param_type = nullptr;
+
return *this;
}
@@ -773,10 +723,12 @@ public:
BareFunctionType (BareFunctionType const &other)
: for_lifetimes (other.for_lifetimes),
function_qualifiers (other.function_qualifiers), params (other.params),
- is_variadic (other.is_variadic),
- return_type (other.return_type->clone_type_no_bounds ()),
- locus (other.locus)
- {}
+ is_variadic (other.is_variadic), locus (other.locus)
+ {
+ // guard to prevent null dereference
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type_no_bounds ();
+ }
// Overload assignment operator to deep copy
BareFunctionType &operator= (BareFunctionType const &other)
@@ -785,9 +737,14 @@ public:
function_qualifiers = other.function_qualifiers;
params = other.params;
is_variadic = other.is_variadic;
- return_type = other.return_type->clone_type_no_bounds ();
locus = other.locus;
+ // guard to prevent null dereference
+ if (other.return_type != nullptr)
+ return_type = other.return_type->clone_type_no_bounds ();
+ else
+ return_type = nullptr;
+
return *this;
}
@@ -804,13 +761,6 @@ public:
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
- BareFunctionType *clone_type_impl () const override
- {
- return new BareFunctionType (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
BareFunctionType *clone_type_no_bounds_impl () const override
{
return new BareFunctionType (*this);
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 4a39be3..a7d2a1a 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -1,8 +1,217 @@
#include "rust-macro-expand.h"
#include "rust-ast-full.h"
// is full really required?
+#include "rust-ast-visitor.h"
namespace Rust {
+ // Visitor used to expand attributes.
+ class AttrVisitor : public AST::ASTVisitor {
+ private:
+ MacroExpander& expander;
+
+ public:
+ AttrVisitor(MacroExpander& expander) : expander(expander) {}
+
+ void visit(AST::Token& tok) override {}
+ void visit(AST::DelimTokenTree& delim_tok_tree) override {}
+ void visit(AST::AttrInputMetaItemContainer& input) override {}
+ void visit(AST::IdentifierExpr& ident_expr) override {}
+ void visit(AST::Lifetime& lifetime) override {}
+ void visit(AST::LifetimeParam& lifetime_param) override {}
+ void visit(AST::MacroInvocationSemi& macro) override {}
+
+ void visit(AST::PathInExpression& path) override {}
+ void visit(AST::TypePathSegment& segment) override {}
+ void visit(AST::TypePathSegmentGeneric& segment) override {}
+ void visit(AST::TypePathSegmentFunction& segment) override {}
+ void visit(AST::TypePath& path) override {}
+ void visit(AST::QualifiedPathInExpression& path) override {}
+ void visit(AST::QualifiedPathInType& path) override {}
+
+ void visit(AST::LiteralExpr& expr) override {}
+ void visit(AST::AttrInputLiteral& attr_input) override {}
+ void visit(AST::MetaItemLitExpr& meta_item) override {}
+ void visit(AST::MetaItemPathLit& meta_item) override {}
+ void visit(AST::BorrowExpr& expr) override {}
+ void visit(AST::DereferenceExpr& expr) override {}
+ void visit(AST::ErrorPropagationExpr& expr) override {}
+ void visit(AST::NegationExpr& expr) override {}
+ void visit(AST::ArithmeticOrLogicalExpr& expr) override {}
+ void visit(AST::ComparisonExpr& expr) override {}
+ void visit(AST::LazyBooleanExpr& expr) override {}
+ void visit(AST::TypeCastExpr& expr) override {}
+ void visit(AST::AssignmentExpr& expr) override {}
+ void visit(AST::CompoundAssignmentExpr& expr) override {}
+ void visit(AST::GroupedExpr& expr) override {}
+ void visit(AST::ArrayElemsValues& elems) override {}
+ void visit(AST::ArrayElemsCopied& elems) override {}
+ void visit(AST::ArrayExpr& expr) override {}
+ void visit(AST::ArrayIndexExpr& expr) override {}
+ void visit(AST::TupleExpr& expr) override {}
+ void visit(AST::TupleIndexExpr& expr) override {}
+ void visit(AST::StructExprStruct& expr) override {}
+ void visit(AST::StructExprFieldIdentifier& field) override {}
+ void visit(AST::StructExprFieldIdentifierValue& field) override {}
+ void visit(AST::StructExprFieldIndexValue& field) override {}
+ void visit(AST::StructExprStructFields& expr) override {}
+ void visit(AST::StructExprStructBase& expr) override {}
+ void visit(AST::StructExprTuple& expr) override {}
+ void visit(AST::StructExprUnit& expr) override {}
+ void visit(AST::EnumExprFieldIdentifier& field) override {}
+ void visit(AST::EnumExprFieldIdentifierValue& field) override {}
+ void visit(AST::EnumExprFieldIndexValue& field) override {}
+ void visit(AST::EnumExprStruct& expr) override {}
+ void visit(AST::EnumExprTuple& expr) override {}
+ void visit(AST::EnumExprFieldless& expr) override {}
+ void visit(AST::CallExpr& expr) override {}
+ void visit(AST::MethodCallExpr& expr) override {}
+ void visit(AST::FieldAccessExpr& expr) override {}
+ void visit(AST::ClosureExprInner& expr) override {}
+ void visit(AST::BlockExpr& expr) override {}
+ void visit(AST::ClosureExprInnerTyped& expr) override {}
+ void visit(AST::ContinueExpr& expr) override {}
+ void visit(AST::BreakExpr& expr) override {}
+ void visit(AST::RangeFromToExpr& expr) override {}
+ void visit(AST::RangeFromExpr& expr) override {}
+ void visit(AST::RangeToExpr& expr) override {}
+ void visit(AST::RangeFullExpr& expr) override {}
+ void visit(AST::RangeFromToInclExpr& expr) override {}
+ void visit(AST::RangeToInclExpr& expr) override {}
+ void visit(AST::ReturnExpr& expr) override {}
+ void visit(AST::UnsafeBlockExpr& expr) override {}
+ void visit(AST::LoopExpr& expr) override {}
+ void visit(AST::WhileLoopExpr& expr) override {}
+ void visit(AST::WhileLetLoopExpr& expr) override {}
+ void visit(AST::ForLoopExpr& expr) override {}
+ void visit(AST::IfExpr& expr) override {}
+ void visit(AST::IfExprConseqElse& expr) override {}
+ void visit(AST::IfExprConseqIf& expr) override {}
+ void visit(AST::IfExprConseqIfLet& expr) override {}
+ void visit(AST::IfLetExpr& expr) override {}
+ void visit(AST::IfLetExprConseqElse& expr) override {}
+ void visit(AST::IfLetExprConseqIf& expr) override {}
+ void visit(AST::IfLetExprConseqIfLet& expr) override {}
+ void visit(AST::MatchExpr& expr) override {}
+ void visit(AST::AwaitExpr& expr) override {}
+ void visit(AST::AsyncBlockExpr& expr) override {}
+
+ void visit(AST::TypeParam& param) override {}
+ void visit(AST::LifetimeWhereClauseItem& item) override {}
+ void visit(AST::TypeBoundWhereClauseItem& item) override {}
+ void visit(AST::Method& method) override {}
+ void visit(AST::ModuleBodied& module) override {}
+ void visit(AST::ModuleNoBody& module) override {}
+ void visit(AST::ExternCrate& crate) override {}
+ void visit(AST::UseTreeGlob& use_tree) override {}
+ void visit(AST::UseTreeList& use_tree) override {}
+ void visit(AST::UseTreeRebind& use_tree) override {}
+ void visit(AST::UseDeclaration& use_decl) override {}
+ void visit(AST::Function& function) override {}
+ void visit(AST::TypeAlias& type_alias) override {}
+ void visit(AST::StructStruct& struct_item) override {}
+ void visit(AST::TupleStruct& tuple_struct) override {}
+ void visit(AST::EnumItem& item) override {}
+ void visit(AST::EnumItemTuple& item) override {}
+ void visit(AST::EnumItemStruct& item) override {}
+ void visit(AST::EnumItemDiscriminant& item) override {}
+ void visit(AST::Enum& enum_item) override {}
+ void visit(AST::Union& union_item) override {}
+ void visit(AST::ConstantItem& const_item) override {}
+ void visit(AST::StaticItem& static_item) override {}
+ void visit(AST::TraitItemFunc& item) override {}
+ void visit(AST::TraitItemMethod& item) override {}
+ void visit(AST::TraitItemConst& item) override {}
+ void visit(AST::TraitItemType& item) override {}
+ void visit(AST::Trait& trait) override {}
+ void visit(AST::InherentImpl& impl) override {}
+ void visit(AST::TraitImpl& impl) override {}
+ void visit(AST::ExternalStaticItem& item) override {}
+ void visit(AST::ExternalFunctionItem& item) override {}
+ void visit(AST::ExternBlock& block) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(block.get_outer_attrs());
+ if (expander.fails_cfg(block.get_outer_attrs())) {
+ block.mark_for_strip();
+ return;
+ }
+
+ // strip test based on inner attrs
+ expander.expand_cfg_attrs(block.get_inner_attrs());
+ if (expander.fails_cfg(block.get_inner_attrs())) {
+ block.mark_for_strip();
+ return;
+ }
+
+ // strip external items if required
+ auto& extern_items = block.get_extern_items();
+ for (auto i = 0; i < extern_items.size(); ) {
+ auto& item = extern_items[i];
+
+ // mark for stripping if required
+ item->accept_vis(*this);
+
+ if (item->is_marked_for_strip ())
+ extern_items.erase (extern_items.begin() + i);
+ else
+ i++;
+
+ }
+ }
+
+ void visit(AST::MacroMatchFragment& match) override {}
+ void visit(AST::MacroMatchRepetition& match) override {}
+ void visit(AST::MacroMatcher& matcher) override {}
+ void visit(AST::MacroRulesDefinition& rules_def) override {}
+ void visit(AST::MacroInvocation& macro_invoc) override {}
+ void visit(AST::MetaItemPath& meta_item) override {}
+ void visit(AST::MetaItemSeq& meta_item) override {}
+ void visit(AST::MetaWord& meta_item) override {}
+ void visit(AST::MetaNameValueStr& meta_item) override {}
+ void visit(AST::MetaListPaths& meta_item) override {}
+ void visit(AST::MetaListNameValueStr& meta_item) override {}
+
+ void visit(AST::LiteralPattern& pattern) override {}
+ void visit(AST::IdentifierPattern& pattern) override {}
+ void visit(AST::WildcardPattern& pattern) override {}
+ void visit(AST::RangePatternBoundLiteral& bound) override {}
+ void visit(AST::RangePatternBoundPath& bound) override {}
+ void visit(AST::RangePatternBoundQualPath& bound) override {}
+ void visit(AST::RangePattern& pattern) override {}
+ void visit(AST::ReferencePattern& pattern) override {}
+ void visit(AST::StructPatternFieldTuplePat& field) override {}
+ void visit(AST::StructPatternFieldIdentPat& field) override {}
+ void visit(AST::StructPatternFieldIdent& field) override {}
+ void visit(AST::StructPattern& pattern) override {}
+ void visit(AST::TupleStructItemsNoRange& tuple_items) override {}
+ void visit(AST::TupleStructItemsRange& tuple_items) override {}
+ void visit(AST::TupleStructPattern& pattern) override {}
+ void visit(AST::TuplePatternItemsMultiple& tuple_items) override {}
+ void visit(AST::TuplePatternItemsRanged& tuple_items) override {}
+ void visit(AST::TuplePattern& pattern) override {}
+ void visit(AST::GroupedPattern& pattern) override {}
+ void visit(AST::SlicePattern& pattern) override {}
+
+ void visit(AST::EmptyStmt& stmt) override {}
+ void visit(AST::LetStmt& stmt) override {}
+ void visit(AST::ExprStmtWithoutBlock& stmt) override {}
+ void visit(AST::ExprStmtWithBlock& stmt) override {}
+
+ void visit(AST::TraitBound& bound) override {}
+ void visit(AST::ImplTraitType& type) override {}
+ void visit(AST::TraitObjectType& type) override {}
+ void visit(AST::ParenthesisedType& type) override {}
+ void visit(AST::ImplTraitTypeOneBound& type) override {}
+ void visit(AST::TraitObjectTypeOneBound& type) override {}
+ void visit(AST::TupleType& type) override {}
+ void visit(AST::NeverType& type) override {}
+ void visit(AST::RawPointerType& type) override {}
+ void visit(AST::ReferenceType& type) override {}
+ void visit(AST::ArrayType& type) override {}
+ void visit(AST::SliceType& type) override {}
+ void visit(AST::InferredType& type) override {}
+ void visit(AST::BareFunctionType& type) override {}
+ };
+
void MacroExpander::expand_invoc(std::unique_ptr<AST::MacroInvocation>& invoc) {
/* if current expansion depth > recursion limit, create an error (maybe fatal
* error) and return */
@@ -24,7 +233,7 @@ namespace Rust {
- derive container macro - unreachable*/
}
- /* Determines whether any cfg predicate is false and hence item with attributes should
+ /* Determines whether any cfg predicate is false and hence item with attributes should
* be stripped. */
bool MacroExpander::fails_cfg(std::vector<AST::Attribute>& attrs) {
for (auto& attr : attrs) {
@@ -81,6 +290,14 @@ namespace Rust {
}
// expand module attributes?
+ // expand attributes recursively
+ AttrVisitor attr_visitor(*this);
+ for (auto& i : crate.items) {
+ i->accept_vis(attr_visitor);
+ }
+ // TODO: should recursive attribute and macro expansion be done in the same transversal? Or in
+ // separate ones like currently?
+
// expand module tree recursively
// post-process
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 7940df7..fd50bf1 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -626,8 +626,7 @@ Session::injection (AST::Crate &crate)
* rustc also has a "quote" macro that is defined differently and is
* supposedly not stable so eh. */
/* TODO: actually implement injection of these macros. In particular, derive
- * macros, cfg, and
- * test should be prioritised since they seem to be used the most. */
+ * macros, cfg, and test should be prioritised since they seem to be used the most. */
// crate injection
std::vector<std::string> names;