libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / rust / ast / rust-builtin-ast-nodes.h
blob3e21d7e718d6bbfa93363ffc5e3a4552cd16bf9a
1 // Copyright (C) 2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #ifndef RUST_AST_BUILTIN_NODES_H
20 #define RUST_AST_BUILTIN_NODES_H
22 #include "rust-system.h"
23 #include "line-map.h"
24 #include "optional.h"
25 #include "rust-ast.h"
26 #include "rust-fmt.h"
28 namespace Rust {
29 namespace AST {
31 // Definitions, from rustc's `FormatArgs` AST struct
32 // https://github.com/rust-lang/rust/blob/1be468815c/compiler/rustc_ast/src/format.rs
34 // format_args!("hello {abc:.xyz$}!!", abc="world");
35 // └──────────────────────────────────────────────┘
36 // FormatArgs
38 // format_args!("hello {abc:.xyz$}!!", abc="world");
39 // └─────────┘
40 // argument
42 // format_args!("hello {abc:.xyz$}!!", abc="world");
43 // └───────────────────┘
44 // template
46 // format_args!("hello {abc:.xyz$}!!", abc="world");
47 // └────┘└─────────┘└┘
48 // pieces
50 // format_args!("hello {abc:.xyz$}!!", abc="world");
51 // └────┘ └┘
52 // literal pieces
54 // format_args!("hello {abc:.xyz$}!!", abc="world");
55 // └─────────┘
56 // placeholder
58 // format_args!("hello {abc:.xyz$}!!", abc="world");
59 // └─┘ └─┘
60 // positions (could be names, numbers, empty, or `*`)
62 // FIXME: Merge with the class below this one?
63 class FormatArgumentKind
65 public:
66 enum class Kind
68 Normal,
69 Named,
70 Captured,
71 } kind;
73 Identifier &get_ident ()
75 rust_assert (kind == Kind::Captured || kind == Kind::Named);
77 return ident.value ();
80 FormatArgumentKind (Kind kind, tl::optional<Identifier> ident)
81 : kind (kind), ident (ident)
84 FormatArgumentKind (const FormatArgumentKind &other)
86 kind = other.kind;
87 ident = other.ident;
90 FormatArgumentKind operator= (const FormatArgumentKind &other)
92 kind = other.kind;
93 ident = other.ident;
95 return *this;
98 private:
99 tl::optional<Identifier> ident;
102 class FormatArgument
104 public:
105 static FormatArgument normal (std::unique_ptr<Expr> expr)
107 return FormatArgument (FormatArgumentKind::Kind::Normal, tl::nullopt,
108 std::move (expr));
111 static FormatArgument named (Identifier ident, std::unique_ptr<Expr> expr)
113 return FormatArgument (FormatArgumentKind::Kind::Named, ident,
114 std::move (expr));
117 static FormatArgument captured (Identifier ident, std::unique_ptr<Expr> expr)
119 return FormatArgument (FormatArgumentKind::Kind::Captured, ident,
120 std::move (expr));
123 FormatArgument (const FormatArgument &other)
124 : kind (other.kind), expr (other.expr->clone_expr ())
127 FormatArgument operator= (const FormatArgument &other)
129 kind = other.kind;
130 expr = other.expr->clone_expr ();
132 return *this;
135 FormatArgumentKind get_kind () const { return kind; }
136 const Expr &get_expr () const { return *expr; }
138 private:
139 FormatArgument (FormatArgumentKind::Kind kind, tl::optional<Identifier> ident,
140 std::unique_ptr<Expr> expr)
141 : kind (FormatArgumentKind (kind, ident)), expr (std::move (expr))
144 FormatArgumentKind kind;
145 std::unique_ptr<Expr> expr;
148 class FormatArguments
150 public:
151 FormatArguments () {}
152 FormatArguments (FormatArguments &&) = default;
153 FormatArguments (const FormatArguments &other)
155 args = std::vector<FormatArgument> ();
156 args.reserve (other.args.size ());
158 for (const auto &arg : other.args)
159 args.emplace_back (arg);
162 FormatArguments &operator= (const FormatArguments &other) = default;
164 void push (FormatArgument &&elt) { args.emplace_back (std::move (elt)); }
165 const FormatArgument at (size_t idx) const { return args.at (idx); }
167 private:
168 std::vector<FormatArgument> args;
171 // TODO: Format documentation better
172 // Having a separate AST node for `format_args!()` expansion allows some
173 // important optimizations which help reduce generated code a lot. For example,
174 // turning `format_args!("a {} {} {}", 15, "hey", 'a')` directly into
175 // `format_args!("a 15 hey a")`, since all arguments are literals. Or,
176 // flattening imbricated `format_args!()` calls: `format_args!("heyo {}",
177 // format_args!("result: {}", some_result))` -> `format_args!("heyo result: {}",
178 // some_result)`
179 // FIXME: Move to rust-macro.h
180 class FormatArgs : public Expr
182 public:
183 enum class Newline
185 Yes,
189 FormatArgs (location_t loc, Fmt::Pieces &&template_str,
190 FormatArguments &&arguments)
191 : loc (loc), template_pieces (std::move (template_str)),
192 arguments (std::move (arguments))
195 FormatArgs (FormatArgs &&other) = default;
196 FormatArgs (const FormatArgs &other) = default;
197 FormatArgs &operator= (const FormatArgs &other) = default;
199 void accept_vis (AST::ASTVisitor &vis) override;
201 const Fmt::Pieces &get_template () const { return template_pieces; }
202 const FormatArguments &get_arguments () const { return arguments; }
203 virtual location_t get_locus () const override;
205 private:
206 location_t loc;
207 // FIXME: This probably needs to be a separate type - it is one in rustc's
208 // expansion of format_args!(). There is extra handling associated with it.
209 // we can maybe do that in rust-fmt.cc? in collect_pieces()? like do the
210 // transformation into something we can handle better
211 Fmt::Pieces template_pieces;
212 FormatArguments arguments;
214 bool marked_for_strip = false;
216 protected:
217 virtual std::string as_string () const override;
218 virtual bool is_expr_without_block () const override;
219 virtual void mark_for_strip () override;
220 virtual bool is_marked_for_strip () const override;
221 virtual std::vector<Attribute> &get_outer_attrs () override;
222 virtual void set_outer_attrs (std::vector<Attribute>) override;
223 virtual Expr *clone_expr_impl () const override;
226 } // namespace AST
227 } // namespace Rust
229 #endif // ! RUST_AST_BUILTIN_NODES_H