diff options
author | Philip Herron <philip.herron@embecosm.com> | 2020-12-14 15:40:17 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-14 15:40:17 +0000 |
commit | 6e4b74fb77c45a6088e0cca22ec05c28c7f0b6dc (patch) | |
tree | 46eb33355b3d0351d4743d19d1d5c46ae9d5677c /gcc/rust/ast/rust-pattern.h | |
parent | cef34bd730d80b4664d8633e2cc27a64c5cae246 (diff) | |
parent | 52cc571b308d3d0103dd498fd277859e2116791a (diff) | |
download | gcc-6e4b74fb77c45a6088e0cca22ec05c28c7f0b6dc.zip gcc-6e4b74fb77c45a6088e0cca22ec05c28c7f0b6dc.tar.gz gcc-6e4b74fb77c45a6088e0cca22ec05c28c7f0b6dc.tar.bz2 |
Merge pull request #62 from SimplyTheOther/master
Expansion code for cfg attributes, bug fixes and minor enhancements in parser
Diffstat (limited to 'gcc/rust/ast/rust-pattern.h')
-rw-r--r-- | gcc/rust/ast/rust-pattern.h | 341 |
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 */ |