diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-02-28 13:49:45 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-01 11:19:11 +0100 |
commit | 12d156566af84ec834abb7e18feac6e8f5884451 (patch) | |
tree | 53dc6f2d0af871c54c32ff851a3005c7ae1cecf5 /gcc/rust/ast/rust-macro.h | |
parent | bf92a1012264f2544e73a7a8dd0ac1e473c7f658 (diff) | |
download | gcc-12d156566af84ec834abb7e18feac6e8f5884451.zip gcc-12d156566af84ec834abb7e18feac6e8f5884451.tar.gz gcc-12d156566af84ec834abb7e18feac6e8f5884451.tar.bz2 |
parser: Allow parsing macro invocations as statements
When parsing a macro invocation as a statement, the parser would parse
an expression and then try parsing a semicolon. Since no actual
lookahead was done (which is a good thing), we couldn't convert a
`MacroInvocation` to a `MacroInvocationSemi` after the fact.
Since, unlike function calls, macro invocations can act differently
based on whether or not they are followed by a semicolon, we actually
need to differentiate between the two up until expansion.
This commits adds a new virtual method for ExprWithoutBlock when
converting to ExprStmtWithoutBlock so that classes inheriting
ExprWithoutBlock can specify a new behavior. In the case of our
MacroInvocation class, it simply means toggling a boolean: If we're
converting a macro from an expression to a statement, it must mean that
it should contain a semicolon.
Diffstat (limited to 'gcc/rust/ast/rust-macro.h')
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 9f8f19c..de1d0a5 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -27,7 +27,6 @@ namespace AST { // Decls as definitions moved to rust-ast.h class MacroItem; -class MacroInvocationSemi; enum MacroFragSpec { @@ -454,6 +453,10 @@ protected: * compile time */ class MacroInvocation : public TypeNoBounds, public Pattern, + public MacroItem, + public TraitItem, + public TraitImplItem, + public InherentImplItem, public ExprWithoutBlock { std::vector<Attribute> outer_attrs; @@ -463,14 +466,18 @@ class MacroInvocation : public TypeNoBounds, // this is the expanded macro ASTFragment fragment; + // Important for when we actually expand the macro + bool is_semi_coloned; + public: std::string as_string () const override; MacroInvocation (MacroInvocData invoc_data, - std::vector<Attribute> outer_attrs, Location locus) + std::vector<Attribute> outer_attrs, Location locus, + bool is_semi_coloned = false) : outer_attrs (std::move (outer_attrs)), invoc_data (std::move (invoc_data)), locus (locus), - fragment (ASTFragment::create_empty ()) + fragment (ASTFragment::create_empty ()), is_semi_coloned (is_semi_coloned) {} Location get_locus () const override final { return locus; } @@ -503,6 +510,8 @@ public: void set_fragment (ASTFragment &&f) { fragment = std::move (f); } + bool has_semicolon () const { return is_semi_coloned; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -529,6 +538,40 @@ protected: { return new MacroInvocation (*this); } + + Item *clone_item_impl () const override + { + return clone_macro_invocation_impl (); + } + + bool is_item () const override { return !has_semicolon (); } + + TraitItem *clone_trait_item_impl () const override + { + return clone_macro_invocation_impl (); + }; + + TraitImplItem *clone_trait_impl_item_impl () const override + { + return clone_macro_invocation_impl (); + }; + + InherentImplItem *clone_inherent_impl_item_impl () const override + { + return clone_macro_invocation_impl (); + } + + ExprWithoutBlock *to_stmt () const override + + + + + { + auto new_impl = clone_macro_invocation_impl(); + new_impl->is_semi_coloned = true; + + return new_impl; + } }; // more generic meta item path-only form |