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
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
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 #include "rust-ast-visitor.h"
21 #include "rust-macro-expand.h"
24 // Visitor used to expand attributes.
25 class AttrVisitor
: public AST::ASTVisitor
28 MacroExpander
&expander
;
29 void maybe_expand_expr (std::unique_ptr
<AST::Expr
> &expr
);
30 void maybe_expand_type (std::unique_ptr
<AST::Type
> &expr
);
33 AttrVisitor (MacroExpander
&expander
) : expander (expander
) {}
35 void expand_struct_fields (std::vector
<AST::StructField
> &fields
);
36 void expand_tuple_fields (std::vector
<AST::TupleField
> &fields
);
37 void expand_function_params (std::vector
<AST::FunctionParam
> ¶ms
);
38 void expand_generic_args (AST::GenericArgs
&args
);
39 void expand_qualified_path_type (AST::QualifiedPathType
&path_type
);
40 void expand_closure_params (std::vector
<AST::ClosureParam
> ¶ms
);
41 void expand_self_param (AST::SelfParam
&self_param
);
42 void expand_where_clause (AST::WhereClause
&where_clause
);
43 void expand_trait_function_decl (AST::TraitFunctionDecl
&decl
);
44 void expand_trait_method_decl (AST::TraitMethodDecl
&decl
);
47 * Expand a set of values, erasing them if they are marked for strip, and
48 * replacing them with expanded macro nodes if necessary.
49 * This function is slightly different from `expand_pointer_allow_strip` as
50 * it can only be called in certain expansion contexts - where macro
51 * invocations are allowed.
53 * @param ctx Context to use for macro expansion
54 * @param values Iterable reference over values to replace or erase
55 * @param extractor Function to call when replacing values with the content
56 * of an expanded AST node
58 template <typename T
, typename U
>
59 void expand_macro_children (MacroExpander::ContextType ctx
, T
&values
,
60 std::function
<U (AST::SingleASTNode
)> extractor
)
62 expander
.push_context (ctx
);
64 for (auto it
= values
.begin (); it
!= values
.end ();)
68 // mark for stripping if required
69 value
->accept_vis (*this);
71 auto final_fragment
= expander
.take_expanded_fragment ();
73 if (final_fragment
.should_expand ())
75 it
= values
.erase (it
);
76 for (auto &node
: final_fragment
.get_nodes ())
78 auto new_node
= extractor (node
);
79 if (new_node
!= nullptr && !new_node
->is_marked_for_strip ())
81 it
= values
.insert (it
, std::move (new_node
));
86 else if (value
->is_marked_for_strip ())
88 it
= values
.erase (it
);
96 expander
.pop_context ();
99 template <typename T
> void expand_pointer_allow_strip (T
&values
)
101 for (auto it
= values
.begin (); it
!= values
.end ();)
105 // mark for stripping if required
106 value
->accept_vis (*this);
107 if (value
->is_marked_for_strip ())
109 it
= values
.erase (it
);
118 void visit (AST::Token
&) override
;
119 void visit (AST::DelimTokenTree
&) override
;
120 void visit (AST::AttrInputMetaItemContainer
&) override
;
121 void visit (AST::IdentifierExpr
&ident_expr
) override
;
122 void visit (AST::Lifetime
&) override
;
123 void visit (AST::LifetimeParam
&) override
;
124 void visit (AST::ConstGenericParam
&) override
;
126 void visit (AST::MacroInvocation
¯o_invoc
) override
;
128 void visit (AST::PathInExpression
&path
) override
;
129 void visit (AST::TypePathSegment
&) override
;
130 void visit (AST::TypePathSegmentGeneric
&segment
) override
;
131 void visit (AST::TypePathSegmentFunction
&segment
) override
;
132 void visit (AST::TypePath
&path
) override
;
133 void visit (AST::QualifiedPathInExpression
&path
) override
;
134 void visit (AST::QualifiedPathInType
&path
) override
;
136 void visit (AST::LiteralExpr
&expr
) override
;
137 void visit (AST::AttrInputLiteral
&) override
;
138 void visit (AST::MetaItemLitExpr
&) override
;
139 void visit (AST::MetaItemPathLit
&) override
;
140 void visit (AST::BorrowExpr
&expr
) override
;
141 void visit (AST::DereferenceExpr
&expr
) override
;
142 void visit (AST::ErrorPropagationExpr
&expr
) override
;
143 void visit (AST::NegationExpr
&expr
) override
;
144 void visit (AST::ArithmeticOrLogicalExpr
&expr
) override
;
145 void visit (AST::ComparisonExpr
&expr
) override
;
146 void visit (AST::LazyBooleanExpr
&expr
) override
;
147 void visit (AST::TypeCastExpr
&expr
) override
;
148 void visit (AST::AssignmentExpr
&expr
) override
;
149 void visit (AST::CompoundAssignmentExpr
&expr
) override
;
150 void visit (AST::GroupedExpr
&expr
) override
;
151 void visit (AST::ArrayElemsValues
&elems
) override
;
152 void visit (AST::ArrayElemsCopied
&elems
) override
;
153 void visit (AST::ArrayExpr
&expr
) override
;
154 void visit (AST::ArrayIndexExpr
&expr
) override
;
155 void visit (AST::TupleExpr
&expr
) override
;
156 void visit (AST::TupleIndexExpr
&expr
) override
;
157 void visit (AST::StructExprStruct
&expr
) override
;
158 void visit (AST::StructExprFieldIdentifier
&) override
;
159 void visit (AST::StructExprFieldIdentifierValue
&field
) override
;
161 void visit (AST::StructExprFieldIndexValue
&field
) override
;
162 void visit (AST::StructExprStructFields
&expr
) override
;
163 void visit (AST::StructExprStructBase
&expr
) override
;
164 void visit (AST::CallExpr
&expr
) override
;
165 void visit (AST::MethodCallExpr
&expr
) override
;
166 void visit (AST::FieldAccessExpr
&expr
) override
;
167 void visit (AST::ClosureExprInner
&expr
) override
;
169 void visit (AST::BlockExpr
&expr
) override
;
171 void visit (AST::ClosureExprInnerTyped
&expr
) override
;
172 void visit (AST::ContinueExpr
&expr
) override
;
173 void visit (AST::BreakExpr
&expr
) override
;
174 void visit (AST::RangeFromToExpr
&expr
) override
;
175 void visit (AST::RangeFromExpr
&expr
) override
;
176 void visit (AST::RangeToExpr
&expr
) override
;
177 void visit (AST::RangeFullExpr
&) override
;
178 void visit (AST::RangeFromToInclExpr
&expr
) override
;
179 void visit (AST::RangeToInclExpr
&expr
) override
;
180 void visit (AST::ReturnExpr
&expr
) override
;
181 void visit (AST::UnsafeBlockExpr
&expr
) override
;
182 void visit (AST::LoopExpr
&expr
) override
;
183 void visit (AST::WhileLoopExpr
&expr
) override
;
184 void visit (AST::WhileLetLoopExpr
&expr
) override
;
185 void visit (AST::ForLoopExpr
&expr
) override
;
186 void visit (AST::IfExpr
&expr
) override
;
187 void visit (AST::IfExprConseqElse
&expr
) override
;
188 void visit (AST::IfExprConseqIf
&expr
) override
;
189 void visit (AST::IfExprConseqIfLet
&expr
) override
;
190 void visit (AST::IfLetExpr
&expr
) override
;
191 void visit (AST::IfLetExprConseqElse
&expr
) override
;
192 void visit (AST::IfLetExprConseqIf
&expr
) override
;
193 void visit (AST::IfLetExprConseqIfLet
&expr
) override
;
194 void visit (AST::MatchExpr
&expr
) override
;
195 void visit (AST::AwaitExpr
&expr
) override
;
196 void visit (AST::AsyncBlockExpr
&expr
) override
;
197 void visit (AST::TypeParam
¶m
) override
;
198 void visit (AST::LifetimeWhereClauseItem
&) override
;
199 void visit (AST::TypeBoundWhereClauseItem
&item
) override
;
200 void visit (AST::Method
&method
) override
;
201 void visit (AST::Module
&module
) override
;
202 void visit (AST::ExternCrate
&crate
) override
;
203 void visit (AST::UseTreeGlob
&) override
;
204 void visit (AST::UseTreeList
&) override
;
205 void visit (AST::UseTreeRebind
&) override
;
206 void visit (AST::UseDeclaration
&use_decl
) override
;
207 void visit (AST::Function
&function
) override
;
208 void visit (AST::TypeAlias
&type_alias
) override
;
209 void visit (AST::StructStruct
&struct_item
) override
;
210 void visit (AST::TupleStruct
&tuple_struct
) override
;
211 void visit (AST::EnumItem
&item
) override
;
212 void visit (AST::EnumItemTuple
&item
) override
;
213 void visit (AST::EnumItemStruct
&item
) override
;
214 void visit (AST::EnumItemDiscriminant
&item
) override
;
215 void visit (AST::Enum
&enum_item
) override
;
216 void visit (AST::Union
&union_item
) override
;
217 void visit (AST::ConstantItem
&const_item
) override
;
218 void visit (AST::StaticItem
&static_item
) override
;
219 void visit (AST::TraitItemFunc
&item
) override
;
220 void visit (AST::TraitItemMethod
&item
) override
;
221 void visit (AST::TraitItemConst
&item
) override
;
222 void visit (AST::TraitItemType
&item
) override
;
223 void visit (AST::Trait
&trait
) override
;
224 void visit (AST::InherentImpl
&impl
) override
;
225 void visit (AST::TraitImpl
&impl
) override
;
226 void visit (AST::ExternalStaticItem
&item
) override
;
227 void visit (AST::ExternalFunctionItem
&item
) override
;
228 void visit (AST::ExternBlock
&block
) override
;
230 // I don't think it would be possible to strip macros without expansion
231 void visit (AST::MacroMatchFragment
&) override
;
232 void visit (AST::MacroMatchRepetition
&) override
;
233 void visit (AST::MacroMatcher
&) override
;
234 void visit (AST::MacroRulesDefinition
&rules_def
) override
;
235 void visit (AST::MetaItemPath
&) override
;
236 void visit (AST::MetaItemSeq
&) override
;
237 void visit (AST::MetaWord
&) override
;
238 void visit (AST::MetaNameValueStr
&) override
;
239 void visit (AST::MetaListPaths
&) override
;
240 void visit (AST::MetaListNameValueStr
&) override
;
241 void visit (AST::LiteralPattern
&) override
;
242 void visit (AST::IdentifierPattern
&pattern
) override
;
243 void visit (AST::WildcardPattern
&) override
;
244 void visit (AST::RangePatternBoundLiteral
&) override
;
245 void visit (AST::RangePatternBoundPath
&bound
) override
;
246 void visit (AST::RangePatternBoundQualPath
&bound
) override
;
247 void visit (AST::RangePattern
&pattern
) override
;
248 void visit (AST::ReferencePattern
&pattern
) override
;
249 void visit (AST::StructPatternFieldTuplePat
&field
) override
;
250 void visit (AST::StructPatternFieldIdentPat
&field
) override
;
251 void visit (AST::StructPatternFieldIdent
&field
) override
;
252 void visit (AST::StructPattern
&pattern
) override
;
253 void visit (AST::TupleStructItemsNoRange
&tuple_items
) override
;
254 void visit (AST::TupleStructItemsRange
&tuple_items
) override
;
255 void visit (AST::TupleStructPattern
&pattern
) override
;
256 void visit (AST::TuplePatternItemsMultiple
&tuple_items
) override
;
257 void visit (AST::TuplePatternItemsRanged
&tuple_items
) override
;
258 void visit (AST::TuplePattern
&pattern
) override
;
259 void visit (AST::GroupedPattern
&pattern
) override
;
260 void visit (AST::SlicePattern
&pattern
) override
;
261 void visit (AST::AltPattern
&pattern
) override
;
263 void visit (AST::EmptyStmt
&) override
;
264 void visit (AST::LetStmt
&stmt
) override
;
265 void visit (AST::ExprStmtWithoutBlock
&stmt
) override
;
266 void visit (AST::ExprStmtWithBlock
&stmt
) override
;
268 void visit (AST::TraitBound
&bound
) override
;
269 void visit (AST::ImplTraitType
&type
) override
;
270 void visit (AST::TraitObjectType
&type
) override
;
271 void visit (AST::ParenthesisedType
&type
) override
;
272 void visit (AST::ImplTraitTypeOneBound
&type
) override
;
273 void visit (AST::TraitObjectTypeOneBound
&type
) override
;
274 void visit (AST::TupleType
&type
) override
;
275 void visit (AST::NeverType
&) override
;
276 void visit (AST::RawPointerType
&type
) override
;
277 void visit (AST::ReferenceType
&type
) override
;
278 void visit (AST::ArrayType
&type
) override
;
279 void visit (AST::SliceType
&type
) override
;
280 void visit (AST::InferredType
&) override
;
281 void visit (AST::BareFunctionType
&type
) override
;