From e76093ca67a255e446b111cb88c4a2e3011d79ae Mon Sep 17 00:00:00 2001 From: peter klausler Date: Tue, 30 Jan 2018 11:54:04 -0800 Subject: [PATCH] [flang] Add parse-tree.{h,cc}. Original-commit: flang-compiler/f18@bface7a17bb774d10f4615e2816f1aa178b49a1a --- flang/parse-tree.cc | 1099 ++++++++++++++++++ flang/parse-tree.h | 3164 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 4263 insertions(+) create mode 100644 flang/parse-tree.cc create mode 100644 flang/parse-tree.h diff --git a/flang/parse-tree.cc b/flang/parse-tree.cc new file mode 100644 index 0000000..52f950e --- /dev/null +++ b/flang/parse-tree.cc @@ -0,0 +1,1099 @@ +#include "parse-tree.h" +#include "idioms.h" +#include "indirection.h" +#include + +namespace Fortran { + +#define UNION_FORMATTER(TYPE) \ + std::ostream &operator<<(std::ostream &o, const TYPE &x) { \ + return o << "(" #TYPE " " << x.u << ')'; \ + } + +UNION_FORMATTER(ProgramUnit) // R502 +UNION_FORMATTER(ImplicitPartStmt) // R506 +UNION_FORMATTER(DeclarationConstruct) // R507 +UNION_FORMATTER(SpecificationConstruct) // R508 +UNION_FORMATTER(ExecutionPartConstruct) // R510 +UNION_FORMATTER(InternalSubprogram) // R512 +UNION_FORMATTER(OtherSpecificationStmt) // R513 +UNION_FORMATTER(ExecutableConstruct) // R514 +UNION_FORMATTER(ActionStmt) // R515 +UNION_FORMATTER(ConstantValue) // R604 +UNION_FORMATTER(LiteralConstant) // R605 +UNION_FORMATTER(DefinedOperator) // R609 +UNION_FORMATTER(TypeParamValue) // R701 +UNION_FORMATTER(TypeSpec) // R702 +UNION_FORMATTER(DeclarationTypeSpec) // R703 +UNION_FORMATTER(IntrinsicTypeSpec) // R704 +UNION_FORMATTER(KindParam) // R709 +UNION_FORMATTER(CharSelector) // R721 +UNION_FORMATTER(ComplexPart) // R718 & R719 +UNION_FORMATTER(LengthSelector) // R722 +UNION_FORMATTER(CharLength) // R723 +UNION_FORMATTER(TypeAttrSpec) // R728 +UNION_FORMATTER(PrivateOrSequence) // R729 +UNION_FORMATTER(ComponentDefStmt) // R736 +UNION_FORMATTER(ComponentAttrSpec) // R738 +UNION_FORMATTER(ComponentArraySpec) // R740 +UNION_FORMATTER(ProcComponentAttrSpec) // R742 +UNION_FORMATTER(Initialization) // R743 & R805 +UNION_FORMATTER(TypeBoundProcBinding) // R748 +UNION_FORMATTER(TypeBoundProcedureStmt) // R749 +UNION_FORMATTER(BindAttr) // R752 +UNION_FORMATTER(AcValue) // R773 +UNION_FORMATTER(AttrSpec) // R802 +UNION_FORMATTER(CoarraySpec) // R809 +UNION_FORMATTER(ArraySpec) // R815 +UNION_FORMATTER(AccessId) // R828 +UNION_FORMATTER(DataStmtObject) // R839 +UNION_FORMATTER(DataIDoObject) // R841 +UNION_FORMATTER(DataStmtRepeat) // R844 +UNION_FORMATTER(DataStmtConstant) // R845 +UNION_FORMATTER(Designator) // R901 +UNION_FORMATTER(Variable) // R902 +UNION_FORMATTER(DataReference) // R911 +UNION_FORMATTER(SectionSubscript) // R920 +UNION_FORMATTER(ImageSelectorSpec) // R926 +UNION_FORMATTER(StatOrErrmsg) // R928, R942 & R1165 +UNION_FORMATTER(AllocOpt) // R928 +UNION_FORMATTER(AllocateObject) // R933 +UNION_FORMATTER(PointerObject) // R940 +UNION_FORMATTER(Expr) // R1001 +UNION_FORMATTER(PointerAssignmentStmt::Bounds) // R1033 +UNION_FORMATTER(WhereBodyConstruct) // R1044 +UNION_FORMATTER(ForallBodyConstruct) // R1052 +UNION_FORMATTER(ForallAssignmentStmt) // R1053 +UNION_FORMATTER(Selector) // R1105 +UNION_FORMATTER(LoopControl) // R1123 +UNION_FORMATTER(LocalitySpec) // R1130 +UNION_FORMATTER(CaseSelector) // R1145 +UNION_FORMATTER(CaseValueRange) // R1146 +UNION_FORMATTER(SelectRankCaseStmt::Rank) // R1150 +UNION_FORMATTER(TypeGuardStmt::Guard) // R1154 +UNION_FORMATTER(StopCode) // R1162 +UNION_FORMATTER(SyncImagesStmt::ImageSet) // R1167 +UNION_FORMATTER(EventWaitStmt::EventWaitSpec) // R1173 +UNION_FORMATTER(FormTeamStmt::FormTeamSpec) // R1177 +UNION_FORMATTER(LockStmt::LockStat) // R1179 +UNION_FORMATTER(IoUnit); // R1201, R1203 +UNION_FORMATTER(ConnectSpec); // R1205 +UNION_FORMATTER(CloseStmt::CloseSpec) // R1209 +UNION_FORMATTER(IoControlSpec) // R1213 +UNION_FORMATTER(Format) // R1215 +UNION_FORMATTER(InputItem) // R1216 +UNION_FORMATTER(OutputItem) // R1217 +UNION_FORMATTER(WaitSpec) // R1223 +UNION_FORMATTER(BackspaceStmt) // R1224 +UNION_FORMATTER(EndfileStmt) // R1225 +UNION_FORMATTER(RewindStmt) // R1226 +UNION_FORMATTER(PositionOrFlushSpec) // R1227 & R1229 +UNION_FORMATTER(FlushStmt) // R1228 +UNION_FORMATTER(InquireStmt); // R1230 +UNION_FORMATTER(InquireSpec) // R1231 +UNION_FORMATTER(ModuleSubprogram) // R1408 +UNION_FORMATTER(Rename) // R1411 +UNION_FORMATTER(Only) // R1412 +UNION_FORMATTER(InterfaceSpecification) // R1502 +UNION_FORMATTER(InterfaceStmt) // R1503 +UNION_FORMATTER(InterfaceBody) // R1505 +UNION_FORMATTER(GenericSpec) // R1508 +UNION_FORMATTER(ProcInterface) // R1513 +UNION_FORMATTER(ProcAttrSpec) // R1514 +UNION_FORMATTER(ProcPointerInit) // R1517 +UNION_FORMATTER(ProcedureDesignator) // R1522 +UNION_FORMATTER(ActualArg) // R1524 +UNION_FORMATTER(PrefixSpec) // R1527 +UNION_FORMATTER(DummyArg) // R1536 +UNION_FORMATTER(StructureField) // legacy extension + +#undef UNION_FORMATTER + +#define TUPLE_FORMATTER(TYPE) \ + std::ostream &operator<<(std::ostream &o, const TYPE &x) { \ + return o << "(" #TYPE " " << x.t << ')'; \ + } + +TUPLE_FORMATTER(SpecificationPart) // R504 +TUPLE_FORMATTER(InternalSubprogramPart) // R511 +TUPLE_FORMATTER(SignedIntLiteralConstant) // R707 +TUPLE_FORMATTER(IntLiteralConstant) // R708 +TUPLE_FORMATTER(SignedRealLiteralConstant) // R713 +TUPLE_FORMATTER(ExponentPart) // R717 +TUPLE_FORMATTER(ComplexLiteralConstant) // R718 +TUPLE_FORMATTER(SignedComplexLiteralConstant) // R718 +TUPLE_FORMATTER(CharLiteralConstant) // R724 +TUPLE_FORMATTER(DerivedTypeDef) // R726, R735 +TUPLE_FORMATTER(DerivedTypeStmt) // R727 +TUPLE_FORMATTER(TypeParamDefStmt) // R732 +TUPLE_FORMATTER(TypeParamDecl) // R733 +TUPLE_FORMATTER(DataComponentDefStmt) // R737 +TUPLE_FORMATTER(ComponentDecl) // R739 +TUPLE_FORMATTER(ProcComponentDefStmt) // R741 +TUPLE_FORMATTER(TypeBoundProcedurePart) // R746 +TUPLE_FORMATTER(TypeBoundProcDecl) // R750 +TUPLE_FORMATTER(TypeBoundGenericStmt) // R751 +TUPLE_FORMATTER(DerivedTypeSpec) // R754 +TUPLE_FORMATTER(TypeParamSpec) // R755 +TUPLE_FORMATTER(EnumDef) // R759 +TUPLE_FORMATTER(StructureConstructor) // R756 +TUPLE_FORMATTER(ComponentSpec) // R757 +TUPLE_FORMATTER(Enumerator) // R762 +TUPLE_FORMATTER(AcValue::Triplet) // R773 +TUPLE_FORMATTER(AcImpliedDo) // R774 +TUPLE_FORMATTER(AcImpliedDoControl) // R775 +TUPLE_FORMATTER(TypeDeclarationStmt) // R801 +TUPLE_FORMATTER(EntityDecl) // R803 +TUPLE_FORMATTER(ExplicitCoshapeSpec) // R811 +TUPLE_FORMATTER(ExplicitShapeSpec) // R816 +TUPLE_FORMATTER(AssumedSizeSpec) // R822 +TUPLE_FORMATTER(AccessStmt) // R827 +TUPLE_FORMATTER(ObjectDecl) // R830 & R860 +TUPLE_FORMATTER(BindStmt) // R832 +TUPLE_FORMATTER(BindEntity) // R833 +TUPLE_FORMATTER(CodimensionDecl) // R835 +TUPLE_FORMATTER(DataStmtSet) // R838 +TUPLE_FORMATTER(DataImpliedDo) // R840 +TUPLE_FORMATTER(DataStmtValue) // R843 +TUPLE_FORMATTER(DimensionStmt::Declaration) // R848 +TUPLE_FORMATTER(IntentStmt) // R849 +TUPLE_FORMATTER(NamedConstantDef) // R852 +TUPLE_FORMATTER(PointerDecl) // R854 +TUPLE_FORMATTER(SavedEntity) // R857, R858 +TUPLE_FORMATTER(ImplicitSpec) // R864 +TUPLE_FORMATTER(LetterSpec) // R865 +TUPLE_FORMATTER(NamelistStmt::Group) // R868, R869 +TUPLE_FORMATTER(CommonStmt::Block) // R873 +TUPLE_FORMATTER(CommonStmt) // R873 +TUPLE_FORMATTER(CommonBlockObject) // R874 +TUPLE_FORMATTER(Substring) // R908, R909 +TUPLE_FORMATTER(CharLiteralConstantSubstring) +TUPLE_FORMATTER(SubstringRange) // R910 +TUPLE_FORMATTER(SubscriptTriplet) // R921 +TUPLE_FORMATTER(ImageSelector) // R924 +TUPLE_FORMATTER(AllocateStmt) // R927 +TUPLE_FORMATTER(Allocation) // R932 +TUPLE_FORMATTER(AllocateShapeSpec) // R934 +TUPLE_FORMATTER(AllocateCoarraySpec) // R937 +TUPLE_FORMATTER(DeallocateStmt) // R941 +TUPLE_FORMATTER(Expr::DefinedUnary) // R1002 +TUPLE_FORMATTER(Expr::IntrinsicBinary) +TUPLE_FORMATTER(Expr::Power) +TUPLE_FORMATTER(Expr::Multiply) +TUPLE_FORMATTER(Expr::Divide) +TUPLE_FORMATTER(Expr::Add) +TUPLE_FORMATTER(Expr::Subtract) +TUPLE_FORMATTER(Expr::Concat) +TUPLE_FORMATTER(Expr::LT) +TUPLE_FORMATTER(Expr::LE) +TUPLE_FORMATTER(Expr::EQ) +TUPLE_FORMATTER(Expr::NE) +TUPLE_FORMATTER(Expr::GE) +TUPLE_FORMATTER(Expr::GT) +TUPLE_FORMATTER(Expr::AND) +TUPLE_FORMATTER(Expr::OR) +TUPLE_FORMATTER(Expr::EQV) +TUPLE_FORMATTER(Expr::NEQV) +TUPLE_FORMATTER(Expr::ComplexConstructor) +TUPLE_FORMATTER(Expr::DefinedBinary) // R1022 +TUPLE_FORMATTER(AssignmentStmt) // R1032 +TUPLE_FORMATTER(PointerAssignmentStmt) // R1033 +TUPLE_FORMATTER(BoundsRemapping) // R1036 +TUPLE_FORMATTER(ProcComponentRef) // R1039 +TUPLE_FORMATTER(WhereStmt) // R1041, R1045, R1046 +TUPLE_FORMATTER(WhereConstruct) // R1042 +TUPLE_FORMATTER(WhereConstruct::MaskedElsewhere) // R1042 +TUPLE_FORMATTER(WhereConstruct::Elsewhere) // R1042 +TUPLE_FORMATTER(WhereConstructStmt) // R1043, R1046 +TUPLE_FORMATTER(MaskedElsewhereStmt) // R1047 +TUPLE_FORMATTER(ForallConstruct) // R1050 +TUPLE_FORMATTER(ForallConstructStmt) // R1051 +TUPLE_FORMATTER(ForallStmt) // R1055 +TUPLE_FORMATTER(AssociateConstruct) // R1102 +TUPLE_FORMATTER(AssociateStmt) // R1103 +TUPLE_FORMATTER(Association) // R1104 +TUPLE_FORMATTER(BlockConstruct) // R1107 +TUPLE_FORMATTER(ChangeTeamConstruct) // R1111 +TUPLE_FORMATTER(ChangeTeamStmt) // R1112 +TUPLE_FORMATTER(CoarrayAssociation) // R1113 +TUPLE_FORMATTER(EndChangeTeamStmt) // R1114 +TUPLE_FORMATTER(CriticalConstruct) // R1116 +TUPLE_FORMATTER(CriticalStmt) // R1117 +TUPLE_FORMATTER(DoConstruct) // R1119 +TUPLE_FORMATTER(LabelDoStmt) // R1121 +TUPLE_FORMATTER(NonLabelDoStmt) // R1122 +TUPLE_FORMATTER(LoopControl::Concurrent) // R1123 +TUPLE_FORMATTER(ConcurrentHeader) // R1125 +TUPLE_FORMATTER(ConcurrentControl) // R1126 +TUPLE_FORMATTER(IfConstruct::ElseIfBlock) // R1134 +TUPLE_FORMATTER(IfConstruct::ElseBlock) // R1134 +TUPLE_FORMATTER(IfConstruct) // R1134 +TUPLE_FORMATTER(IfThenStmt) // R1135 +TUPLE_FORMATTER(ElseIfStmt) // R1136 +TUPLE_FORMATTER(IfStmt) // R1139 +TUPLE_FORMATTER(CaseConstruct) // R1140 +TUPLE_FORMATTER(CaseConstruct::Case) // R1140 +TUPLE_FORMATTER(SelectCaseStmt) // R1141, R1144 +TUPLE_FORMATTER(CaseStmt) // R1142 +TUPLE_FORMATTER(SelectRankConstruct) // R1148 +TUPLE_FORMATTER(SelectRankConstruct::RankCase) // R1148 +TUPLE_FORMATTER(SelectRankStmt) // R1149 +TUPLE_FORMATTER(SelectRankCaseStmt) // R1150 +TUPLE_FORMATTER(SelectTypeConstruct) // R1152 +TUPLE_FORMATTER(SelectTypeConstruct::TypeCase) // R1152 +TUPLE_FORMATTER(SelectTypeStmt) // R1153 +TUPLE_FORMATTER(TypeGuardStmt) // R1154 +TUPLE_FORMATTER(ComputedGotoStmt) // R1158 +TUPLE_FORMATTER(StopStmt) // R1160, R1161 +TUPLE_FORMATTER(SyncImagesStmt) // R1166 +TUPLE_FORMATTER(SyncTeamStmt) // R1169 +TUPLE_FORMATTER(EventPostStmt) // R1170, R1171 +TUPLE_FORMATTER(EventWaitStmt) // R1172 +TUPLE_FORMATTER(FormTeamStmt) // R1175 +TUPLE_FORMATTER(LockStmt) // R1178 +TUPLE_FORMATTER(UnlockStmt) // R1180 +TUPLE_FORMATTER(ConnectSpec::CharExpr) // R1205 +TUPLE_FORMATTER(PrintStmt) // R1212 +TUPLE_FORMATTER(IoControlSpec::CharExpr) // R1213 +TUPLE_FORMATTER(InputImpliedDo) // R1218, R1219 +TUPLE_FORMATTER(OutputImpliedDo) // R1218, R1219 +TUPLE_FORMATTER(InquireStmt::Iolength) // R1230 +TUPLE_FORMATTER(InquireSpec::CharVar) // R1231 +TUPLE_FORMATTER(InquireSpec::IntVar) // R1231 +TUPLE_FORMATTER(InquireSpec::LogVar) // R1231 +TUPLE_FORMATTER(MainProgram) // R1401 +TUPLE_FORMATTER(Module) // R1404 +TUPLE_FORMATTER(ModuleSubprogramPart) // R1407 +// TUPLE_FORMATTER(Rename::Names) // R1411 +TUPLE_FORMATTER(Rename::Operators) // R1414, R1415 +TUPLE_FORMATTER(Submodule) // R1416 +TUPLE_FORMATTER(SubmoduleStmt) // R1417 +TUPLE_FORMATTER(ParentIdentifier) // R1418 +TUPLE_FORMATTER(BlockData) // R1420 +TUPLE_FORMATTER(InterfaceBlock) // R1501 +TUPLE_FORMATTER(InterfaceBody::Function) // R1505 +TUPLE_FORMATTER(InterfaceBody::Subroutine) // R1505 +TUPLE_FORMATTER(GenericStmt) // R1510 +TUPLE_FORMATTER(ProcedureDeclarationStmt) // R1512 +TUPLE_FORMATTER(ProcDecl) // R1515 +TUPLE_FORMATTER(Call) // R1520 & R1521 +TUPLE_FORMATTER(ActualArgSpec) // R1523 +TUPLE_FORMATTER(FunctionSubprogram) // R1529 +TUPLE_FORMATTER(FunctionStmt) // R1530 +TUPLE_FORMATTER(SubroutineSubprogram) // R1534 +TUPLE_FORMATTER(SubroutineStmt) // R1535 +TUPLE_FORMATTER(SeparateModuleSubprogram) // R1538 +TUPLE_FORMATTER(EntryStmt) // R1541 +TUPLE_FORMATTER(StmtFunctionStmt) // R1544 + +// Extensions and legacies +TUPLE_FORMATTER(BasedPointerStmt) +TUPLE_FORMATTER(RedimensionStmt) +TUPLE_FORMATTER(StructureStmt) +TUPLE_FORMATTER(StructureDef) +TUPLE_FORMATTER(Union) +TUPLE_FORMATTER(Map) +TUPLE_FORMATTER(ArithmeticIfStmt) +TUPLE_FORMATTER(AssignStmt) +TUPLE_FORMATTER(AssignedGotoStmt) + +std::ostream &operator<<(std::ostream &o, const Rename::Names &x) { // R1411 + return o << "(Rename::Names " << std::get<0>(x.t) << ' ' + << std::get<1>(x.t) << ')'; +} + +#undef TUPLE_FORMATTER + +// R1302 format-specification +std::ostream &operator<<(std::ostream &o, const FormatSpecification &x) { + return o << "(FormatSpecification " << x.items << ' ' + << x.unlimitedItems << ')'; +} + +// Wrapper class formatting +#define WRAPPER_FORMATTER(TYPE) \ + std::ostream &operator<<(std::ostream &o, const TYPE &x) { \ + return o << "(" #TYPE " " << x.v << ')'; \ + } + +WRAPPER_FORMATTER(Program) // R501 +WRAPPER_FORMATTER(ImplicitPart) // R505 +WRAPPER_FORMATTER(NamedConstant) // R606 +WRAPPER_FORMATTER(DefinedOpName) // R1003, R1023, R1414, R1415 +WRAPPER_FORMATTER(DeclarationTypeSpec::Record) // R703 extension +WRAPPER_FORMATTER(IntrinsicTypeSpec::NCharacter) // R704 extension +WRAPPER_FORMATTER(IntegerTypeSpec) // R705 +WRAPPER_FORMATTER(KindSelector) // R706 +WRAPPER_FORMATTER(HollerithLiteralConstant) // extension +WRAPPER_FORMATTER(LogicalLiteralConstant) // R725 +WRAPPER_FORMATTER(EndTypeStmt) // R730 +WRAPPER_FORMATTER(Pass) // R742 & R752 +WRAPPER_FORMATTER(FinalProcedureStmt) // R753 +WRAPPER_FORMATTER(ComponentDataSource) // R758 +WRAPPER_FORMATTER(EnumeratorDefStmt) // R761 +WRAPPER_FORMATTER(BOZLiteralConstant) // R764, R765, R766, R767 +WRAPPER_FORMATTER(ArrayConstructor) // R769 +WRAPPER_FORMATTER(LanguageBindingSpec) // R808 & R1528 +WRAPPER_FORMATTER(DeferredCoshapeSpecList) // R810 +WRAPPER_FORMATTER(AssumedShapeSpec) // R819 +WRAPPER_FORMATTER(DeferredShapeSpecList) // R820 +WRAPPER_FORMATTER(AssumedImpliedSpec) // R821 +WRAPPER_FORMATTER(ImpliedShapeSpec) // R823 & R824 +WRAPPER_FORMATTER(AllocatableStmt) // R829 +WRAPPER_FORMATTER(AsynchronousStmt) // R831 +WRAPPER_FORMATTER(CodimensionStmt) // R834 +WRAPPER_FORMATTER(ContiguousStmt) // R836 +WRAPPER_FORMATTER(DataStmt) // R837 +WRAPPER_FORMATTER(DimensionStmt) // R848 +WRAPPER_FORMATTER(OptionalStmt) // R850 +WRAPPER_FORMATTER(ParameterStmt) // R851 +WRAPPER_FORMATTER(PointerStmt) // R853 +WRAPPER_FORMATTER(ProtectedStmt) // R855 +WRAPPER_FORMATTER(SaveStmt) // R856 +WRAPPER_FORMATTER(TargetStmt) // R859 +WRAPPER_FORMATTER(ValueStmt) // R861 +WRAPPER_FORMATTER(VolatileStmt) // R862 +WRAPPER_FORMATTER(NamelistStmt) // R868 +WRAPPER_FORMATTER(EquivalenceStmt) // R870, R871 +WRAPPER_FORMATTER(EquivalenceObject) // R872 +WRAPPER_FORMATTER(CharVariable) // R905 +WRAPPER_FORMATTER(ComplexPartDesignator) // R915 +WRAPPER_FORMATTER(TypeParamInquiry) // R916 +WRAPPER_FORMATTER(ArraySection) // R918 +WRAPPER_FORMATTER(ImageSelectorSpec::Stat) // R926 +WRAPPER_FORMATTER(ImageSelectorSpec::Team) // R926 +WRAPPER_FORMATTER(ImageSelectorSpec::Team_Number) // R926 +WRAPPER_FORMATTER(AllocOpt::Mold) // R928 +WRAPPER_FORMATTER(AllocOpt::Source) // R928 +WRAPPER_FORMATTER(StatVariable) // R929 +WRAPPER_FORMATTER(MsgVariable) // R930 & R1207 +WRAPPER_FORMATTER(NullifyStmt) // R939 +WRAPPER_FORMATTER(Expr::Parentheses) // R1001 +WRAPPER_FORMATTER(Expr::UnaryPlus) // R1006, R1009 +WRAPPER_FORMATTER(Expr::Negate) // R1006, R1009 +WRAPPER_FORMATTER(Expr::NOT) // R1014, R1018 +WRAPPER_FORMATTER(Expr::PercentLoc) // extension +WRAPPER_FORMATTER(SpecificationExpr) // R1028 +WRAPPER_FORMATTER(BoundsSpec) // R1035 +WRAPPER_FORMATTER(ElsewhereStmt) // R1048 +WRAPPER_FORMATTER(EndWhereStmt) // R1049 +WRAPPER_FORMATTER(EndForallStmt) // R1054 +WRAPPER_FORMATTER(EndAssociateStmt) // R1106 +WRAPPER_FORMATTER(BlockStmt) // R1108 +WRAPPER_FORMATTER(BlockSpecificationPart) // R1109 +WRAPPER_FORMATTER(EndBlockStmt) // R1110 +WRAPPER_FORMATTER(EndCriticalStmt) // R1118 +WRAPPER_FORMATTER(LocalitySpec::Local) // R1130 +WRAPPER_FORMATTER(LocalitySpec::LocalInit) // R1130 +WRAPPER_FORMATTER(LocalitySpec::Shared) // R1130 +WRAPPER_FORMATTER(EndDoStmt) // R1132 +WRAPPER_FORMATTER(CycleStmt) // R1133 +WRAPPER_FORMATTER(ElseStmt) // R1137 +WRAPPER_FORMATTER(EndIfStmt) // R1138 +WRAPPER_FORMATTER(EndSelectStmt) // R1143, R1151, R1155 +WRAPPER_FORMATTER(ExitStmt) // R1156 +WRAPPER_FORMATTER(GotoStmt) // R1157 +WRAPPER_FORMATTER(SyncAllStmt) // R1164 +WRAPPER_FORMATTER(SyncMemoryStmt) // R1168 +WRAPPER_FORMATTER(FileUnitNumber) // R1202 +WRAPPER_FORMATTER(OpenStmt) // R1204 +WRAPPER_FORMATTER(StatusExpr) // R1205 & seq. +WRAPPER_FORMATTER(ErrLabel) // R1205 & seq. +WRAPPER_FORMATTER(ConnectSpec::Recl) // R1205 +WRAPPER_FORMATTER(ConnectSpec::Newunit) // R1205 +WRAPPER_FORMATTER(CloseStmt) // R1208 +WRAPPER_FORMATTER(IoControlSpec::Asynchronous) // R1213 +WRAPPER_FORMATTER(EndLabel) // R1213 & R1223 +WRAPPER_FORMATTER(EorLabel) // R1213 & R1223 +WRAPPER_FORMATTER(IoControlSpec::Pos) // R1213 +WRAPPER_FORMATTER(IoControlSpec::Rec) // R1213 +WRAPPER_FORMATTER(IoControlSpec::Size) // R1213 +WRAPPER_FORMATTER(IdVariable) // R1214 +WRAPPER_FORMATTER(WaitStmt) // R1222 +WRAPPER_FORMATTER(IdExpr) // R1223 & R1231 +WRAPPER_FORMATTER(FormatStmt) // R1301 +WRAPPER_FORMATTER(EndProgramStmt) // R1403 +WRAPPER_FORMATTER(ModuleStmt) // R1405 +WRAPPER_FORMATTER(EndModuleStmt) // R1406 +WRAPPER_FORMATTER(EndSubmoduleStmt) // R1419 +WRAPPER_FORMATTER(BlockDataStmt) // R1420 +WRAPPER_FORMATTER(EndBlockDataStmt) // R1421 +WRAPPER_FORMATTER(EndInterfaceStmt) // R1504 +WRAPPER_FORMATTER(ExternalStmt) // R1511 +WRAPPER_FORMATTER(IntrinsicStmt) // R1519 +WRAPPER_FORMATTER(FunctionReference) // R1520 +WRAPPER_FORMATTER(CallStmt) // R1521 +WRAPPER_FORMATTER(ActualArg::PercentRef) // R1524 extension +WRAPPER_FORMATTER(ActualArg::PercentVal) // R1524 extension +WRAPPER_FORMATTER(AltReturnSpec) // R1525 +WRAPPER_FORMATTER(EndFunctionStmt) // R1533 +WRAPPER_FORMATTER(EndSubroutineStmt) // R1537 +WRAPPER_FORMATTER(MpSubprogramStmt) // R1539 +WRAPPER_FORMATTER(EndMpSubprogramStmt) // R1540 +WRAPPER_FORMATTER(ReturnStmt) // R1542 +WRAPPER_FORMATTER(PauseStmt) // legacy + +#undef WRAPPER_FORMATTER + +#define EMPTY_TYPE_FORMATTER(TYPE) \ + std::ostream &operator<<(std::ostream &o, const TYPE &) { \ + return o << #TYPE; \ + } + +EMPTY_TYPE_FORMATTER(ErrorRecovery) +EMPTY_TYPE_FORMATTER(Star) // R701, R1215, R1536 +EMPTY_TYPE_FORMATTER(TypeParamValue::Deferred) // R701 +EMPTY_TYPE_FORMATTER(DeclarationTypeSpec::ClassStar) // R703 +EMPTY_TYPE_FORMATTER(DeclarationTypeSpec::TypeStar) // R703 +EMPTY_TYPE_FORMATTER(IntrinsicTypeSpec::DoublePrecision) // R704 +EMPTY_TYPE_FORMATTER(IntrinsicTypeSpec::DoubleComplex) // R704 extension +EMPTY_TYPE_FORMATTER(KindParam::Kanji) // R724 extension +EMPTY_TYPE_FORMATTER(Abstract) // R728 +EMPTY_TYPE_FORMATTER(TypeAttrSpec::BindC) // R728 +EMPTY_TYPE_FORMATTER(Allocatable) // R738 & R802 +EMPTY_TYPE_FORMATTER(Contiguous) // R738 & R802 +EMPTY_TYPE_FORMATTER(SequenceStmt) // R731 +EMPTY_TYPE_FORMATTER(NoPass) // R742 & R752 +EMPTY_TYPE_FORMATTER(Pointer) // R738, R742, R802, & R1514 +EMPTY_TYPE_FORMATTER(PrivateStmt) // R745, R747 +EMPTY_TYPE_FORMATTER(BindAttr::Deferred) // R752 +EMPTY_TYPE_FORMATTER(BindAttr::Non_Overridable) // R752 +EMPTY_TYPE_FORMATTER(EnumDefStmt) // R760 +EMPTY_TYPE_FORMATTER(EndEnumStmt) // R763 +EMPTY_TYPE_FORMATTER(Asynchronous) // R802 +EMPTY_TYPE_FORMATTER(External) // R802 +EMPTY_TYPE_FORMATTER(Intrinsic) // R802 +EMPTY_TYPE_FORMATTER(Optional) // R802 & R1514 +EMPTY_TYPE_FORMATTER(Parameter) // R802 +EMPTY_TYPE_FORMATTER(Protected) // R802 & R1514 +EMPTY_TYPE_FORMATTER(Save) // R802 & R1514 +EMPTY_TYPE_FORMATTER(Target) // R802 +EMPTY_TYPE_FORMATTER(Value) // R802 +EMPTY_TYPE_FORMATTER(Volatile) // R802 +EMPTY_TYPE_FORMATTER(NullInit) // R806 +EMPTY_TYPE_FORMATTER(AssumedRankSpec) // R825 +EMPTY_TYPE_FORMATTER(LocalitySpec::DefaultNone) // R1130 +EMPTY_TYPE_FORMATTER(Default) // R1145, R1150, R1154 +EMPTY_TYPE_FORMATTER(ContinueStmt) // R1159 +EMPTY_TYPE_FORMATTER(FailImageStmt) // R1163 +EMPTY_TYPE_FORMATTER(GenericSpec::Assignment) // R1508 +EMPTY_TYPE_FORMATTER(GenericSpec::ReadFormatted) // R1509 +EMPTY_TYPE_FORMATTER(GenericSpec::ReadUnformatted) // R1509 +EMPTY_TYPE_FORMATTER(GenericSpec::WriteFormatted) // R1509 +EMPTY_TYPE_FORMATTER(GenericSpec::WriteUnformatted) // R1509 +EMPTY_TYPE_FORMATTER(PrefixSpec::Elemental) // R1527 +EMPTY_TYPE_FORMATTER(PrefixSpec::Impure) // R1527 +EMPTY_TYPE_FORMATTER(PrefixSpec::Module) // R1527 +EMPTY_TYPE_FORMATTER(PrefixSpec::Non_Recursive) // R1527 +EMPTY_TYPE_FORMATTER(PrefixSpec::Pure) // R1527 +EMPTY_TYPE_FORMATTER(PrefixSpec::Recursive) // R1527 +EMPTY_TYPE_FORMATTER(ContainsStmt) // R1543 +EMPTY_TYPE_FORMATTER(StructureDef::EndStructureStmt) +EMPTY_TYPE_FORMATTER(Union::UnionStmt) +EMPTY_TYPE_FORMATTER(Union::EndUnionStmt) +EMPTY_TYPE_FORMATTER(Map::MapStmt) +EMPTY_TYPE_FORMATTER(Map::EndMapStmt) + +#undef EMPTY_TYPE_FORMATTER + +// R609 +std::ostream &operator<<(std::ostream &o, + DefinedOperator::IntrinsicOperator x) { + switch (x) { + case DefinedOperator::IntrinsicOperator::Power: return o << "Power"; + case DefinedOperator::IntrinsicOperator::Multiply: return o << "Multiply"; + case DefinedOperator::IntrinsicOperator::Divide: return o << "Divide"; + case DefinedOperator::IntrinsicOperator::Add: return o << "Add"; + case DefinedOperator::IntrinsicOperator::Subtract: return o << "Subtract"; + case DefinedOperator::IntrinsicOperator::Concat: return o << "Concat"; + case DefinedOperator::IntrinsicOperator::LT: return o << "LT"; + case DefinedOperator::IntrinsicOperator::LE: return o << "LE"; + case DefinedOperator::IntrinsicOperator::EQ: return o << "EQ"; + case DefinedOperator::IntrinsicOperator::NE: return o << "NE"; + case DefinedOperator::IntrinsicOperator::GE: return o << "GE"; + case DefinedOperator::IntrinsicOperator::GT: return o << "GT"; + case DefinedOperator::IntrinsicOperator::NOT: return o << "NOT"; + case DefinedOperator::IntrinsicOperator::AND: return o << "AND"; + case DefinedOperator::IntrinsicOperator::OR: return o << "OR"; + case DefinedOperator::IntrinsicOperator::EQV: return o << "EQV"; + case DefinedOperator::IntrinsicOperator::NEQV: return o << "NEQV"; + DEFAULT_CRASH; + } + return o; +} + +// R703 +std::ostream &operator<<(std::ostream &o, const DeclarationTypeSpec::Type &x) { + return o << "(DeclarationTypeSpec TYPE " << x.derived << ')'; +} + +std::ostream &operator<<(std::ostream &o, const DeclarationTypeSpec::Class &x) { + return o << "(DeclarationTypeSpec CLASS " << x.derived << ')'; +} + +// R704 +std::ostream &operator<<(std::ostream &o, const IntrinsicTypeSpec::Real &x) { + return o << "(Real " << x.kind << ')'; +} + +std::ostream &operator<<(std::ostream &o, const IntrinsicTypeSpec::Complex &x) { + return o << "(Complex " << x.kind << ')'; +} + +std::ostream &operator<<(std::ostream &o, + const IntrinsicTypeSpec::Character &x) { + return o << "(Character " << x.selector << ')'; +} + +std::ostream &operator<<(std::ostream &o, const IntrinsicTypeSpec::Logical &x) { + return o << "(Logical " << x.kind << ')'; +} + +// R706 +// TODO: Abstract part of this away to utility functions &/or constructors +KindSelector::KindSelector(std::uint64_t &&k) + : v{IntConstantExpr{ConstantExpr{Indirection{ + Expr{LiteralConstant{IntLiteralConstant{std::move(k)}}}}}}} {} + +// R712 sign +std::ostream &operator<<(std::ostream &o, Sign x) { + switch (x) { + case Sign::Positive: return o << "Positive"; + case Sign::Negative: return o << "Negative"; + DEFAULT_CRASH; + } + return o; +} + +// R714 real-literal-constant +// R715 significand +static std::string charListToString(std::list &&cs) { + std::string result; + for (auto ch : cs) { + result += ch; + } + return result; +} + +RealLiteralConstant::RealLiteralConstant(std::list &&i, + std::list &&f, + std::optional &&expo, + std::optional &&k) + : intPart{charListToString(std::move(i))}, + fraction{charListToString(std::move(f))}, + exponent(std::move(expo)), kind(std::move(k)) {} + +RealLiteralConstant::RealLiteralConstant(std::list &&f, + std::optional &&expo, + std::optional &&k) + : fraction{charListToString(std::move(f))}, + exponent(std::move(expo)), kind(std::move(k)) {} + +RealLiteralConstant::RealLiteralConstant(std::list &&i, + ExponentPart &&expo, + std::optional &&k) + : intPart{charListToString(std::move(i))}, + exponent(std::move(expo)), kind(std::move(k)) {} + +std::ostream &operator<<(std::ostream &o, const RealLiteralConstant &x) { + return o << "(RealLiteralConstant " << x.intPart << ' ' << x.fraction << ' ' + << x.exponent << ' ' << x.kind << ')'; +} + +// R721 char-selector +std::ostream &operator<<(std::ostream &o, + const CharSelector::LengthAndKind &x) { + return o << "(LengthAndKind " << x.length << ' ' << x.kind << ')'; +} + +// R728 type-attr-spec +std::ostream &operator<<(std::ostream &o, const TypeAttrSpec::Extends &x) { + return o << "(Extends " << x.name << ')'; +} + +// R734 type-param-attr-spec +std::ostream &operator<<(std::ostream &o, + const TypeParamDefStmt::KindOrLength &x) { + switch (x) { + case TypeParamDefStmt::KindOrLength::Kind: o << "Kind"; break; + case TypeParamDefStmt::KindOrLength::Length: o << "Length"; break; + DEFAULT_CRASH; + } + return o; +} + +// R749 type-bound-procedure-stmt +std::ostream &operator<<(std::ostream &o, + const TypeBoundProcedureStmt::WithoutInterface &x) { + return o << "(TypeBoundProcedureStmt () " << x.attributes << ' ' << + x.declarations << ')'; +} + +std::ostream &operator<<(std::ostream &o, + const TypeBoundProcedureStmt::WithInterface &x) { + return o << "(TypeBoundProcedureStmt " << x.interfaceName << ' ' << + x.attributes << ' ' << x.bindingNames << ')'; +} + +// R770 ac-spec +std::ostream &operator<<(std::ostream &o, const AcSpec &x) { + return o << "(AcSpec " << x.type << ' ' << x.values << ')'; +} + +// R807 access-spec +std::ostream &operator<<(std::ostream &o, const AccessSpec &x) { + switch (x.v) { + case AccessSpec::Kind::Public: return o << "(Public)"; + case AccessSpec::Kind::Private: return o << "(Private)"; + DEFAULT_CRASH; + } + return o; +} + +// R826 intent-spec +std::ostream &operator<<(std::ostream &o, const IntentSpec &x) { + switch (x.v) { + case IntentSpec::Intent::In: return o << "(Intent In)"; + case IntentSpec::Intent::Out: return o << "(Intent Out)"; + case IntentSpec::Intent::InOut: return o << "(Intent InOut)"; + DEFAULT_CRASH; + } + return o; +} + +// R863 implicit-stmt +std::ostream &operator<<(std::ostream &o, const ImplicitStmt &x) { + o << "(ImplicitStmt "; + if (std::holds_alternative< + std::list>(x.u)) { + o << "NONE "; + } + std::visit([&o](auto &&y){ o << y; }, x.u); + return o << ')'; +} + +// R866 +std::ostream &operator<<(std::ostream &o, + ImplicitStmt::ImplicitNoneNameSpec x) { + switch (x) { + case ImplicitStmt::ImplicitNoneNameSpec::External: return o << "External"; + case ImplicitStmt::ImplicitNoneNameSpec::Type: return o << "Type"; + DEFAULT_CRASH; + } + return o; +} + +// R867 +ImportStmt::ImportStmt(Kind &&k, std::list &&n) + : kind{k}, names(std::move(n)) { + CHECK(kind == Kind::Default || kind == Kind::Only || names.empty()); +} + +std::ostream &operator<<(std::ostream &o, const ImportStmt &x) { + o << "(ImportStmt "; + switch (x.kind) { + case ImportStmt::Kind::Default: + return o << x.names << ')'; + case ImportStmt::Kind::Only: + return o << "Only " << x.names << ')'; + case ImportStmt::Kind::None: + return o << "None)"; + case ImportStmt::Kind::All: + return o << "All)"; + DEFAULT_CRASH; + } + return o; +} + +// R901 designator +bool Designator::EndsInBareName() const { + return std::visit(visitors{ + [](const ObjectName &){ return true; }, + [](const DataReference &dr){ + return std::holds_alternative(dr.u) || + std::holds_alternative>(dr.u); + }, + [](const Substring &){ return false; }}, + u); +} + +ProcedureDesignator Designator::ConvertToProcedureDesignator() { + return std::visit(visitors{ + [](ObjectName &n) -> ProcedureDesignator { return {std::move(n)}; }, + [](DataReference &dr) -> ProcedureDesignator { + if (Name *n = std::get_if(&dr.u)) { + return {std::move(*n)}; + } + StructureComponent + &sc{*std::get>(dr.u)}; + return {ProcComponentRef{Scalar{ + Indirection{std::move(sc.base)}}, + std::move(sc.component)}}; + }, + [](Substring &) -> ProcedureDesignator { + CHECK(!"can't get here"); + return {Name{""}}; + }}, + u); +} + +std::optional Designator::ConvertToCall() { + return std::visit(visitors{ + [](ObjectName &n) -> std::optional { + return {Call{ProcedureDesignator{std:move(n)}, + std::list{}}}; + }, + [this](DataReference &dr) -> std::optional { + if (std::holds_alternative>(dr.u)) { + return {}; + } + if (Name *n = std::get_if(&dr.u)) { + return {Call{ProcedureDesignator{std::move(*n)}, + std::list{}}}; + } + if (auto *isc = std::get_if>(&dr.u)) { + StructureComponent &sc{**isc}; + Variable var{Indirection{std::move(sc.base)}}; + ProcComponentRef pcr{Scalar{std::move(var)}, + std::move(sc.component)}; + return {Call{ProcedureDesignator{std::move(pcr)}, + std::list{}}}; + } + ArrayElement &ae{*std::get>(dr.u)}; + if (std::any_of(ae.subscripts.begin(), ae.subscripts.end(), + [](const SectionSubscript &ss){ + return !ss.CanConvertToActualArgument(); })) { + return {}; + } + std::list args; + for (auto &ss : ae.subscripts) { + args.emplace_back(std::optional{}, + ss.ConvertToActualArgument()); + } + if (Name *n{std::get_if(&ae.base.u)}) { + return {Call{ProcedureDesignator{std::move(*n)}, std::move(args)}}; + } + StructureComponent + &bsc{*std::get>(ae.base.u)}; + Variable var{Indirection{std::move(bsc.base)}}; + ProcComponentRef pcr{Scalar{std::move(var)}, + std::move(bsc.component)}; + return {Call{ProcedureDesignator{std::move(pcr)}, + std::move(args)}}; + }, + [](const Substring &) -> std::optional { return {}; }}, + u); +} + +// R911 data-ref -> part-ref [% part-ref]... +DataReference::DataReference(std::list &&prl) + : u{std::move(prl.front().name)} { + for (bool first{true}; !prl.empty(); first = false, prl.pop_front()) { + PartRef &pr{prl.front()}; + if (!first) { + u = Indirection{ + std::move(*this), std::move(pr.name)}; + } + if (!pr.subscripts.empty()) { + u = Indirection{ + std::move(*this), std::move(pr.subscripts)}; + } + if (pr.imageSelector.has_value()) { + u = Indirection{ + std::move(*this), std::move(*pr.imageSelector)}; + } + } +} + +// R913 structure-component -> data-ref +std::ostream &operator<<(std::ostream &o, const StructureComponent &x) { + return o << "(StructureComponent " << x.base << ' ' << x.component << ')'; +} + +// R914 coindexed-named-object -> data-ref +std::ostream &operator<<(std::ostream &o, const CoindexedNamedObject &x) { + return o << "(CoindexedNamedObject " << x.base << ' ' + << x.imageSelector << ')'; +} + +// R912 part-ref +std::ostream &operator<<(std::ostream &o, const PartRef &pr) { + return o << "(PartRef " << pr.name << ' ' << pr.subscripts << ' ' + << pr.imageSelector << ')'; +} + +// R917 array-element -> data-ref +std::ostream &operator<<(std::ostream &o, const ArrayElement &x) { + return o << "(ArrayElement " << x.base << ' ' << x.subscripts << ')'; +} + +// R920 section-subscript +bool SectionSubscript::CanConvertToActualArgument() const { + return std::visit(visitors{ + [](const VectorSubscript &){ return true; }, + [](const ScalarIntExpr &){ return true; }, + [](const SubscriptTriplet &){ return false; }}, + u); +} + +ActualArg SectionSubscript::ConvertToActualArgument() { + return std::visit(visitors{ + [](VectorSubscript &vs) -> ActualArg { + return vs.thing->ConvertToActualArgument(); + }, + [](ScalarIntExpr &vs) -> ActualArg { + return vs.thing.thing->ConvertToActualArgument(); + }, + [](SubscriptTriplet &) -> ActualArg { + CHECK(!"can't happen"); + return {Name{"bad"}}; + }}, + u); +} + +// R1001 - R1022 expression +Expr::Expr(Designator &&x) : u{Indirection(std::move(x))} {} +Expr::Expr(FunctionReference &&x) + : u{Indirection(std::move(x))} {} + +std::optional Expr::ConvertToVariable() { + if (Indirection *id = std::get_if>(&u)) { + return {Variable{std::move(*id)}}; + } + if (Indirection *ifr = + std::get_if>(&u)) { + return {Variable{std::move(*ifr)}}; + } + return {}; +} + +ActualArg Expr::ConvertToActualArgument() { + if (std::optional var{ConvertToVariable()}) { + return {std::move(var.value())}; + } + return {std::move(*this)}; +} + +// R1146 +std::ostream &operator<<(std::ostream &o, const CaseValueRange::Range &x) { + return o << "(Range " << x.lower << ' ' << x.upper << ')'; +} + +// R1205 +std::ostream &operator<<(std::ostream &o, const ConnectSpec::CharExpr::Kind x) { + switch (x) { + case ConnectSpec::CharExpr::Kind::Access: o << "Access"; break; + case ConnectSpec::CharExpr::Kind::Action: o << "Action"; break; + case ConnectSpec::CharExpr::Kind::Asynchronous: o << "Asynchronous"; break; + case ConnectSpec::CharExpr::Kind::Blank: o << "Blank"; break; + case ConnectSpec::CharExpr::Kind::Decimal: o << "Decimal"; break; + case ConnectSpec::CharExpr::Kind::Delim: o << "Delim"; break; + case ConnectSpec::CharExpr::Kind::Encoding: o << "Encoding"; break; + case ConnectSpec::CharExpr::Kind::Form: o << "Form"; break; + case ConnectSpec::CharExpr::Kind::Pad: o << "Pad"; break; + case ConnectSpec::CharExpr::Kind::Position: o << "Position"; break; + case ConnectSpec::CharExpr::Kind::Round: o << "Round"; break; + case ConnectSpec::CharExpr::Kind::Sign: o << "Sign"; break; + case ConnectSpec::CharExpr::Kind::Dispose: o << "Dispose"; break; + DEFAULT_CRASH; + } + return o; +} + +// R1213 +std::ostream &operator<<(std::ostream &o, IoControlSpec::CharExpr::Kind x) { + switch (x) { + case IoControlSpec::CharExpr::Kind::Advance: o << "Advance"; break; + case IoControlSpec::CharExpr::Kind::Blank: o << "Blank"; break; + case IoControlSpec::CharExpr::Kind::Decimal: o << "Decimal"; break; + case IoControlSpec::CharExpr::Kind::Delim: o << "Delim"; break; + case IoControlSpec::CharExpr::Kind::Pad: o << "Pad"; break; + case IoControlSpec::CharExpr::Kind::Round: o << "Round"; break; + case IoControlSpec::CharExpr::Kind::Sign: o << "Sign"; break; + DEFAULT_CRASH; + } + return o; +} + +// R1231 +std::ostream &operator<<(std::ostream &o, const InquireSpec::CharVar::Kind x) { + switch (x) { + case InquireSpec::CharVar::Kind::Access: o << "Access"; break; + case InquireSpec::CharVar::Kind::Action: o << "Action"; break; + case InquireSpec::CharVar::Kind::Asynchronous: o << "Asynchronous"; break; + case InquireSpec::CharVar::Kind::Blank: o << "Blank"; break; + case InquireSpec::CharVar::Kind::Decimal: o << "Decimal"; break; + case InquireSpec::CharVar::Kind::Delim: o << "Delim"; break; + case InquireSpec::CharVar::Kind::Encoding: o << "Encoding"; break; + case InquireSpec::CharVar::Kind::Form: o << "Form"; break; + case InquireSpec::CharVar::Kind::Formatted: o << "Formatted"; break; + case InquireSpec::CharVar::Kind::Iomsg: o << "Iomsg"; break; + case InquireSpec::CharVar::Kind::Name: o << "Name"; break; + case InquireSpec::CharVar::Kind::Pad: o << "Pad"; break; + case InquireSpec::CharVar::Kind::Position: o << "Position"; break; + case InquireSpec::CharVar::Kind::Read: o << "Read"; break; + case InquireSpec::CharVar::Kind::Readwrite: o << "Readwrite"; break; + case InquireSpec::CharVar::Kind::Round: o << "Round"; break; + case InquireSpec::CharVar::Kind::Sequential: o << "Sequential"; break; + case InquireSpec::CharVar::Kind::Sign: o << "Sign"; break; + case InquireSpec::CharVar::Kind::Stream: o << "Stream"; break; + case InquireSpec::CharVar::Kind::Status: o << "Status"; break; + case InquireSpec::CharVar::Kind::Write: o << "Write"; break; + DEFAULT_CRASH; + } + return o; +} + +std::ostream &operator<<(std::ostream &o, const InquireSpec::IntVar::Kind x) { + switch (x) { + case InquireSpec::IntVar::Kind::Iostat: o << "Iostat"; break; + case InquireSpec::IntVar::Kind::Nextrec: o << "Nextrec"; break; + case InquireSpec::IntVar::Kind::Number: o << "Number"; break; + case InquireSpec::IntVar::Kind::Pos: o << "Pos"; break; + case InquireSpec::IntVar::Kind::Recl: o << "Recl"; break; + case InquireSpec::IntVar::Kind::Size: o << "Size"; break; + DEFAULT_CRASH; + } + return o; +} + +std::ostream &operator<<(std::ostream &o, const InquireSpec::LogVar::Kind x) { + switch (x) { + case InquireSpec::LogVar::Kind::Exist: o << "Exist"; break; + case InquireSpec::LogVar::Kind::Named: o << "Named"; break; + case InquireSpec::LogVar::Kind::Opened: o << "Opened"; break; + case InquireSpec::LogVar::Kind::Pending: o << "Pending"; break; + DEFAULT_CRASH; + } + return o; +} + +// R1307 data-edit-desc (part 1 of 2) +std::ostream &operator<<(std::ostream &o, const IntrinsicTypeDataEditDesc &x) { + o << "(IntrinsicTypeDataEditDesc "; + switch (x.kind) { + case IntrinsicTypeDataEditDesc::Kind::I: o << "I "; break; + case IntrinsicTypeDataEditDesc::Kind::B: o << "B "; break; + case IntrinsicTypeDataEditDesc::Kind::O: o << "O "; break; + case IntrinsicTypeDataEditDesc::Kind::Z: o << "Z "; break; + case IntrinsicTypeDataEditDesc::Kind::F: o << "F "; break; + case IntrinsicTypeDataEditDesc::Kind::E: o << "E "; break; + case IntrinsicTypeDataEditDesc::Kind::EN: o << "EN "; break; + case IntrinsicTypeDataEditDesc::Kind::ES: o << "ES "; break; + case IntrinsicTypeDataEditDesc::Kind::EX: o << "EX "; break; + case IntrinsicTypeDataEditDesc::Kind::G: o << "G "; break; + case IntrinsicTypeDataEditDesc::Kind::L: o << "L "; break; + case IntrinsicTypeDataEditDesc::Kind::A: o << "A "; break; + case IntrinsicTypeDataEditDesc::Kind::D: o << "D "; break; + DEFAULT_CRASH; + } + return o << x.width << ' ' << x.digits << ' ' << x.exponentWidth << ')'; +} + +// R1160, R1161 +std::ostream &operator<<(std::ostream &o, StopStmt::Kind x) { + switch (x) { + case StopStmt::Kind::Stop: o << "Stop"; break; + case StopStmt::Kind::ErrorStop: o << "ErrorStop"; break; + DEFAULT_CRASH; + } + return o; +} + +// R1210 read-stmt +std::ostream &operator<<(std::ostream &o, const ReadStmt &x) { + return o << "(ReadStmt " << x.iounit << ' ' << x.format << ' ' << x.controls + << ' ' << x.items << ')'; +} + +// R1211 write-stmt +std::ostream &operator<<(std::ostream &o, const WriteStmt &x) { + return o << "(WriteStmt " << x.iounit << ' ' << x.format << ' ' << x.controls + << ' ' << x.items << ')'; +} + +// R1307 data-edit-desc (part 2 of 2) +std::ostream &operator<<(std::ostream &o, const DerivedTypeDataEditDesc &x) { + return o << "(DerivedTypeDataEditDesc " << x.type << ' ' << x.parameters + << ')'; +} + +// R1313 control-edit-desc +std::ostream &operator<<(std::ostream &o, const ControlEditDesc &x) { + o << "(ControlEditDesc "; + switch (x.kind) { + case ControlEditDesc::Kind::T: o << "T "; break; + case ControlEditDesc::Kind::TL: o << "TL "; break; + case ControlEditDesc::Kind::TR: o << "TR "; break; + case ControlEditDesc::Kind::X: o << "X "; break; + case ControlEditDesc::Kind::Slash: o << "/ "; break; + case ControlEditDesc::Kind::Colon: o << ": "; break; + case ControlEditDesc::Kind::SS: o << "SS "; break; + case ControlEditDesc::Kind::SP: o << "SP "; break; + case ControlEditDesc::Kind::S: o << "S "; break; + case ControlEditDesc::Kind::P: o << "P "; break; + case ControlEditDesc::Kind::BN: o << "BN "; break; + case ControlEditDesc::Kind::BZ: o << "BZ "; break; + case ControlEditDesc::Kind::RU: o << "RU "; break; + case ControlEditDesc::Kind::RD: o << "RD "; break; + case ControlEditDesc::Kind::RN: o << "RN "; break; + case ControlEditDesc::Kind::RC: o << "RC "; break; + case ControlEditDesc::Kind::RP: o << "RP "; break; + case ControlEditDesc::Kind::DC: o << "DC "; break; + case ControlEditDesc::Kind::DP: o << "DP "; break; + DEFAULT_CRASH; + } + return o << x.count << ')'; +} + +// R1304 format-item +std::ostream &operator<<(std::ostream &o, const FormatItem &x) { + o << "(FormatItem " << x.repeatCount; + std::visit([&o](const auto &y){ o << y; }, x.u); + return o << ')'; +} + +// R1409, R1410 +std::ostream &operator<<(std::ostream &o, const UseStmt &x) { + o << "(UseStmt "; + if (x.nature) { + switch (*x.nature) { + case UseStmt::ModuleNature::Intrinsic: + o << "Intrinsic"; + break; + case UseStmt::ModuleNature::Non_Intrinsic: + o << "Non_Intrinsic"; + break; + DEFAULT_CRASH; + } + } else { + o << "()"; + } + o << ' ' << x.moduleName << ' '; + std::visit(visitors{ + [&o](const std::list &y) -> void { o << "RENAME " << y; }, + [&o](const std::list &y) -> void { o << "ONLY " << y; }, + }, x.u); + return o << ')'; +} + +// R1506 +std::ostream &operator<<(std::ostream &o, const ProcedureStmt::Kind &x) { + switch (x) { + case ProcedureStmt::Kind::ModuleProcedure: return o << "ModuleProcedure"; + case ProcedureStmt::Kind::Procedure: return o << "Procedure"; + DEFAULT_CRASH; + } + return o; +} + +std::ostream &operator<<(std::ostream &o, const ProcedureStmt &x) { + return o << "(ProcedureStmt " << std::get<0>(x.t) << ' ' + << std::get<1>(x.t) << ')'; +} + +// R1532 suffix +std::ostream &operator<<(std::ostream &o, const Suffix &x) { + return o << "(Suffix " << x.binding << ' ' << x.resultName << ')'; +} +} // namespace Fortran diff --git a/flang/parse-tree.h b/flang/parse-tree.h new file mode 100644 index 0000000..1dbccae --- /dev/null +++ b/flang/parse-tree.h @@ -0,0 +1,3164 @@ +#ifndef FORTRAN_PARSE_TREE_H_ +#define FORTRAN_PARSE_TREE_H_ + +// Defines the classes used to represent successful reductions of productions +// in the Fortran grammar. The names and content of these definitions +// adhere closely to the syntax specifications in the language standard (q.v.) +// that are transcribed here and referenced via their requirement numbers. +// The representations of some productions that may also be of use in the +// run-time I/O support library have been isolated into a distinct header file +// (viz. format-specification.h). + +#include "format-specification.h" +#include "idioms.h" +#include "indirection.h" +#include "message.h" +#include "position.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Parse tree node class types do not have default constructors. They +// explicitly declare "T() {} = delete;" to make this clear. This restriction +// avoids what would otherwise become a viral requirement to include +// std::monostate among most std::variant<> discriminated union members. + +// Parse tree node class types do not have copy constructors or copy assignment +// operators. They are explicitly declared "= delete;" to make this clear, +// although a C++ compiler wouldn't default them anyway due to the presence +// of move constructors and move assignments. + +// Most non-template classes in this file use these default definitions +// for their move constructor and move assignment operator=, and should +// declare an operator<< for formatting. +#define BOILERPLATE(classname) \ + classname(classname &&) = default; \ + classname &operator=(classname &&) = default; \ + friend std::ostream &operator<<(std::ostream &, const classname &); \ + classname() = delete; \ + classname(const classname &) = delete; \ + classname &operator=(const classname &) = delete + +// Empty classes are often used below as alternatives in std::variant<> +// discriminated unions. +#define EMPTY_CLASS(classname) \ + struct classname { \ + classname() {} \ + classname(const classname &) {} \ + classname(classname &&) {} \ + classname &operator=(const classname &) { return *this; }; \ + classname &operator=(classname &&) { return *this; }; \ + friend std::ostream &operator<<(std::ostream &, const classname &); \ + } + +// Many classes below simply wrap a std::variant<> discriminated union, +// which is conventionally named "u". +#define UNION_CLASS_BOILERPLATE(classname) \ + BOILERPLATE(classname); \ + template classname(A &&x) : u(std::move(x)) {} + +// Many other classes below simply wrap a std::tuple<> structure, which +// is conventionally named "t". +#define TUPLE_CLASS_BOILERPLATE(classname) \ + BOILERPLATE(classname); \ + template classname(Ts &&...args) \ + : t(std::forward(args)...) {} + +// Many other classes below simply wrap a single data member, which is +// conventionally named "v". +#define WRAPPER_CLASS_BOILERPLATE(classname, type) \ + BOILERPLATE(classname); \ + classname(type &&x) : v(std::move(x)) {} \ + type v; + +#define WRAPPER_CLASS(classname, type) \ + struct classname { WRAPPER_CLASS_BOILERPLATE(classname, type); } + +namespace Fortran { + +// These are the unavoidable recursively-defined productions of Fortran. +// Some references to the representations of their parses require +// indirection. The Indirect<> pointer wrapper class is used to +// enforce ownership semantics and non-nullability. +struct SpecificationPart; // R504 +struct ExecutableConstruct; // R514 +struct ActionStmt; // R515 +struct AcImpliedDo; // R774 +struct DataImpliedDo; // R840 +struct Designator; // R901 +struct Variable; // R902 +struct Expr; // R1001 +struct WhereConstruct; // R1042 +struct ForallConstruct; // R1050 +struct InputImpliedDo; // R1218 +struct OutputImpliedDo; // R1218 +struct FormatItems; // R1303 +struct FunctionReference; // R1520 +struct FunctionSubprogram; // R1529 +struct SubroutineSubprogram; // R1534 + +// These additional forward references are declared so that the order of +// class definitions in this header file can remain reasonably consistent +// with order of the the requirement productions in the grammar. +struct DerivedTypeDef; // R726 +struct EnumDef; // R759 +struct TypeDeclarationStmt; // R801 +struct AccessStmt; // R827 +struct AllocatableStmt; // R829 +struct AsynchronousStmt; // R831 +struct BindStmt; // R832 +struct CodimensionStmt; // R834 +struct ContiguousStmt; // R836 +struct DataStmt; // R837 +struct DataStmtValue; // R843 +struct DimensionStmt; // R848 +struct IntentStmt; // R849 +struct OptionalStmt; // R850 +struct ParameterStmt; // R851 +struct PointerStmt; // R853 +struct ProtectedStmt; // R855 +struct SaveStmt; // R856 +struct TargetStmt; // R859 +struct ValueStmt; // R861 +struct VolatileStmt; // R862 +struct ImplicitStmt; // R863 +struct ImportStmt; // R867 +struct NamelistStmt; // R868 +struct EquivalenceStmt; // R870 +struct CommonStmt; // R873 +struct Substring; // R908 +struct CharLiteralConstantSubstring; +struct DataReference; // R911 +struct StructureComponent; // R913 +struct CoindexedNamedObject; // R914 +struct TypeParamInquiry; // R916 +struct ArrayElement; // R917 +struct AllocateStmt; // R927 +struct NullifyStmt; // R939 +struct DeallocateStmt; // R941 +struct AssignmentStmt; // R1032 +struct PointerAssignmentStmt; // R1033 +struct WhereStmt; // R1041, R1045, R1046 +struct ForallStmt; // R1055 +struct AssociateConstruct; // R1102 +struct BlockConstruct; // R1107 +struct ChangeTeamConstruct; // R1111 +struct CriticalConstruct; // R1116 +struct DoConstruct; // R1119 +struct LabelDoStmt; // R1121 +struct ConcurrentHeader; // R1125 +struct EndDoStmt; // R1132 +struct CycleStmt; // R1133 +struct IfConstruct; // R1134 +struct IfStmt; // R1139 +struct CaseConstruct; // R1140 +struct SelectRankConstruct; // R1148 +struct SelectTypeConstruct; // R1152 +struct ExitStmt; // R1156 +struct GotoStmt; // R1157 +struct ComputedGotoStmt; // R1158 +struct StopStmt; // R1160, R1161 +struct SyncAllStmt; // R1164 +struct SyncImagesStmt; // R1166 +struct SyncMemoryStmt; // R1168 +struct SyncTeamStmt; // R1169 +struct EventPostStmt; // R1170, R1171 +struct EventWaitStmt; // R1172, R1173, R1174 +struct FormTeamStmt; // R1175, R1176, R1177 +struct LockStmt; // R1178 +struct UnlockStmt; // R1180 +struct OpenStmt; // R1204 +struct CloseStmt; // R1208 +struct ReadStmt; // R1210 +struct WriteStmt; // R1211 +struct PrintStmt; // R1212 +struct WaitStmt; // R1222 +struct BackspaceStmt; // R1224 +struct EndfileStmt; // R1225 +struct RewindStmt; // R1226 +struct FlushStmt; // R1228 +struct InquireStmt; // R1230 +struct FormatStmt; // R1301 +struct MainProgram; // R1401 +struct Module; // R1404 +struct UseStmt; // R1409 +struct Submodule; // R1416 +struct BlockData; // R1420 +struct InterfaceBlock; // R1501 +struct GenericSpec; // R1508 +struct GenericStmt; // R1510 +struct ExternalStmt; // R1511 +struct ProcedureDeclarationStmt; // R1512 +struct IntrinsicStmt; // R1519 +struct Call; // R1520 & R1521 +struct CallStmt; // R1521 +struct ProcedureDesignator; // R1522 +struct ActualArg; // R1524 +struct SeparateModuleSubprogram; // R1538 +struct EntryStmt; // R1541 +struct ReturnStmt; // R1542 +struct StmtFunctionStmt; // R1544 + +// Extension and deprecated statements +struct BasedPointerStmt; +struct RedimensionStmt; +struct StructureDef; +struct ArithmeticIfStmt; +struct AssignStmt; +struct AssignedGotoStmt; +struct PauseStmt; + +// Implicit definitions of the Standard +using Keyword = std::string; + +// R403 scalar-xyz -> xyz +// These template class wrappers correspond to the Standard's modifiers +// scalar-xyz, constant-xzy, int-xzy, default-char-xyz, & logical-xyz. +template +struct Scalar { + Scalar(Scalar &&that) = default; + Scalar(A &&that) : thing(std::move(that)) {} + Scalar &operator=(Scalar &&) = default; + A thing; +}; + +template +struct Constant { + Constant(Constant &&that) = default; + Constant(A &&that) : thing(std::move(that)) {} + Constant &operator=(Constant &&) = default; + A thing; +}; + +template +struct Integer { + Integer(Integer &&that) = default; + Integer(A &&that) : thing(std::move(that)) {} + Integer &operator=(Integer &&) = default; + A thing; +}; + +template +struct Logical { + Logical(Logical &&that) = default; + Logical(A &&that) : thing(std::move(that)) {} + Logical &operator=(Logical &&) = default; + A thing; +}; + +template +struct DefaultChar { + DefaultChar(DefaultChar &&that) = default; + DefaultChar(A &&that) : thing(std::move(that)) {} + DefaultChar &operator=(DefaultChar &&) = default; + A thing; +}; + +using LogicalExpr = Logical>; // R1024 +using DefaultCharExpr = DefaultChar>; // R1025 +using IntExpr = Integer>; // R1026 +using ConstantExpr = Constant>; // R1029 +using IntConstantExpr = Integer; // R1031 +using ScalarLogicalExpr = Scalar; +using ScalarIntExpr = Scalar; +using ScalarIntConstantExpr = Scalar; +using ScalarDefaultCharExpr = Scalar; +// R1030 default-char-constant-expr is used in the Standard only as part of +// scalar-default-char-constant-expr. +using ScalarDefaultCharConstantExpr = Scalar>; + +// R611 label -> digit [digit]... +using Label = std::uint64_t; // validated later, must be in [1..99999] + +// A wrapper for xzy-stmt productions that are statements, so that +// source positions and labels have a uniform representation. +template +struct Statement { + Statement(Position &&pos, std::optional &&lab, bool &&accept, A &&s) + : position(std::move(pos)), label(std::move(lab)), + isLabelInAcceptableField{accept}, statement(std::move(s)) {} + Position position; + std::optional