diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-03-06 20:50:55 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-06 20:50:55 +0000 |
commit | e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd (patch) | |
tree | 6e9e933267fd6c651c59607668e2fa08641b8b9d /gcc/rust/ast/rust-macro.h | |
parent | d89c8ccf3237e66029125c0fe007297bb86eca74 (diff) | |
parent | 58d1721529e99c7c633615e7491b777a6198ed00 (diff) | |
download | gcc-e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd.zip gcc-e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd.tar.gz gcc-e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd.tar.bz2 |
Merge #985
985: Parse macro!(); as MacroInvocation with semicolon r=CohenArthur a=CohenArthur
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.
Closes #941
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc/rust/ast/rust-macro.h')
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 9f8f19c..2b39624 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,22 @@ class MacroInvocation : public TypeNoBounds, // this is the expanded macro ASTFragment fragment; + // Important for when we actually expand the macro + bool is_semi_coloned; + + NodeId node_id; + 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), + node_id (Analysis::Mappings::get ()->get_next_node_id ()) {} Location get_locus () const override final { return locus; } @@ -497,12 +508,16 @@ public: return ExprWithoutBlock::get_node_id (); } + NodeId get_macro_node_id () const { return node_id; } + MacroInvocData &get_invoc_data () { return invoc_data; } ASTFragment &get_fragment () { return fragment; } 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 +544,37 @@ 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 |