]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/ast/rust-ast-fragment.h
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / ast / rust-ast-fragment.h
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
2
3 // This file is part of GCC.
4
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
8 // version.
9
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
18
19 #ifndef RUST_AST_FRAGMENT_H
20 #define RUST_AST_FRAGMENT_H
21
22 #include "rust-ast.h"
23 #include "rust-system.h"
24
25 namespace Rust {
26 namespace AST {
27
28 enum class FragmentKind
29 {
30 /**
31 * A completely expanded AST Fragment. This signifies that all
32 * `SingleASTNode`s in the `nodes` vector are valid.
33 *
34 * Note that this doesn't imply that the expansion is "done". One of the
35 * expanded nodes could very well be another macro invocation
36 */
37 Complete,
38 /**
39 * An error fragment.
40 */
41 Error,
42 };
43
44 /**
45 * An AST Fragment. Previously named `ASTFragment`.
46 *
47 * Basically, a "fragment" that can be incorporated into the AST, created as
48 * a result of macro expansion. Really annoying to work with due to the fact
49 * that macros can really expand to anything. As such, horrible representation
50 * at the moment.
51 */
52 class Fragment
53 {
54 public:
55 Fragment (Fragment const &other);
56 Fragment &operator= (Fragment const &other);
57
58 /**
59 * Create an error fragment
60 */
61 static Fragment create_error ();
62
63 /**
64 * Create a complete AST fragment
65 */
66 Fragment (std::vector<AST::SingleASTNode> nodes,
67 std::vector<std::unique_ptr<AST::Token>> tokens);
68
69 /**
70 * Create a complete AST fragment made of a single token
71 */
72 Fragment (std::vector<AST::SingleASTNode> nodes,
73 std::unique_ptr<AST::Token> tok);
74
75 FragmentKind get_kind () const;
76 std::vector<SingleASTNode> &get_nodes ();
77 std::vector<std::unique_ptr<AST::Token>> &get_tokens ();
78
79 bool is_error () const;
80 bool should_expand () const;
81
82 bool is_expression_fragment () const;
83 bool is_type_fragment () const;
84
85 std::unique_ptr<Expr> take_expression_fragment ();
86 std::unique_ptr<Type> take_type_fragment ();
87
88 void accept_vis (ASTVisitor &vis);
89
90 private:
91 Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes,
92 std::vector<std::unique_ptr<AST::Token>> tokens);
93
94 FragmentKind kind;
95
96 /**
97 * Basic idea: essentially, a vector of tagged unions of different AST node
98 * types. Now, this could actually be stored without a tagged union if the
99 * different AST node types had a unified parent, but that would create
100 * issues with the diamond problem or significant performance penalties. So
101 * a tagged union had to be used instead. A vector is used to represent the
102 * ability for a macro to expand to two statements, for instance.
103 */
104 std::vector<SingleASTNode> nodes;
105
106 /**
107 * The tokens associated with an AST fragment. This vector represents the
108 * actual tokens of the various nodes that are part of the fragment.
109 */
110 std::vector<std::unique_ptr<AST::Token>> tokens;
111
112 /**
113 * We need to make a special case for Expression and Type fragments as only
114 * one Node will be extracted from the `nodes` vector
115 */
116 bool is_single_fragment () const;
117 bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const;
118 void assert_single_fragment (SingleASTNode::NodeType expected) const;
119 };
120 } // namespace AST
121 } // namespace Rust
122
123 #endif // !RUST_AST_FRAGMENT_H