1 // Copyright (C) 2020-2023 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-dump.h"
24 Indent::Indent () : tabs (0) {}
27 operator<< (std::ostream
&stream
, const Indent
&indent
)
29 return stream
<< std::string (indent
.tabs
, '\t');
41 rust_assert (tabs
!= 0);
45 Dump::Dump (std::ostream
&stream
) : stream (stream
), indentation (Indent ()) {}
48 Dump::go (AST::Crate
&crate
)
50 for (auto &item
: crate
.items
)
52 stream
<< indentation
;
53 item
->accept_vis (*this);
59 Dump::go (AST::Item
&item
)
61 item
.accept_vis (*this);
65 Dump::format_function_param (FunctionParam
¶m
)
67 param
.get_pattern ()->accept_vis (*this);
69 param
.get_type ()->accept_vis (*this);
73 Dump::emit_attrib (const Attribute
&attrib
)
78 for (size_t i
= 0; i
< attrib
.get_path ().get_segments ().size (); i
++)
80 const auto &seg
= attrib
.get_path ().get_segments ().at (i
);
81 bool has_next
= (i
+ 1) < attrib
.get_path ().get_segments ().size ();
83 stream
<< seg
.get_segment_name ();
88 if (attrib
.has_attr_input ())
92 bool is_literal
= attrib
.get_attr_input ().get_attr_input_type ()
93 == AST::AttrInput::AttrInputType::LITERAL
;
97 = static_cast<AST::AttrInputLiteral
&> (attrib
.get_attr_input ());
98 const auto &value
= literal
.get_literal ().as_string ();
100 stream
<< "\"" << value
<< "\"";
112 Dump::visit (Token
&tok
)
116 Dump::visit (DelimTokenTree
&delim_tok_tree
)
120 Dump::visit (AttrInputMetaItemContainer
&input
)
124 Dump::visit (IdentifierExpr
&ident_expr
)
126 stream
<< ident_expr
.get_ident ();
130 Dump::visit (Lifetime
&lifetime
)
134 Dump::visit (LifetimeParam
&lifetime_param
)
138 Dump::visit (ConstGenericParam
&lifetime_param
)
143 Dump::visit (PathInExpression
&path
)
147 Dump::visit (TypePathSegment
&segment
)
151 Dump::visit (TypePathSegmentGeneric
&segment
)
155 Dump::visit (TypePathSegmentFunction
&segment
)
159 Dump::visit (TypePath
&path
)
161 stream
<< path
.as_string ();
165 Dump::visit (QualifiedPathInExpression
&path
)
169 Dump::visit (QualifiedPathInType
&path
)
174 Dump::visit (LiteralExpr
&expr
)
176 stream
<< expr
.as_string ();
180 Dump::visit (AttrInputLiteral
&attr_input
)
184 Dump::visit (MetaItemLitExpr
&meta_item
)
188 Dump::visit (MetaItemPathLit
&meta_item
)
192 Dump::visit (BorrowExpr
&expr
)
196 Dump::visit (DereferenceExpr
&expr
)
200 Dump::visit (ErrorPropagationExpr
&expr
)
204 Dump::visit (NegationExpr
&expr
)
208 Dump::visit (ArithmeticOrLogicalExpr
&expr
)
210 expr
.get_left_expr ()->accept_vis (*this);
213 switch (expr
.get_expr_type ())
215 case ArithmeticOrLogicalOperator::ADD
:
219 case ArithmeticOrLogicalOperator::SUBTRACT
:
223 case ArithmeticOrLogicalOperator::MULTIPLY
:
227 case ArithmeticOrLogicalOperator::DIVIDE
:
231 case ArithmeticOrLogicalOperator::MODULUS
:
235 case ArithmeticOrLogicalOperator::BITWISE_AND
:
239 case ArithmeticOrLogicalOperator::BITWISE_OR
:
243 case ArithmeticOrLogicalOperator::BITWISE_XOR
:
247 case ArithmeticOrLogicalOperator::LEFT_SHIFT
:
251 case ArithmeticOrLogicalOperator::RIGHT_SHIFT
:
257 expr
.get_right_expr ()->accept_vis (*this);
261 Dump::visit (ComparisonExpr
&expr
)
265 Dump::visit (LazyBooleanExpr
&expr
)
269 Dump::visit (TypeCastExpr
&expr
)
273 Dump::visit (AssignmentExpr
&expr
)
277 Dump::visit (CompoundAssignmentExpr
&expr
)
281 Dump::visit (GroupedExpr
&expr
)
285 Dump::visit (ArrayElemsValues
&elems
)
289 Dump::visit (ArrayElemsCopied
&elems
)
293 Dump::visit (ArrayExpr
&expr
)
297 Dump::visit (ArrayIndexExpr
&expr
)
301 Dump::visit (TupleExpr
&expr
)
305 Dump::visit (TupleIndexExpr
&expr
)
309 Dump::visit (StructExprStruct
&expr
)
313 Dump::visit (StructExprFieldIdentifier
&field
)
317 Dump::visit (StructExprFieldIdentifierValue
&field
)
321 Dump::visit (StructExprFieldIndexValue
&field
)
325 Dump::visit (StructExprStructFields
&expr
)
329 Dump::visit (StructExprStructBase
&expr
)
333 Dump::visit (CallExpr
&expr
)
337 Dump::visit (MethodCallExpr
&expr
)
341 Dump::visit (FieldAccessExpr
&expr
)
345 Dump::visit (ClosureExprInner
&expr
)
349 Dump::visit (BlockExpr
&expr
)
352 indentation
.increment ();
354 for (auto &stmt
: expr
.get_statements ())
356 stream
<< indentation
;
357 stmt
->accept_vis (*this);
361 if (expr
.has_tail_expr ())
363 stream
<< indentation
;
364 expr
.get_tail_expr ()->accept_vis (*this);
367 indentation
.decrement ();
368 stream
<< "\n" << indentation
<< "}\n";
372 Dump::visit (ClosureExprInnerTyped
&expr
)
376 Dump::visit (ContinueExpr
&expr
)
380 Dump::visit (BreakExpr
&expr
)
384 Dump::visit (RangeFromToExpr
&expr
)
388 Dump::visit (RangeFromExpr
&expr
)
392 Dump::visit (RangeToExpr
&expr
)
396 Dump::visit (RangeFullExpr
&expr
)
400 Dump::visit (RangeFromToInclExpr
&expr
)
404 Dump::visit (RangeToInclExpr
&expr
)
408 Dump::visit (ReturnExpr
&expr
)
412 Dump::visit (UnsafeBlockExpr
&expr
)
416 Dump::visit (LoopExpr
&expr
)
420 Dump::visit (WhileLoopExpr
&expr
)
424 Dump::visit (WhileLetLoopExpr
&expr
)
428 Dump::visit (ForLoopExpr
&expr
)
432 Dump::visit (IfExpr
&expr
)
436 Dump::visit (IfExprConseqElse
&expr
)
440 Dump::visit (IfExprConseqIf
&expr
)
444 Dump::visit (IfExprConseqIfLet
&expr
)
448 Dump::visit (IfLetExpr
&expr
)
452 Dump::visit (IfLetExprConseqElse
&expr
)
456 Dump::visit (IfLetExprConseqIf
&expr
)
460 Dump::visit (IfLetExprConseqIfLet
&expr
)
464 Dump::visit (MatchExpr
&expr
)
468 Dump::visit (AwaitExpr
&expr
)
472 Dump::visit (AsyncBlockExpr
&expr
)
477 Dump::visit (TypeParam
¶m
)
479 stream
<< param
.get_type_representation ();
480 if (param
.has_type ())
483 param
.get_type ()->accept_vis (*this);
488 Dump::visit (LifetimeWhereClauseItem
&item
)
492 Dump::visit (TypeBoundWhereClauseItem
&item
)
496 Dump::visit (Method
&method
)
498 stream
<< indentation
<< "fn " << method
.get_method_name () << '(';
500 auto &self
= method
.get_self_param ();
501 stream
<< self
.as_string ();
503 auto ¶ms
= method
.get_function_params ();
504 for (auto ¶m
: params
)
507 format_function_param (param
);
512 if (method
.has_return_type ())
515 method
.get_return_type ()->accept_vis (*this);
519 auto &block
= method
.get_definition ();
523 block
->accept_vis (*this);
529 Dump::visit (Module
&module
)
533 Dump::visit (ExternCrate
&crate
)
537 Dump::visit (UseTreeGlob
&use_tree
)
541 Dump::visit (UseTreeList
&use_tree
)
545 Dump::visit (UseTreeRebind
&use_tree
)
549 Dump::visit (UseDeclaration
&use_decl
)
553 Dump::visit (Function
&function
)
555 stream
<< "fn " << function
.get_function_name ();
557 if (function
.has_generics ())
560 for (size_t i
= 0; i
< function
.get_generic_params ().size (); i
++)
562 auto ¶m
= function
.get_generic_params ().at (i
);
563 param
->accept_vis (*this);
565 bool has_next
= (i
+ 1) < function
.get_generic_params ().size ();
573 auto ¶ms
= function
.get_function_params ();
574 if (params
.size () >= 1)
576 format_function_param (params
[0]);
577 for (size_t i
= 1; i
< params
.size (); i
++)
580 format_function_param (params
[i
]);
586 if (function
.has_return_type ())
589 function
.get_return_type ()->accept_vis (*this);
593 auto &block
= function
.get_definition ();
597 block
->accept_vis (*this);
603 Dump::visit (TypeAlias
&type_alias
)
607 Dump::visit (StructStruct
&struct_item
)
611 Dump::visit (TupleStruct
&tuple_struct
)
615 Dump::visit (EnumItem
&item
)
619 Dump::visit (EnumItemTuple
&item
)
623 Dump::visit (EnumItemStruct
&item
)
627 Dump::visit (EnumItemDiscriminant
&item
)
631 Dump::visit (Enum
&enum_item
)
635 Dump::visit (Union
&union_item
)
639 Dump::visit (ConstantItem
&const_item
)
643 Dump::visit (StaticItem
&static_item
)
647 Dump::format_function_common (std::unique_ptr
<Type
> &return_type
,
648 std::unique_ptr
<BlockExpr
> &block
)
653 return_type
->accept_vis (*this);
660 block
->accept_vis (*this);
667 Dump::visit (TraitItemFunc
&item
)
669 auto func
= item
.get_trait_function_decl ();
670 stream
<< indentation
<< "fn " << func
.get_identifier () << '(';
672 auto ¶ms
= func
.get_function_params ();
673 for (auto ¶m
: params
)
676 format_function_param (param
);
681 format_function_common (func
.get_return_type (), item
.get_definition ());
685 Dump::visit (TraitItemMethod
&item
)
687 auto method
= item
.get_trait_method_decl ();
688 stream
<< indentation
<< "fn " << method
.get_identifier () << '(';
690 auto &self
= method
.get_self_param ();
691 stream
<< self
.as_string ();
693 auto ¶ms
= method
.get_function_params ();
694 for (auto ¶m
: params
)
697 format_function_param (param
);
702 format_function_common (method
.get_return_type (), item
.get_definition ());
706 Dump::visit (TraitItemConst
&item
)
708 stream
<< indentation
<< "const " << item
.get_identifier () << ": ";
709 item
.get_type ()->accept_vis (*this);
714 Dump::visit (TraitItemType
&item
)
716 stream
<< indentation
<< "type " << item
.get_identifier () << ";\n";
720 Dump::visit (Trait
&trait
)
722 for (const auto &attr
: trait
.get_outer_attrs ())
725 stream
<< "\n" << indentation
;
728 stream
<< "trait " << trait
.get_identifier ();
730 // Traits actually have an implicit Self thrown at the start so we must expect
731 // the number of generic params to be > 1
732 if (trait
.get_generic_params ().size () > 1)
735 for (size_t i
= 1; i
< trait
.get_generic_params ().size (); i
++)
737 auto ¶m
= trait
.get_generic_params ().at (i
);
738 param
->accept_vis (*this);
740 bool has_next
= (i
+ 1) < trait
.get_generic_params ().size ();
749 indentation
.increment ();
751 for (auto &item
: trait
.get_trait_items ())
752 item
->accept_vis (*this);
754 indentation
.decrement ();
759 Dump::visit (InherentImpl
&impl
)
763 // FIXME: Handle generics
765 impl
.get_type ()->accept_vis (*this);
767 // FIXME: Handle where-clause
768 // FIXME: Handle inner attributes
771 indentation
.increment ();
773 for (auto &item
: impl
.get_impl_items ())
774 item
->accept_vis (*this);
776 indentation
.decrement ();
781 Dump::visit (TraitImpl
&impl
)
784 impl
.get_trait_path ().accept_vis (*this);
786 impl
.get_type ()->accept_vis (*this);
789 indentation
.increment ();
791 for (auto &item
: impl
.get_impl_items ())
792 item
->accept_vis (*this);
794 indentation
.decrement ();
799 Dump::visit (ExternalStaticItem
&item
)
803 Dump::visit (ExternalFunctionItem
&function
)
805 stream
<< "fn " << function
.get_identifier () << '(';
807 for (size_t i
= 0; i
< function
.get_function_params ().size (); i
++)
809 auto ¶m
= function
.get_function_params ().at (i
);
810 bool has_next
= (i
+ 1) < function
.get_function_params ().size ();
812 stream
<< param
.get_name () << ": ";
813 param
.get_type ()->accept_vis (*this);
820 if (function
.has_return_type ())
823 function
.get_return_type ()->accept_vis (*this);
828 Dump::visit (ExternBlock
&block
)
832 if (block
.has_abi ())
835 stream
<< block
.get_abi ();
840 indentation
.increment ();
842 for (auto &item
: block
.get_extern_items ())
844 stream
<< indentation
;
845 item
->accept_vis (*this);
849 indentation
.decrement ();
850 stream
<< "\n" << indentation
<< "}\n";
855 Dump::visit (MacroMatchFragment
&match
)
859 Dump::visit (MacroMatchRepetition
&match
)
863 Dump::visit (MacroMatcher
&matcher
)
867 Dump::visit (MacroRulesDefinition
&rules_def
)
871 Dump::visit (MacroInvocation
¯o_invoc
)
875 Dump::visit (MetaItemPath
&meta_item
)
879 Dump::visit (MetaItemSeq
&meta_item
)
883 Dump::visit (MetaWord
&meta_item
)
887 Dump::visit (MetaNameValueStr
&meta_item
)
891 Dump::visit (MetaListPaths
&meta_item
)
895 Dump::visit (MetaListNameValueStr
&meta_item
)
900 Dump::visit (LiteralPattern
&pattern
)
904 Dump::visit (IdentifierPattern
&pattern
)
906 stream
<< pattern
.get_ident ();
910 Dump::visit (WildcardPattern
&pattern
)
913 // void Dump::visit(RangePatternBound& bound){}
916 Dump::visit (RangePatternBoundLiteral
&bound
)
920 Dump::visit (RangePatternBoundPath
&bound
)
924 Dump::visit (RangePatternBoundQualPath
&bound
)
928 Dump::visit (RangePattern
&pattern
)
932 Dump::visit (ReferencePattern
&pattern
)
935 // void Dump::visit(StructPatternField& field){}
938 Dump::visit (StructPatternFieldTuplePat
&field
)
942 Dump::visit (StructPatternFieldIdentPat
&field
)
946 Dump::visit (StructPatternFieldIdent
&field
)
950 Dump::visit (StructPattern
&pattern
)
953 // void Dump::visit(TupleStructItems& tuple_items){}
956 Dump::visit (TupleStructItemsNoRange
&tuple_items
)
960 Dump::visit (TupleStructItemsRange
&tuple_items
)
964 Dump::visit (TupleStructPattern
&pattern
)
967 // void Dump::visit(TuplePatternItems& tuple_items){}
970 Dump::visit (TuplePatternItemsMultiple
&tuple_items
)
974 Dump::visit (TuplePatternItemsRanged
&tuple_items
)
978 Dump::visit (TuplePattern
&pattern
)
982 Dump::visit (GroupedPattern
&pattern
)
986 Dump::visit (SlicePattern
&pattern
)
991 Dump::visit (EmptyStmt
&stmt
)
995 Dump::visit (LetStmt
&stmt
)
998 auto &pattern
= stmt
.get_pattern ();
1000 pattern
->accept_vis (*this);
1002 if (stmt
.has_type ())
1005 stmt
.get_type ()->accept_vis (*this);
1008 if (stmt
.has_init_expr ())
1011 stmt
.get_init_expr ()->accept_vis (*this);
1016 Dump::visit (ExprStmtWithoutBlock
&stmt
)
1020 Dump::visit (ExprStmtWithBlock
&stmt
)
1025 Dump::visit (TraitBound
&bound
)
1029 Dump::visit (ImplTraitType
&type
)
1033 Dump::visit (TraitObjectType
&type
)
1037 Dump::visit (ParenthesisedType
&type
)
1041 Dump::visit (ImplTraitTypeOneBound
&type
)
1045 Dump::visit (TraitObjectTypeOneBound
&type
)
1049 Dump::visit (TupleType
&type
)
1053 Dump::visit (NeverType
&type
)
1057 Dump::visit (RawPointerType
&type
)
1061 Dump::visit (ReferenceType
&type
)
1063 type
.get_type_referenced ()->accept_vis (*this);
1067 Dump::visit (ArrayType
&type
)
1069 type
.get_elem_type ()->accept_vis (*this);
1073 Dump::visit (SliceType
&type
)
1075 type
.get_elem_type ()->accept_vis (*this);
1079 Dump::visit (InferredType
&type
)
1085 Dump::visit (BareFunctionType
&type
)