libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / rust / expand / rust-expand-visitor.h
blob8885b3876f2578371777795aab05787f148614f2
1 // Copyright (C) 2020-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_EXPAND_VISITOR_H
20 #define RUST_EXPAND_VISITOR_H
22 #include "rust-ast-visitor.h"
23 #include "rust-macro-expand.h"
24 #include "rust-proc-macro.h"
26 namespace Rust {
28 /**
29 * Whether or not an attribute is a derive attribute
31 bool
32 is_derive (AST::Attribute &attr);
34 /**
35 * Whether or not an attribute is builtin
37 bool
38 is_builtin (AST::Attribute &attr);
40 class ExpandVisitor : public AST::DefaultASTVisitor
42 public:
43 ExpandVisitor (MacroExpander &expander) : expander (expander) {}
45 /* Expand all of the macro invocations currently contained in a crate */
46 void go (AST::Crate &crate);
48 using AST::DefaultASTVisitor::visit;
51 Maybe expand a macro invocation in lieu of an expression
52 expr : Core guidelines R33, this function reseat the pointer.
54 void maybe_expand_expr (std::unique_ptr<AST::Expr> &expr);
57 Maybe expand a macro invocation in lieu of a type
58 type : Core guidelines R33, this function reseat the pointer.
60 void maybe_expand_type (std::unique_ptr<AST::Type> &type);
62 /**
63 * Expand all macro invocations in lieu of types within a vector of struct
64 * fields
66 void expand_struct_fields (std::vector<AST::StructField> &fields);
68 /**
69 * Expand all macro invocations in lieu of types within a vector of tuple
70 * fields
72 void expand_tuple_fields (std::vector<AST::TupleField> &fields);
74 /**
75 * Expand all macro invocations in lieu of types within a list of function
76 * parameters
78 void
79 expand_function_params (std::vector<std::unique_ptr<AST::Param>> &params);
81 /**
82 * Expand all macro invocations in lieu of types within a list of generic
83 * arguments
85 void expand_generic_args (AST::GenericArgs &args);
87 /**
88 * Expand a macro invocation in lieu of a qualified path type
90 void expand_qualified_path_type (AST::QualifiedPathType &path_type);
92 // FIXME: Add documentation
93 void expand_closure_params (std::vector<AST::ClosureParam> &params);
94 void expand_where_clause (AST::WhereClause &where_clause);
96 /**
97 * Expand a set of values, erasing them if they are marked for strip, and
98 * replacing them with expanded macro nodes if necessary.
99 * This function is slightly different from `expand_pointer_allow_strip` as
100 * it can only be called in certain expansion contexts - where macro
101 * invocations are allowed.
103 * @param ctx Context to use for macro expansion
104 * @param values Iterable reference over values to replace or erase
105 * @param extractor Function to call when replacing values with the content
106 * of an expanded AST node
108 template <typename T, typename U>
109 void expand_macro_children (MacroExpander::ContextType ctx, T &values,
110 std::function<U (AST::SingleASTNode)> extractor)
112 expander.push_context (ctx);
114 expand_macro_children (values, extractor);
116 expander.pop_context ();
120 * Same as `expand_macro_children`, but does not push a context. This is
121 * useful if you're already pushing the context manually anyway for proc macro
122 * expansion, like in `expand_inner_{items, stmts}`
124 template <typename T, typename U>
125 void expand_macro_children (T &values,
126 std::function<U (AST::SingleASTNode)> extractor)
128 for (auto it = values.begin (); it != values.end ();)
130 auto &value = *it;
132 // Perform expansion
133 value->accept_vis (*this);
135 auto final_fragment = expander.take_expanded_fragment ();
137 // FIXME: Is that correct? It seems *extremely* dodgy
138 if (final_fragment.should_expand ())
140 it = values.erase (it);
141 for (auto &node : final_fragment.get_nodes ())
143 auto new_node = extractor (node);
144 if (new_node != nullptr)
146 it = values.insert (it, std::move (new_node));
147 it++;
151 else
153 ++it;
159 * Perform in-place expansion of procedural macros and macro invocations for
160 * an item container or statement container, such as `AST::Crate`,
161 * `AST::Module` or `AST::BlockExpr`. This function will insert the expanded
162 * nodes in place, and replace macro invocations with their expanded nodes.
164 * @param values Vector of values to mutate in-place and append into
166 void expand_inner_items (std::vector<std::unique_ptr<AST::Item>> &values);
167 void expand_inner_stmts (AST::BlockExpr &expr);
169 // TODO: See if possible to make more specialization for Impl items, Block
170 // stmts etc? This could allow us to remove expand_macro_children or at least
171 // its extractor parameter
173 * These functions allow to easily visit `std::unique_ptr`s as well as
174 * _replace_ them when necessary, e.g when expanding macro invocations in a
175 * list of expressions or types. The most generic version of the function will
176 * simply call the visitor again on the pointer, but there are two
177 * specializations for `std::unique_ptr<Expr>` and `std::unique_ptr<Type>` to
178 * enable replacing as well.
180 template <typename T> void visit (std::unique_ptr<T> &value)
182 value->accept_vis (*this);
185 template <typename T> void visit (std::unique_ptr<AST::Expr> &expr)
187 maybe_expand_expr (expr);
190 template <typename T> void visit (std::unique_ptr<AST::Type> &type)
192 maybe_expand_type (type);
195 void visit (AST::Crate &crate) override;
196 void visit (AST::DelimTokenTree &) override;
197 void visit (AST::AttrInputMetaItemContainer &) override;
198 void visit (AST::IdentifierExpr &ident_expr) override;
199 void visit (AST::LifetimeParam &) override;
200 void visit (AST::ConstGenericParam &) override;
202 void visit (AST::MacroInvocation &macro_invoc) override;
204 void visit (AST::PathInExpression &path) override;
205 void visit (AST::TypePathSegmentGeneric &segment) override;
206 void visit (AST::TypePathSegmentFunction &segment) override;
207 void visit (AST::QualifiedPathInExpression &path) override;
208 void visit (AST::QualifiedPathInType &path) override;
210 void visit (AST::LiteralExpr &expr) override;
211 void visit (AST::AttrInputLiteral &) override;
212 void visit (AST::AttrInputMacro &) override;
213 void visit (AST::MetaItemLitExpr &) override;
214 void visit (AST::MetaItemPathLit &) override;
215 void visit (AST::ErrorPropagationExpr &expr) override;
216 void visit (AST::ArithmeticOrLogicalExpr &expr) override;
217 void visit (AST::ComparisonExpr &expr) override;
218 void visit (AST::LazyBooleanExpr &expr) override;
219 void visit (AST::AssignmentExpr &expr) override;
220 void visit (AST::CompoundAssignmentExpr &expr) override;
221 void visit (AST::GroupedExpr &expr) override;
222 void visit (AST::StructExprStruct &expr) override;
224 void visit (AST::CallExpr &expr) override;
225 void visit (AST::MethodCallExpr &expr) override;
226 void visit (AST::ClosureExprInner &expr) override;
228 void visit (AST::BlockExpr &expr) override;
230 void visit (AST::ClosureExprInnerTyped &expr) override;
231 void visit (AST::ContinueExpr &expr) override;
232 void visit (AST::IfExpr &expr) override;
233 void visit (AST::IfExprConseqElse &expr) override;
234 void visit (AST::IfLetExpr &expr) override;
235 void visit (AST::IfLetExprConseqElse &expr) override;
236 void visit (AST::MatchExpr &expr) override;
237 void visit (AST::TypeParam &param) override;
238 void visit (AST::LifetimeWhereClauseItem &) override;
239 void visit (AST::TypeBoundWhereClauseItem &item) override;
240 void visit (AST::ExternCrate &crate) override;
241 void visit (AST::UseTreeGlob &) override;
242 void visit (AST::UseTreeList &) override;
243 void visit (AST::UseTreeRebind &) override;
244 void visit (AST::UseDeclaration &use_decl) override;
245 void visit (AST::Function &function) override;
246 void visit (AST::StructStruct &struct_item) override;
247 void visit (AST::TupleStruct &tuple_struct) override;
248 void visit (AST::EnumItem &item) override;
249 void visit (AST::EnumItemTuple &item) override;
250 void visit (AST::EnumItemStruct &item) override;
251 void visit (AST::EnumItemDiscriminant &item) override;
252 void visit (AST::Union &union_item) override;
253 void visit (AST::ConstantItem &const_item) override;
254 void visit (AST::StaticItem &static_item) override;
255 void visit (AST::TraitItemConst &item) override;
256 void visit (AST::Trait &trait) override;
257 void visit (AST::InherentImpl &impl) override;
258 void visit (AST::TraitImpl &impl) override;
259 void visit (AST::ExternalTypeItem &item) override;
260 void visit (AST::ExternalStaticItem &item) override;
261 void visit (AST::ExternBlock &block) override;
263 // I don't think it would be possible to strip macros without expansion
264 void visit (AST::MacroMatchRepetition &) override;
265 void visit (AST::MacroMatcher &) override;
266 void visit (AST::MacroRulesDefinition &rules_def) override;
267 void visit (AST::MetaItemPath &) override;
268 void visit (AST::MetaItemSeq &) override;
269 void visit (AST::MetaListPaths &) override;
270 void visit (AST::MetaListNameValueStr &) override;
271 void visit (AST::StructPatternFieldIdent &field) override;
272 void visit (AST::GroupedPattern &pattern) override;
274 void visit (AST::LetStmt &stmt) override;
275 void visit (AST::ExprStmt &stmt) override;
277 void visit (AST::BareFunctionType &type) override;
278 void visit (AST::FunctionParam &type) override;
279 void visit (AST::SelfParam &type) override;
281 template <typename T>
282 void expand_inner_attribute (T &item, AST::SimplePath &Path);
284 template <typename T>
285 void visit_inner_using_attrs (T &item, std::vector<AST::Attribute> &attrs);
287 template <typename T> void visit_inner_attrs (T &item);
289 private:
290 MacroExpander &expander;
293 } // namespace Rust
295 #endif // RUST_EXPAND_VISITOR_H