aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast/rust-pattern.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/ast/rust-pattern.h')
-rw-r--r--gcc/rust/ast/rust-pattern.h341
1 files changed, 297 insertions, 44 deletions
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 4e639a5..3a87a83 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -34,6 +34,7 @@ public:
{}
Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
@@ -49,7 +50,6 @@ protected:
// Identifier pattern AST node (bind value matched to a variable)
class IdentifierPattern : public Pattern
{
-public:
Identifier variable_ident;
bool is_ref;
bool is_mut;
@@ -59,6 +59,7 @@ public:
Location locus;
+public:
std::string as_string () const;
// Returns whether the IdentifierPattern has a pattern to bind.
@@ -77,7 +78,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 +91,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;
}
@@ -102,9 +105,19 @@ public:
IdentifierPattern &operator= (IdentifierPattern &&other) = default;
Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
+ // TODO: is this better? Or is a "vis_pattern" better?
+ std::unique_ptr<Pattern> &get_pattern_to_bind ()
+ {
+ rust_assert (has_pattern_to_bind ());
+ return to_bind;
+ }
+
+ Identifier get_ident () const { return variable_ident; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -125,6 +138,7 @@ public:
WildcardPattern (Location locus) : locus (locus) {}
Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
@@ -210,6 +224,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // TODO: this mutable getter seems kinda dodgy
+ PathInExpression &get_path () { return path; }
+ const PathInExpression &get_path () const { return path; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -238,6 +256,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // TODO: this mutable getter seems kinda dodgy
+ QualifiedPathInExpression &get_qualified_path () { return path; }
+ const QualifiedPathInExpression &get_qualified_path () const { return path; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -293,9 +315,23 @@ public:
RangePattern &operator= (RangePattern &&other) = default;
Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
+ // TODO: is this better? or is a "vis_bound" better?
+ std::unique_ptr<RangePatternBound> &get_lower_bound ()
+ {
+ rust_assert (lower != nullptr);
+ return lower;
+ }
+
+ std::unique_ptr<RangePatternBound> &get_upper_bound ()
+ {
+ rust_assert (upper != nullptr);
+ return upper;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -343,8 +379,18 @@ public:
ReferencePattern (ReferencePattern &&other) = default;
ReferencePattern &operator= (ReferencePattern &&other) = default;
+ Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
+
void accept_vis (ASTVisitor &vis) override;
+ // TODO: is this better? Or is a "vis_pattern" better?
+ std::unique_ptr<Pattern> &get_referenced_pattern ()
+ {
+ rust_assert (pattern != nullptr);
+ return pattern;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -354,6 +400,7 @@ protected:
}
};
+#if 0
// aka StructPatternEtCetera; potential element in struct pattern
struct StructPatternEtc
{
@@ -373,6 +420,7 @@ public:
return StructPatternEtc (std::vector<Attribute> ());
}
};
+#endif
// Base class for a single field in a struct pattern - abstract
class StructPatternField
@@ -396,6 +444,13 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
+ virtual void mark_for_strip () = 0;
+ virtual bool is_marked_for_strip () const = 0;
+
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
+ const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
+
protected:
StructPatternField (std::vector<Attribute> outer_attribs, Location locus)
: outer_attrs (std::move (outer_attribs)), locus (locus)
@@ -422,19 +477,27 @@ public:
// Copy constructor requires clone
StructPatternFieldTuplePat (StructPatternFieldTuplePat const &other)
- : StructPatternField (other), index (other.index),
- tuple_pattern (other.tuple_pattern->clone_pattern ())
- {}
+ : StructPatternField (other), index (other.index)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.tuple_pattern != nullptr)
+ tuple_pattern = other.tuple_pattern->clone_pattern ();
+ }
// Overload assignment operator to perform clone
StructPatternFieldTuplePat &
operator= (StructPatternFieldTuplePat const &other)
{
StructPatternField::operator= (other);
- tuple_pattern = other.tuple_pattern->clone_pattern ();
index = other.index;
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.tuple_pattern != nullptr)
+ tuple_pattern = other.tuple_pattern->clone_pattern ();
+ else
+ tuple_pattern = nullptr;
+
return *this;
}
@@ -447,6 +510,20 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // based on idea of tuple pattern no longer existing
+ void mark_for_strip () override { tuple_pattern = nullptr; }
+ bool is_marked_for_strip () const override
+ {
+ return tuple_pattern == nullptr;
+ }
+
+ // TODO: is this better? Or is a "vis_pattern" better?
+ std::unique_ptr<Pattern> &get_index_pattern ()
+ {
+ rust_assert (tuple_pattern != nullptr);
+ return tuple_pattern;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -473,9 +550,12 @@ public:
// Copy constructor requires clone
StructPatternFieldIdentPat (StructPatternFieldIdentPat const &other)
- : StructPatternField (other), ident (other.ident),
- ident_pattern (other.ident_pattern->clone_pattern ())
- {}
+ : StructPatternField (other), ident (other.ident)
+ {
+ // guard to prevent null dereference (only required if error state)
+ if (other.ident_pattern != nullptr)
+ ident_pattern = other.ident_pattern->clone_pattern ();
+ }
// Overload assignment operator to clone
StructPatternFieldIdentPat &
@@ -483,9 +563,14 @@ public:
{
StructPatternField::operator= (other);
ident = other.ident;
- ident_pattern = other.ident_pattern->clone_pattern ();
// outer_attrs = other.outer_attrs;
+ // guard to prevent null dereference (only required if error state)
+ if (other.ident_pattern != nullptr)
+ ident_pattern = other.ident_pattern->clone_pattern ();
+ else
+ ident_pattern = nullptr;
+
return *this;
}
@@ -498,6 +583,20 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // based on idea of identifier pattern no longer existing
+ void mark_for_strip () override { ident_pattern = nullptr; }
+ bool is_marked_for_strip () const override
+ {
+ return ident_pattern == nullptr;
+ }
+
+ // TODO: is this better? Or is a "vis_pattern" better?
+ std::unique_ptr<Pattern> &get_ident_pattern ()
+ {
+ rust_assert (ident_pattern != nullptr);
+ return ident_pattern;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -525,6 +624,10 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // based on idea of identifier no longer existing
+ void mark_for_strip () override { ident = {}; }
+ bool is_marked_for_strip () const override { return ident.empty (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -539,10 +642,11 @@ struct StructPatternElements
{
private:
// bool has_struct_pattern_fields;
- std::vector<std::unique_ptr<StructPatternField>> fields;
+ std::vector<std::unique_ptr<StructPatternField> > fields;
bool has_struct_pattern_etc;
- StructPatternEtc etc;
+ std::vector<Attribute> struct_pattern_etc_attrs;
+ // StructPatternEtc etc;
// must have at least one of the two and maybe both
@@ -559,24 +663,27 @@ public:
return !has_struct_pattern_fields () && !has_struct_pattern_etc;
}
+ bool has_etc () const { return has_struct_pattern_etc; }
+
// Constructor for StructPatternElements with both (potentially)
StructPatternElements (
- std::vector<std::unique_ptr<StructPatternField>> fields,
- StructPatternEtc etc)
+ std::vector<std::unique_ptr<StructPatternField> > fields,
+ std::vector<Attribute> etc_attrs)
: fields (std::move (fields)), has_struct_pattern_etc (true),
- etc (std::move (etc))
+ struct_pattern_etc_attrs (std::move (etc_attrs))
{}
// Constructor for StructPatternElements with no StructPatternEtc
StructPatternElements (
- std::vector<std::unique_ptr<StructPatternField>> fields)
+ std::vector<std::unique_ptr<StructPatternField> > fields)
: fields (std::move (fields)), has_struct_pattern_etc (false),
- etc (StructPatternEtc::create_empty ())
+ struct_pattern_etc_attrs ()
{}
// Copy constructor with vector clone
StructPatternElements (StructPatternElements const &other)
- : has_struct_pattern_etc (other.has_struct_pattern_etc), etc (other.etc)
+ : has_struct_pattern_etc (other.has_struct_pattern_etc),
+ struct_pattern_etc_attrs (other.struct_pattern_etc_attrs)
{
fields.reserve (other.fields.size ());
for (const auto &e : other.fields)
@@ -586,7 +693,7 @@ public:
// Overloaded assignment operator with vector clone
StructPatternElements &operator= (StructPatternElements const &other)
{
- etc = other.etc;
+ struct_pattern_etc_attrs = other.struct_pattern_etc_attrs;
has_struct_pattern_etc = other.has_struct_pattern_etc;
fields.reserve (other.fields.size ());
@@ -604,10 +711,38 @@ public:
static StructPatternElements create_empty ()
{
return StructPatternElements (
- std::vector<std::unique_ptr<StructPatternField>> ());
+ std::vector<std::unique_ptr<StructPatternField> > ());
}
std::string as_string () const;
+
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<StructPatternField> > &
+ get_struct_pattern_fields ()
+ {
+ return fields;
+ }
+ const std::vector<std::unique_ptr<StructPatternField> > &
+ get_struct_pattern_fields () const
+ {
+ return fields;
+ }
+
+ std::vector<Attribute> &get_etc_outer_attrs ()
+ {
+ return struct_pattern_etc_attrs;
+ }
+ const std::vector<Attribute> &get_etc_outer_attrs () const
+ {
+ return struct_pattern_etc_attrs;
+ }
+
+ void strip_etc ()
+ {
+ has_struct_pattern_etc = false;
+ struct_pattern_etc_attrs.clear ();
+ struct_pattern_etc_attrs.shrink_to_fit ();
+ }
};
// Struct pattern AST node representation
@@ -638,9 +773,20 @@ public:
bool has_struct_pattern_elems () const { return !elems.is_empty (); }
Location get_locus () const { return path.get_locus (); }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ StructPatternElements &get_struct_pattern_elems () { return elems; }
+ const StructPatternElements &get_struct_pattern_elems () const
+ {
+ return elems;
+ }
+
+ PathInExpression &get_path () { return path; }
+ const PathInExpression &get_path () const { return path; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -676,10 +822,10 @@ protected:
// Class for non-ranged tuple struct pattern patterns
class TupleStructItemsNoRange : public TupleStructItems
{
- std::vector<std::unique_ptr<Pattern>> patterns;
+ std::vector<std::unique_ptr<Pattern> > patterns;
public:
- TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern>> patterns)
+ TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern> > patterns)
: patterns (std::move (patterns))
{}
@@ -710,6 +856,13 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<Pattern> > &get_patterns () { return patterns; }
+ const std::vector<std::unique_ptr<Pattern> > &get_patterns () const
+ {
+ return patterns;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -722,12 +875,12 @@ protected:
// Class for ranged tuple struct pattern patterns
class TupleStructItemsRange : public TupleStructItems
{
- std::vector<std::unique_ptr<Pattern>> lower_patterns;
- std::vector<std::unique_ptr<Pattern>> upper_patterns;
+ std::vector<std::unique_ptr<Pattern> > lower_patterns;
+ std::vector<std::unique_ptr<Pattern> > upper_patterns;
public:
- TupleStructItemsRange (std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ TupleStructItemsRange (std::vector<std::unique_ptr<Pattern> > lower_patterns,
+ std::vector<std::unique_ptr<Pattern> > upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
@@ -766,6 +919,26 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<Pattern> > &get_lower_patterns ()
+ {
+ return lower_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () const
+ {
+ return lower_patterns;
+ }
+
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<Pattern> > &get_upper_patterns ()
+ {
+ return upper_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () const
+ {
+ return upper_patterns;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -787,21 +960,32 @@ class TupleStructPattern : public Pattern
public:
std::string as_string () const override;
+ // Returns whether the pattern has tuple struct items.
+ bool has_items () const { return items != nullptr; }
+
TupleStructPattern (PathInExpression tuple_struct_path,
std::unique_ptr<TupleStructItems> items)
: path (std::move (tuple_struct_path)), items (std::move (items))
{}
// Copy constructor required to clone
- TupleStructPattern (TupleStructPattern const &other)
- : path (other.path), items (other.items->clone_tuple_struct_items ())
- {}
+ TupleStructPattern (TupleStructPattern const &other) : path (other.path)
+ {
+ // guard to protect from null dereference
+ if (other.items != nullptr)
+ items = other.items->clone_tuple_struct_items ();
+ }
// Operator overload assignment operator to clone
TupleStructPattern &operator= (TupleStructPattern const &other)
{
path = other.path;
- items = other.items->clone_tuple_struct_items ();
+
+ // guard to protect from null dereference
+ if (other.items != nullptr)
+ items = other.items->clone_tuple_struct_items ();
+ else
+ items = nullptr;
return *this;
}
@@ -811,9 +995,20 @@ public:
TupleStructPattern &operator= (TupleStructPattern &&other) = default;
Location get_locus () const { return path.get_locus (); }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::unique_ptr<TupleStructItems> &get_items ()
+ {
+ rust_assert (has_items ());
+ return items;
+ }
+
+ PathInExpression &get_path () { return path; }
+ const PathInExpression &get_path () const { return path; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -885,10 +1080,10 @@ TuplePatternItemsSingle(*this);
// Class representing TuplePattern patterns where there are multiple patterns
class TuplePatternItemsMultiple : public TuplePatternItems
{
- std::vector<std::unique_ptr<Pattern>> patterns;
+ std::vector<std::unique_ptr<Pattern> > patterns;
public:
- TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern>> patterns)
+ TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern> > patterns)
: patterns (std::move (patterns))
{}
@@ -919,6 +1114,13 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<Pattern> > &get_patterns () { return patterns; }
+ const std::vector<std::unique_ptr<Pattern> > &get_patterns () const
+ {
+ return patterns;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -931,13 +1133,13 @@ protected:
// Class representing TuplePattern patterns where there are a range of patterns
class TuplePatternItemsRanged : public TuplePatternItems
{
- std::vector<std::unique_ptr<Pattern>> lower_patterns;
- std::vector<std::unique_ptr<Pattern>> upper_patterns;
+ std::vector<std::unique_ptr<Pattern> > lower_patterns;
+ std::vector<std::unique_ptr<Pattern> > upper_patterns;
public:
TuplePatternItemsRanged (
- std::vector<std::unique_ptr<Pattern>> lower_patterns,
- std::vector<std::unique_ptr<Pattern>> upper_patterns)
+ std::vector<std::unique_ptr<Pattern> > lower_patterns,
+ std::vector<std::unique_ptr<Pattern> > upper_patterns)
: lower_patterns (std::move (lower_patterns)),
upper_patterns (std::move (upper_patterns))
{}
@@ -977,6 +1179,26 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<Pattern> > &get_lower_patterns ()
+ {
+ return lower_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () const
+ {
+ return lower_patterns;
+ }
+
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<Pattern> > &get_upper_patterns ()
+ {
+ return upper_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () const
+ {
+ return upper_patterns;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -991,7 +1213,6 @@ class TuplePattern : public Pattern
{
// bool has_tuple_pattern_items;
std::unique_ptr<TuplePatternItems> items;
-
Location locus;
public:
@@ -1005,23 +1226,39 @@ public:
{}
// Copy constructor requires clone
- TuplePattern (TuplePattern const &other)
- : items (other.items->clone_tuple_pattern_items ()), locus (other.locus)
- {}
+ TuplePattern (TuplePattern const &other) : 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;
}
Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::unique_ptr<TuplePatternItems> &get_items ()
+ {
+ rust_assert (has_tuple_pattern_items ());
+ return items;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1067,9 +1304,17 @@ public:
GroupedPattern &operator= (GroupedPattern &&other) = default;
Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::unique_ptr<Pattern> &get_pattern_in_parens ()
+ {
+ rust_assert (pattern_in_parens != nullptr);
+ return pattern_in_parens;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1082,13 +1327,13 @@ protected:
// AST node representing patterns that can match slices and arrays
class SlicePattern : public Pattern
{
- std::vector<std::unique_ptr<Pattern>> items;
+ std::vector<std::unique_ptr<Pattern> > items;
Location locus;
public:
std::string as_string () const override;
- SlicePattern (std::vector<std::unique_ptr<Pattern>> items, Location locus)
+ SlicePattern (std::vector<std::unique_ptr<Pattern> > items, Location locus)
: items (std::move (items)), locus (locus)
{}
@@ -1117,9 +1362,17 @@ public:
SlicePattern &operator= (SlicePattern &&other) = default;
Location get_locus () const { return locus; }
+ Location get_locus_slow () const final override { return get_locus (); }
void accept_vis (ASTVisitor &vis) override;
+ // TODO: seems kinda dodgy. Think of better way.
+ std::vector<std::unique_ptr<Pattern> > &get_items () { return items; }
+ const std::vector<std::unique_ptr<Pattern> > &get_items () const
+ {
+ return items;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */