FLANG
dump-parse-tree.h
1//===-- include/flang/Parser/dump-parse-tree.h ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_PARSER_DUMP_PARSE_TREE_H_
10#define FORTRAN_PARSER_DUMP_PARSE_TREE_H_
11
12#include "format-specification.h"
13#include "parse-tree-visitor.h"
14#include "parse-tree.h"
15#include "tools.h"
16#include "unparse.h"
17#include "flang/Common/idioms.h"
18#include "flang/Common/indirection.h"
19#include "flang/Support/Fortran.h"
20#include "llvm/Frontend/OpenMP/OMP.h"
21#include "llvm/Support/raw_ostream.h"
22#include <string>
23#include <type_traits>
24
25namespace Fortran::parser {
26
27//
28// Dump the Parse Tree hierarchy of any node 'x' of the parse tree.
29//
30
31class ParseTreeDumper {
32public:
33 explicit ParseTreeDumper(llvm::raw_ostream &out,
34 const AnalyzedObjectsAsFortran *asFortran = nullptr)
35 : out_(out), asFortran_{asFortran} {}
36
37 static constexpr const char *GetNodeName(const char *) { return "char *"; }
38#define NODE_NAME(T, N) \
39 static constexpr const char *GetNodeName(const T &) { return N; }
40#define NODE_ENUM(T, E) \
41 static std::string GetNodeName(const T::E &x) { \
42 return #E " = "s + std::string{T::EnumToString(x)}; \
43 }
44#define NODE(T1, T2) NODE_NAME(T1::T2, #T2)
45 NODE_NAME(bool, "bool")
46 NODE_NAME(int, "int")
47 NODE(std, string)
48 NODE(std, int64_t)
49 NODE(std, uint64_t)
50 NODE_ENUM(common, CUDADataAttr)
51 NODE_ENUM(common, CUDASubprogramAttrs)
52 NODE_ENUM(common, OmpMemoryOrderType)
53 NODE_ENUM(common, OpenACCDeviceType)
54 NODE(format, ControlEditDesc)
55 NODE(format::ControlEditDesc, Kind)
56 NODE(format, DerivedTypeDataEditDesc)
57 NODE(format, FormatItem)
58 NODE(format, FormatSpecification)
59 NODE(format, IntrinsicTypeDataEditDesc)
61 NODE(parser, Abstract)
63 NODE(AccAtomicCapture, Stmt1)
64 NODE(AccAtomicCapture, Stmt2)
72 NODE(parser, AccClause)
73#define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
74#include "llvm/Frontend/OpenACC/ACC.inc"
77 static std::string GetNodeName(const llvm::acc::DefaultValue &x) {
78 return llvm::Twine(
79 "llvm::acc::DefaultValue = ", llvm::acc::getOpenACCDefaultValueName(x))
80 .str();
81 }
85 NODE_ENUM(parser::AccDataModifier, Modifier)
87 NODE(parser, AccEndAtomic)
91 NODE(parser, AccGangArg)
92 NODE(AccGangArg, Num)
93 NODE(AccGangArg, Dim)
94 NODE(AccGangArg, Static)
96 NODE(parser, AccObject)
97 NODE(parser, AccObjectList)
100 NODE(parser, AccSizeExpr)
102 NODE(parser, AccSelfClause)
105
107 NODE(parser, AccTileExpr)
110 NODE(parser, AccEndLoop)
112 static std::string GetNodeName(const llvm::acc::Directive &x) {
113 return llvm::Twine(
114 "llvm::acc::Directive = ", llvm::acc::getOpenACCDirectiveName(x))
115 .str();
116 }
117 NODE(parser, AcImpliedDo)
119 NODE(parser, AcValue)
120 NODE(parser, AccessStmt)
121 NODE(parser, AccessId)
122 NODE(parser, AccessSpec)
123 NODE_ENUM(AccessSpec, Kind)
124 NODE(parser, AcSpec)
125 NODE(parser, ActionStmt)
126 NODE(parser, ActualArg)
127 NODE(ActualArg, PercentRef)
128 NODE(ActualArg, PercentVal)
129 NODE(parser, ActualArgSpec)
130 NODE(AcValue, Triplet)
131 NODE(parser, AllocOpt)
132 NODE(AllocOpt, Mold)
133 NODE(AllocOpt, Source)
134 NODE(AllocOpt, Stream)
135 NODE(AllocOpt, Pinned)
136 NODE(parser, Allocatable)
137 NODE(parser, AllocatableStmt)
141 NODE(parser, AllocateStmt)
142 NODE(parser, Allocation)
143 NODE(parser, AltReturnSpec)
145 NODE(parser, ArrayConstructor)
146 NODE(parser, ArrayElement)
147 NODE(parser, ArraySpec)
148 NODE(parser, AssignStmt)
152 NODE(parser, AssociateStmt)
153 NODE(parser, Association)
154 NODE(parser, AssumedImpliedSpec)
155 NODE(parser, AssumedRankSpec)
156 NODE(parser, AssumedShapeSpec)
158 NODE(parser, Asynchronous)
159 NODE(parser, AsynchronousStmt)
160 NODE(parser, AttrSpec)
161 NODE(parser, BOZLiteralConstant)
162 NODE(parser, BackspaceStmt)
163 NODE(parser, BasedPointer)
164 NODE(parser, BasedPointerStmt)
165 NODE(parser, BindAttr)
166 NODE(BindAttr, Deferred)
167 NODE(BindAttr, Non_Overridable)
168 NODE(parser, BindEntity)
169 NODE_ENUM(BindEntity, Kind)
170 NODE(parser, BindStmt)
171 NODE(parser, Block)
173 NODE(parser, BlockData)
174 NODE(parser, BlockDataStmt)
175 NODE(parser, BlockSpecificationPart)
176 NODE(parser, BlockStmt)
178 NODE(parser, BoundsSpec)
179 NODE(parser, Call)
180 NODE(parser, CallStmt)
181 NODE(CallStmt, Chevrons)
182 NODE(CallStmt, StarOrExpr)
183 NODE(parser, CaseConstruct)
184 NODE(CaseConstruct, Case)
185 NODE(parser, CaseSelector)
186 NODE(parser, CaseStmt)
188 NODE(CaseValueRange, Range)
191 NODE(parser, CharLength)
194 NODE(parser, CharSelector)
195 NODE(CharSelector, LengthAndKind)
196 NODE(parser, CloseStmt)
197 NODE(CloseStmt, CloseSpec)
199 NODE(parser, CoarraySpec)
201 NODE(parser, CodimensionStmt)
204 NODE(parser, CommonStmt)
205 NODE(CommonStmt, Block)
207 NODE(CompilerDirective, AssumeAligned)
208 NODE(CompilerDirective, IgnoreTKR)
209 NODE(CompilerDirective, LoopCount)
210 NODE(CompilerDirective, NameValue)
211 NODE(CompilerDirective, Unrecognized)
212 NODE(CompilerDirective, VectorAlways)
213 NODE(CompilerDirective, Unroll)
214 NODE(CompilerDirective, UnrollAndJam)
215 NODE(CompilerDirective, NoVector)
216 NODE(CompilerDirective, NoUnroll)
217 NODE(CompilerDirective, NoUnrollAndJam)
219 NODE(parser, ComplexPart)
222 NODE(parser, ComponentDataSource)
223 NODE(parser, ComponentDecl)
224 NODE(parser, FillDecl)
227 NODE(parser, ComponentSpec)
231 NODE(parser, ConnectSpec)
232 NODE(ConnectSpec, CharExpr)
233 NODE_ENUM(ConnectSpec::CharExpr, Kind)
234 NODE(ConnectSpec, Newunit)
235 NODE(ConnectSpec, Recl)
236 NODE(parser, ContainsStmt)
237 NODE(parser, Contiguous)
238 NODE(parser, ContiguousStmt)
239 NODE(parser, ContinueStmt)
241 NODE(parser, CriticalStmt)
244 NODE(CUFKernelDoConstruct, StarOrExpr)
245 NODE(CUFKernelDoConstruct, Directive)
246 NODE(CUFKernelDoConstruct, LaunchConfiguration)
247 NODE(parser, CUFReduction)
248 NODE(parser, CycleStmt)
250 NODE(parser, DataIDoObject)
251 NODE(parser, DataImpliedDo)
252 NODE(parser, DataRef)
253 NODE(parser, DataStmt)
257 NODE(parser, DataStmtSet)
258 NODE(parser, DataStmtValue)
262 NODE(DeclarationTypeSpec, Class)
263 NODE(DeclarationTypeSpec, ClassStar)
264 NODE(DeclarationTypeSpec, Record)
265 NODE(DeclarationTypeSpec, Type)
266 NODE(DeclarationTypeSpec, TypeStar)
267 NODE(parser, Default)
268 NODE(parser, DeferredCoshapeSpecList)
269 NODE(parser, DeferredShapeSpecList)
270 NODE(parser, DefinedOpName)
272 NODE_ENUM(DefinedOperator, IntrinsicOperator)
276 NODE(parser, Designator)
277 NODE(parser, DimensionStmt)
278 NODE(DimensionStmt, Declaration)
279 NODE(parser, DoConstruct)
280 NODE(parser, DummyArg)
281 NODE(parser, ElseIfStmt)
282 NODE(parser, ElseStmt)
283 NODE(parser, ElsewhereStmt)
284 NODE(parser, EndAssociateStmt)
285 NODE(parser, EndBlockDataStmt)
286 NODE(parser, EndBlockStmt)
288 NODE(parser, EndCriticalStmt)
289 NODE(parser, EndDoStmt)
290 NODE(parser, EndEnumStmt)
291 NODE(parser, EndForallStmt)
292 NODE(parser, EndFunctionStmt)
293 NODE(parser, EndIfStmt)
294 NODE(parser, EndInterfaceStmt)
295 NODE(parser, EndLabel)
296 NODE(parser, EndModuleStmt)
297 NODE(parser, EndMpSubprogramStmt)
298 NODE(parser, EndProgramStmt)
299 NODE(parser, EndSelectStmt)
300 NODE(parser, EndSubmoduleStmt)
301 NODE(parser, EndSubroutineStmt)
302 NODE(parser, EndTypeStmt)
303 NODE(parser, EndWhereStmt)
304 NODE(parser, EndfileStmt)
305 NODE(parser, EntityDecl)
306 NODE(parser, EntryStmt)
307 NODE(parser, EnumDef)
308 NODE(parser, EnumDefStmt)
309 NODE(parser, Enumerator)
310 NODE(parser, EnumeratorDefStmt)
311 NODE(parser, EorLabel)
312 NODE(parser, EquivalenceObject)
313 NODE(parser, EquivalenceStmt)
314 NODE(parser, ErrLabel)
315 NODE(parser, ErrorRecovery)
316 NODE(parser, EventPostStmt)
317 NODE(parser, EventWaitSpec)
318 NODE(parser, EventWaitStmt)
320 NODE(parser, ExecutionPart)
322 NODE(parser, ExitStmt)
325 NODE(parser, Expr)
326 NODE(Expr, Parentheses)
327 NODE(Expr, UnaryPlus)
328 NODE(Expr, Negate)
329 NODE(Expr, NOT)
330 NODE(Expr, PercentLoc)
331 NODE(Expr, DefinedUnary)
332 NODE(Expr, Power)
333 NODE(Expr, Multiply)
334 NODE(Expr, Divide)
335 NODE(Expr, Add)
336 NODE(Expr, Subtract)
337 NODE(Expr, Concat)
338 NODE(Expr, LT)
339 NODE(Expr, LE)
340 NODE(Expr, EQ)
341 NODE(Expr, NE)
342 NODE(Expr, GE)
343 NODE(Expr, GT)
344 NODE(Expr, AND)
345 NODE(Expr, OR)
346 NODE(Expr, EQV)
347 NODE(Expr, NEQV)
348 NODE(Expr, DefinedBinary)
349 NODE(Expr, ComplexConstructor)
350 NODE(parser, External)
351 NODE(parser, ExternalStmt)
352 NODE(parser, FailImageStmt)
353 NODE(parser, FileUnitNumber)
354 NODE(parser, FinalProcedureStmt)
355 NODE(parser, FlushStmt)
360 NODE(parser, ForallStmt)
361 NODE(parser, FormTeamStmt)
362 NODE(FormTeamStmt, FormTeamSpec)
363 NODE(parser, Format)
364 NODE(parser, FormatStmt)
366 NODE(parser, FunctionStmt)
368 NODE(parser, GenericSpec)
369 NODE(GenericSpec, Assignment)
370 NODE(GenericSpec, ReadFormatted)
371 NODE(GenericSpec, ReadUnformatted)
372 NODE(GenericSpec, WriteFormatted)
373 NODE(GenericSpec, WriteUnformatted)
374 NODE(parser, GenericStmt)
375 NODE(parser, GotoStmt)
377 NODE(parser, IdExpr)
378 NODE(parser, IdVariable)
379 NODE(parser, IfConstruct)
380 NODE(IfConstruct, ElseBlock)
381 NODE(IfConstruct, ElseIfBlock)
382 NODE(parser, IfStmt)
383 NODE(parser, IfThenStmt)
384 NODE(parser, TeamValue)
385 NODE(parser, ImageSelector)
387 NODE(ImageSelectorSpec, Stat)
388 NODE(ImageSelectorSpec, Team_Number)
389 NODE(parser, ImplicitPart)
391 NODE(parser, ImplicitSpec)
392 NODE(parser, ImplicitStmt)
393 NODE_ENUM(ImplicitStmt, ImplicitNoneNameSpec)
394 NODE(parser, ImpliedShapeSpec)
395 NODE(parser, ImportStmt)
398 NODE(parser, InputItem)
399 NODE(parser, InquireSpec)
400 NODE(InquireSpec, CharVar)
401 NODE_ENUM(InquireSpec::CharVar, Kind)
402 NODE(InquireSpec, IntVar)
403 NODE_ENUM(InquireSpec::IntVar, Kind)
404 NODE(InquireSpec, LogVar)
405 NODE_ENUM(InquireSpec::LogVar, Kind)
406 NODE(parser, InquireStmt)
407 NODE(InquireStmt, Iolength)
408 NODE(parser, IntegerTypeSpec)
409 NODE(parser, IntentSpec)
410 NODE_ENUM(IntentSpec, Intent)
411 NODE(parser, IntentStmt)
413 NODE(parser, InterfaceBody)
414 NODE(InterfaceBody, Function)
415 NODE(InterfaceBody, Subroutine)
417 NODE(parser, InterfaceStmt)
420 NODE(parser, Intrinsic)
421 NODE(parser, IntrinsicStmt)
423 NODE(IntrinsicTypeSpec, Character)
424 NODE(IntrinsicTypeSpec, Complex)
425 NODE(IntrinsicTypeSpec, DoubleComplex)
426 NODE(IntrinsicTypeSpec, DoublePrecision)
428 NODE(IntrinsicTypeSpec, Real)
429 NODE(parser, IoControlSpec)
430 NODE(IoControlSpec, Asynchronous)
431 NODE(IoControlSpec, CharExpr)
432 NODE_ENUM(IoControlSpec::CharExpr, Kind)
433 NODE(IoControlSpec, Pos)
434 NODE(IoControlSpec, Rec)
435 NODE(IoControlSpec, Size)
436 NODE(parser, IoUnit)
437 NODE(parser, Keyword)
438 NODE(parser, KindParam)
439 NODE(parser, KindSelector)
440 NODE(KindSelector, StarSize)
441 NODE(parser, LabelDoStmt)
444 NODE(parser, LetterSpec)
448 NODE_ENUM(parser::ReductionOperator, Operator)
449 NODE(parser, LocalitySpec)
450 NODE(LocalitySpec, DefaultNone)
451 NODE(LocalitySpec, Local)
452 NODE(LocalitySpec, LocalInit)
453 NODE(LocalitySpec, Reduce)
454 NODE(LocalitySpec, Shared)
455 NODE(parser, LockStmt)
456 NODE(LockStmt, LockStat)
458 NODE_NAME(LoopControl::Bounds, "LoopBounds")
459 NODE_NAME(AcImpliedDoControl::Bounds, "LoopBounds")
460 NODE_NAME(DataImpliedDo::Bounds, "LoopBounds")
461 NODE(parser, LoopControl)
462 NODE(LoopControl, Concurrent)
463 NODE(parser, MainProgram)
464 NODE(parser, Map)
465 NODE(Map, EndMapStmt)
466 NODE(Map, MapStmt)
468 NODE(parser, Module)
469 NODE(parser, ModuleStmt)
472 NODE(parser, MpSubprogramStmt)
473 NODE(parser, MsgVariable)
474 NODE(parser, Name)
475 NODE(parser, NamedConstant)
477 NODE(parser, NamelistStmt)
478 NODE(NamelistStmt, Group)
480 NODE(parser, NoPass)
482 NODE(parser, NullifyStmt)
483 NODE(parser, NullInit)
484 NODE(parser, ObjectDecl)
485 NODE(parser, OldParameterStmt)
486
487 static std::string GetNodeName(const llvm::omp::Directive &x) {
488 return llvm::Twine("llvm::omp::Directive = ",
489 llvm::omp::getOpenMPDirectiveName(x, llvm::omp::FallbackVersion))
490 .str();
491 }
492 static std::string GetNodeName(const llvm::omp::Clause &x) {
493 return llvm::Twine(
494 "llvm::omp::Clause = ", llvm::omp::getOpenMPClauseName(x))
495 .str();
496 }
499 NODE_ENUM(OmpAccessGroup, Value)
501 NODE(OmpAdjustArgsClause, OmpAdjustOp)
502 NODE_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value)
504 NODE(OmpAffinityClause, Modifier)
507 NODE(OmpAlignedClause, Modifier)
508 NODE(parser, OmpAlignment)
511 NODE(OmpAllocateClause, Modifier)
515 NODE_ENUM(OmpAlwaysModifier, Value)
517 NODE(OmpAppendArgsClause, OmpAppendOp)
518 NODE(parser, OmpArgument)
520 NODE(parser, OmpAtClause)
521 NODE_ENUM(OmpAtClause, ActionTime)
524 NODE_ENUM(OmpAutomapModifier, Value)
529 NODE(parser, OmpBindClause)
530 NODE_ENUM(OmpBindClause, Binding)
534 NODE_ENUM(OmpChunkModifier, Value)
535 NODE(parser, OmpClause)
536 NODE(parser, OmpClauseList)
538 NODE_ENUM(OmpCloseModifier, Value)
543 NODE_ENUM(OmpDefaultClause, DataSharingAttribute)
545 NODE(OmpDefaultmapClause, Modifier)
546 NODE_ENUM(OmpDefaultmapClause, ImplicitBehavior)
548 NODE_ENUM(OmpDeleteModifier, Value)
550 NODE(OmpDependClause, TaskDep)
551 NODE(OmpDependClause::TaskDep, Modifier)
553 NODE_ENUM(OmpDependenceType, Value)
554 NODE(parser, OmpDestroyClause)
557 NODE(OmpDeviceClause, Modifier)
559 NODE_ENUM(OmpDeviceModifier, Value)
561 NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
564 NODE_ENUM(OmpDirectiveSpecification, Flags)
565 NODE(parser, OmpDoacross)
566 NODE(OmpDoacross, Sink)
567 NODE(OmpDoacross, Source)
568 NODE(parser, OmpDoacrossClause)
570 NODE(OmpDynGroupprivateClause, Modifier)
575 NODE(OmpEnterClause, Modifier)
578 NODE_ENUM(OmpExpectation, Value)
579 NODE(parser, OmpFailClause)
580 NODE(parser, OmpFromClause)
581 NODE(OmpFromClause, Modifier)
583 NODE(OmpGrainsizeClause, Modifier)
586 NODE(parser, OmpHintClause)
588 NODE(parser, OmpIfClause)
589 NODE(OmpIfClause, Modifier)
591 NODE(parser, OmpInitClause)
592 NODE(OmpInitClause, Modifier)
596 NODE(OmpInReductionClause, Modifier)
600 NODE_ENUM(OmpInteropType, Value)
601 NODE(parser, OmpIteration)
603 NODE(parser, OmpIterationVector)
604 NODE(parser, OmpIterator)
607 NODE(OmpLastprivateClause, Modifier)
609 NODE_ENUM(OmpLastprivateModifier, Value)
611 NODE(OmpLinearClause, Modifier)
613 NODE_ENUM(OmpLinearModifier, Value)
614 NODE(parser, OmpLocator)
615 NODE(parser, OmpLocatorList)
617 NODE(parser, OmpMapClause)
618 NODE(OmpMapClause, Modifier)
619 NODE(parser, OmpMapper)
621 NODE(parser, OmpMapType)
622 NODE_ENUM(OmpMapType, Value)
624 NODE_ENUM(OmpMapTypeModifier, Value)
628 NODE(parser, OmpNoOpenMPClause)
629 NODE(parser, OmpNoOpenMPRoutinesClause)
630 NODE(parser, OmpNoParallelismClause)
633 NODE(OmpNumTasksClause, Modifier)
634 NODE(parser, OmpObject)
635 NODE(OmpObject, Invalid)
636 NODE_ENUM(OmpObject::Invalid, Kind)
637 NODE(parser, OmpObjectList)
639 NODE(OmpOrderClause, Modifier)
640 NODE_ENUM(OmpOrderClause, Ordering)
642 NODE_ENUM(OmpOrderingModifier, Value)
644 NODE_ENUM(OmpOrderModifier, Value)
647 NODE_ENUM(OmpPrescriptiveness, Value)
649 NODE_ENUM(OmpPresentModifier, Value)
651 NODE_ENUM(OmpProcBindClause, AffinityPolicy)
653 NODE(OmpReductionClause, Modifier)
657 NODE_ENUM(OmpReductionModifier, Value)
660 NODE_ENUM(OmpRefModifier, Value)
663 NODE(OmpScheduleClause, Modifier)
664 NODE_ENUM(OmpScheduleClause, Kind)
666 NODE_ENUM(OmpSelfModifier, Value)
668 NODE_ENUM(OmpSeverityClause, Severity)
672 NODE_ENUM(OmpTaskDependenceType, Value)
674 NODE(OmpTaskReductionClause, Modifier)
675 NODE(parser, OmpToClause)
676 NODE(OmpToClause, Modifier)
679 NODE(OmpTraitPropertyExtension, Complex)
681 NODE(parser, OmpTraitScore)
683 NODE(OmpTraitSelector, Properties)
685 NODE_ENUM(OmpTraitSelectorName, Value)
688 NODE_ENUM(OmpTraitSetSelectorName, Value)
690 NODE(parser, OmpTypeNameList)
693 NODE(parser, OmpUseClause)
695 NODE_ENUM(OmpVariableCategory, Value)
696 NODE(parser, OmpWhenClause)
697 NODE(OmpWhenClause, Modifier)
699 NODE_ENUM(OmpxHoldModifier, Value)
700#define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
701#include "llvm/Frontend/OpenMP/OMP.inc"
702
703 NODE(parser, Only)
717
745
746 NODE(parser, OpenStmt)
747 NODE(parser, Optional)
748 NODE(parser, OptionalStmt)
751 NODE(parser, OutputItem)
752 NODE(parser, Parameter)
753 NODE(parser, ParameterStmt)
755 NODE(parser, Pass)
756 NODE(parser, PauseStmt)
757 NODE(parser, Pointer)
759 NODE(PointerAssignmentStmt, Bounds)
760 NODE(parser, PointerDecl)
761 NODE(parser, PointerObject)
762 NODE(parser, PointerStmt)
764 NODE(parser, PrefixSpec)
765 NODE(PrefixSpec, Elemental)
766 NODE(PrefixSpec, Impure)
767 NODE(PrefixSpec, Module)
768 NODE(PrefixSpec, Non_Recursive)
769 NODE(PrefixSpec, Pure)
770 NODE(PrefixSpec, Recursive)
771 NODE(PrefixSpec, Attributes)
772 NODE(PrefixSpec, Launch_Bounds)
773 NODE(PrefixSpec, Cluster_Dims)
774 NODE(parser, PrintStmt)
775 NODE(parser, PrivateStmt)
777 NODE(parser, ProcAttrSpec)
781 NODE(parser, ProcDecl)
782 NODE(parser, ProcInterface)
786 NODE(parser, ProcedureStmt)
787 NODE_ENUM(ProcedureStmt, Kind)
788 NODE(parser, Program)
789 NODE(parser, ProgramStmt)
790 NODE(parser, ProgramUnit)
791 NODE(parser, Protected)
792 NODE(parser, ProtectedStmt)
793 NODE(parser, ReadStmt)
795 NODE(RealLiteralConstant, Real)
796 NODE(parser, Rename)
797 NODE(Rename, Names)
798 NODE(Rename, Operators)
799 NODE(parser, ReturnStmt)
800 NODE(parser, RewindStmt)
801 NODE(parser, Save)
802 NODE(parser, SaveStmt)
803 NODE(parser, SavedEntity)
804 NODE_ENUM(SavedEntity, Kind)
808 NODE(SelectRankCaseStmt, Rank)
810 NODE(SelectRankConstruct, RankCase)
813 NODE(SelectTypeConstruct, TypeCase)
815 NODE(parser, Selector)
817 NODE(parser, SequenceStmt)
818 NODE(parser, Sign)
823 NODE(parser, SpecificationExpr)
825 NODE(parser, Star)
826 NODE(parser, StatOrErrmsg)
827 NODE(parser, StatVariable)
828 NODE(parser, StatusExpr)
830 NODE(parser, StopCode)
831 NODE(parser, StopStmt)
832 NODE_ENUM(StopStmt, Kind)
835 NODE(parser, StructureDef)
836 NODE(StructureDef, EndStructureStmt)
838 NODE(parser, StructureStmt)
839 NODE(parser, Submodule)
840 NODE(parser, SubmoduleStmt)
844 NODE(parser, Substring)
847 NODE(parser, Suffix)
848 NODE(parser, SyncAllStmt)
850 NODE(SyncImagesStmt, ImageSet)
851 NODE(parser, SyncMemoryStmt)
852 NODE(parser, SyncTeamStmt)
853 NODE(parser, Target)
854 NODE(parser, TargetStmt)
855 NODE(parser, TypeAttrSpec)
856 NODE(TypeAttrSpec, BindC)
857 NODE(TypeAttrSpec, Extends)
863 NODE(TypeBoundProcedureStmt, WithInterface)
864 NODE(TypeBoundProcedureStmt, WithoutInterface)
866 NODE(parser, TypeGuardStmt)
867 NODE(TypeGuardStmt, Guard)
868 NODE(parser, TypeParamDecl)
870 NODE(common, TypeParamAttr)
871 NODE(parser, TypeParamSpec)
873 NODE(TypeParamValue, Deferred)
874 NODE(parser, TypeSpec)
875 NODE(parser, Union)
876 NODE(Union, EndUnionStmt)
877 NODE(Union, UnionStmt)
878 NODE(parser, UnlockStmt)
880 NODE(parser, UnsignedTypeSpec)
881 NODE(parser, UseStmt)
882 NODE_ENUM(UseStmt, ModuleNature)
883 NODE(parser, Value)
884 NODE(parser, ValueStmt)
885 NODE(parser, Variable)
887 NODE(VectorTypeSpec, PairVectorTypeSpec)
888 NODE(VectorTypeSpec, QuadVectorTypeSpec)
889 NODE(parser, IntrinsicVectorTypeSpec)
891 NODE(parser, Verbatim)
892 NODE(parser, Volatile)
893 NODE(parser, VolatileStmt)
894 NODE(parser, WaitSpec)
895 NODE(parser, WaitStmt)
898 NODE(WhereConstruct, Elsewhere)
899 NODE(WhereConstruct, MaskedElsewhere)
901 NODE(parser, WhereStmt)
902 NODE(parser, WriteStmt)
903#undef NODE
904#undef NODE_NAME
905
906 template <typename T> bool Pre(const T &x) {
907 std::string fortran{AsFortran<T>(x)};
908 if (fortran.empty() && (UnionTrait<T> || WrapperTrait<T>)) {
909 Prefix(GetNodeName(x));
910 } else {
911 IndentEmptyLine();
912 out_ << GetNodeName(x);
913 if (!fortran.empty()) {
914 out_ << " = '" << fortran << '\'';
915 }
916 EndLine();
917 ++indent_;
918 }
919 return true;
920 }
921
922 template <typename T> void Post(const T &x) {
923 if (AsFortran<T>(x).empty() && (UnionTrait<T> || WrapperTrait<T>)) {
924 EndLineIfNonempty();
925 } else {
926 --indent_;
927 }
928 }
929
930 // A few types we want to ignore
931
932 bool Pre(const CharBlock &) { return true; }
933 void Post(const CharBlock &) {}
934
935 template <typename T> bool Pre(const Statement<T> &) { return true; }
936 template <typename T> void Post(const Statement<T> &) {}
937 template <typename T> bool Pre(const UnlabeledStatement<T> &) { return true; }
938 template <typename T> void Post(const UnlabeledStatement<T> &) {}
939
940 template <typename T> bool Pre(const common::Indirection<T> &) {
941 return true;
942 }
943 template <typename T> void Post(const common::Indirection<T> &) {}
944
945 template <typename A> bool Pre(const Scalar<A> &) {
946 Prefix("Scalar");
947 return true;
948 }
949 template <typename A> void Post(const Scalar<A> &) { EndLineIfNonempty(); }
950
951 template <typename A> bool Pre(const Constant<A> &) {
952 Prefix("Constant");
953 return true;
954 }
955 template <typename A> void Post(const Constant<A> &) { EndLineIfNonempty(); }
956
957 template <typename A> bool Pre(const Integer<A> &) {
958 Prefix("Integer");
959 return true;
960 }
961 template <typename A> void Post(const Integer<A> &) { EndLineIfNonempty(); }
962
963 template <typename A> bool Pre(const Logical<A> &) {
964 Prefix("Logical");
965 return true;
966 }
967 template <typename A> void Post(const Logical<A> &) { EndLineIfNonempty(); }
968
969 template <typename A> bool Pre(const DefaultChar<A> &) {
970 Prefix("DefaultChar");
971 return true;
972 }
973 template <typename A> void Post(const DefaultChar<A> &) {
974 EndLineIfNonempty();
975 }
976
977 template <typename... A> bool Pre(const std::tuple<A...> &) { return true; }
978 template <typename... A> void Post(const std::tuple<A...> &) {}
979
980 template <typename... A> bool Pre(const std::variant<A...> &) { return true; }
981 template <typename... A> void Post(const std::variant<A...> &) {}
982
983protected:
984 // Return a Fortran representation of this node to include in the dump
985 template <typename T> std::string AsFortran(const T &x) {
986 std::string buf;
987 llvm::raw_string_ostream ss{buf};
988 if constexpr (HasTypedExpr<T>::value) {
989 if (asFortran_ && x.typedExpr) {
990 asFortran_->expr(ss, *x.typedExpr);
991 }
992 } else if constexpr (std::is_same_v<T, AssignmentStmt> ||
993 std::is_same_v<T, PointerAssignmentStmt>) {
994 if (asFortran_ && x.typedAssignment) {
995 asFortran_->assignment(ss, *x.typedAssignment);
996 }
997 } else if constexpr (std::is_same_v<T, CallStmt>) {
998 if (asFortran_ && x.typedCall) {
999 asFortran_->call(ss, *x.typedCall);
1000 }
1001 } else if constexpr (std::is_same_v<T, IntLiteralConstant> ||
1002 std::is_same_v<T, SignedIntLiteralConstant> ||
1003 std::is_same_v<T, UnsignedLiteralConstant>) {
1004 ss << std::get<CharBlock>(x.t);
1005 } else if constexpr (std::is_same_v<T, RealLiteralConstant::Real>) {
1006 ss << x.source;
1007 } else if constexpr (std::is_same_v<T, std::string> ||
1008 std::is_same_v<T, std::int64_t> || std::is_same_v<T, std::uint64_t>) {
1009 ss << x;
1010 }
1011 if (ss.tell()) {
1012 return buf;
1013 }
1014 if constexpr (std::is_same_v<T, Name>) {
1015 return x.source.ToString();
1016#ifdef SHOW_ALL_SOURCE_MEMBERS
1017 } else if constexpr (HasSource<T>::value) {
1018 return x.source.ToString();
1019#endif
1020 } else if constexpr (std::is_same_v<T, int>) {
1021 return std::to_string(x);
1022 } else if constexpr (std::is_same_v<T, bool>) {
1023 return x ? "true" : "false";
1024 } else {
1025 return "";
1026 }
1027 }
1028
1029 void IndentEmptyLine() {
1030 if (emptyline_ && indent_ > 0) {
1031 for (int i{0}; i < indent_; ++i) {
1032 out_ << "| ";
1033 }
1034 emptyline_ = false;
1035 }
1036 }
1037
1038 void Prefix(const char *str) {
1039 IndentEmptyLine();
1040 out_ << str << " -> ";
1041 emptyline_ = false;
1042 }
1043
1044 void Prefix(const std::string &str) {
1045 IndentEmptyLine();
1046 out_ << str << " -> ";
1047 emptyline_ = false;
1048 }
1049
1050 void EndLine() {
1051 out_ << '\n';
1052 emptyline_ = true;
1053 }
1054
1055 void EndLineIfNonempty() {
1056 if (!emptyline_) {
1057 EndLine();
1058 }
1059 }
1060
1061private:
1062 int indent_{0};
1063 llvm::raw_ostream &out_;
1064 const AnalyzedObjectsAsFortran *const asFortran_;
1065 bool emptyline_{false};
1066};
1067
1068template <typename T>
1069llvm::raw_ostream &DumpTree(llvm::raw_ostream &out, const T &x,
1070 const AnalyzedObjectsAsFortran *asFortran = nullptr) {
1071 ParseTreeDumper dumper{out, asFortran};
1072 Walk(x, dumper);
1073 return out;
1074}
1075
1076} // namespace Fortran::parser
1077#endif // FORTRAN_PARSER_DUMP_PARSE_TREE_H_
Definition indirection.h:31
Definition char-block.h:28
Definition dump-parse-tree.h:31
Definition bit-population-count.h:20
Definition check-expression.h:19
Definition format-specification.h:76
Definition format-specification.h:38
Definition parse-tree.h:1303
Definition parse-tree.h:1310
Definition parse-tree.h:1269
Definition parse-tree.h:1257
Definition parse-tree.h:5417
Definition parse-tree.h:5393
Definition parse-tree.h:5409
Definition parse-tree.h:5401
Definition parse-tree.h:5378
Definition parse-tree.h:5442
Definition parse-tree.h:5372
Definition parse-tree.h:5248
Definition parse-tree.h:5221
Definition parse-tree.h:5349
Definition parse-tree.h:5334
Definition parse-tree.h:5329
Definition parse-tree.h:5237
Definition parse-tree.h:5259
Definition parse-tree.h:5242
Definition parse-tree.h:5254
Definition parse-tree.h:5286
Definition parse-tree.h:5280
Definition parse-tree.h:5384
Definition parse-tree.h:5448
Definition parse-tree.h:5325
Definition parse-tree.h:5316
Definition parse-tree.h:5226
Definition parse-tree.h:5265
Definition parse-tree.h:5213
Definition parse-tree.h:5309
Definition parse-tree.h:5305
Definition parse-tree.h:5301
Definition parse-tree.h:5231
Definition parse-tree.h:5297
Definition parse-tree.h:5291
Definition parse-tree.h:5275
Definition parse-tree.h:909
Definition parse-tree.h:1427
Definition parse-tree.h:490
Definition parse-tree.h:3253
Definition parse-tree.h:3243
Definition parse-tree.h:1980
Definition parse-tree.h:1945
Definition parse-tree.h:1924
Definition parse-tree.h:1936
Definition parse-tree.h:1991
Definition parse-tree.h:1953
Definition parse-tree.h:3451
Definition parse-tree.h:1912
Definition parse-tree.h:1358
Definition parse-tree.h:3456
Definition parse-tree.h:3461
Definition parse-tree.h:2017
Definition parse-tree.h:2174
Definition parse-tree.h:2165
Definition parse-tree.h:2158
Definition parse-tree.h:1340
Definition parse-tree.h:1388
Definition parse-tree.h:3401
Definition parse-tree.h:1127
Definition parse-tree.h:1449
Definition parse-tree.h:1456
Definition parse-tree.h:2196
Definition parse-tree.h:3028
Definition parse-tree.h:2029
Definition parse-tree.h:3395
Definition parse-tree.h:5518
Definition parse-tree.h:5512
Definition parse-tree.h:3277
Definition parse-tree.h:3260
Definition parse-tree.h:2438
Definition parse-tree.h:2420
Definition parse-tree.h:2426
Definition parse-tree.h:2406
Definition parse-tree.h:2227
Definition parse-tree.h:2212
Definition parse-tree.h:663
Definition parse-tree.h:868
Definition parse-tree.h:679
Definition parse-tree.h:2696
Definition parse-tree.h:2204
Definition parse-tree.h:984
Definition parse-tree.h:1462
Definition parse-tree.h:1903
Definition parse-tree.h:1626
Definition parse-tree.h:1634
Definition parse-tree.h:3359
Definition parse-tree.h:854
Definition parse-tree.h:846
Definition parse-tree.h:995
Definition parse-tree.h:1008
Definition parse-tree.h:1039
Definition parse-tree.h:1116
Definition parse-tree.h:1061
Definition parse-tree.h:1220
Definition parse-tree.h:2525
Definition parse-tree.h:2252
Definition parse-tree.h:2261
Definition parse-tree.h:2674
Definition parse-tree.h:2672
Definition parse-tree.h:300
Definition parse-tree.h:2243
Definition parse-tree.h:2234
Definition parse-tree.h:1069
Definition parse-tree.h:1516
Definition parse-tree.h:1528
Definition parse-tree.h:1819
Definition parse-tree.h:1487
Definition parse-tree.h:1536
Definition parse-tree.h:1502
Definition parse-tree.h:1542
Definition parse-tree.h:1508
Definition parse-tree.h:2011
Definition parse-tree.h:431
Definition parse-tree.h:768
Definition parse-tree.h:324
Definition parse-tree.h:605
Definition parse-tree.h:1205
Definition parse-tree.h:750
Definition parse-tree.h:926
Definition parse-tree.h:1858
Definition parse-tree.h:1553
Definition parse-tree.h:2339
Definition parse-tree.h:3161
Definition parse-tree.h:2359
Definition parse-tree.h:2221
Definition parse-tree.h:1403
Definition parse-tree.h:3333
Definition parse-tree.h:1249
Definition parse-tree.h:1235
Definition parse-tree.h:2579
Definition parse-tree.h:2585
Definition parse-tree.h:2593
Definition parse-tree.h:523
Definition parse-tree.h:547
Definition parse-tree.h:978
Definition parse-tree.h:965
Definition parse-tree.h:1701
Definition parse-tree.h:1055
Definition parse-tree.h:2115
Definition parse-tree.h:2131
Definition parse-tree.h:2109
Definition parse-tree.h:2144
Definition parse-tree.h:2121
Definition parse-tree.h:2605
Definition parse-tree.h:2708
Definition parse-tree.h:3265
Definition parse-tree.h:3150
Definition parse-tree.h:3299
Definition parse-tree.h:3041
Definition parse-tree.h:3056
Definition tools.h:128
Definition tools.h:134
Definition parse-tree.h:2373
Definition parse-tree.h:2389
Definition parse-tree.h:2352
Definition parse-tree.h:1686
Definition parse-tree.h:1695
Definition parse-tree.h:413
Definition parse-tree.h:1610
Definition parse-tree.h:1619
Definition parse-tree.h:618
Definition parse-tree.h:1026
Definition parse-tree.h:2803
Definition parse-tree.h:2747
Definition parse-tree.h:2890
Definition parse-tree.h:2898
Definition parse-tree.h:2903
Definition parse-tree.h:2888
Definition parse-tree.h:2916
Definition parse-tree.h:802
Definition parse-tree.h:308
Definition parse-tree.h:1366
Definition parse-tree.h:1562
Definition parse-tree.h:3217
Definition parse-tree.h:3182
Definition parse-tree.h:3207
Definition parse-tree.h:3062
Definition parse-tree.h:469
Definition parse-tree.h:457
Definition parse-tree.h:700
Definition parse-tree.h:2732
Definition parse-tree.h:2730
Definition parse-tree.h:2644
Definition parse-tree.h:789
Definition parse-tree.h:651
Definition parse-tree.h:2316
Definition parse-tree.h:1319
Definition parse-tree.h:669
Definition parse-tree.h:1604
Definition parse-tree.h:900
Definition parse-tree.h:2284
Definition parse-tree.h:2619
Definition parse-tree.h:882
Definition parse-tree.h:316
Definition parse-tree.h:2304
Definition parse-tree.h:2937
Definition parse-tree.h:3417
Definition parse-tree.h:2076
Definition parse-tree.h:2961
Definition parse-tree.h:2951
Definition parse-tree.h:2972
Definition parse-tree.h:580
Definition parse-tree.h:1325
Definition parse-tree.h:631
Definition parse-tree.h:2322
Definition parse-tree.h:2547
Definition parse-tree.h:1436
Definition parse-tree.h:4159
Definition parse-tree.h:4163
Definition parse-tree.h:4178
Definition parse-tree.h:4185
Definition parse-tree.h:4193
Definition parse-tree.h:4208
Definition parse-tree.h:4215
Definition parse-tree.h:4224
Definition parse-tree.h:4836
Definition parse-tree.h:5167
Definition parse-tree.h:4907
Definition parse-tree.h:4247
Definition parse-tree.h:4846
Definition parse-tree.h:4807
Definition parse-tree.h:4791
Definition parse-tree.h:4262
Definition parse-tree.h:4279
Definition parse-tree.h:4297
Definition parse-tree.h:4354
Definition parse-tree.h:4352
Definition parse-tree.h:4380
Definition parse-tree.h:4390
Definition parse-tree.h:4400
Definition parse-tree.h:3487
Definition parse-tree.h:4814
Definition parse-tree.h:4334
Definition parse-tree.h:4405
Definition parse-tree.h:4841
Definition parse-tree.h:5171
Definition parse-tree.h:4912
Definition parse-tree.h:4416
Definition parse-tree.h:4874
Definition parse-tree.h:4424
Definition parse-tree.h:4437
Definition parse-tree.h:4448
Definition parse-tree.h:4458
Definition parse-tree.h:4466
Definition parse-tree.h:4471
Definition parse-tree.h:4479
Definition parse-tree.h:4495
Definition parse-tree.h:4505
Definition parse-tree.h:4484
Definition parse-tree.h:4779
Definition parse-tree.h:4518
Definition parse-tree.h:4513
Definition parse-tree.h:4309
Definition parse-tree.h:4318
Definition parse-tree.h:4528
Definition parse-tree.h:4543
Definition parse-tree.h:4554
Definition parse-tree.h:4578
Definition parse-tree.h:4590
Definition parse-tree.h:4599
Definition parse-tree.h:4859
Definition parse-tree.h:4868
Definition parse-tree.h:4623
Definition parse-tree.h:3511
Definition parse-tree.h:3508
Definition parse-tree.h:4634
Definition parse-tree.h:4647
Definition parse-tree.h:4659
Definition parse-tree.h:4670
Definition parse-tree.h:3539
Definition parse-tree.h:3529
Definition parse-tree.h:4680
Definition parse-tree.h:4692
Definition parse-tree.h:4702
Definition parse-tree.h:4711
Definition parse-tree.h:4727
Definition parse-tree.h:4737
Definition parse-tree.h:4752
Definition parse-tree.h:4763
Definition parse-tree.h:3072
Definition parse-tree.h:5424
Definition parse-tree.h:5431
Definition parse-tree.h:5360
Definition parse-tree.h:5453
Definition parse-tree.h:5492
Definition parse-tree.h:5481
Definition parse-tree.h:5472
Definition parse-tree.h:5354
Definition parse-tree.h:5366
Definition parse-tree.h:5056
Definition parse-tree.h:4901
Definition parse-tree.h:5061
Definition parse-tree.h:5098
Definition parse-tree.h:5201
Definition parse-tree.h:5033
Definition parse-tree.h:5015
Definition parse-tree.h:4889
Definition parse-tree.h:5109
Definition parse-tree.h:5123
Definition parse-tree.h:5041
Definition parse-tree.h:5139
Definition parse-tree.h:4997
Definition parse-tree.h:5147
Definition parse-tree.h:5178
Definition parse-tree.h:5003
Definition parse-tree.h:4921
Definition parse-tree.h:4927
Definition parse-tree.h:5158
Definition parse-tree.h:5009
Definition parse-tree.h:4878
Definition parse-tree.h:372
Definition parse-tree.h:2808
Definition parse-tree.h:2771
Definition parse-tree.h:2997
Definition parse-tree.h:2041
Definition parse-tree.h:1572
Definition parse-tree.h:2000
Definition parse-tree.h:2834
Definition parse-tree.h:3117
Definition parse-tree.h:2792
Definition parse-tree.h:939
Definition parse-tree.h:3095
Definition parse-tree.h:1080
Definition parse-tree.h:1108
Definition parse-tree.h:1898
Definition parse-tree.h:1100
Definition parse-tree.h:1094
Definition parse-tree.h:1087
Definition parse-tree.h:3105
Definition parse-tree.h:3232
Definition parse-tree.h:3200
Definition parse-tree.h:564
Definition parse-tree.h:2755
Definition parse-tree.h:821
Definition parse-tree.h:2273
Definition parse-tree.h:2983
Definition parse-tree.h:1585
Definition parse-tree.h:292
Definition parse-tree.h:1672
Definition parse-tree.h:2396
Definition parse-tree.h:2461
Definition parse-tree.h:2473
Definition parse-tree.h:2452
Definition parse-tree.h:2507
Definition parse-tree.h:2487
Definition parse-tree.h:2152
Definition parse-tree.h:3325
Definition parse-tree.h:394
Definition parse-tree.h:445
Definition parse-tree.h:1969
Definition parse-tree.h:355
Definition parse-tree.h:3343
Definition parse-tree.h:2539
Definition parse-tree.h:1888
Definition parse-tree.h:1226
Definition parse-tree.h:3438
Definition parse-tree.h:3410
Definition parse-tree.h:3433
Definition parse-tree.h:3003
Definition parse-tree.h:3014
Definition parse-tree.h:3169
Definition parse-tree.h:3309
Definition parse-tree.h:1663
Definition parse-tree.h:1850
Definition parse-tree.h:1654
Definition parse-tree.h:1836
Definition parse-tree.h:3136
Definition parse-tree.h:2557
Definition parse-tree.h:2570
Definition parse-tree.h:917
Definition parse-tree.h:1169
Definition parse-tree.h:1182
Definition parse-tree.h:1135
Definition parse-tree.h:1191
Definition parse-tree.h:1145
Definition parse-tree.h:1417
Definition parse-tree.h:2496
Definition parse-tree.h:945
Definition parse-tree.h:953
Definition parse-tree.h:744
Definition parse-tree.h:642
Definition parse-tree.h:757
Definition parse-tree.h:3426
Definition parse-tree.h:350
Definition parse-tree.h:2629
Definition parse-tree.h:808
Definition parse-tree.h:3081
Definition parse-tree.h:1866
Definition parse-tree.h:730
Definition parse-tree.h:735
Definition parse-tree.h:279
Definition parse-tree.h:2818
Definition parse-tree.h:2067
Definition parse-tree.h:2060
Definition parse-tree.h:2091
Definition parse-tree.h:2054
Definition parse-tree.h:2777
Definition parse-tree.h:3605
Definition parse-tree.h:3596
Definition parse-tree.h:3566
Definition parse-tree.h:3552
Definition parse-tree.h:3576
Definition parse-tree.h:3589
Definition parse-tree.h:3545
Definition parse-tree.h:3760
Definition parse-tree.h:3777
Definition parse-tree.h:3769
Definition parse-tree.h:3805
Definition parse-tree.h:3815
Definition parse-tree.h:3826
Definition parse-tree.h:3839
Definition parse-tree.h:3851
Definition parse-tree.h:3872
Definition parse-tree.h:3881
Definition parse-tree.h:3914
Definition parse-tree.h:3932
Definition parse-tree.h:3941
Definition parse-tree.h:3953
Definition parse-tree.h:3963
Definition parse-tree.h:3971
Definition parse-tree.h:3980
Definition parse-tree.h:4015
Definition parse-tree.h:4002
Definition parse-tree.h:3989
Definition parse-tree.h:4039
Definition parse-tree.h:4030
Definition parse-tree.h:4049
Definition parse-tree.h:4062
Definition parse-tree.h:4071
Definition parse-tree.h:4081
Definition parse-tree.h:4091
Definition parse-tree.h:4100
Definition parse-tree.h:4108
Definition parse-tree.h:4118
Definition parse-tree.h:4129
Definition parse-tree.h:4142
Definition parse-tree.h:3643
Definition parse-tree.h:3626
Definition parse-tree.h:3667
Definition parse-tree.h:3633
Definition parse-tree.h:3694
Definition parse-tree.h:3706
Definition parse-tree.h:3719
Definition parse-tree.h:3728