Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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 AST_BUILDER_H
20 : : #define AST_BUILDER_H
21 : :
22 : : #include "rust-ast-full.h"
23 : : #include "rust-expr.h"
24 : : #include "rust-ast.h"
25 : : #include "rust-item.h"
26 : : #include "rust-operators.h"
27 : :
28 : : namespace Rust {
29 : : namespace AST {
30 : :
31 : : template <typename T>
32 : : std::vector<std::unique_ptr<T>>
33 : 222 : vec (std::unique_ptr<T> &&t)
34 : : {
35 : 220 : auto v = std::vector<std::unique_ptr<T>> ();
36 : :
37 : 222 : v.emplace_back (std::move (t));
38 : :
39 : : return v;
40 : : }
41 : :
42 : : template <typename T>
43 : : std::vector<std::unique_ptr<T>>
44 : 102 : vec (std::unique_ptr<T> &&t1, std::unique_ptr<T> &&t2)
45 : : {
46 : 102 : auto v = std::vector<std::unique_ptr<T>> ();
47 : :
48 : 102 : v.emplace_back (std::move (t1));
49 : 102 : v.emplace_back (std::move (t2));
50 : :
51 : 102 : return v;
52 : : }
53 : :
54 : : /* Pointer-ify something */
55 : : template <typename T>
56 : : static std::unique_ptr<T>
57 : 34 : ptrify (T value)
58 : : {
59 : 34 : return std::unique_ptr<T> (new T (value));
60 : : }
61 : :
62 : : // TODO: Use this builder when expanding regular macros
63 : : /* Builder class with helper methods to create AST nodes. This builder is
64 : : * tailored towards generating multiple AST nodes from a single location, and
65 : : * may not be suitable to other purposes */
66 : : class Builder
67 : : {
68 : : public:
69 : 170 : Builder (location_t loc) : loc (loc) {}
70 : :
71 : : /* Create an expression statement from an expression */
72 : : std::unique_ptr<Stmt> statementify (std::unique_ptr<Expr> &&value,
73 : : bool semicolon_followed = true) const;
74 : :
75 : : /* Create a string literal expression ("content") */
76 : : std::unique_ptr<Expr> literal_string (std::string &&content) const;
77 : :
78 : : /* Create a boolean literal expression (true) */
79 : : std::unique_ptr<Expr> literal_bool (bool b) const;
80 : :
81 : : /* Create an identifier expression (`variable`) */
82 : : std::unique_ptr<Expr> identifier (std::string name) const;
83 : : std::unique_ptr<Pattern> identifier_pattern (std::string name,
84 : : bool mut = false) const;
85 : :
86 : : /* Create a tuple index expression (`receiver.0`) */
87 : : std::unique_ptr<Expr> tuple_idx (std::string receiver, int idx) const;
88 : :
89 : : /* Create a tuple expression (`(a1, a2, a3)`) */
90 : : std::unique_ptr<Expr> tuple (std::vector<std::unique_ptr<Expr>> &&values
91 : : = {}) const;
92 : :
93 : : /* Create a reference to an expression (`&of`) */
94 : : std::unique_ptr<Expr> ref (std::unique_ptr<Expr> &&of,
95 : : bool mut = false) const;
96 : :
97 : : /* Create a dereference of an expression (`*of`) */
98 : : std::unique_ptr<Expr> deref (std::unique_ptr<Expr> &&of) const;
99 : :
100 : : /* Build a comparison expression (`lhs == rhs`) */
101 : : std::unique_ptr<Expr> comparison_expr (std::unique_ptr<Expr> &&lhs,
102 : : std::unique_ptr<Expr> &&rhs,
103 : : ComparisonOperator op) const;
104 : :
105 : : /* Build a lazy boolean operator expression (`lhs && rhs`) */
106 : : std::unique_ptr<Expr> boolean_operation (std::unique_ptr<Expr> &&lhs,
107 : : std::unique_ptr<Expr> &&rhs,
108 : : LazyBooleanOperator op) const;
109 : :
110 : : /* Create a block with an optional tail expression */
111 : : std::unique_ptr<BlockExpr> block (std::vector<std::unique_ptr<Stmt>> &&stmts,
112 : : std::unique_ptr<Expr> &&tail_expr
113 : : = nullptr) const;
114 : : std::unique_ptr<BlockExpr> block (tl::optional<std::unique_ptr<Stmt>> &&stmt,
115 : : std::unique_ptr<Expr> &&tail_expr
116 : : = nullptr) const;
117 : : /* Create an empty block */
118 : : std::unique_ptr<BlockExpr> block () const;
119 : :
120 : : /* Create an early return expression with an optional expression */
121 : : std::unique_ptr<Expr> return_expr (std::unique_ptr<Expr> &&to_return
122 : : = nullptr);
123 : :
124 : : /* Create a let binding with an optional type and initializer (`let <name> :
125 : : * <type> = <init>`) */
126 : : std::unique_ptr<Stmt> let (std::unique_ptr<Pattern> &&pattern,
127 : : std::unique_ptr<Type> &&type = nullptr,
128 : : std::unique_ptr<Expr> &&init = nullptr) const;
129 : :
130 : : /**
131 : : * Create a call expression to a function, struct or enum variant, given its
132 : : * arguments (`path(arg0, arg1, arg2)`)
133 : : */
134 : : std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
135 : : std::vector<std::unique_ptr<Expr>> &&args
136 : : = {}) const;
137 : : std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
138 : : std::unique_ptr<Expr> &&arg) const;
139 : :
140 : : /**
141 : : * Create an array expression (`[member0, member1, member2]`)
142 : : */
143 : : std::unique_ptr<Expr>
144 : : array (std::vector<std::unique_ptr<Expr>> &&members) const;
145 : :
146 : : /* Create a qualified path in expression (`<type as Trait>::seg::expr`) */
147 : : std::unique_ptr<Expr>
148 : : qualified_path_in_expression (std::unique_ptr<Type> &&type, TypePath trait,
149 : : PathExprSegment segment) const;
150 : : std::unique_ptr<Expr>
151 : : qualified_path_in_expression (std::unique_ptr<Type> &&type, TypePath trait,
152 : : std::vector<PathExprSegment> &&segments
153 : : = {}) const;
154 : :
155 : : /* Self parameter for a function definition (`&self`) */
156 : : std::unique_ptr<Param> self_ref_param (bool mutability = false) const;
157 : : /* A regular named function parameter for a definition (`a: type`) */
158 : : std::unique_ptr<Param> function_param (std::unique_ptr<Pattern> &&pattern,
159 : : std::unique_ptr<Type> &&type) const;
160 : :
161 : : /* Empty function qualifiers, with no specific qualifiers */
162 : : FunctionQualifiers fn_qualifiers () const;
163 : :
164 : : std::unique_ptr<Function>
165 : : function (std::string function_name,
166 : : std::vector<std::unique_ptr<Param>> params,
167 : : std::unique_ptr<Type> return_type, std::unique_ptr<BlockExpr> block,
168 : : std::vector<std::unique_ptr<GenericParam>> generic_params = {},
169 : : FunctionQualifiers qualifiers
170 : : = FunctionQualifiers (UNKNOWN_LOCATION, Async::No, Const::No,
171 : : Unsafety::Normal),
172 : : WhereClause where_clause = WhereClause::create_empty (),
173 : : Visibility visibility = Visibility::create_private ()) const;
174 : :
175 : : /* Create a single path segment from one string */
176 : : PathExprSegment path_segment (std::string seg) const;
177 : :
178 : : /* And similarly for type path segments */
179 : : std::unique_ptr<TypePathSegment> type_path_segment (std::string seg) const;
180 : : std::unique_ptr<TypePathSegment>
181 : : type_path_segment (LangItem::Kind lang_item) const;
182 : :
183 : : std::unique_ptr<TypePathSegment>
184 : : type_path_segment_generic (std::string seg, GenericArgs args) const;
185 : : std::unique_ptr<TypePathSegment>
186 : : type_path_segment_generic (LangItem::Kind lang_item, GenericArgs args) const;
187 : :
188 : : /* Create a Type from a single string - the most basic kind of type in our AST
189 : : */
190 : : std::unique_ptr<Type> single_type_path (std::string type) const;
191 : : std::unique_ptr<Type> single_type_path (LangItem::Kind lang_item) const;
192 : :
193 : : std::unique_ptr<Type> single_generic_type_path (std::string type,
194 : : GenericArgs args) const;
195 : : std::unique_ptr<Type> single_generic_type_path (LangItem::Kind lang_item,
196 : : GenericArgs args) const;
197 : :
198 : : TypePath type_path (std::vector<std::unique_ptr<TypePathSegment>> &&segment,
199 : : bool opening_scope = false) const;
200 : : TypePath type_path (std::vector<std::string> &&segments,
201 : : bool opening_scope = false) const;
202 : : TypePath type_path (std::unique_ptr<TypePathSegment> &&segment) const;
203 : : TypePath type_path (std::string type) const;
204 : : TypePath type_path (LangItem::Kind lang_item) const;
205 : :
206 : : std::unique_ptr<Type>
207 : : reference_type (std::unique_ptr<TypeNoBounds> &&inner_type,
208 : : bool mutability = false) const;
209 : :
210 : : /**
211 : : * Create a path in expression from multiple segments (`Clone::clone`). You
212 : : * do not need to separate the segments using `::`, you can simply provide a
213 : : * vector of strings to the functions which will get turned into path segments
214 : : */
215 : : PathInExpression path_in_expression (std::vector<std::string> &&segments,
216 : : bool opening_scope = false) const;
217 : :
218 : : /**
219 : : * Create a path in expression from a lang item.
220 : : */
221 : : PathInExpression path_in_expression (LangItem::Kind lang_item) const;
222 : :
223 : : /* Create the path to an enum's variant (`Result::Ok`) */
224 : : PathInExpression variant_path (const std::string &enum_path,
225 : : const std::string &variant) const;
226 : :
227 : : /* Create a new struct */
228 : : std::unique_ptr<Stmt>
229 : : struct_struct (std::string struct_name,
230 : : std::vector<std::unique_ptr<GenericParam>> &&generics,
231 : : std::vector<StructField> &&fields);
232 : :
233 : : /* Create a struct expression for unit structs (`S`) */
234 : : std::unique_ptr<Expr> struct_expr_struct (std::string struct_name) const;
235 : :
236 : : /**
237 : : * Create an expression for struct instantiation with fields (`S { a, b: c }`)
238 : : * Named tuple expressions (`S(a, b, c)`) are call expressions and can thus be
239 : : * constructed with `call`
240 : : */
241 : : std::unique_ptr<Expr>
242 : : struct_expr (std::string struct_name,
243 : : std::vector<std::unique_ptr<StructExprField>> &&fields) const;
244 : : std::unique_ptr<Expr>
245 : : struct_expr (PathInExpression struct_name,
246 : : std::vector<std::unique_ptr<StructExprField>> &&fields) const;
247 : :
248 : : /* Create a field expression for struct instantiation (`field_name: value`) */
249 : : std::unique_ptr<StructExprField>
250 : : struct_expr_field (std::string field_name,
251 : : std::unique_ptr<Expr> &&value) const;
252 : :
253 : : /* Create a field access expression (`instance.field`) */
254 : : std::unique_ptr<Expr> field_access (std::unique_ptr<Expr> &&instance,
255 : : std::string field) const;
256 : :
257 : : /* Create a wildcard pattern (`_`) */
258 : : std::unique_ptr<Pattern> wildcard () const;
259 : : /* Create a reference pattern (`&pattern`) */
260 : : std::unique_ptr<Pattern> ref_pattern (std::unique_ptr<Pattern> &&inner) const;
261 : :
262 : : /* Create a lang item path usable as a general path */
263 : : std::unique_ptr<Path> lang_item_path (LangItem::Kind) const;
264 : :
265 : : /* Create match expressions and their components */
266 : : std::unique_ptr<Expr> match (std::unique_ptr<Expr> &&scrutinee,
267 : : std::vector<MatchCase> &&cases);
268 : : MatchArm match_arm (std::unique_ptr<Pattern> &&pattern);
269 : : MatchCase match_case (std::unique_ptr<Pattern> &&pattern,
270 : : std::unique_ptr<Expr> &&expr);
271 : :
272 : : /* Create a loop expression */
273 : : std::unique_ptr<Expr> loop (std::vector<std::unique_ptr<Stmt>> &&stmts);
274 : :
275 : : std::unique_ptr<TypeParamBound> trait_bound (TypePath bound);
276 : : std::unique_ptr<Item>
277 : : trait_impl (TypePath trait_path, std::unique_ptr<Type> target,
278 : : std::vector<std::unique_ptr<AssociatedItem>> trait_items = {},
279 : : std::vector<std::unique_ptr<GenericParam>> generics = {},
280 : : WhereClause where_clause = WhereClause::create_empty (),
281 : : Visibility visibility = Visibility::create_private ()) const;
282 : :
283 : : std::unique_ptr<GenericParam>
284 : : generic_type_param (std::string type_representation,
285 : : std::vector<std::unique_ptr<TypeParamBound>> &&bounds,
286 : : std::unique_ptr<Type> &&type = nullptr);
287 : :
288 : : static std::unique_ptr<Type> new_type (Type &type);
289 : :
290 : : static std::unique_ptr<GenericParam>
291 : : new_lifetime_param (LifetimeParam ¶m);
292 : :
293 : : static std::unique_ptr<GenericParam> new_type_param (
294 : : TypeParam ¶m,
295 : : std::vector<std::unique_ptr<TypeParamBound>> extra_trait_bounds = {});
296 : :
297 : : static Lifetime new_lifetime (const Lifetime &lifetime);
298 : :
299 : : static GenericArgs new_generic_args (GenericArgs &args);
300 : :
301 : : private:
302 : : /**
303 : : * Location of the generated AST nodes
304 : : */
305 : : location_t loc;
306 : : };
307 : :
308 : : } // namespace AST
309 : : } // namespace Rust
310 : :
311 : : #endif // AST_BUILDER_H
|