xref: /llvm-project/flang/lib/Parser/unparse.cpp (revision 15ab7be2e049bc0f4ea6744ca037395686a923bc)
164ab3302SCarolineConcatto //===-- lib/Parser/unparse.cpp --------------------------------------------===//
264ab3302SCarolineConcatto //
364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information.
564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
664ab3302SCarolineConcatto //
764ab3302SCarolineConcatto //===----------------------------------------------------------------------===//
864ab3302SCarolineConcatto 
964ab3302SCarolineConcatto // Generates Fortran from the content of a parse tree, using the
1064ab3302SCarolineConcatto // traversal templates in parse-tree-visitor.h.
1164ab3302SCarolineConcatto 
1264ab3302SCarolineConcatto #include "flang/Parser/unparse.h"
1364ab3302SCarolineConcatto #include "flang/Common/Fortran.h"
1464ab3302SCarolineConcatto #include "flang/Common/idioms.h"
1564ab3302SCarolineConcatto #include "flang/Common/indirection.h"
1664ab3302SCarolineConcatto #include "flang/Parser/characters.h"
1764ab3302SCarolineConcatto #include "flang/Parser/parse-tree-visitor.h"
1864ab3302SCarolineConcatto #include "flang/Parser/parse-tree.h"
1992d27b96SJean Perier #include "flang/Parser/tools.h"
208670e499SCaroline Concatto #include "llvm/Support/raw_ostream.h"
2164ab3302SCarolineConcatto #include <algorithm>
2264ab3302SCarolineConcatto #include <cinttypes>
2364ab3302SCarolineConcatto #include <cstddef>
2464ab3302SCarolineConcatto #include <set>
2564ab3302SCarolineConcatto 
2664ab3302SCarolineConcatto namespace Fortran::parser {
2764ab3302SCarolineConcatto 
2864ab3302SCarolineConcatto class UnparseVisitor {
2964ab3302SCarolineConcatto public:
308670e499SCaroline Concatto   UnparseVisitor(llvm::raw_ostream &out, int indentationAmount,
318670e499SCaroline Concatto       Encoding encoding, bool capitalize, bool backslashEscapes,
328670e499SCaroline Concatto       preStatementType *preStatement, AnalyzedObjectsAsFortran *asFortran)
3364ab3302SCarolineConcatto       : out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding},
3464ab3302SCarolineConcatto         capitalizeKeywords_{capitalize}, backslashEscapes_{backslashEscapes},
3564ab3302SCarolineConcatto         preStatement_{preStatement}, asFortran_{asFortran} {}
3664ab3302SCarolineConcatto 
3764ab3302SCarolineConcatto   // In nearly all cases, this code avoids defining Boolean-valued Pre()
3864ab3302SCarolineConcatto   // callbacks for the parse tree walking framework in favor of two void
3964ab3302SCarolineConcatto   // functions, Before() and Unparse(), which imply true and false return
4064ab3302SCarolineConcatto   // values for Pre() respectively.
4164ab3302SCarolineConcatto   template <typename T> void Before(const T &) {}
4264ab3302SCarolineConcatto   template <typename T> double Unparse(const T &); // not void, never used
4364ab3302SCarolineConcatto 
4464ab3302SCarolineConcatto   template <typename T> bool Pre(const T &x) {
4564ab3302SCarolineConcatto     if constexpr (std::is_void_v<decltype(Unparse(x))>) {
4664ab3302SCarolineConcatto       // There is a local definition of Unparse() for this type.  It
4764ab3302SCarolineConcatto       // overrides the parse tree walker's default Walk() over the descendents.
4864ab3302SCarolineConcatto       Before(x);
4964ab3302SCarolineConcatto       Unparse(x);
5064ab3302SCarolineConcatto       Post(x);
5164ab3302SCarolineConcatto       return false; // Walk() does not visit descendents
5292d27b96SJean Perier     } else if constexpr (HasTypedExpr<T>::value) {
5392d27b96SJean Perier       // Format the expression representation from semantics
5492d27b96SJean Perier       if (asFortran_ && x.typedExpr) {
5592d27b96SJean Perier         asFortran_->expr(out_, *x.typedExpr);
5692d27b96SJean Perier         return false;
5792d27b96SJean Perier       } else {
5892d27b96SJean Perier         return true;
5992d27b96SJean Perier       }
6064ab3302SCarolineConcatto     } else {
6164ab3302SCarolineConcatto       Before(x);
6264ab3302SCarolineConcatto       return true; // there's no Unparse() defined here, Walk() the descendents
6364ab3302SCarolineConcatto     }
6464ab3302SCarolineConcatto   }
6564ab3302SCarolineConcatto   template <typename T> void Post(const T &) {}
6664ab3302SCarolineConcatto 
6764ab3302SCarolineConcatto   // Emit simple types as-is.
6864ab3302SCarolineConcatto   void Unparse(const std::string &x) { Put(x); }
6964ab3302SCarolineConcatto   void Unparse(int x) { Put(std::to_string(x)); }
7064ab3302SCarolineConcatto   void Unparse(unsigned int x) { Put(std::to_string(x)); }
7164ab3302SCarolineConcatto   void Unparse(long x) { Put(std::to_string(x)); }
7264ab3302SCarolineConcatto   void Unparse(unsigned long x) { Put(std::to_string(x)); }
7364ab3302SCarolineConcatto   void Unparse(long long x) { Put(std::to_string(x)); }
7464ab3302SCarolineConcatto   void Unparse(unsigned long long x) { Put(std::to_string(x)); }
7564ab3302SCarolineConcatto   void Unparse(char x) { Put(x); }
7664ab3302SCarolineConcatto 
7764ab3302SCarolineConcatto   // Statement labels and ends of lines
7864ab3302SCarolineConcatto   template <typename T> void Before(const Statement<T> &x) {
7964ab3302SCarolineConcatto     if (preStatement_) {
8064ab3302SCarolineConcatto       (*preStatement_)(x.source, out_, indent_);
8164ab3302SCarolineConcatto     }
8264ab3302SCarolineConcatto     Walk(x.label, " ");
8364ab3302SCarolineConcatto   }
8464ab3302SCarolineConcatto   template <typename T> void Post(const Statement<T> &) { Put('\n'); }
8564ab3302SCarolineConcatto 
8664ab3302SCarolineConcatto   // The special-case formatting functions for these productions are
8764ab3302SCarolineConcatto   // ordered to correspond roughly to their order of appearance in
8864ab3302SCarolineConcatto   // the Fortran 2018 standard (and parse-tree.h).
8964ab3302SCarolineConcatto 
9064ab3302SCarolineConcatto   void Unparse(const Program &x) { // R501
9164ab3302SCarolineConcatto     Walk("", x.v, "\n"); // put blank lines between ProgramUnits
9264ab3302SCarolineConcatto   }
9364ab3302SCarolineConcatto 
9464ab3302SCarolineConcatto   void Unparse(const Name &x) { // R603
9564ab3302SCarolineConcatto     Put(x.ToString());
9664ab3302SCarolineConcatto   }
9764ab3302SCarolineConcatto   void Unparse(const DefinedOperator::IntrinsicOperator &x) { // R608
9864ab3302SCarolineConcatto     switch (x) {
991f879005STim Keith     case DefinedOperator::IntrinsicOperator::Power:
1001f879005STim Keith       Put("**");
1011f879005STim Keith       break;
1021f879005STim Keith     case DefinedOperator::IntrinsicOperator::Multiply:
1031f879005STim Keith       Put('*');
1041f879005STim Keith       break;
1051f879005STim Keith     case DefinedOperator::IntrinsicOperator::Divide:
1061f879005STim Keith       Put('/');
1071f879005STim Keith       break;
1081f879005STim Keith     case DefinedOperator::IntrinsicOperator::Add:
1091f879005STim Keith       Put('+');
1101f879005STim Keith       break;
1111f879005STim Keith     case DefinedOperator::IntrinsicOperator::Subtract:
1121f879005STim Keith       Put('-');
1131f879005STim Keith       break;
1141f879005STim Keith     case DefinedOperator::IntrinsicOperator::Concat:
1151f879005STim Keith       Put("//");
1161f879005STim Keith       break;
1171f879005STim Keith     case DefinedOperator::IntrinsicOperator::LT:
1181f879005STim Keith       Put('<');
1191f879005STim Keith       break;
1201f879005STim Keith     case DefinedOperator::IntrinsicOperator::LE:
1211f879005STim Keith       Put("<=");
1221f879005STim Keith       break;
1231f879005STim Keith     case DefinedOperator::IntrinsicOperator::EQ:
1241f879005STim Keith       Put("==");
1251f879005STim Keith       break;
1261f879005STim Keith     case DefinedOperator::IntrinsicOperator::NE:
1271f879005STim Keith       Put("/=");
1281f879005STim Keith       break;
1291f879005STim Keith     case DefinedOperator::IntrinsicOperator::GE:
1301f879005STim Keith       Put(">=");
1311f879005STim Keith       break;
1321f879005STim Keith     case DefinedOperator::IntrinsicOperator::GT:
1331f879005STim Keith       Put('>');
1341f879005STim Keith       break;
1351f879005STim Keith     default:
1361f879005STim Keith       Put('.'), Word(DefinedOperator::EnumToString(x)), Put('.');
13764ab3302SCarolineConcatto     }
13864ab3302SCarolineConcatto   }
13964ab3302SCarolineConcatto   void Post(const Star &) { Put('*'); } // R701 &c.
14064ab3302SCarolineConcatto   void Post(const TypeParamValue::Deferred &) { Put(':'); } // R701
14164ab3302SCarolineConcatto   void Unparse(const DeclarationTypeSpec::Type &x) { // R703
14264ab3302SCarolineConcatto     Word("TYPE("), Walk(x.derived), Put(')');
14364ab3302SCarolineConcatto   }
14464ab3302SCarolineConcatto   void Unparse(const DeclarationTypeSpec::Class &x) {
14564ab3302SCarolineConcatto     Word("CLASS("), Walk(x.derived), Put(')');
14664ab3302SCarolineConcatto   }
14764ab3302SCarolineConcatto   void Post(const DeclarationTypeSpec::ClassStar &) { Word("CLASS(*)"); }
14864ab3302SCarolineConcatto   void Post(const DeclarationTypeSpec::TypeStar &) { Word("TYPE(*)"); }
14964ab3302SCarolineConcatto   void Unparse(const DeclarationTypeSpec::Record &x) {
15064ab3302SCarolineConcatto     Word("RECORD/"), Walk(x.v), Put('/');
15164ab3302SCarolineConcatto   }
15264ab3302SCarolineConcatto   void Before(const IntrinsicTypeSpec::Real &) { // R704
15364ab3302SCarolineConcatto     Word("REAL");
15464ab3302SCarolineConcatto   }
15564ab3302SCarolineConcatto   void Before(const IntrinsicTypeSpec::Complex &) { Word("COMPLEX"); }
15664ab3302SCarolineConcatto   void Post(const IntrinsicTypeSpec::DoublePrecision &) {
15764ab3302SCarolineConcatto     Word("DOUBLE PRECISION");
15864ab3302SCarolineConcatto   }
15964ab3302SCarolineConcatto   void Before(const IntrinsicTypeSpec::Character &) { Word("CHARACTER"); }
16064ab3302SCarolineConcatto   void Before(const IntrinsicTypeSpec::Logical &) { Word("LOGICAL"); }
16164ab3302SCarolineConcatto   void Post(const IntrinsicTypeSpec::DoubleComplex &) {
16264ab3302SCarolineConcatto     Word("DOUBLE COMPLEX");
16364ab3302SCarolineConcatto   }
164ef934174SKelvin Li   void Before(const UnsignedTypeSpec &) { Word("UNSIGNED"); }
165ef934174SKelvin Li   void Before(const IntrinsicVectorTypeSpec &) { Word("VECTOR("); }
166ef934174SKelvin Li   void Post(const IntrinsicVectorTypeSpec &) { Put(')'); }
167ef934174SKelvin Li   void Post(const VectorTypeSpec::PairVectorTypeSpec &) {
168ef934174SKelvin Li     Word("__VECTOR_PAIR");
169ef934174SKelvin Li   }
170ef934174SKelvin Li   void Post(const VectorTypeSpec::QuadVectorTypeSpec &) {
171ef934174SKelvin Li     Word("__VECTOR_QUAD");
172ef934174SKelvin Li   }
17364ab3302SCarolineConcatto   void Before(const IntegerTypeSpec &) { // R705
17464ab3302SCarolineConcatto     Word("INTEGER");
17564ab3302SCarolineConcatto   }
17664ab3302SCarolineConcatto   void Unparse(const KindSelector &x) { // R706
177cd03e96fSPeter Klausler     common::visit(
17864ab3302SCarolineConcatto         common::visitors{
17964ab3302SCarolineConcatto             [&](const ScalarIntConstantExpr &y) {
18064ab3302SCarolineConcatto               Put('('), Word("KIND="), Walk(y), Put(')');
18164ab3302SCarolineConcatto             },
18264ab3302SCarolineConcatto             [&](const KindSelector::StarSize &y) { Put('*'), Walk(y.v); },
18364ab3302SCarolineConcatto         },
18464ab3302SCarolineConcatto         x.u);
18564ab3302SCarolineConcatto   }
18664ab3302SCarolineConcatto   void Unparse(const SignedIntLiteralConstant &x) { // R707
18764ab3302SCarolineConcatto     Put(std::get<CharBlock>(x.t).ToString());
18864ab3302SCarolineConcatto     Walk("_", std::get<std::optional<KindParam>>(x.t));
18964ab3302SCarolineConcatto   }
19064ab3302SCarolineConcatto   void Unparse(const IntLiteralConstant &x) { // R708
19164ab3302SCarolineConcatto     Put(std::get<CharBlock>(x.t).ToString());
19264ab3302SCarolineConcatto     Walk("_", std::get<std::optional<KindParam>>(x.t));
19364ab3302SCarolineConcatto   }
19464ab3302SCarolineConcatto   void Unparse(const Sign &x) { // R712
19564ab3302SCarolineConcatto     Put(x == Sign::Negative ? '-' : '+');
19664ab3302SCarolineConcatto   }
19764ab3302SCarolineConcatto   void Unparse(const RealLiteralConstant &x) { // R714, R715
19864ab3302SCarolineConcatto     Put(x.real.source.ToString()), Walk("_", x.kind);
19964ab3302SCarolineConcatto   }
20064ab3302SCarolineConcatto   void Unparse(const ComplexLiteralConstant &x) { // R718 - R720
20164ab3302SCarolineConcatto     Put('('), Walk(x.t, ","), Put(')');
20264ab3302SCarolineConcatto   }
20364ab3302SCarolineConcatto   void Unparse(const CharSelector::LengthAndKind &x) { // R721
20464ab3302SCarolineConcatto     Put('('), Word("KIND="), Walk(x.kind);
20564ab3302SCarolineConcatto     Walk(", LEN=", x.length), Put(')');
20664ab3302SCarolineConcatto   }
20764ab3302SCarolineConcatto   void Unparse(const LengthSelector &x) { // R722
208cd03e96fSPeter Klausler     common::visit(common::visitors{
20964ab3302SCarolineConcatto                       [&](const TypeParamValue &y) {
21064ab3302SCarolineConcatto                         Put('('), Word("LEN="), Walk(y), Put(')');
21164ab3302SCarolineConcatto                       },
21264ab3302SCarolineConcatto                       [&](const CharLength &y) { Put('*'), Walk(y); },
21364ab3302SCarolineConcatto                   },
21464ab3302SCarolineConcatto         x.u);
21564ab3302SCarolineConcatto   }
21664ab3302SCarolineConcatto   void Unparse(const CharLength &x) { // R723
217cd03e96fSPeter Klausler     common::visit(
21864ab3302SCarolineConcatto         common::visitors{
21964ab3302SCarolineConcatto             [&](const TypeParamValue &y) { Put('('), Walk(y), Put(')'); },
22064ab3302SCarolineConcatto             [&](const std::int64_t &y) { Walk(y); },
22164ab3302SCarolineConcatto         },
22264ab3302SCarolineConcatto         x.u);
22364ab3302SCarolineConcatto   }
22464ab3302SCarolineConcatto   void Unparse(const CharLiteralConstant &x) { // R724
22564ab3302SCarolineConcatto     const auto &str{std::get<std::string>(x.t)};
22664ab3302SCarolineConcatto     if (const auto &k{std::get<std::optional<KindParam>>(x.t)}) {
22764ab3302SCarolineConcatto       Walk(*k), Put('_');
22864ab3302SCarolineConcatto     }
22964ab3302SCarolineConcatto     PutNormalized(str);
23064ab3302SCarolineConcatto   }
23164ab3302SCarolineConcatto   void Unparse(const HollerithLiteralConstant &x) {
23264ab3302SCarolineConcatto     auto ucs{DecodeString<std::u32string, Encoding::UTF_8>(x.v, false)};
23364ab3302SCarolineConcatto     Unparse(ucs.size());
23464ab3302SCarolineConcatto     Put('H');
23564ab3302SCarolineConcatto     for (char32_t ch : ucs) {
23664ab3302SCarolineConcatto       EncodedCharacter encoded{EncodeCharacter(encoding_, ch)};
23764ab3302SCarolineConcatto       for (int j{0}; j < encoded.bytes; ++j) {
23864ab3302SCarolineConcatto         Put(encoded.buffer[j]);
23964ab3302SCarolineConcatto       }
24064ab3302SCarolineConcatto     }
24164ab3302SCarolineConcatto   }
24264ab3302SCarolineConcatto   void Unparse(const LogicalLiteralConstant &x) { // R725
24364ab3302SCarolineConcatto     Put(std::get<bool>(x.t) ? ".TRUE." : ".FALSE.");
24464ab3302SCarolineConcatto     Walk("_", std::get<std::optional<KindParam>>(x.t));
24564ab3302SCarolineConcatto   }
24664ab3302SCarolineConcatto   void Unparse(const DerivedTypeStmt &x) { // R727
24764ab3302SCarolineConcatto     Word("TYPE"), Walk(", ", std::get<std::list<TypeAttrSpec>>(x.t), ", ");
24864ab3302SCarolineConcatto     Put(" :: "), Walk(std::get<Name>(x.t));
24964ab3302SCarolineConcatto     Walk("(", std::get<std::list<Name>>(x.t), ", ", ")");
25064ab3302SCarolineConcatto     Indent();
25164ab3302SCarolineConcatto   }
25264ab3302SCarolineConcatto   void Unparse(const Abstract &) { // R728, &c.
25364ab3302SCarolineConcatto     Word("ABSTRACT");
25464ab3302SCarolineConcatto   }
25564ab3302SCarolineConcatto   void Post(const TypeAttrSpec::BindC &) { Word("BIND(C)"); }
25664ab3302SCarolineConcatto   void Unparse(const TypeAttrSpec::Extends &x) {
25764ab3302SCarolineConcatto     Word("EXTENDS("), Walk(x.v), Put(')');
25864ab3302SCarolineConcatto   }
25964ab3302SCarolineConcatto   void Unparse(const EndTypeStmt &x) { // R730
26064ab3302SCarolineConcatto     Outdent(), Word("END TYPE"), Walk(" ", x.v);
26164ab3302SCarolineConcatto   }
26264ab3302SCarolineConcatto   void Unparse(const SequenceStmt &) { // R731
26364ab3302SCarolineConcatto     Word("SEQUENCE");
26464ab3302SCarolineConcatto   }
26564ab3302SCarolineConcatto   void Unparse(const TypeParamDefStmt &x) { // R732
26664ab3302SCarolineConcatto     Walk(std::get<IntegerTypeSpec>(x.t));
26764ab3302SCarolineConcatto     Put(", "), Walk(std::get<common::TypeParamAttr>(x.t));
26864ab3302SCarolineConcatto     Put(" :: "), Walk(std::get<std::list<TypeParamDecl>>(x.t), ", ");
26964ab3302SCarolineConcatto   }
27064ab3302SCarolineConcatto   void Unparse(const TypeParamDecl &x) { // R733
27164ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
27264ab3302SCarolineConcatto     Walk("=", std::get<std::optional<ScalarIntConstantExpr>>(x.t));
27364ab3302SCarolineConcatto   }
27464ab3302SCarolineConcatto   void Unparse(const DataComponentDefStmt &x) { // R737
27564ab3302SCarolineConcatto     const auto &dts{std::get<DeclarationTypeSpec>(x.t)};
27664ab3302SCarolineConcatto     const auto &attrs{std::get<std::list<ComponentAttrSpec>>(x.t)};
277c14cf92bSPeter Klausler     const auto &decls{std::get<std::list<ComponentOrFill>>(x.t)};
27864ab3302SCarolineConcatto     Walk(dts), Walk(", ", attrs, ", ");
27964ab3302SCarolineConcatto     if (!attrs.empty() ||
28064ab3302SCarolineConcatto         (!std::holds_alternative<DeclarationTypeSpec::Record>(dts.u) &&
28164ab3302SCarolineConcatto             std::none_of(
282c14cf92bSPeter Klausler                 decls.begin(), decls.end(), [](const ComponentOrFill &c) {
283cd03e96fSPeter Klausler                   return common::visit(
284c14cf92bSPeter Klausler                       common::visitors{
285c14cf92bSPeter Klausler                           [](const ComponentDecl &d) {
28664ab3302SCarolineConcatto                             const auto &init{
28764ab3302SCarolineConcatto                                 std::get<std::optional<Initialization>>(d.t)};
28864ab3302SCarolineConcatto                             return init &&
289c14cf92bSPeter Klausler                                 std::holds_alternative<std::list<
290c14cf92bSPeter Klausler                                     common::Indirection<DataStmtValue>>>(
29164ab3302SCarolineConcatto                                     init->u);
292c14cf92bSPeter Klausler                           },
293c14cf92bSPeter Klausler                           [](const FillDecl &) { return false; },
294c14cf92bSPeter Klausler                       },
295c14cf92bSPeter Klausler                       c.u);
29664ab3302SCarolineConcatto                 }))) {
29764ab3302SCarolineConcatto       Put(" ::");
29864ab3302SCarolineConcatto     }
29964ab3302SCarolineConcatto     Put(' '), Walk(decls, ", ");
30064ab3302SCarolineConcatto   }
30164ab3302SCarolineConcatto   void Unparse(const Allocatable &) { // R738
30264ab3302SCarolineConcatto     Word("ALLOCATABLE");
30364ab3302SCarolineConcatto   }
30464ab3302SCarolineConcatto   void Unparse(const Pointer &) { Word("POINTER"); }
30564ab3302SCarolineConcatto   void Unparse(const Contiguous &) { Word("CONTIGUOUS"); }
30664ab3302SCarolineConcatto   void Before(const ComponentAttrSpec &x) {
307cd03e96fSPeter Klausler     common::visit(common::visitors{
30864ab3302SCarolineConcatto                       [&](const CoarraySpec &) { Word("CODIMENSION["); },
30964ab3302SCarolineConcatto                       [&](const ComponentArraySpec &) { Word("DIMENSION("); },
31064ab3302SCarolineConcatto                       [](const auto &) {},
31164ab3302SCarolineConcatto                   },
31264ab3302SCarolineConcatto         x.u);
31364ab3302SCarolineConcatto   }
31464ab3302SCarolineConcatto   void Post(const ComponentAttrSpec &x) {
315cd03e96fSPeter Klausler     common::visit(common::visitors{
31664ab3302SCarolineConcatto                       [&](const CoarraySpec &) { Put(']'); },
31764ab3302SCarolineConcatto                       [&](const ComponentArraySpec &) { Put(')'); },
31864ab3302SCarolineConcatto                       [](const auto &) {},
31964ab3302SCarolineConcatto                   },
32064ab3302SCarolineConcatto         x.u);
32164ab3302SCarolineConcatto   }
32264ab3302SCarolineConcatto   void Unparse(const ComponentDecl &x) { // R739
32364ab3302SCarolineConcatto     Walk(std::get<ObjectName>(x.t));
32464ab3302SCarolineConcatto     Walk("(", std::get<std::optional<ComponentArraySpec>>(x.t), ")");
32564ab3302SCarolineConcatto     Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
32664ab3302SCarolineConcatto     Walk("*", std::get<std::optional<CharLength>>(x.t));
32764ab3302SCarolineConcatto     Walk(std::get<std::optional<Initialization>>(x.t));
32864ab3302SCarolineConcatto   }
329c14cf92bSPeter Klausler   void Unparse(const FillDecl &x) { // DEC extension
330c14cf92bSPeter Klausler     Put("%FILL");
331c14cf92bSPeter Klausler     Walk("(", std::get<std::optional<ComponentArraySpec>>(x.t), ")");
332c14cf92bSPeter Klausler     Walk("*", std::get<std::optional<CharLength>>(x.t));
333c14cf92bSPeter Klausler   }
33464ab3302SCarolineConcatto   void Unparse(const ComponentArraySpec &x) { // R740
335cd03e96fSPeter Klausler     common::visit(
336cd03e96fSPeter Klausler         common::visitors{
33764ab3302SCarolineConcatto             [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
33864ab3302SCarolineConcatto             [&](const DeferredShapeSpecList &y) { Walk(y); },
33964ab3302SCarolineConcatto         },
34064ab3302SCarolineConcatto         x.u);
34164ab3302SCarolineConcatto   }
34264ab3302SCarolineConcatto   void Unparse(const ProcComponentDefStmt &x) { // R741
34364ab3302SCarolineConcatto     Word("PROCEDURE(");
34464ab3302SCarolineConcatto     Walk(std::get<std::optional<ProcInterface>>(x.t)), Put(')');
34564ab3302SCarolineConcatto     Walk(", ", std::get<std::list<ProcComponentAttrSpec>>(x.t), ", ");
34664ab3302SCarolineConcatto     Put(" :: "), Walk(std::get<std::list<ProcDecl>>(x.t), ", ");
34764ab3302SCarolineConcatto   }
34864ab3302SCarolineConcatto   void Unparse(const NoPass &) { // R742
34964ab3302SCarolineConcatto     Word("NOPASS");
35064ab3302SCarolineConcatto   }
35164ab3302SCarolineConcatto   void Unparse(const Pass &x) { Word("PASS"), Walk("(", x.v, ")"); }
35264ab3302SCarolineConcatto   void Unparse(const Initialization &x) { // R743 & R805
353cd03e96fSPeter Klausler     common::visit(
354cd03e96fSPeter Klausler         common::visitors{
35564ab3302SCarolineConcatto             [&](const ConstantExpr &y) { Put(" = "), Walk(y); },
35664ab3302SCarolineConcatto             [&](const NullInit &y) { Put(" => "), Walk(y); },
35764ab3302SCarolineConcatto             [&](const InitialDataTarget &y) { Put(" => "), Walk(y); },
35864ab3302SCarolineConcatto             [&](const std::list<common::Indirection<DataStmtValue>> &y) {
35964ab3302SCarolineConcatto               Walk("/", y, ", ", "/");
36064ab3302SCarolineConcatto             },
36164ab3302SCarolineConcatto         },
36264ab3302SCarolineConcatto         x.u);
36364ab3302SCarolineConcatto   }
36464ab3302SCarolineConcatto   void Unparse(const PrivateStmt &) { // R745
36564ab3302SCarolineConcatto     Word("PRIVATE");
36664ab3302SCarolineConcatto   }
36764ab3302SCarolineConcatto   void Unparse(const TypeBoundProcedureStmt::WithoutInterface &x) { // R749
36864ab3302SCarolineConcatto     Word("PROCEDURE"), Walk(", ", x.attributes, ", ");
36964ab3302SCarolineConcatto     Put(" :: "), Walk(x.declarations, ", ");
37064ab3302SCarolineConcatto   }
37164ab3302SCarolineConcatto   void Unparse(const TypeBoundProcedureStmt::WithInterface &x) {
37264ab3302SCarolineConcatto     Word("PROCEDURE("), Walk(x.interfaceName), Put("), ");
37364ab3302SCarolineConcatto     Walk(x.attributes);
37464ab3302SCarolineConcatto     Put(" :: "), Walk(x.bindingNames, ", ");
37564ab3302SCarolineConcatto   }
37664ab3302SCarolineConcatto   void Unparse(const TypeBoundProcDecl &x) { // R750
37764ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
37864ab3302SCarolineConcatto     Walk(" => ", std::get<std::optional<Name>>(x.t));
37964ab3302SCarolineConcatto   }
38064ab3302SCarolineConcatto   void Unparse(const TypeBoundGenericStmt &x) { // R751
38164ab3302SCarolineConcatto     Word("GENERIC"), Walk(", ", std::get<std::optional<AccessSpec>>(x.t));
38264ab3302SCarolineConcatto     Put(" :: "), Walk(std::get<common::Indirection<GenericSpec>>(x.t));
38364ab3302SCarolineConcatto     Put(" => "), Walk(std::get<std::list<Name>>(x.t), ", ");
38464ab3302SCarolineConcatto   }
38564ab3302SCarolineConcatto   void Post(const BindAttr::Deferred &) { Word("DEFERRED"); } // R752
38664ab3302SCarolineConcatto   void Post(const BindAttr::Non_Overridable &) { Word("NON_OVERRIDABLE"); }
38764ab3302SCarolineConcatto   void Unparse(const FinalProcedureStmt &x) { // R753
38864ab3302SCarolineConcatto     Word("FINAL :: "), Walk(x.v, ", ");
38964ab3302SCarolineConcatto   }
39064ab3302SCarolineConcatto   void Unparse(const DerivedTypeSpec &x) { // R754
39164ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
39264ab3302SCarolineConcatto     Walk("(", std::get<std::list<TypeParamSpec>>(x.t), ",", ")");
39364ab3302SCarolineConcatto   }
39464ab3302SCarolineConcatto   void Unparse(const TypeParamSpec &x) { // R755
39564ab3302SCarolineConcatto     Walk(std::get<std::optional<Keyword>>(x.t), "=");
39664ab3302SCarolineConcatto     Walk(std::get<TypeParamValue>(x.t));
39764ab3302SCarolineConcatto   }
39864ab3302SCarolineConcatto   void Unparse(const StructureConstructor &x) { // R756
39964ab3302SCarolineConcatto     Walk(std::get<DerivedTypeSpec>(x.t));
40064ab3302SCarolineConcatto     Put('('), Walk(std::get<std::list<ComponentSpec>>(x.t), ", "), Put(')');
40164ab3302SCarolineConcatto   }
40264ab3302SCarolineConcatto   void Unparse(const ComponentSpec &x) { // R757
40364ab3302SCarolineConcatto     Walk(std::get<std::optional<Keyword>>(x.t), "=");
40464ab3302SCarolineConcatto     Walk(std::get<ComponentDataSource>(x.t));
40564ab3302SCarolineConcatto   }
40664ab3302SCarolineConcatto   void Unparse(const EnumDefStmt &) { // R760
40764ab3302SCarolineConcatto     Word("ENUM, BIND(C)"), Indent();
40864ab3302SCarolineConcatto   }
40964ab3302SCarolineConcatto   void Unparse(const EnumeratorDefStmt &x) { // R761
41064ab3302SCarolineConcatto     Word("ENUMERATOR :: "), Walk(x.v, ", ");
41164ab3302SCarolineConcatto   }
41264ab3302SCarolineConcatto   void Unparse(const Enumerator &x) { // R762
41364ab3302SCarolineConcatto     Walk(std::get<NamedConstant>(x.t));
41464ab3302SCarolineConcatto     Walk(" = ", std::get<std::optional<ScalarIntConstantExpr>>(x.t));
41564ab3302SCarolineConcatto   }
41664ab3302SCarolineConcatto   void Post(const EndEnumStmt &) { // R763
41764ab3302SCarolineConcatto     Outdent(), Word("END ENUM");
41864ab3302SCarolineConcatto   }
41964ab3302SCarolineConcatto   void Unparse(const BOZLiteralConstant &x) { // R764 - R767
42064ab3302SCarolineConcatto     Put(x.v);
42164ab3302SCarolineConcatto   }
42264ab3302SCarolineConcatto   void Unparse(const AcValue::Triplet &x) { // R773
42364ab3302SCarolineConcatto     Walk(std::get<0>(x.t)), Put(':'), Walk(std::get<1>(x.t));
42464ab3302SCarolineConcatto     Walk(":", std::get<std::optional<ScalarIntExpr>>(x.t));
42564ab3302SCarolineConcatto   }
42664ab3302SCarolineConcatto   void Unparse(const ArrayConstructor &x) { // R769
42764ab3302SCarolineConcatto     Put('['), Walk(x.v), Put(']');
42864ab3302SCarolineConcatto   }
42964ab3302SCarolineConcatto   void Unparse(const AcSpec &x) { // R770
43064ab3302SCarolineConcatto     Walk(x.type, "::"), Walk(x.values, ", ");
43164ab3302SCarolineConcatto   }
43264ab3302SCarolineConcatto   template <typename A, typename B> void Unparse(const LoopBounds<A, B> &x) {
43364ab3302SCarolineConcatto     Walk(x.name), Put('='), Walk(x.lower), Put(','), Walk(x.upper);
43464ab3302SCarolineConcatto     Walk(",", x.step);
43564ab3302SCarolineConcatto   }
43664ab3302SCarolineConcatto   void Unparse(const AcImpliedDo &x) { // R774
43764ab3302SCarolineConcatto     Put('('), Walk(std::get<std::list<AcValue>>(x.t), ", ");
43864ab3302SCarolineConcatto     Put(", "), Walk(std::get<AcImpliedDoControl>(x.t)), Put(')');
43964ab3302SCarolineConcatto   }
44064ab3302SCarolineConcatto   void Unparse(const AcImpliedDoControl &x) { // R775
44164ab3302SCarolineConcatto     Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
44264ab3302SCarolineConcatto     Walk(std::get<AcImpliedDoControl::Bounds>(x.t));
44364ab3302SCarolineConcatto   }
44464ab3302SCarolineConcatto 
44564ab3302SCarolineConcatto   void Unparse(const TypeDeclarationStmt &x) { // R801
44664ab3302SCarolineConcatto     const auto &dts{std::get<DeclarationTypeSpec>(x.t)};
44764ab3302SCarolineConcatto     const auto &attrs{std::get<std::list<AttrSpec>>(x.t)};
44864ab3302SCarolineConcatto     const auto &decls{std::get<std::list<EntityDecl>>(x.t)};
44964ab3302SCarolineConcatto     Walk(dts), Walk(", ", attrs, ", ");
45064ab3302SCarolineConcatto 
45164ab3302SCarolineConcatto     static const auto isInitializerOldStyle{[](const Initialization &i) {
45264ab3302SCarolineConcatto       return std::holds_alternative<
45364ab3302SCarolineConcatto           std::list<common::Indirection<DataStmtValue>>>(i.u);
45464ab3302SCarolineConcatto     }};
45564ab3302SCarolineConcatto     static const auto hasAssignmentInitializer{[](const EntityDecl &d) {
45664ab3302SCarolineConcatto       // Does a declaration have a new-style =x initializer?
45764ab3302SCarolineConcatto       const auto &init{std::get<std::optional<Initialization>>(d.t)};
45864ab3302SCarolineConcatto       return init && !isInitializerOldStyle(*init);
45964ab3302SCarolineConcatto     }};
46064ab3302SCarolineConcatto     static const auto hasSlashDelimitedInitializer{[](const EntityDecl &d) {
46164ab3302SCarolineConcatto       // Does a declaration have an old-style /x/ initializer?
46264ab3302SCarolineConcatto       const auto &init{std::get<std::optional<Initialization>>(d.t)};
46364ab3302SCarolineConcatto       return init && isInitializerOldStyle(*init);
46464ab3302SCarolineConcatto     }};
46564ab3302SCarolineConcatto     const auto useDoubledColons{[&]() {
46664ab3302SCarolineConcatto       bool isRecord{std::holds_alternative<DeclarationTypeSpec::Record>(dts.u)};
46764ab3302SCarolineConcatto       if (!attrs.empty()) {
46864ab3302SCarolineConcatto         // Attributes after the type require :: before the entities.
46964ab3302SCarolineConcatto         CHECK(!isRecord);
47064ab3302SCarolineConcatto         return true;
47164ab3302SCarolineConcatto       }
47264ab3302SCarolineConcatto       if (std::any_of(decls.begin(), decls.end(), hasAssignmentInitializer)) {
47364ab3302SCarolineConcatto         // Always use :: with new style standard initializers (=x),
47464ab3302SCarolineConcatto         // since the standard requires them to appear (even in free form,
47564ab3302SCarolineConcatto         // where mandatory spaces already disambiguate INTEGER J=666).
47664ab3302SCarolineConcatto         CHECK(!isRecord);
47764ab3302SCarolineConcatto         return true;
47864ab3302SCarolineConcatto       }
47964ab3302SCarolineConcatto       if (isRecord) {
48064ab3302SCarolineConcatto         // Never put :: in a legacy extension RECORD// statement.
48164ab3302SCarolineConcatto         return false;
48264ab3302SCarolineConcatto       }
48364ab3302SCarolineConcatto       // The :: is optional for this declaration.  Avoid usage that can
48464ab3302SCarolineConcatto       // crash the pgf90 compiler.
48564ab3302SCarolineConcatto       if (std::any_of(
48664ab3302SCarolineConcatto               decls.begin(), decls.end(), hasSlashDelimitedInitializer)) {
48764ab3302SCarolineConcatto         // Don't use :: when a declaration uses legacy DATA-statement-like
48864ab3302SCarolineConcatto         // /x/ initialization.
48964ab3302SCarolineConcatto         return false;
49064ab3302SCarolineConcatto       }
49164ab3302SCarolineConcatto       // Don't use :: with intrinsic types.  Otherwise, use it.
49264ab3302SCarolineConcatto       return !std::holds_alternative<IntrinsicTypeSpec>(dts.u);
49364ab3302SCarolineConcatto     }};
49464ab3302SCarolineConcatto 
49564ab3302SCarolineConcatto     if (useDoubledColons()) {
49664ab3302SCarolineConcatto       Put(" ::");
49764ab3302SCarolineConcatto     }
49864ab3302SCarolineConcatto     Put(' '), Walk(std::get<std::list<EntityDecl>>(x.t), ", ");
49964ab3302SCarolineConcatto   }
50064ab3302SCarolineConcatto   void Before(const AttrSpec &x) { // R802
501cd03e96fSPeter Klausler     common::visit(common::visitors{
50264ab3302SCarolineConcatto                       [&](const CoarraySpec &) { Word("CODIMENSION["); },
50364ab3302SCarolineConcatto                       [&](const ArraySpec &) { Word("DIMENSION("); },
50464ab3302SCarolineConcatto                       [](const auto &) {},
50564ab3302SCarolineConcatto                   },
50664ab3302SCarolineConcatto         x.u);
50764ab3302SCarolineConcatto   }
50864ab3302SCarolineConcatto   void Post(const AttrSpec &x) {
509cd03e96fSPeter Klausler     common::visit(common::visitors{
51064ab3302SCarolineConcatto                       [&](const CoarraySpec &) { Put(']'); },
51164ab3302SCarolineConcatto                       [&](const ArraySpec &) { Put(')'); },
51264ab3302SCarolineConcatto                       [](const auto &) {},
51364ab3302SCarolineConcatto                   },
51464ab3302SCarolineConcatto         x.u);
51564ab3302SCarolineConcatto   }
51664ab3302SCarolineConcatto   void Unparse(const EntityDecl &x) { // R803
51764ab3302SCarolineConcatto     Walk(std::get<ObjectName>(x.t));
51864ab3302SCarolineConcatto     Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
51964ab3302SCarolineConcatto     Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
52064ab3302SCarolineConcatto     Walk("*", std::get<std::optional<CharLength>>(x.t));
52164ab3302SCarolineConcatto     Walk(std::get<std::optional<Initialization>>(x.t));
52264ab3302SCarolineConcatto   }
52364ab3302SCarolineConcatto   void Unparse(const NullInit &) { // R806
52464ab3302SCarolineConcatto     Word("NULL()");
52564ab3302SCarolineConcatto   }
52664ab3302SCarolineConcatto   void Unparse(const LanguageBindingSpec &x) { // R808 & R1528
527f3c227b7SPeter Klausler     Word("BIND(C");
528f3c227b7SPeter Klausler     Walk(
529f3c227b7SPeter Klausler         ", NAME=", std::get<std::optional<ScalarDefaultCharConstantExpr>>(x.t));
530f3c227b7SPeter Klausler     if (std::get<bool>(x.t)) {
531f3c227b7SPeter Klausler       Word(", CDEFINED");
532f3c227b7SPeter Klausler     }
533f3c227b7SPeter Klausler     Put(')');
53464ab3302SCarolineConcatto   }
53564ab3302SCarolineConcatto   void Unparse(const CoarraySpec &x) { // R809
536cd03e96fSPeter Klausler     common::visit(common::visitors{
53764ab3302SCarolineConcatto                       [&](const DeferredCoshapeSpecList &y) { Walk(y); },
53864ab3302SCarolineConcatto                       [&](const ExplicitCoshapeSpec &y) { Walk(y); },
53964ab3302SCarolineConcatto                   },
54064ab3302SCarolineConcatto         x.u);
54164ab3302SCarolineConcatto   }
54264ab3302SCarolineConcatto   void Unparse(const DeferredCoshapeSpecList &x) { // R810
54364ab3302SCarolineConcatto     for (auto j{x.v}; j > 0; --j) {
54464ab3302SCarolineConcatto       Put(':');
54564ab3302SCarolineConcatto       if (j > 1) {
54664ab3302SCarolineConcatto         Put(',');
54764ab3302SCarolineConcatto       }
54864ab3302SCarolineConcatto     }
54964ab3302SCarolineConcatto   }
55064ab3302SCarolineConcatto   void Unparse(const ExplicitCoshapeSpec &x) { // R811
55164ab3302SCarolineConcatto     Walk(std::get<std::list<ExplicitShapeSpec>>(x.t), ",", ",");
55264ab3302SCarolineConcatto     Walk(std::get<std::optional<SpecificationExpr>>(x.t), ":"), Put('*');
55364ab3302SCarolineConcatto   }
55464ab3302SCarolineConcatto   void Unparse(const ExplicitShapeSpec &x) { // R812 - R813 & R816 - R818
55564ab3302SCarolineConcatto     Walk(std::get<std::optional<SpecificationExpr>>(x.t), ":");
55664ab3302SCarolineConcatto     Walk(std::get<SpecificationExpr>(x.t));
55764ab3302SCarolineConcatto   }
55864ab3302SCarolineConcatto   void Unparse(const ArraySpec &x) { // R815
559cd03e96fSPeter Klausler     common::visit(
560cd03e96fSPeter Klausler         common::visitors{
56164ab3302SCarolineConcatto             [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
56264ab3302SCarolineConcatto             [&](const std::list<AssumedShapeSpec> &y) { Walk(y, ","); },
56364ab3302SCarolineConcatto             [&](const DeferredShapeSpecList &y) { Walk(y); },
56464ab3302SCarolineConcatto             [&](const AssumedSizeSpec &y) { Walk(y); },
56564ab3302SCarolineConcatto             [&](const ImpliedShapeSpec &y) { Walk(y); },
56664ab3302SCarolineConcatto             [&](const AssumedRankSpec &y) { Walk(y); },
56764ab3302SCarolineConcatto         },
56864ab3302SCarolineConcatto         x.u);
56964ab3302SCarolineConcatto   }
57064ab3302SCarolineConcatto   void Post(const AssumedShapeSpec &) { Put(':'); } // R819
57164ab3302SCarolineConcatto   void Unparse(const DeferredShapeSpecList &x) { // R820
57264ab3302SCarolineConcatto     for (auto j{x.v}; j > 0; --j) {
57364ab3302SCarolineConcatto       Put(':');
57464ab3302SCarolineConcatto       if (j > 1) {
57564ab3302SCarolineConcatto         Put(',');
57664ab3302SCarolineConcatto       }
57764ab3302SCarolineConcatto     }
57864ab3302SCarolineConcatto   }
57964ab3302SCarolineConcatto   void Unparse(const AssumedImpliedSpec &x) { // R821
58064ab3302SCarolineConcatto     Walk(x.v, ":");
58164ab3302SCarolineConcatto     Put('*');
58264ab3302SCarolineConcatto   }
58364ab3302SCarolineConcatto   void Unparse(const AssumedSizeSpec &x) { // R822
58464ab3302SCarolineConcatto     Walk(std::get<std::list<ExplicitShapeSpec>>(x.t), ",", ",");
58564ab3302SCarolineConcatto     Walk(std::get<AssumedImpliedSpec>(x.t));
58664ab3302SCarolineConcatto   }
58764ab3302SCarolineConcatto   void Unparse(const ImpliedShapeSpec &x) { // R823
58864ab3302SCarolineConcatto     Walk(x.v, ",");
58964ab3302SCarolineConcatto   }
59064ab3302SCarolineConcatto   void Post(const AssumedRankSpec &) { Put(".."); } // R825
59164ab3302SCarolineConcatto   void Post(const Asynchronous &) { Word("ASYNCHRONOUS"); }
59264ab3302SCarolineConcatto   void Post(const External &) { Word("EXTERNAL"); }
59364ab3302SCarolineConcatto   void Post(const Intrinsic &) { Word("INTRINSIC"); }
59464ab3302SCarolineConcatto   void Post(const Optional &) { Word("OPTIONAL"); }
59564ab3302SCarolineConcatto   void Post(const Parameter &) { Word("PARAMETER"); }
59664ab3302SCarolineConcatto   void Post(const Protected &) { Word("PROTECTED"); }
59764ab3302SCarolineConcatto   void Post(const Save &) { Word("SAVE"); }
59864ab3302SCarolineConcatto   void Post(const Target &) { Word("TARGET"); }
59964ab3302SCarolineConcatto   void Post(const Value &) { Word("VALUE"); }
60064ab3302SCarolineConcatto   void Post(const Volatile &) { Word("VOLATILE"); }
60164ab3302SCarolineConcatto   void Unparse(const IntentSpec &x) { // R826
60264ab3302SCarolineConcatto     Word("INTENT("), Walk(x.v), Put(")");
60364ab3302SCarolineConcatto   }
60464ab3302SCarolineConcatto   void Unparse(const AccessStmt &x) { // R827
60564ab3302SCarolineConcatto     Walk(std::get<AccessSpec>(x.t));
60664ab3302SCarolineConcatto     Walk(" :: ", std::get<std::list<AccessId>>(x.t), ", ");
60764ab3302SCarolineConcatto   }
60864ab3302SCarolineConcatto   void Unparse(const AllocatableStmt &x) { // R829
60964ab3302SCarolineConcatto     Word("ALLOCATABLE :: "), Walk(x.v, ", ");
61064ab3302SCarolineConcatto   }
61164ab3302SCarolineConcatto   void Unparse(const ObjectDecl &x) { // R830 & R860
61264ab3302SCarolineConcatto     Walk(std::get<ObjectName>(x.t));
61364ab3302SCarolineConcatto     Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
61464ab3302SCarolineConcatto     Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
61564ab3302SCarolineConcatto   }
61664ab3302SCarolineConcatto   void Unparse(const AsynchronousStmt &x) { // R831
61764ab3302SCarolineConcatto     Word("ASYNCHRONOUS :: "), Walk(x.v, ", ");
61864ab3302SCarolineConcatto   }
61964ab3302SCarolineConcatto   void Unparse(const BindStmt &x) { // R832
62064ab3302SCarolineConcatto     Walk(x.t, " :: ");
62164ab3302SCarolineConcatto   }
62264ab3302SCarolineConcatto   void Unparse(const BindEntity &x) { // R833
62364ab3302SCarolineConcatto     bool isCommon{std::get<BindEntity::Kind>(x.t) == BindEntity::Kind::Common};
62464ab3302SCarolineConcatto     const char *slash{isCommon ? "/" : ""};
62564ab3302SCarolineConcatto     Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
62664ab3302SCarolineConcatto   }
62764ab3302SCarolineConcatto   void Unparse(const CodimensionStmt &x) { // R834
62864ab3302SCarolineConcatto     Word("CODIMENSION :: "), Walk(x.v, ", ");
62964ab3302SCarolineConcatto   }
63064ab3302SCarolineConcatto   void Unparse(const CodimensionDecl &x) { // R835
63164ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
63264ab3302SCarolineConcatto     Put('['), Walk(std::get<CoarraySpec>(x.t)), Put(']');
63364ab3302SCarolineConcatto   }
63464ab3302SCarolineConcatto   void Unparse(const ContiguousStmt &x) { // R836
63564ab3302SCarolineConcatto     Word("CONTIGUOUS :: "), Walk(x.v, ", ");
63664ab3302SCarolineConcatto   }
63764ab3302SCarolineConcatto   void Unparse(const DataStmt &x) { // R837
63864ab3302SCarolineConcatto     Word("DATA "), Walk(x.v, ", ");
63964ab3302SCarolineConcatto   }
64064ab3302SCarolineConcatto   void Unparse(const DataStmtSet &x) { // R838
64164ab3302SCarolineConcatto     Walk(std::get<std::list<DataStmtObject>>(x.t), ", ");
64264ab3302SCarolineConcatto     Put('/'), Walk(std::get<std::list<DataStmtValue>>(x.t), ", "), Put('/');
64364ab3302SCarolineConcatto   }
64464ab3302SCarolineConcatto   void Unparse(const DataImpliedDo &x) { // R840, R842
64564ab3302SCarolineConcatto     Put('('), Walk(std::get<std::list<DataIDoObject>>(x.t), ", "), Put(',');
64664ab3302SCarolineConcatto     Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
64764ab3302SCarolineConcatto     Walk(std::get<DataImpliedDo::Bounds>(x.t)), Put(')');
64864ab3302SCarolineConcatto   }
64964ab3302SCarolineConcatto   void Unparse(const DataStmtValue &x) { // R843
65064ab3302SCarolineConcatto     Walk(std::get<std::optional<DataStmtRepeat>>(x.t), "*");
65164ab3302SCarolineConcatto     Walk(std::get<DataStmtConstant>(x.t));
65264ab3302SCarolineConcatto   }
65364ab3302SCarolineConcatto   void Unparse(const DimensionStmt &x) { // R848
65464ab3302SCarolineConcatto     Word("DIMENSION :: "), Walk(x.v, ", ");
65564ab3302SCarolineConcatto   }
65664ab3302SCarolineConcatto   void Unparse(const DimensionStmt::Declaration &x) {
65764ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
65864ab3302SCarolineConcatto     Put('('), Walk(std::get<ArraySpec>(x.t)), Put(')');
65964ab3302SCarolineConcatto   }
66064ab3302SCarolineConcatto   void Unparse(const IntentStmt &x) { // R849
66164ab3302SCarolineConcatto     Walk(x.t, " :: ");
66264ab3302SCarolineConcatto   }
66364ab3302SCarolineConcatto   void Unparse(const OptionalStmt &x) { // R850
66464ab3302SCarolineConcatto     Word("OPTIONAL :: "), Walk(x.v, ", ");
66564ab3302SCarolineConcatto   }
66664ab3302SCarolineConcatto   void Unparse(const ParameterStmt &x) { // R851
66764ab3302SCarolineConcatto     Word("PARAMETER("), Walk(x.v, ", "), Put(')');
66864ab3302SCarolineConcatto   }
66964ab3302SCarolineConcatto   void Unparse(const NamedConstantDef &x) { // R852
67064ab3302SCarolineConcatto     Walk(x.t, "=");
67164ab3302SCarolineConcatto   }
67264ab3302SCarolineConcatto   void Unparse(const PointerStmt &x) { // R853
67364ab3302SCarolineConcatto     Word("POINTER :: "), Walk(x.v, ", ");
67464ab3302SCarolineConcatto   }
67564ab3302SCarolineConcatto   void Unparse(const PointerDecl &x) { // R854
67664ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
67764ab3302SCarolineConcatto     Walk("(", std::get<std::optional<DeferredShapeSpecList>>(x.t), ")");
67864ab3302SCarolineConcatto   }
67964ab3302SCarolineConcatto   void Unparse(const ProtectedStmt &x) { // R855
68064ab3302SCarolineConcatto     Word("PROTECTED :: "), Walk(x.v, ", ");
68164ab3302SCarolineConcatto   }
68264ab3302SCarolineConcatto   void Unparse(const SaveStmt &x) { // R856
68364ab3302SCarolineConcatto     Word("SAVE"), Walk(" :: ", x.v, ", ");
68464ab3302SCarolineConcatto   }
68564ab3302SCarolineConcatto   void Unparse(const SavedEntity &x) { // R857, R858
68664ab3302SCarolineConcatto     bool isCommon{
68764ab3302SCarolineConcatto         std::get<SavedEntity::Kind>(x.t) == SavedEntity::Kind::Common};
68864ab3302SCarolineConcatto     const char *slash{isCommon ? "/" : ""};
68964ab3302SCarolineConcatto     Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
69064ab3302SCarolineConcatto   }
69164ab3302SCarolineConcatto   void Unparse(const TargetStmt &x) { // R859
69264ab3302SCarolineConcatto     Word("TARGET :: "), Walk(x.v, ", ");
69364ab3302SCarolineConcatto   }
69464ab3302SCarolineConcatto   void Unparse(const ValueStmt &x) { // R861
69564ab3302SCarolineConcatto     Word("VALUE :: "), Walk(x.v, ", ");
69664ab3302SCarolineConcatto   }
69764ab3302SCarolineConcatto   void Unparse(const VolatileStmt &x) { // R862
69864ab3302SCarolineConcatto     Word("VOLATILE :: "), Walk(x.v, ", ");
69964ab3302SCarolineConcatto   }
70064ab3302SCarolineConcatto   void Unparse(const ImplicitStmt &x) { // R863
70164ab3302SCarolineConcatto     Word("IMPLICIT ");
702cd03e96fSPeter Klausler     common::visit(
703cd03e96fSPeter Klausler         common::visitors{
70464ab3302SCarolineConcatto             [&](const std::list<ImplicitSpec> &y) { Walk(y, ", "); },
70564ab3302SCarolineConcatto             [&](const std::list<ImplicitStmt::ImplicitNoneNameSpec> &y) {
70664ab3302SCarolineConcatto               Word("NONE"), Walk(" (", y, ", ", ")");
70764ab3302SCarolineConcatto             },
70864ab3302SCarolineConcatto         },
70964ab3302SCarolineConcatto         x.u);
71064ab3302SCarolineConcatto   }
71164ab3302SCarolineConcatto   void Unparse(const ImplicitSpec &x) { // R864
71264ab3302SCarolineConcatto     Walk(std::get<DeclarationTypeSpec>(x.t));
71364ab3302SCarolineConcatto     Put('('), Walk(std::get<std::list<LetterSpec>>(x.t), ", "), Put(')');
71464ab3302SCarolineConcatto   }
71564ab3302SCarolineConcatto   void Unparse(const LetterSpec &x) { // R865
71664ab3302SCarolineConcatto     Put(*std::get<const char *>(x.t));
71764ab3302SCarolineConcatto     auto second{std::get<std::optional<const char *>>(x.t)};
71864ab3302SCarolineConcatto     if (second) {
71964ab3302SCarolineConcatto       Put('-'), Put(**second);
72064ab3302SCarolineConcatto     }
72164ab3302SCarolineConcatto   }
72264ab3302SCarolineConcatto   void Unparse(const ImportStmt &x) { // R867
72364ab3302SCarolineConcatto     Word("IMPORT");
72464ab3302SCarolineConcatto     switch (x.kind) {
7251f879005STim Keith     case common::ImportKind::Default:
7261f879005STim Keith       Walk(" :: ", x.names, ", ");
7271f879005STim Keith       break;
72864ab3302SCarolineConcatto     case common::ImportKind::Only:
72964ab3302SCarolineConcatto       Put(", "), Word("ONLY: ");
73064ab3302SCarolineConcatto       Walk(x.names, ", ");
73164ab3302SCarolineConcatto       break;
7321f879005STim Keith     case common::ImportKind::None:
7331f879005STim Keith       Word(", NONE");
7341f879005STim Keith       break;
7351f879005STim Keith     case common::ImportKind::All:
7361f879005STim Keith       Word(", ALL");
7371f879005STim Keith       break;
73864ab3302SCarolineConcatto     }
73964ab3302SCarolineConcatto   }
74064ab3302SCarolineConcatto   void Unparse(const NamelistStmt &x) { // R868
74164ab3302SCarolineConcatto     Word("NAMELIST"), Walk(x.v, ", ");
74264ab3302SCarolineConcatto   }
74364ab3302SCarolineConcatto   void Unparse(const NamelistStmt::Group &x) {
74464ab3302SCarolineConcatto     Put('/'), Walk(std::get<Name>(x.t)), Put('/');
74564ab3302SCarolineConcatto     Walk(std::get<std::list<Name>>(x.t), ", ");
74664ab3302SCarolineConcatto   }
74764ab3302SCarolineConcatto   void Unparse(const EquivalenceStmt &x) { // R870, R871
74864ab3302SCarolineConcatto     Word("EQUIVALENCE");
74964ab3302SCarolineConcatto     const char *separator{" "};
75064ab3302SCarolineConcatto     for (const std::list<EquivalenceObject> &y : x.v) {
75164ab3302SCarolineConcatto       Put(separator), Put('('), Walk(y), Put(')');
75264ab3302SCarolineConcatto       separator = ", ";
75364ab3302SCarolineConcatto     }
75464ab3302SCarolineConcatto   }
75564ab3302SCarolineConcatto   void Unparse(const CommonStmt &x) { // R873
75664ab3302SCarolineConcatto     Word("COMMON ");
75764ab3302SCarolineConcatto     Walk(x.blocks);
75864ab3302SCarolineConcatto   }
75964ab3302SCarolineConcatto   void Unparse(const CommonBlockObject &x) { // R874
76064ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
76164ab3302SCarolineConcatto     Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
76264ab3302SCarolineConcatto   }
76364ab3302SCarolineConcatto   void Unparse(const CommonStmt::Block &x) {
76464ab3302SCarolineConcatto     Word("/"), Walk(std::get<std::optional<Name>>(x.t)), Word("/");
76564ab3302SCarolineConcatto     Walk(std::get<std::list<CommonBlockObject>>(x.t));
76664ab3302SCarolineConcatto   }
76764ab3302SCarolineConcatto 
76864ab3302SCarolineConcatto   void Unparse(const Substring &x) { // R908, R909
76964ab3302SCarolineConcatto     Walk(std::get<DataRef>(x.t));
77064ab3302SCarolineConcatto     Put('('), Walk(std::get<SubstringRange>(x.t)), Put(')');
77164ab3302SCarolineConcatto   }
77264ab3302SCarolineConcatto   void Unparse(const CharLiteralConstantSubstring &x) {
77364ab3302SCarolineConcatto     Walk(std::get<CharLiteralConstant>(x.t));
77464ab3302SCarolineConcatto     Put('('), Walk(std::get<SubstringRange>(x.t)), Put(')');
77564ab3302SCarolineConcatto   }
776e03664d4SPeter Klausler   void Unparse(const SubstringInquiry &x) {
777e03664d4SPeter Klausler     Walk(x.v);
778e03664d4SPeter Klausler     Put(x.source.end()[-1] == 'n' ? "%LEN" : "%KIND");
779e03664d4SPeter Klausler   }
78064ab3302SCarolineConcatto   void Unparse(const SubstringRange &x) { // R910
78164ab3302SCarolineConcatto     Walk(x.t, ":");
78264ab3302SCarolineConcatto   }
78364ab3302SCarolineConcatto   void Unparse(const PartRef &x) { // R912
78464ab3302SCarolineConcatto     Walk(x.name);
78564ab3302SCarolineConcatto     Walk("(", x.subscripts, ",", ")");
78664ab3302SCarolineConcatto     Walk(x.imageSelector);
78764ab3302SCarolineConcatto   }
78864ab3302SCarolineConcatto   void Unparse(const StructureComponent &x) { // R913
78964ab3302SCarolineConcatto     Walk(x.base);
79064ab3302SCarolineConcatto     if (structureComponents_.find(x.component.source) !=
79164ab3302SCarolineConcatto         structureComponents_.end()) {
79264ab3302SCarolineConcatto       Put('.');
79364ab3302SCarolineConcatto     } else {
79464ab3302SCarolineConcatto       Put('%');
79564ab3302SCarolineConcatto     }
79664ab3302SCarolineConcatto     Walk(x.component);
79764ab3302SCarolineConcatto   }
79864ab3302SCarolineConcatto   void Unparse(const ArrayElement &x) { // R917
79964ab3302SCarolineConcatto     Walk(x.base);
80064ab3302SCarolineConcatto     Put('('), Walk(x.subscripts, ","), Put(')');
80164ab3302SCarolineConcatto   }
80264ab3302SCarolineConcatto   void Unparse(const SubscriptTriplet &x) { // R921
80364ab3302SCarolineConcatto     Walk(std::get<0>(x.t)), Put(':'), Walk(std::get<1>(x.t));
80464ab3302SCarolineConcatto     Walk(":", std::get<2>(x.t));
80564ab3302SCarolineConcatto   }
80664ab3302SCarolineConcatto   void Unparse(const ImageSelector &x) { // R924
80764ab3302SCarolineConcatto     Put('['), Walk(std::get<std::list<Cosubscript>>(x.t), ",");
80864ab3302SCarolineConcatto     Walk(",", std::get<std::list<ImageSelectorSpec>>(x.t), ","), Put(']');
80964ab3302SCarolineConcatto   }
81064ab3302SCarolineConcatto   void Before(const ImageSelectorSpec::Stat &) { // R926
81164ab3302SCarolineConcatto     Word("STAT=");
81264ab3302SCarolineConcatto   }
81364ab3302SCarolineConcatto   void Before(const ImageSelectorSpec::Team_Number &) { Word("TEAM_NUMBER="); }
81464ab3302SCarolineConcatto   void Before(const ImageSelectorSpec &x) {
81564ab3302SCarolineConcatto     if (std::holds_alternative<TeamValue>(x.u)) {
81664ab3302SCarolineConcatto       Word("TEAM=");
81764ab3302SCarolineConcatto     }
81864ab3302SCarolineConcatto   }
81964ab3302SCarolineConcatto   void Unparse(const AllocateStmt &x) { // R927
82064ab3302SCarolineConcatto     Word("ALLOCATE(");
82164ab3302SCarolineConcatto     Walk(std::get<std::optional<TypeSpec>>(x.t), "::");
82264ab3302SCarolineConcatto     Walk(std::get<std::list<Allocation>>(x.t), ", ");
82364ab3302SCarolineConcatto     Walk(", ", std::get<std::list<AllocOpt>>(x.t), ", "), Put(')');
82464ab3302SCarolineConcatto   }
82564ab3302SCarolineConcatto   void Before(const AllocOpt &x) { // R928, R931
826cd03e96fSPeter Klausler     common::visit(common::visitors{
82764ab3302SCarolineConcatto                       [&](const AllocOpt::Mold &) { Word("MOLD="); },
82864ab3302SCarolineConcatto                       [&](const AllocOpt::Source &) { Word("SOURCE="); },
8294ad72793SPeter Klausler                       [&](const AllocOpt::Stream &) { Word("STREAM="); },
8304ad72793SPeter Klausler                       [&](const AllocOpt::Pinned &) { Word("PINNED="); },
83164ab3302SCarolineConcatto                       [](const StatOrErrmsg &) {},
83264ab3302SCarolineConcatto                   },
83364ab3302SCarolineConcatto         x.u);
83464ab3302SCarolineConcatto   }
83564ab3302SCarolineConcatto   void Unparse(const Allocation &x) { // R932
83664ab3302SCarolineConcatto     Walk(std::get<AllocateObject>(x.t));
83764ab3302SCarolineConcatto     Walk("(", std::get<std::list<AllocateShapeSpec>>(x.t), ",", ")");
83864ab3302SCarolineConcatto     Walk("[", std::get<std::optional<AllocateCoarraySpec>>(x.t), "]");
83964ab3302SCarolineConcatto   }
84064ab3302SCarolineConcatto   void Unparse(const AllocateShapeSpec &x) { // R934 & R938
84164ab3302SCarolineConcatto     Walk(std::get<std::optional<BoundExpr>>(x.t), ":");
84264ab3302SCarolineConcatto     Walk(std::get<BoundExpr>(x.t));
84364ab3302SCarolineConcatto   }
84464ab3302SCarolineConcatto   void Unparse(const AllocateCoarraySpec &x) { // R937
84564ab3302SCarolineConcatto     Walk(std::get<std::list<AllocateCoshapeSpec>>(x.t), ",", ",");
84664ab3302SCarolineConcatto     Walk(std::get<std::optional<BoundExpr>>(x.t), ":"), Put('*');
84764ab3302SCarolineConcatto   }
84864ab3302SCarolineConcatto   void Unparse(const NullifyStmt &x) { // R939
84964ab3302SCarolineConcatto     Word("NULLIFY("), Walk(x.v, ", "), Put(')');
85064ab3302SCarolineConcatto   }
85164ab3302SCarolineConcatto   void Unparse(const DeallocateStmt &x) { // R941
85264ab3302SCarolineConcatto     Word("DEALLOCATE(");
85364ab3302SCarolineConcatto     Walk(std::get<std::list<AllocateObject>>(x.t), ", ");
85464ab3302SCarolineConcatto     Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
85564ab3302SCarolineConcatto   }
85664ab3302SCarolineConcatto   void Before(const StatOrErrmsg &x) { // R942 & R1165
857cd03e96fSPeter Klausler     common::visit(common::visitors{
85864ab3302SCarolineConcatto                       [&](const StatVariable &) { Word("STAT="); },
85964ab3302SCarolineConcatto                       [&](const MsgVariable &) { Word("ERRMSG="); },
86064ab3302SCarolineConcatto                   },
86164ab3302SCarolineConcatto         x.u);
86264ab3302SCarolineConcatto   }
86364ab3302SCarolineConcatto 
86464ab3302SCarolineConcatto   // R1001 - R1022
86564ab3302SCarolineConcatto   void Unparse(const Expr::Parentheses &x) { Put('('), Walk(x.v), Put(')'); }
86664ab3302SCarolineConcatto   void Before(const Expr::UnaryPlus &) { Put("+"); }
86764ab3302SCarolineConcatto   void Before(const Expr::Negate &) { Put("-"); }
86864ab3302SCarolineConcatto   void Before(const Expr::NOT &) { Word(".NOT."); }
86964ab3302SCarolineConcatto   void Unparse(const Expr::PercentLoc &x) {
87064ab3302SCarolineConcatto     Word("%LOC("), Walk(x.v), Put(')');
87164ab3302SCarolineConcatto   }
87264ab3302SCarolineConcatto   void Unparse(const Expr::Power &x) { Walk(x.t, "**"); }
87364ab3302SCarolineConcatto   void Unparse(const Expr::Multiply &x) { Walk(x.t, "*"); }
87464ab3302SCarolineConcatto   void Unparse(const Expr::Divide &x) { Walk(x.t, "/"); }
87564ab3302SCarolineConcatto   void Unparse(const Expr::Add &x) { Walk(x.t, "+"); }
87664ab3302SCarolineConcatto   void Unparse(const Expr::Subtract &x) { Walk(x.t, "-"); }
87764ab3302SCarolineConcatto   void Unparse(const Expr::Concat &x) { Walk(x.t, "//"); }
87864ab3302SCarolineConcatto   void Unparse(const Expr::LT &x) { Walk(x.t, "<"); }
87964ab3302SCarolineConcatto   void Unparse(const Expr::LE &x) { Walk(x.t, "<="); }
88064ab3302SCarolineConcatto   void Unparse(const Expr::EQ &x) { Walk(x.t, "=="); }
88164ab3302SCarolineConcatto   void Unparse(const Expr::NE &x) { Walk(x.t, "/="); }
88264ab3302SCarolineConcatto   void Unparse(const Expr::GE &x) { Walk(x.t, ">="); }
88364ab3302SCarolineConcatto   void Unparse(const Expr::GT &x) { Walk(x.t, ">"); }
88464ab3302SCarolineConcatto   void Unparse(const Expr::AND &x) { Walk(x.t, ".AND."); }
88564ab3302SCarolineConcatto   void Unparse(const Expr::OR &x) { Walk(x.t, ".OR."); }
88664ab3302SCarolineConcatto   void Unparse(const Expr::EQV &x) { Walk(x.t, ".EQV."); }
88764ab3302SCarolineConcatto   void Unparse(const Expr::NEQV &x) { Walk(x.t, ".NEQV."); }
88864ab3302SCarolineConcatto   void Unparse(const Expr::ComplexConstructor &x) {
88964ab3302SCarolineConcatto     Put('('), Walk(x.t, ","), Put(')');
89064ab3302SCarolineConcatto   }
89164ab3302SCarolineConcatto   void Unparse(const Expr::DefinedBinary &x) {
89264ab3302SCarolineConcatto     Walk(std::get<1>(x.t)); // left
89364ab3302SCarolineConcatto     Walk(std::get<DefinedOpName>(x.t));
89464ab3302SCarolineConcatto     Walk(std::get<2>(x.t)); // right
89564ab3302SCarolineConcatto   }
89664ab3302SCarolineConcatto   void Unparse(const DefinedOpName &x) { // R1003, R1023, R1414, & R1415
89764ab3302SCarolineConcatto     Walk(x.v);
89864ab3302SCarolineConcatto   }
89964ab3302SCarolineConcatto   void Unparse(const AssignmentStmt &x) { // R1032
90064ab3302SCarolineConcatto     if (asFortran_ && x.typedAssignment.get()) {
90164ab3302SCarolineConcatto       Put(' ');
90264ab3302SCarolineConcatto       asFortran_->assignment(out_, *x.typedAssignment);
90364ab3302SCarolineConcatto       Put('\n');
90464ab3302SCarolineConcatto     } else {
90564ab3302SCarolineConcatto       Walk(x.t, " = ");
90664ab3302SCarolineConcatto     }
90764ab3302SCarolineConcatto   }
90864ab3302SCarolineConcatto   void Unparse(const PointerAssignmentStmt &x) { // R1033, R1034, R1038
90964ab3302SCarolineConcatto     if (asFortran_ && x.typedAssignment.get()) {
91064ab3302SCarolineConcatto       Put(' ');
91164ab3302SCarolineConcatto       asFortran_->assignment(out_, *x.typedAssignment);
91264ab3302SCarolineConcatto       Put('\n');
91364ab3302SCarolineConcatto     } else {
91464ab3302SCarolineConcatto       Walk(std::get<DataRef>(x.t));
915cd03e96fSPeter Klausler       common::visit(
91664ab3302SCarolineConcatto           common::visitors{
91764ab3302SCarolineConcatto               [&](const std::list<BoundsRemapping> &y) {
91864ab3302SCarolineConcatto                 Put('('), Walk(y), Put(')');
91964ab3302SCarolineConcatto               },
92064ab3302SCarolineConcatto               [&](const std::list<BoundsSpec> &y) { Walk("(", y, ", ", ")"); },
92164ab3302SCarolineConcatto           },
92264ab3302SCarolineConcatto           std::get<PointerAssignmentStmt::Bounds>(x.t).u);
92364ab3302SCarolineConcatto       Put(" => "), Walk(std::get<Expr>(x.t));
92464ab3302SCarolineConcatto     }
92564ab3302SCarolineConcatto   }
92664ab3302SCarolineConcatto   void Post(const BoundsSpec &) { // R1035
92764ab3302SCarolineConcatto     Put(':');
92864ab3302SCarolineConcatto   }
92964ab3302SCarolineConcatto   void Unparse(const BoundsRemapping &x) { // R1036
93064ab3302SCarolineConcatto     Walk(x.t, ":");
93164ab3302SCarolineConcatto   }
93264ab3302SCarolineConcatto   void Unparse(const WhereStmt &x) { // R1041, R1045, R1046
93364ab3302SCarolineConcatto     Word("WHERE ("), Walk(x.t, ") ");
93464ab3302SCarolineConcatto   }
93564ab3302SCarolineConcatto   void Unparse(const WhereConstructStmt &x) { // R1043
93664ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
93764ab3302SCarolineConcatto     Word("WHERE ("), Walk(std::get<LogicalExpr>(x.t)), Put(')');
93864ab3302SCarolineConcatto     Indent();
93964ab3302SCarolineConcatto   }
94064ab3302SCarolineConcatto   void Unparse(const MaskedElsewhereStmt &x) { // R1047
94164ab3302SCarolineConcatto     Outdent();
94264ab3302SCarolineConcatto     Word("ELSEWHERE ("), Walk(std::get<LogicalExpr>(x.t)), Put(')');
94364ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<Name>>(x.t));
94464ab3302SCarolineConcatto     Indent();
94564ab3302SCarolineConcatto   }
94664ab3302SCarolineConcatto   void Unparse(const ElsewhereStmt &x) { // R1048
94764ab3302SCarolineConcatto     Outdent(), Word("ELSEWHERE"), Walk(" ", x.v), Indent();
94864ab3302SCarolineConcatto   }
94964ab3302SCarolineConcatto   void Unparse(const EndWhereStmt &x) { // R1049
95064ab3302SCarolineConcatto     Outdent(), Word("END WHERE"), Walk(" ", x.v);
95164ab3302SCarolineConcatto   }
95264ab3302SCarolineConcatto   void Unparse(const ForallConstructStmt &x) { // R1051
95364ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
95464ab3302SCarolineConcatto     Word("FORALL"), Walk(std::get<common::Indirection<ConcurrentHeader>>(x.t));
95564ab3302SCarolineConcatto     Indent();
95664ab3302SCarolineConcatto   }
95764ab3302SCarolineConcatto   void Unparse(const EndForallStmt &x) { // R1054
95864ab3302SCarolineConcatto     Outdent(), Word("END FORALL"), Walk(" ", x.v);
95964ab3302SCarolineConcatto   }
96064ab3302SCarolineConcatto   void Before(const ForallStmt &) { // R1055
96164ab3302SCarolineConcatto     Word("FORALL");
96264ab3302SCarolineConcatto   }
96364ab3302SCarolineConcatto 
96464ab3302SCarolineConcatto   void Unparse(const AssociateStmt &x) { // R1103
96564ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
96664ab3302SCarolineConcatto     Word("ASSOCIATE (");
96764ab3302SCarolineConcatto     Walk(std::get<std::list<Association>>(x.t), ", "), Put(')'), Indent();
96864ab3302SCarolineConcatto   }
96964ab3302SCarolineConcatto   void Unparse(const Association &x) { // R1104
97064ab3302SCarolineConcatto     Walk(x.t, " => ");
97164ab3302SCarolineConcatto   }
97264ab3302SCarolineConcatto   void Unparse(const EndAssociateStmt &x) { // R1106
97364ab3302SCarolineConcatto     Outdent(), Word("END ASSOCIATE"), Walk(" ", x.v);
97464ab3302SCarolineConcatto   }
97564ab3302SCarolineConcatto   void Unparse(const BlockStmt &x) { // R1108
97664ab3302SCarolineConcatto     Walk(x.v, ": "), Word("BLOCK"), Indent();
97764ab3302SCarolineConcatto   }
97864ab3302SCarolineConcatto   void Unparse(const EndBlockStmt &x) { // R1110
97964ab3302SCarolineConcatto     Outdent(), Word("END BLOCK"), Walk(" ", x.v);
98064ab3302SCarolineConcatto   }
98164ab3302SCarolineConcatto   void Unparse(const ChangeTeamStmt &x) { // R1112
98264ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
98364ab3302SCarolineConcatto     Word("CHANGE TEAM ("), Walk(std::get<TeamValue>(x.t));
98464ab3302SCarolineConcatto     Walk(", ", std::get<std::list<CoarrayAssociation>>(x.t), ", ");
98564ab3302SCarolineConcatto     Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
98664ab3302SCarolineConcatto     Indent();
98764ab3302SCarolineConcatto   }
98864ab3302SCarolineConcatto   void Unparse(const CoarrayAssociation &x) { // R1113
98964ab3302SCarolineConcatto     Walk(x.t, " => ");
99064ab3302SCarolineConcatto   }
99164ab3302SCarolineConcatto   void Unparse(const EndChangeTeamStmt &x) { // R1114
99264ab3302SCarolineConcatto     Outdent(), Word("END TEAM (");
99364ab3302SCarolineConcatto     Walk(std::get<std::list<StatOrErrmsg>>(x.t), ", ");
99464ab3302SCarolineConcatto     Put(')'), Walk(" ", std::get<std::optional<Name>>(x.t));
99564ab3302SCarolineConcatto   }
99664ab3302SCarolineConcatto   void Unparse(const CriticalStmt &x) { // R1117
99764ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
99864ab3302SCarolineConcatto     Word("CRITICAL ("), Walk(std::get<std::list<StatOrErrmsg>>(x.t), ", ");
99964ab3302SCarolineConcatto     Put(')'), Indent();
100064ab3302SCarolineConcatto   }
100164ab3302SCarolineConcatto   void Unparse(const EndCriticalStmt &x) { // R1118
100264ab3302SCarolineConcatto     Outdent(), Word("END CRITICAL"), Walk(" ", x.v);
100364ab3302SCarolineConcatto   }
100464ab3302SCarolineConcatto   void Unparse(const DoConstruct &x) { // R1119, R1120
100564ab3302SCarolineConcatto     Walk(std::get<Statement<NonLabelDoStmt>>(x.t));
100664ab3302SCarolineConcatto     Indent(), Walk(std::get<Block>(x.t), ""), Outdent();
100764ab3302SCarolineConcatto     Walk(std::get<Statement<EndDoStmt>>(x.t));
100864ab3302SCarolineConcatto   }
100964ab3302SCarolineConcatto   void Unparse(const LabelDoStmt &x) { // R1121
101064ab3302SCarolineConcatto     Word("DO "), Walk(std::get<Label>(x.t));
101164ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<LoopControl>>(x.t));
101264ab3302SCarolineConcatto   }
101364ab3302SCarolineConcatto   void Unparse(const NonLabelDoStmt &x) { // R1122
101464ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
101581d04709SPeter Klausler     Word("DO ");
101681d04709SPeter Klausler     Walk(std::get<std::optional<Label>>(x.t), " ");
101781d04709SPeter Klausler     Walk(std::get<std::optional<LoopControl>>(x.t));
101864ab3302SCarolineConcatto   }
101964ab3302SCarolineConcatto   void Unparse(const LoopControl &x) { // R1123
1020cd03e96fSPeter Klausler     common::visit(common::visitors{
102164ab3302SCarolineConcatto                       [&](const ScalarLogicalExpr &y) {
102264ab3302SCarolineConcatto                         Word("WHILE ("), Walk(y), Put(')');
102364ab3302SCarolineConcatto                       },
102464ab3302SCarolineConcatto                       [&](const auto &y) { Walk(y); },
102564ab3302SCarolineConcatto                   },
102664ab3302SCarolineConcatto         x.u);
102764ab3302SCarolineConcatto   }
102864ab3302SCarolineConcatto   void Unparse(const ConcurrentHeader &x) { // R1125
102964ab3302SCarolineConcatto     Put('('), Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
103064ab3302SCarolineConcatto     Walk(std::get<std::list<ConcurrentControl>>(x.t), ", ");
103164ab3302SCarolineConcatto     Walk(", ", std::get<std::optional<ScalarLogicalExpr>>(x.t)), Put(')');
103264ab3302SCarolineConcatto   }
103364ab3302SCarolineConcatto   void Unparse(const ConcurrentControl &x) { // R1126 - R1128
103464ab3302SCarolineConcatto     Walk(std::get<Name>(x.t)), Put('='), Walk(std::get<1>(x.t));
103564ab3302SCarolineConcatto     Put(':'), Walk(std::get<2>(x.t));
103664ab3302SCarolineConcatto     Walk(":", std::get<std::optional<ScalarIntExpr>>(x.t));
103764ab3302SCarolineConcatto   }
103864ab3302SCarolineConcatto   void Before(const LoopControl::Concurrent &) { // R1129
103964ab3302SCarolineConcatto     Word("CONCURRENT");
104064ab3302SCarolineConcatto   }
104164ab3302SCarolineConcatto   void Unparse(const LocalitySpec::Local &x) {
104264ab3302SCarolineConcatto     Word("LOCAL("), Walk(x.v, ", "), Put(')');
104364ab3302SCarolineConcatto   }
104464ab3302SCarolineConcatto   void Unparse(const LocalitySpec::LocalInit &x) {
104564ab3302SCarolineConcatto     Word("LOCAL_INIT("), Walk(x.v, ", "), Put(')');
104664ab3302SCarolineConcatto   }
10473af717d6Skhaki3   void Unparse(const LocalitySpec::Reduce &x) {
10483af717d6Skhaki3     Word("REDUCE("), Walk(std::get<parser::ReductionOperator>(x.t));
10493af717d6Skhaki3     Walk(":", std::get<std::list<parser::Name>>(x.t), ",", ")");
10503af717d6Skhaki3   }
105164ab3302SCarolineConcatto   void Unparse(const LocalitySpec::Shared &x) {
105264ab3302SCarolineConcatto     Word("SHARED("), Walk(x.v, ", "), Put(')');
105364ab3302SCarolineConcatto   }
105464ab3302SCarolineConcatto   void Post(const LocalitySpec::DefaultNone &) { Word("DEFAULT(NONE)"); }
105564ab3302SCarolineConcatto   void Unparse(const EndDoStmt &x) { // R1132
105664ab3302SCarolineConcatto     Word("END DO"), Walk(" ", x.v);
105764ab3302SCarolineConcatto   }
105864ab3302SCarolineConcatto   void Unparse(const CycleStmt &x) { // R1133
105964ab3302SCarolineConcatto     Word("CYCLE"), Walk(" ", x.v);
106064ab3302SCarolineConcatto   }
106164ab3302SCarolineConcatto   void Unparse(const IfThenStmt &x) { // R1135
106264ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
106364ab3302SCarolineConcatto     Word("IF ("), Walk(std::get<ScalarLogicalExpr>(x.t));
106464ab3302SCarolineConcatto     Put(") "), Word("THEN"), Indent();
106564ab3302SCarolineConcatto   }
106664ab3302SCarolineConcatto   void Unparse(const ElseIfStmt &x) { // R1136
106764ab3302SCarolineConcatto     Outdent(), Word("ELSE IF (");
106864ab3302SCarolineConcatto     Walk(std::get<ScalarLogicalExpr>(x.t)), Put(") "), Word("THEN");
106964ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
107064ab3302SCarolineConcatto   }
107164ab3302SCarolineConcatto   void Unparse(const ElseStmt &x) { // R1137
107264ab3302SCarolineConcatto     Outdent(), Word("ELSE"), Walk(" ", x.v), Indent();
107364ab3302SCarolineConcatto   }
107464ab3302SCarolineConcatto   void Unparse(const EndIfStmt &x) { // R1138
107564ab3302SCarolineConcatto     Outdent(), Word("END IF"), Walk(" ", x.v);
107664ab3302SCarolineConcatto   }
107764ab3302SCarolineConcatto   void Unparse(const IfStmt &x) { // R1139
107864ab3302SCarolineConcatto     Word("IF ("), Walk(x.t, ") ");
107964ab3302SCarolineConcatto   }
108064ab3302SCarolineConcatto   void Unparse(const SelectCaseStmt &x) { // R1141, R1144
108164ab3302SCarolineConcatto     Walk(std::get<std::optional<Name>>(x.t), ": ");
108264ab3302SCarolineConcatto     Word("SELECT CASE (");
108364ab3302SCarolineConcatto     Walk(std::get<Scalar<Expr>>(x.t)), Put(')'), Indent();
108464ab3302SCarolineConcatto   }
108564ab3302SCarolineConcatto   void Unparse(const CaseStmt &x) { // R1142
108664ab3302SCarolineConcatto     Outdent(), Word("CASE "), Walk(std::get<CaseSelector>(x.t));
108764ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
108864ab3302SCarolineConcatto   }
108964ab3302SCarolineConcatto   void Unparse(const EndSelectStmt &x) { // R1143 & R1151 & R1155
109064ab3302SCarolineConcatto     Outdent(), Word("END SELECT"), Walk(" ", x.v);
109164ab3302SCarolineConcatto   }
109264ab3302SCarolineConcatto   void Unparse(const CaseSelector &x) { // R1145
1093cd03e96fSPeter Klausler     common::visit(common::visitors{
109464ab3302SCarolineConcatto                       [&](const std::list<CaseValueRange> &y) {
109564ab3302SCarolineConcatto                         Put('('), Walk(y), Put(')');
109664ab3302SCarolineConcatto                       },
109764ab3302SCarolineConcatto                       [&](const Default &) { Word("DEFAULT"); },
109864ab3302SCarolineConcatto                   },
109964ab3302SCarolineConcatto         x.u);
110064ab3302SCarolineConcatto   }
110164ab3302SCarolineConcatto   void Unparse(const CaseValueRange::Range &x) { // R1146
110264ab3302SCarolineConcatto     Walk(x.lower), Put(':'), Walk(x.upper);
110364ab3302SCarolineConcatto   }
110464ab3302SCarolineConcatto   void Unparse(const SelectRankStmt &x) { // R1149
110564ab3302SCarolineConcatto     Walk(std::get<0>(x.t), ": ");
110664ab3302SCarolineConcatto     Word("SELECT RANK ("), Walk(std::get<1>(x.t), " => ");
110764ab3302SCarolineConcatto     Walk(std::get<Selector>(x.t)), Put(')'), Indent();
110864ab3302SCarolineConcatto   }
110964ab3302SCarolineConcatto   void Unparse(const SelectRankCaseStmt &x) { // R1150
111064ab3302SCarolineConcatto     Outdent(), Word("RANK ");
1111cd03e96fSPeter Klausler     common::visit(common::visitors{
111264ab3302SCarolineConcatto                       [&](const ScalarIntConstantExpr &y) {
111364ab3302SCarolineConcatto                         Put('('), Walk(y), Put(')');
111464ab3302SCarolineConcatto                       },
111564ab3302SCarolineConcatto                       [&](const Star &) { Put("(*)"); },
111664ab3302SCarolineConcatto                       [&](const Default &) { Word("DEFAULT"); },
111764ab3302SCarolineConcatto                   },
111864ab3302SCarolineConcatto         std::get<SelectRankCaseStmt::Rank>(x.t).u);
111964ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
112064ab3302SCarolineConcatto   }
112164ab3302SCarolineConcatto   void Unparse(const SelectTypeStmt &x) { // R1153
112264ab3302SCarolineConcatto     Walk(std::get<0>(x.t), ": ");
112364ab3302SCarolineConcatto     Word("SELECT TYPE ("), Walk(std::get<1>(x.t), " => ");
112464ab3302SCarolineConcatto     Walk(std::get<Selector>(x.t)), Put(')'), Indent();
112564ab3302SCarolineConcatto   }
112664ab3302SCarolineConcatto   void Unparse(const TypeGuardStmt &x) { // R1154
112764ab3302SCarolineConcatto     Outdent(), Walk(std::get<TypeGuardStmt::Guard>(x.t));
112864ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
112964ab3302SCarolineConcatto   }
113064ab3302SCarolineConcatto   void Unparse(const TypeGuardStmt::Guard &x) {
1131cd03e96fSPeter Klausler     common::visit(
113264ab3302SCarolineConcatto         common::visitors{
113364ab3302SCarolineConcatto             [&](const TypeSpec &y) { Word("TYPE IS ("), Walk(y), Put(')'); },
113464ab3302SCarolineConcatto             [&](const DerivedTypeSpec &y) {
113564ab3302SCarolineConcatto               Word("CLASS IS ("), Walk(y), Put(')');
113664ab3302SCarolineConcatto             },
113764ab3302SCarolineConcatto             [&](const Default &) { Word("CLASS DEFAULT"); },
113864ab3302SCarolineConcatto         },
113964ab3302SCarolineConcatto         x.u);
114064ab3302SCarolineConcatto   }
114164ab3302SCarolineConcatto   void Unparse(const ExitStmt &x) { // R1156
114264ab3302SCarolineConcatto     Word("EXIT"), Walk(" ", x.v);
114364ab3302SCarolineConcatto   }
114464ab3302SCarolineConcatto   void Before(const GotoStmt &) { // R1157
114564ab3302SCarolineConcatto     Word("GO TO ");
114664ab3302SCarolineConcatto   }
114764ab3302SCarolineConcatto   void Unparse(const ComputedGotoStmt &x) { // R1158
114864ab3302SCarolineConcatto     Word("GO TO ("), Walk(x.t, "), ");
114964ab3302SCarolineConcatto   }
115064ab3302SCarolineConcatto   void Unparse(const ContinueStmt &) { // R1159
115164ab3302SCarolineConcatto     Word("CONTINUE");
115264ab3302SCarolineConcatto   }
115364ab3302SCarolineConcatto   void Unparse(const StopStmt &x) { // R1160, R1161
115464ab3302SCarolineConcatto     if (std::get<StopStmt::Kind>(x.t) == StopStmt::Kind::ErrorStop) {
115564ab3302SCarolineConcatto       Word("ERROR ");
115664ab3302SCarolineConcatto     }
115764ab3302SCarolineConcatto     Word("STOP"), Walk(" ", std::get<std::optional<StopCode>>(x.t));
115864ab3302SCarolineConcatto     Walk(", QUIET=", std::get<std::optional<ScalarLogicalExpr>>(x.t));
115964ab3302SCarolineConcatto   }
116064ab3302SCarolineConcatto   void Unparse(const FailImageStmt &) { // R1163
116164ab3302SCarolineConcatto     Word("FAIL IMAGE");
116264ab3302SCarolineConcatto   }
1163a2d7af75SKatherine Rasmussen   void Unparse(const NotifyWaitStmt &x) { // F2023: R1166
1164a2d7af75SKatherine Rasmussen     Word("NOTIFY WAIT ("), Walk(std::get<Scalar<Variable>>(x.t));
1165a2d7af75SKatherine Rasmussen     Walk(", ", std::get<std::list<EventWaitSpec>>(x.t), ", ");
1166a2d7af75SKatherine Rasmussen     Put(')');
1167a2d7af75SKatherine Rasmussen   }
116864ab3302SCarolineConcatto   void Unparse(const SyncAllStmt &x) { // R1164
116964ab3302SCarolineConcatto     Word("SYNC ALL ("), Walk(x.v, ", "), Put(')');
117064ab3302SCarolineConcatto   }
117164ab3302SCarolineConcatto   void Unparse(const SyncImagesStmt &x) { // R1166
117264ab3302SCarolineConcatto     Word("SYNC IMAGES (");
117364ab3302SCarolineConcatto     Walk(std::get<SyncImagesStmt::ImageSet>(x.t));
117464ab3302SCarolineConcatto     Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
117564ab3302SCarolineConcatto   }
117664ab3302SCarolineConcatto   void Unparse(const SyncMemoryStmt &x) { // R1168
117764ab3302SCarolineConcatto     Word("SYNC MEMORY ("), Walk(x.v, ", "), Put(')');
117864ab3302SCarolineConcatto   }
117964ab3302SCarolineConcatto   void Unparse(const SyncTeamStmt &x) { // R1169
118064ab3302SCarolineConcatto     Word("SYNC TEAM ("), Walk(std::get<TeamValue>(x.t));
118164ab3302SCarolineConcatto     Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
118264ab3302SCarolineConcatto   }
118364ab3302SCarolineConcatto   void Unparse(const EventPostStmt &x) { // R1170
118464ab3302SCarolineConcatto     Word("EVENT POST ("), Walk(std::get<EventVariable>(x.t));
118564ab3302SCarolineConcatto     Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
118664ab3302SCarolineConcatto   }
1187a2d7af75SKatherine Rasmussen   void Before(const EventWaitSpec &x) { // R1173, R1174
1188cd03e96fSPeter Klausler     common::visit(common::visitors{
118964ab3302SCarolineConcatto                       [&](const ScalarIntExpr &) { Word("UNTIL_COUNT="); },
119064ab3302SCarolineConcatto                       [](const StatOrErrmsg &) {},
119164ab3302SCarolineConcatto                   },
119264ab3302SCarolineConcatto         x.u);
119364ab3302SCarolineConcatto   }
119464ab3302SCarolineConcatto   void Unparse(const EventWaitStmt &x) { // R1170
119564ab3302SCarolineConcatto     Word("EVENT WAIT ("), Walk(std::get<EventVariable>(x.t));
1196a2d7af75SKatherine Rasmussen     Walk(", ", std::get<std::list<EventWaitSpec>>(x.t), ", ");
119764ab3302SCarolineConcatto     Put(')');
119864ab3302SCarolineConcatto   }
119964ab3302SCarolineConcatto   void Unparse(const FormTeamStmt &x) { // R1175, R1177
120064ab3302SCarolineConcatto     Word("FORM TEAM ("), Walk(std::get<ScalarIntExpr>(x.t));
120164ab3302SCarolineConcatto     Put(','), Walk(std::get<TeamVariable>(x.t));
120264ab3302SCarolineConcatto     Walk(", ", std::get<std::list<FormTeamStmt::FormTeamSpec>>(x.t), ", ");
120364ab3302SCarolineConcatto     Put(')');
120464ab3302SCarolineConcatto   }
120564ab3302SCarolineConcatto   void Before(const FormTeamStmt::FormTeamSpec &x) { // R1176, R1178
1206cd03e96fSPeter Klausler     common::visit(common::visitors{
120764ab3302SCarolineConcatto                       [&](const ScalarIntExpr &) { Word("NEW_INDEX="); },
120864ab3302SCarolineConcatto                       [](const StatOrErrmsg &) {},
120964ab3302SCarolineConcatto                   },
121064ab3302SCarolineConcatto         x.u);
121164ab3302SCarolineConcatto   }
121264ab3302SCarolineConcatto   void Unparse(const LockStmt &x) { // R1179
121364ab3302SCarolineConcatto     Word("LOCK ("), Walk(std::get<LockVariable>(x.t));
121464ab3302SCarolineConcatto     Walk(", ", std::get<std::list<LockStmt::LockStat>>(x.t), ", ");
121564ab3302SCarolineConcatto     Put(')');
121664ab3302SCarolineConcatto   }
121764ab3302SCarolineConcatto   void Before(const LockStmt::LockStat &x) { // R1180
1218cd03e96fSPeter Klausler     common::visit(
121964ab3302SCarolineConcatto         common::visitors{
122064ab3302SCarolineConcatto             [&](const ScalarLogicalVariable &) { Word("ACQUIRED_LOCK="); },
122164ab3302SCarolineConcatto             [](const StatOrErrmsg &) {},
122264ab3302SCarolineConcatto         },
122364ab3302SCarolineConcatto         x.u);
122464ab3302SCarolineConcatto   }
122564ab3302SCarolineConcatto   void Unparse(const UnlockStmt &x) { // R1181
122664ab3302SCarolineConcatto     Word("UNLOCK ("), Walk(std::get<LockVariable>(x.t));
122764ab3302SCarolineConcatto     Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", ");
122864ab3302SCarolineConcatto     Put(')');
122964ab3302SCarolineConcatto   }
123064ab3302SCarolineConcatto 
123164ab3302SCarolineConcatto   void Unparse(const OpenStmt &x) { // R1204
123264ab3302SCarolineConcatto     Word("OPEN ("), Walk(x.v, ", "), Put(')');
123364ab3302SCarolineConcatto   }
123464ab3302SCarolineConcatto   bool Pre(const ConnectSpec &x) { // R1205
1235cd03e96fSPeter Klausler     return common::visit(common::visitors{
123664ab3302SCarolineConcatto                              [&](const FileUnitNumber &) {
123764ab3302SCarolineConcatto                                Word("UNIT=");
123864ab3302SCarolineConcatto                                return true;
123964ab3302SCarolineConcatto                              },
124064ab3302SCarolineConcatto                              [&](const FileNameExpr &) {
124164ab3302SCarolineConcatto                                Word("FILE=");
124264ab3302SCarolineConcatto                                return true;
124364ab3302SCarolineConcatto                              },
124464ab3302SCarolineConcatto                              [&](const ConnectSpec::CharExpr &y) {
124564ab3302SCarolineConcatto                                Walk(y.t, "=");
124664ab3302SCarolineConcatto                                return false;
124764ab3302SCarolineConcatto                              },
124864ab3302SCarolineConcatto                              [&](const MsgVariable &) {
124964ab3302SCarolineConcatto                                Word("IOMSG=");
125064ab3302SCarolineConcatto                                return true;
125164ab3302SCarolineConcatto                              },
125264ab3302SCarolineConcatto                              [&](const StatVariable &) {
125364ab3302SCarolineConcatto                                Word("IOSTAT=");
125464ab3302SCarolineConcatto                                return true;
125564ab3302SCarolineConcatto                              },
125664ab3302SCarolineConcatto                              [&](const ConnectSpec::Recl &) {
125764ab3302SCarolineConcatto                                Word("RECL=");
125864ab3302SCarolineConcatto                                return true;
125964ab3302SCarolineConcatto                              },
126064ab3302SCarolineConcatto                              [&](const ConnectSpec::Newunit &) {
126164ab3302SCarolineConcatto                                Word("NEWUNIT=");
126264ab3302SCarolineConcatto                                return true;
126364ab3302SCarolineConcatto                              },
126464ab3302SCarolineConcatto                              [&](const ErrLabel &) {
126564ab3302SCarolineConcatto                                Word("ERR=");
126664ab3302SCarolineConcatto                                return true;
126764ab3302SCarolineConcatto                              },
126864ab3302SCarolineConcatto                              [&](const StatusExpr &) {
126964ab3302SCarolineConcatto                                Word("STATUS=");
127064ab3302SCarolineConcatto                                return true;
127164ab3302SCarolineConcatto                              },
127264ab3302SCarolineConcatto                          },
127364ab3302SCarolineConcatto         x.u);
127464ab3302SCarolineConcatto   }
127564ab3302SCarolineConcatto   void Unparse(const CloseStmt &x) { // R1208
127664ab3302SCarolineConcatto     Word("CLOSE ("), Walk(x.v, ", "), Put(')');
127764ab3302SCarolineConcatto   }
127864ab3302SCarolineConcatto   void Before(const CloseStmt::CloseSpec &x) { // R1209
1279cd03e96fSPeter Klausler     common::visit(common::visitors{
128064ab3302SCarolineConcatto                       [&](const FileUnitNumber &) { Word("UNIT="); },
128164ab3302SCarolineConcatto                       [&](const StatVariable &) { Word("IOSTAT="); },
128264ab3302SCarolineConcatto                       [&](const MsgVariable &) { Word("IOMSG="); },
128364ab3302SCarolineConcatto                       [&](const ErrLabel &) { Word("ERR="); },
128464ab3302SCarolineConcatto                       [&](const StatusExpr &) { Word("STATUS="); },
128564ab3302SCarolineConcatto                   },
128664ab3302SCarolineConcatto         x.u);
128764ab3302SCarolineConcatto   }
128864ab3302SCarolineConcatto   void Unparse(const ReadStmt &x) { // R1210
128964ab3302SCarolineConcatto     Word("READ ");
129064ab3302SCarolineConcatto     if (x.iounit) {
129164ab3302SCarolineConcatto       Put('('), Walk(x.iounit);
129264ab3302SCarolineConcatto       if (x.format) {
129364ab3302SCarolineConcatto         Put(", "), Walk(x.format);
129464ab3302SCarolineConcatto       }
129564ab3302SCarolineConcatto       Walk(", ", x.controls, ", ");
129664ab3302SCarolineConcatto       Put(')');
129764ab3302SCarolineConcatto     } else if (x.format) {
129864ab3302SCarolineConcatto       Walk(x.format);
129964ab3302SCarolineConcatto       if (!x.items.empty()) {
130064ab3302SCarolineConcatto         Put(", ");
130164ab3302SCarolineConcatto       }
130264ab3302SCarolineConcatto     } else {
130364ab3302SCarolineConcatto       Put('('), Walk(x.controls, ", "), Put(')');
130464ab3302SCarolineConcatto     }
130564ab3302SCarolineConcatto     Walk(" ", x.items, ", ");
130664ab3302SCarolineConcatto   }
130764ab3302SCarolineConcatto   void Unparse(const WriteStmt &x) { // R1211
130864ab3302SCarolineConcatto     Word("WRITE (");
130964ab3302SCarolineConcatto     if (x.iounit) {
131064ab3302SCarolineConcatto       Walk(x.iounit);
131164ab3302SCarolineConcatto       if (x.format) {
131264ab3302SCarolineConcatto         Put(", "), Walk(x.format);
131364ab3302SCarolineConcatto       }
131464ab3302SCarolineConcatto       Walk(", ", x.controls, ", ");
131564ab3302SCarolineConcatto     } else {
131664ab3302SCarolineConcatto       Walk(x.controls, ", ");
131764ab3302SCarolineConcatto     }
131864ab3302SCarolineConcatto     Put(')'), Walk(" ", x.items, ", ");
131964ab3302SCarolineConcatto   }
132064ab3302SCarolineConcatto   void Unparse(const PrintStmt &x) { // R1212
132164ab3302SCarolineConcatto     Word("PRINT "), Walk(std::get<Format>(x.t));
132264ab3302SCarolineConcatto     Walk(", ", std::get<std::list<OutputItem>>(x.t), ", ");
132364ab3302SCarolineConcatto   }
132464ab3302SCarolineConcatto   bool Pre(const IoControlSpec &x) { // R1213
1325cd03e96fSPeter Klausler     return common::visit(common::visitors{
132664ab3302SCarolineConcatto                              [&](const IoUnit &) {
132764ab3302SCarolineConcatto                                Word("UNIT=");
132864ab3302SCarolineConcatto                                return true;
132964ab3302SCarolineConcatto                              },
133064ab3302SCarolineConcatto                              [&](const Format &) {
133164ab3302SCarolineConcatto                                Word("FMT=");
133264ab3302SCarolineConcatto                                return true;
133364ab3302SCarolineConcatto                              },
133464ab3302SCarolineConcatto                              [&](const Name &) {
133564ab3302SCarolineConcatto                                Word("NML=");
133664ab3302SCarolineConcatto                                return true;
133764ab3302SCarolineConcatto                              },
133864ab3302SCarolineConcatto                              [&](const IoControlSpec::CharExpr &y) {
133964ab3302SCarolineConcatto                                Walk(y.t, "=");
134064ab3302SCarolineConcatto                                return false;
134164ab3302SCarolineConcatto                              },
134264ab3302SCarolineConcatto                              [&](const IoControlSpec::Asynchronous &) {
134364ab3302SCarolineConcatto                                Word("ASYNCHRONOUS=");
134464ab3302SCarolineConcatto                                return true;
134564ab3302SCarolineConcatto                              },
134664ab3302SCarolineConcatto                              [&](const EndLabel &) {
134764ab3302SCarolineConcatto                                Word("END=");
134864ab3302SCarolineConcatto                                return true;
134964ab3302SCarolineConcatto                              },
135064ab3302SCarolineConcatto                              [&](const EorLabel &) {
135164ab3302SCarolineConcatto                                Word("EOR=");
135264ab3302SCarolineConcatto                                return true;
135364ab3302SCarolineConcatto                              },
135464ab3302SCarolineConcatto                              [&](const ErrLabel &) {
135564ab3302SCarolineConcatto                                Word("ERR=");
135664ab3302SCarolineConcatto                                return true;
135764ab3302SCarolineConcatto                              },
135864ab3302SCarolineConcatto                              [&](const IdVariable &) {
135964ab3302SCarolineConcatto                                Word("ID=");
136064ab3302SCarolineConcatto                                return true;
136164ab3302SCarolineConcatto                              },
136264ab3302SCarolineConcatto                              [&](const MsgVariable &) {
136364ab3302SCarolineConcatto                                Word("IOMSG=");
136464ab3302SCarolineConcatto                                return true;
136564ab3302SCarolineConcatto                              },
136664ab3302SCarolineConcatto                              [&](const StatVariable &) {
136764ab3302SCarolineConcatto                                Word("IOSTAT=");
136864ab3302SCarolineConcatto                                return true;
136964ab3302SCarolineConcatto                              },
137064ab3302SCarolineConcatto                              [&](const IoControlSpec::Pos &) {
137164ab3302SCarolineConcatto                                Word("POS=");
137264ab3302SCarolineConcatto                                return true;
137364ab3302SCarolineConcatto                              },
137464ab3302SCarolineConcatto                              [&](const IoControlSpec::Rec &) {
137564ab3302SCarolineConcatto                                Word("REC=");
137664ab3302SCarolineConcatto                                return true;
137764ab3302SCarolineConcatto                              },
137864ab3302SCarolineConcatto                              [&](const IoControlSpec::Size &) {
137964ab3302SCarolineConcatto                                Word("SIZE=");
138064ab3302SCarolineConcatto                                return true;
138164ab3302SCarolineConcatto                              },
138264ab3302SCarolineConcatto                          },
138364ab3302SCarolineConcatto         x.u);
138464ab3302SCarolineConcatto   }
138564ab3302SCarolineConcatto   void Unparse(const InputImpliedDo &x) { // R1218
138664ab3302SCarolineConcatto     Put('('), Walk(std::get<std::list<InputItem>>(x.t), ", "), Put(", ");
138764ab3302SCarolineConcatto     Walk(std::get<IoImpliedDoControl>(x.t)), Put(')');
138864ab3302SCarolineConcatto   }
138964ab3302SCarolineConcatto   void Unparse(const OutputImpliedDo &x) { // R1219
139064ab3302SCarolineConcatto     Put('('), Walk(std::get<std::list<OutputItem>>(x.t), ", "), Put(", ");
139164ab3302SCarolineConcatto     Walk(std::get<IoImpliedDoControl>(x.t)), Put(')');
139264ab3302SCarolineConcatto   }
139364ab3302SCarolineConcatto   void Unparse(const WaitStmt &x) { // R1222
139464ab3302SCarolineConcatto     Word("WAIT ("), Walk(x.v, ", "), Put(')');
139564ab3302SCarolineConcatto   }
139664ab3302SCarolineConcatto   void Before(const WaitSpec &x) { // R1223
1397cd03e96fSPeter Klausler     common::visit(common::visitors{
139864ab3302SCarolineConcatto                       [&](const FileUnitNumber &) { Word("UNIT="); },
139964ab3302SCarolineConcatto                       [&](const EndLabel &) { Word("END="); },
140064ab3302SCarolineConcatto                       [&](const EorLabel &) { Word("EOR="); },
140164ab3302SCarolineConcatto                       [&](const ErrLabel &) { Word("ERR="); },
140264ab3302SCarolineConcatto                       [&](const IdExpr &) { Word("ID="); },
140364ab3302SCarolineConcatto                       [&](const MsgVariable &) { Word("IOMSG="); },
140464ab3302SCarolineConcatto                       [&](const StatVariable &) { Word("IOSTAT="); },
140564ab3302SCarolineConcatto                   },
140664ab3302SCarolineConcatto         x.u);
140764ab3302SCarolineConcatto   }
140864ab3302SCarolineConcatto   void Unparse(const BackspaceStmt &x) { // R1224
140964ab3302SCarolineConcatto     Word("BACKSPACE ("), Walk(x.v, ", "), Put(')');
141064ab3302SCarolineConcatto   }
141164ab3302SCarolineConcatto   void Unparse(const EndfileStmt &x) { // R1225
141264ab3302SCarolineConcatto     Word("ENDFILE ("), Walk(x.v, ", "), Put(')');
141364ab3302SCarolineConcatto   }
141464ab3302SCarolineConcatto   void Unparse(const RewindStmt &x) { // R1226
141564ab3302SCarolineConcatto     Word("REWIND ("), Walk(x.v, ", "), Put(')');
141664ab3302SCarolineConcatto   }
141764ab3302SCarolineConcatto   void Before(const PositionOrFlushSpec &x) { // R1227 & R1229
1418cd03e96fSPeter Klausler     common::visit(common::visitors{
141964ab3302SCarolineConcatto                       [&](const FileUnitNumber &) { Word("UNIT="); },
142064ab3302SCarolineConcatto                       [&](const MsgVariable &) { Word("IOMSG="); },
142164ab3302SCarolineConcatto                       [&](const StatVariable &) { Word("IOSTAT="); },
142264ab3302SCarolineConcatto                       [&](const ErrLabel &) { Word("ERR="); },
142364ab3302SCarolineConcatto                   },
142464ab3302SCarolineConcatto         x.u);
142564ab3302SCarolineConcatto   }
142664ab3302SCarolineConcatto   void Unparse(const FlushStmt &x) { // R1228
142764ab3302SCarolineConcatto     Word("FLUSH ("), Walk(x.v, ", "), Put(')');
142864ab3302SCarolineConcatto   }
142964ab3302SCarolineConcatto   void Unparse(const InquireStmt &x) { // R1230
143064ab3302SCarolineConcatto     Word("INQUIRE (");
1431cd03e96fSPeter Klausler     common::visit(
143264ab3302SCarolineConcatto         common::visitors{
143364ab3302SCarolineConcatto             [&](const InquireStmt::Iolength &y) {
143464ab3302SCarolineConcatto               Word("IOLENGTH="), Walk(y.t, ") ");
143564ab3302SCarolineConcatto             },
143664ab3302SCarolineConcatto             [&](const std::list<InquireSpec> &y) { Walk(y, ", "), Put(')'); },
143764ab3302SCarolineConcatto         },
143864ab3302SCarolineConcatto         x.u);
143964ab3302SCarolineConcatto   }
144064ab3302SCarolineConcatto   bool Pre(const InquireSpec &x) { // R1231
1441cd03e96fSPeter Klausler     return common::visit(common::visitors{
144264ab3302SCarolineConcatto                              [&](const FileUnitNumber &) {
144364ab3302SCarolineConcatto                                Word("UNIT=");
144464ab3302SCarolineConcatto                                return true;
144564ab3302SCarolineConcatto                              },
144664ab3302SCarolineConcatto                              [&](const FileNameExpr &) {
144764ab3302SCarolineConcatto                                Word("FILE=");
144864ab3302SCarolineConcatto                                return true;
144964ab3302SCarolineConcatto                              },
145064ab3302SCarolineConcatto                              [&](const InquireSpec::CharVar &y) {
145164ab3302SCarolineConcatto                                Walk(y.t, "=");
145264ab3302SCarolineConcatto                                return false;
145364ab3302SCarolineConcatto                              },
145464ab3302SCarolineConcatto                              [&](const InquireSpec::IntVar &y) {
145564ab3302SCarolineConcatto                                Walk(y.t, "=");
145664ab3302SCarolineConcatto                                return false;
145764ab3302SCarolineConcatto                              },
145864ab3302SCarolineConcatto                              [&](const InquireSpec::LogVar &y) {
145964ab3302SCarolineConcatto                                Walk(y.t, "=");
146064ab3302SCarolineConcatto                                return false;
146164ab3302SCarolineConcatto                              },
146264ab3302SCarolineConcatto                              [&](const IdExpr &) {
146364ab3302SCarolineConcatto                                Word("ID=");
146464ab3302SCarolineConcatto                                return true;
146564ab3302SCarolineConcatto                              },
146664ab3302SCarolineConcatto                              [&](const ErrLabel &) {
146764ab3302SCarolineConcatto                                Word("ERR=");
146864ab3302SCarolineConcatto                                return true;
146964ab3302SCarolineConcatto                              },
147064ab3302SCarolineConcatto                          },
147164ab3302SCarolineConcatto         x.u);
147264ab3302SCarolineConcatto   }
147364ab3302SCarolineConcatto 
147464ab3302SCarolineConcatto   void Before(const FormatStmt &) { // R1301
147564ab3302SCarolineConcatto     Word("FORMAT");
147664ab3302SCarolineConcatto   }
147764ab3302SCarolineConcatto   void Unparse(const format::FormatSpecification &x) { // R1302, R1303, R1305
147864ab3302SCarolineConcatto     Put('('), Walk("", x.items, ",", x.unlimitedItems.empty() ? "" : ",");
147964ab3302SCarolineConcatto     Walk("*(", x.unlimitedItems, ",", ")"), Put(')');
148064ab3302SCarolineConcatto   }
148164ab3302SCarolineConcatto   void Unparse(const format::FormatItem &x) { // R1304, R1306, R1321
148264ab3302SCarolineConcatto     if (x.repeatCount) {
148364ab3302SCarolineConcatto       Walk(*x.repeatCount);
148464ab3302SCarolineConcatto     }
1485cd03e96fSPeter Klausler     common::visit(common::visitors{
148664ab3302SCarolineConcatto                       [&](const std::string &y) { PutNormalized(y); },
148764ab3302SCarolineConcatto                       [&](const std::list<format::FormatItem> &y) {
148864ab3302SCarolineConcatto                         Walk("(", y, ",", ")");
148964ab3302SCarolineConcatto                       },
149064ab3302SCarolineConcatto                       [&](const auto &y) { Walk(y); },
149164ab3302SCarolineConcatto                   },
149264ab3302SCarolineConcatto         x.u);
149364ab3302SCarolineConcatto   }
149464ab3302SCarolineConcatto   void Unparse(
149564ab3302SCarolineConcatto       const format::IntrinsicTypeDataEditDesc &x) { // R1307(1/2) - R1311
149664ab3302SCarolineConcatto     switch (x.kind) {
149764ab3302SCarolineConcatto #define FMT(x) \
14981f879005STim Keith   case format::IntrinsicTypeDataEditDesc::Kind::x: \
14991f879005STim Keith     Put(#x); \
15001f879005STim Keith     break
150164ab3302SCarolineConcatto       FMT(I);
150264ab3302SCarolineConcatto       FMT(B);
150364ab3302SCarolineConcatto       FMT(O);
150464ab3302SCarolineConcatto       FMT(Z);
150564ab3302SCarolineConcatto       FMT(F);
150664ab3302SCarolineConcatto       FMT(E);
150764ab3302SCarolineConcatto       FMT(EN);
150864ab3302SCarolineConcatto       FMT(ES);
150964ab3302SCarolineConcatto       FMT(EX);
151064ab3302SCarolineConcatto       FMT(G);
151164ab3302SCarolineConcatto       FMT(L);
151264ab3302SCarolineConcatto       FMT(A);
151364ab3302SCarolineConcatto       FMT(D);
151464ab3302SCarolineConcatto #undef FMT
151564ab3302SCarolineConcatto     }
151664ab3302SCarolineConcatto     Walk(x.width), Walk(".", x.digits), Walk("E", x.exponentWidth);
151764ab3302SCarolineConcatto   }
151864ab3302SCarolineConcatto   void Unparse(const format::DerivedTypeDataEditDesc &x) { // R1307(2/2), R1312
151964ab3302SCarolineConcatto     Word("DT");
152064ab3302SCarolineConcatto     if (!x.type.empty()) {
152164ab3302SCarolineConcatto       Put('"'), Put(x.type), Put('"');
152264ab3302SCarolineConcatto     }
152364ab3302SCarolineConcatto     Walk("(", x.parameters, ",", ")");
152464ab3302SCarolineConcatto   }
152564ab3302SCarolineConcatto   void Unparse(const format::ControlEditDesc &x) { // R1313, R1315-R1320
152664ab3302SCarolineConcatto     switch (x.kind) {
152764ab3302SCarolineConcatto     case format::ControlEditDesc::Kind::T:
152864ab3302SCarolineConcatto       Word("T");
152964ab3302SCarolineConcatto       Walk(x.count);
153064ab3302SCarolineConcatto       break;
153164ab3302SCarolineConcatto     case format::ControlEditDesc::Kind::TL:
153264ab3302SCarolineConcatto       Word("TL");
153364ab3302SCarolineConcatto       Walk(x.count);
153464ab3302SCarolineConcatto       break;
153564ab3302SCarolineConcatto     case format::ControlEditDesc::Kind::TR:
153664ab3302SCarolineConcatto       Word("TR");
153764ab3302SCarolineConcatto       Walk(x.count);
153864ab3302SCarolineConcatto       break;
153964ab3302SCarolineConcatto     case format::ControlEditDesc::Kind::X:
154064ab3302SCarolineConcatto       if (x.count != 1) {
154164ab3302SCarolineConcatto         Walk(x.count);
154264ab3302SCarolineConcatto       }
154364ab3302SCarolineConcatto       Word("X");
154464ab3302SCarolineConcatto       break;
154564ab3302SCarolineConcatto     case format::ControlEditDesc::Kind::Slash:
154664ab3302SCarolineConcatto       if (x.count != 1) {
154764ab3302SCarolineConcatto         Walk(x.count);
154864ab3302SCarolineConcatto       }
154964ab3302SCarolineConcatto       Put('/');
155064ab3302SCarolineConcatto       break;
15511f879005STim Keith     case format::ControlEditDesc::Kind::Colon:
15521f879005STim Keith       Put(':');
15531f879005STim Keith       break;
155464ab3302SCarolineConcatto     case format::ControlEditDesc::Kind::P:
155564ab3302SCarolineConcatto       Walk(x.count);
155664ab3302SCarolineConcatto       Word("P");
155764ab3302SCarolineConcatto       break;
155864ab3302SCarolineConcatto #define FMT(x) \
15591f879005STim Keith   case format::ControlEditDesc::Kind::x: \
15601f879005STim Keith     Put(#x); \
15611f879005STim Keith     break
156264ab3302SCarolineConcatto       FMT(SS);
156364ab3302SCarolineConcatto       FMT(SP);
156464ab3302SCarolineConcatto       FMT(S);
156564ab3302SCarolineConcatto       FMT(BN);
156664ab3302SCarolineConcatto       FMT(BZ);
156764ab3302SCarolineConcatto       FMT(RU);
156864ab3302SCarolineConcatto       FMT(RD);
156964ab3302SCarolineConcatto       FMT(RZ);
157064ab3302SCarolineConcatto       FMT(RN);
157164ab3302SCarolineConcatto       FMT(RC);
157264ab3302SCarolineConcatto       FMT(RP);
157364ab3302SCarolineConcatto       FMT(DC);
157464ab3302SCarolineConcatto       FMT(DP);
157564ab3302SCarolineConcatto #undef FMT
15761f879005STim Keith     case format::ControlEditDesc::Kind::Dollar:
15771f879005STim Keith       Put('$');
15781f879005STim Keith       break;
15791f879005STim Keith     case format::ControlEditDesc::Kind::Backslash:
15801f879005STim Keith       Put('\\');
15811f879005STim Keith       break;
158264ab3302SCarolineConcatto     }
158364ab3302SCarolineConcatto   }
158464ab3302SCarolineConcatto 
158564ab3302SCarolineConcatto   void Before(const MainProgram &x) { // R1401
158664ab3302SCarolineConcatto     if (!std::get<std::optional<Statement<ProgramStmt>>>(x.t)) {
158764ab3302SCarolineConcatto       Indent();
158864ab3302SCarolineConcatto     }
158964ab3302SCarolineConcatto   }
159064ab3302SCarolineConcatto   void Before(const ProgramStmt &) { // R1402
159164ab3302SCarolineConcatto     Word("PROGRAM "), Indent();
159264ab3302SCarolineConcatto   }
159364ab3302SCarolineConcatto   void Unparse(const EndProgramStmt &x) { // R1403
159464ab3302SCarolineConcatto     EndSubprogram("PROGRAM", x.v);
159564ab3302SCarolineConcatto   }
159664ab3302SCarolineConcatto   void Before(const ModuleStmt &) { // R1405
159764ab3302SCarolineConcatto     Word("MODULE "), Indent();
159864ab3302SCarolineConcatto   }
159964ab3302SCarolineConcatto   void Unparse(const EndModuleStmt &x) { // R1406
160064ab3302SCarolineConcatto     EndSubprogram("MODULE", x.v);
160164ab3302SCarolineConcatto   }
160264ab3302SCarolineConcatto   void Unparse(const UseStmt &x) { // R1409
160364ab3302SCarolineConcatto     Word("USE"), Walk(", ", x.nature), Put(" :: "), Walk(x.moduleName);
1604cd03e96fSPeter Klausler     common::visit(
1605cd03e96fSPeter Klausler         common::visitors{
160664ab3302SCarolineConcatto             [&](const std::list<Rename> &y) { Walk(", ", y, ", "); },
160764ab3302SCarolineConcatto             [&](const std::list<Only> &y) { Walk(", ONLY: ", y, ", "); },
160864ab3302SCarolineConcatto         },
160964ab3302SCarolineConcatto         x.u);
161064ab3302SCarolineConcatto   }
161164ab3302SCarolineConcatto   void Unparse(const Rename &x) { // R1411
1612cd03e96fSPeter Klausler     common::visit(common::visitors{
161364ab3302SCarolineConcatto                       [&](const Rename::Names &y) { Walk(y.t, " => "); },
161464ab3302SCarolineConcatto                       [&](const Rename::Operators &y) {
1615cd03e96fSPeter Klausler                         Word("OPERATOR("), Walk(y.t, ") => OPERATOR("),
1616cd03e96fSPeter Klausler                             Put(")");
161764ab3302SCarolineConcatto                       },
161864ab3302SCarolineConcatto                   },
161964ab3302SCarolineConcatto         x.u);
162064ab3302SCarolineConcatto   }
162164ab3302SCarolineConcatto   void Unparse(const SubmoduleStmt &x) { // R1417
162264ab3302SCarolineConcatto     Word("SUBMODULE ("), WalkTupleElements(x.t, ")"), Indent();
162364ab3302SCarolineConcatto   }
162464ab3302SCarolineConcatto   void Unparse(const ParentIdentifier &x) { // R1418
162564ab3302SCarolineConcatto     Walk(std::get<Name>(x.t)), Walk(":", std::get<std::optional<Name>>(x.t));
162664ab3302SCarolineConcatto   }
162764ab3302SCarolineConcatto   void Unparse(const EndSubmoduleStmt &x) { // R1419
162864ab3302SCarolineConcatto     EndSubprogram("SUBMODULE", x.v);
162964ab3302SCarolineConcatto   }
163064ab3302SCarolineConcatto   void Unparse(const BlockDataStmt &x) { // R1421
163164ab3302SCarolineConcatto     Word("BLOCK DATA"), Walk(" ", x.v), Indent();
163264ab3302SCarolineConcatto   }
163364ab3302SCarolineConcatto   void Unparse(const EndBlockDataStmt &x) { // R1422
163464ab3302SCarolineConcatto     EndSubprogram("BLOCK DATA", x.v);
163564ab3302SCarolineConcatto   }
163664ab3302SCarolineConcatto 
163764ab3302SCarolineConcatto   void Unparse(const InterfaceStmt &x) { // R1503
1638cd03e96fSPeter Klausler     common::visit(common::visitors{
163964ab3302SCarolineConcatto                       [&](const std::optional<GenericSpec> &y) {
164064ab3302SCarolineConcatto                         Word("INTERFACE"), Walk(" ", y);
164164ab3302SCarolineConcatto                       },
164264ab3302SCarolineConcatto                       [&](const Abstract &) { Word("ABSTRACT INTERFACE"); },
164364ab3302SCarolineConcatto                   },
164464ab3302SCarolineConcatto         x.u);
164564ab3302SCarolineConcatto     Indent();
164664ab3302SCarolineConcatto   }
164764ab3302SCarolineConcatto   void Unparse(const EndInterfaceStmt &x) { // R1504
164864ab3302SCarolineConcatto     Outdent(), Word("END INTERFACE"), Walk(" ", x.v);
164964ab3302SCarolineConcatto   }
165064ab3302SCarolineConcatto   void Unparse(const ProcedureStmt &x) { // R1506
165164ab3302SCarolineConcatto     if (std::get<ProcedureStmt::Kind>(x.t) ==
165264ab3302SCarolineConcatto         ProcedureStmt::Kind::ModuleProcedure) {
165364ab3302SCarolineConcatto       Word("MODULE ");
165464ab3302SCarolineConcatto     }
165564ab3302SCarolineConcatto     Word("PROCEDURE :: ");
165664ab3302SCarolineConcatto     Walk(std::get<std::list<Name>>(x.t), ", ");
165764ab3302SCarolineConcatto   }
165864ab3302SCarolineConcatto   void Before(const GenericSpec &x) { // R1508, R1509
1659cd03e96fSPeter Klausler     common::visit(
166064ab3302SCarolineConcatto         common::visitors{
166164ab3302SCarolineConcatto             [&](const DefinedOperator &) { Word("OPERATOR("); },
166264ab3302SCarolineConcatto             [&](const GenericSpec::Assignment &) { Word("ASSIGNMENT(=)"); },
166364ab3302SCarolineConcatto             [&](const GenericSpec::ReadFormatted &) {
166464ab3302SCarolineConcatto               Word("READ(FORMATTED)");
166564ab3302SCarolineConcatto             },
166664ab3302SCarolineConcatto             [&](const GenericSpec::ReadUnformatted &) {
166764ab3302SCarolineConcatto               Word("READ(UNFORMATTED)");
166864ab3302SCarolineConcatto             },
166964ab3302SCarolineConcatto             [&](const GenericSpec::WriteFormatted &) {
167064ab3302SCarolineConcatto               Word("WRITE(FORMATTED)");
167164ab3302SCarolineConcatto             },
167264ab3302SCarolineConcatto             [&](const GenericSpec::WriteUnformatted &) {
167364ab3302SCarolineConcatto               Word("WRITE(UNFORMATTED)");
167464ab3302SCarolineConcatto             },
167564ab3302SCarolineConcatto             [](const auto &) {},
167664ab3302SCarolineConcatto         },
167764ab3302SCarolineConcatto         x.u);
167864ab3302SCarolineConcatto   }
167964ab3302SCarolineConcatto   void Post(const GenericSpec &x) {
1680cd03e96fSPeter Klausler     common::visit(common::visitors{
168164ab3302SCarolineConcatto                       [&](const DefinedOperator &) { Put(')'); },
168264ab3302SCarolineConcatto                       [](const auto &) {},
168364ab3302SCarolineConcatto                   },
168464ab3302SCarolineConcatto         x.u);
168564ab3302SCarolineConcatto   }
168664ab3302SCarolineConcatto   void Unparse(const GenericStmt &x) { // R1510
168764ab3302SCarolineConcatto     Word("GENERIC"), Walk(", ", std::get<std::optional<AccessSpec>>(x.t));
168864ab3302SCarolineConcatto     Put(" :: "), Walk(std::get<GenericSpec>(x.t)), Put(" => ");
168964ab3302SCarolineConcatto     Walk(std::get<std::list<Name>>(x.t), ", ");
169064ab3302SCarolineConcatto   }
169164ab3302SCarolineConcatto   void Unparse(const ExternalStmt &x) { // R1511
169264ab3302SCarolineConcatto     Word("EXTERNAL :: "), Walk(x.v, ", ");
169364ab3302SCarolineConcatto   }
169464ab3302SCarolineConcatto   void Unparse(const ProcedureDeclarationStmt &x) { // R1512
169564ab3302SCarolineConcatto     Word("PROCEDURE("), Walk(std::get<std::optional<ProcInterface>>(x.t));
169664ab3302SCarolineConcatto     Put(')'), Walk(", ", std::get<std::list<ProcAttrSpec>>(x.t), ", ");
169764ab3302SCarolineConcatto     Put(" :: "), Walk(std::get<std::list<ProcDecl>>(x.t), ", ");
169864ab3302SCarolineConcatto   }
169964ab3302SCarolineConcatto   void Unparse(const ProcDecl &x) { // R1515
170064ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
170164ab3302SCarolineConcatto     Walk(" => ", std::get<std::optional<ProcPointerInit>>(x.t));
170264ab3302SCarolineConcatto   }
170364ab3302SCarolineConcatto   void Unparse(const IntrinsicStmt &x) { // R1519
170464ab3302SCarolineConcatto     Word("INTRINSIC :: "), Walk(x.v, ", ");
170564ab3302SCarolineConcatto   }
1706fe5a64d1SValentin Clement (バレンタイン クレメン)   void Unparse(const CallStmt::StarOrExpr &x) {
1707fe5a64d1SValentin Clement (バレンタイン クレメン)     if (x.v) {
1708fe5a64d1SValentin Clement (バレンタイン クレメン)       Walk(*x.v);
1709fe5a64d1SValentin Clement (バレンタイン クレメン)     } else {
1710fe5a64d1SValentin Clement (バレンタイン クレメン)       Word("*");
1711fe5a64d1SValentin Clement (バレンタイン クレメン)     }
1712fe5a64d1SValentin Clement (バレンタイン クレメン)   }
17134ad72793SPeter Klausler   void Unparse(const CallStmt::Chevrons &x) { // CUDA
17144ad72793SPeter Klausler     Walk(std::get<0>(x.t)); // grid
17154ad72793SPeter Klausler     Word(","), Walk(std::get<1>(x.t)); // block
17164ad72793SPeter Klausler     Walk(",", std::get<2>(x.t)); // bytes
17174ad72793SPeter Klausler     Walk(",", std::get<3>(x.t)); // stream
17184ad72793SPeter Klausler   }
171964ab3302SCarolineConcatto   void Unparse(const FunctionReference &x) { // R1520
172064ab3302SCarolineConcatto     Walk(std::get<ProcedureDesignator>(x.v.t));
172164ab3302SCarolineConcatto     Put('('), Walk(std::get<std::list<ActualArgSpec>>(x.v.t), ", "), Put(')');
172264ab3302SCarolineConcatto   }
172364ab3302SCarolineConcatto   void Unparse(const CallStmt &x) { // R1521
1724f674ddc1SPeter Klausler     if (asFortran_ && x.typedCall.get()) {
172564ab3302SCarolineConcatto       Put(' ');
172664ab3302SCarolineConcatto       asFortran_->call(out_, *x.typedCall);
172764ab3302SCarolineConcatto       Put('\n');
172864ab3302SCarolineConcatto     } else {
17294ad72793SPeter Klausler       const auto &pd{std::get<ProcedureDesignator>(x.call.t)};
173064ab3302SCarolineConcatto       Word("CALL "), Walk(pd);
17314ad72793SPeter Klausler       Walk("<<<", x.chevrons, ">>>");
17324ad72793SPeter Klausler       const auto &args{std::get<std::list<ActualArgSpec>>(x.call.t)};
173364ab3302SCarolineConcatto       if (args.empty()) {
173464ab3302SCarolineConcatto         if (std::holds_alternative<ProcComponentRef>(pd.u)) {
173564ab3302SCarolineConcatto           Put("()"); // pgf90 crashes on CALL to tbp without parentheses
173664ab3302SCarolineConcatto         }
173764ab3302SCarolineConcatto       } else {
173864ab3302SCarolineConcatto         Walk("(", args, ", ", ")");
173964ab3302SCarolineConcatto       }
174064ab3302SCarolineConcatto     }
174164ab3302SCarolineConcatto   }
174264ab3302SCarolineConcatto   void Unparse(const ActualArgSpec &x) { // R1523
174364ab3302SCarolineConcatto     Walk(std::get<std::optional<Keyword>>(x.t), "=");
174464ab3302SCarolineConcatto     Walk(std::get<ActualArg>(x.t));
174564ab3302SCarolineConcatto   }
174664ab3302SCarolineConcatto   void Unparse(const ActualArg::PercentRef &x) { // R1524
174764ab3302SCarolineConcatto     Word("%REF("), Walk(x.v), Put(')');
174864ab3302SCarolineConcatto   }
174964ab3302SCarolineConcatto   void Unparse(const ActualArg::PercentVal &x) {
175064ab3302SCarolineConcatto     Word("%VAL("), Walk(x.v), Put(')');
175164ab3302SCarolineConcatto   }
175264ab3302SCarolineConcatto   void Before(const AltReturnSpec &) { // R1525
175364ab3302SCarolineConcatto     Put('*');
175464ab3302SCarolineConcatto   }
175564ab3302SCarolineConcatto   void Post(const PrefixSpec::Elemental) { Word("ELEMENTAL"); } // R1527
175664ab3302SCarolineConcatto   void Post(const PrefixSpec::Impure) { Word("IMPURE"); }
175764ab3302SCarolineConcatto   void Post(const PrefixSpec::Module) { Word("MODULE"); }
175864ab3302SCarolineConcatto   void Post(const PrefixSpec::Non_Recursive) { Word("NON_RECURSIVE"); }
175964ab3302SCarolineConcatto   void Post(const PrefixSpec::Pure) { Word("PURE"); }
176064ab3302SCarolineConcatto   void Post(const PrefixSpec::Recursive) { Word("RECURSIVE"); }
17614ad72793SPeter Klausler   void Unparse(const PrefixSpec::Attributes &x) {
17624ad72793SPeter Klausler     Word("ATTRIBUTES("), Walk(x.v), Word(")");
17634ad72793SPeter Klausler   }
17644ad72793SPeter Klausler   void Unparse(const PrefixSpec::Launch_Bounds &x) {
17654ad72793SPeter Klausler     Word("LAUNCH_BOUNDS("), Walk(x.v), Word(")");
17664ad72793SPeter Klausler   }
17674ad72793SPeter Klausler   void Unparse(const PrefixSpec::Cluster_Dims &x) {
17684ad72793SPeter Klausler     Word("CLUSTER_DIMS("), Walk(x.v), Word(")");
17694ad72793SPeter Klausler   }
177064ab3302SCarolineConcatto   void Unparse(const FunctionStmt &x) { // R1530
177164ab3302SCarolineConcatto     Walk("", std::get<std::list<PrefixSpec>>(x.t), " ", " ");
177264ab3302SCarolineConcatto     Word("FUNCTION "), Walk(std::get<Name>(x.t)), Put("(");
177364ab3302SCarolineConcatto     Walk(std::get<std::list<Name>>(x.t), ", "), Put(')');
177464ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<Suffix>>(x.t)), Indent();
177564ab3302SCarolineConcatto   }
177664ab3302SCarolineConcatto   void Unparse(const Suffix &x) { // R1532
177764ab3302SCarolineConcatto     if (x.resultName) {
177864ab3302SCarolineConcatto       Word("RESULT("), Walk(x.resultName), Put(')');
177964ab3302SCarolineConcatto       Walk(" ", x.binding);
178064ab3302SCarolineConcatto     } else {
178164ab3302SCarolineConcatto       Walk(x.binding);
178264ab3302SCarolineConcatto     }
178364ab3302SCarolineConcatto   }
178464ab3302SCarolineConcatto   void Unparse(const EndFunctionStmt &x) { // R1533
178564ab3302SCarolineConcatto     EndSubprogram("FUNCTION", x.v);
178664ab3302SCarolineConcatto   }
178764ab3302SCarolineConcatto   void Unparse(const SubroutineStmt &x) { // R1535
178864ab3302SCarolineConcatto     Walk("", std::get<std::list<PrefixSpec>>(x.t), " ", " ");
178964ab3302SCarolineConcatto     Word("SUBROUTINE "), Walk(std::get<Name>(x.t));
179064ab3302SCarolineConcatto     const auto &args{std::get<std::list<DummyArg>>(x.t)};
179164ab3302SCarolineConcatto     const auto &bind{std::get<std::optional<LanguageBindingSpec>>(x.t)};
179264ab3302SCarolineConcatto     if (args.empty()) {
179364ab3302SCarolineConcatto       Walk(" () ", bind);
179464ab3302SCarolineConcatto     } else {
179564ab3302SCarolineConcatto       Walk(" (", args, ", ", ")");
179664ab3302SCarolineConcatto       Walk(" ", bind);
179764ab3302SCarolineConcatto     }
179864ab3302SCarolineConcatto     Indent();
179964ab3302SCarolineConcatto   }
180064ab3302SCarolineConcatto   void Unparse(const EndSubroutineStmt &x) { // R1537
180164ab3302SCarolineConcatto     EndSubprogram("SUBROUTINE", x.v);
180264ab3302SCarolineConcatto   }
180364ab3302SCarolineConcatto   void Before(const MpSubprogramStmt &) { // R1539
180464ab3302SCarolineConcatto     Word("MODULE PROCEDURE "), Indent();
180564ab3302SCarolineConcatto   }
180664ab3302SCarolineConcatto   void Unparse(const EndMpSubprogramStmt &x) { // R1540
180764ab3302SCarolineConcatto     EndSubprogram("PROCEDURE", x.v);
180864ab3302SCarolineConcatto   }
180964ab3302SCarolineConcatto   void Unparse(const EntryStmt &x) { // R1541
181064ab3302SCarolineConcatto     Word("ENTRY "), Walk(std::get<Name>(x.t)), Put("(");
181164ab3302SCarolineConcatto     Walk(std::get<std::list<DummyArg>>(x.t), ", "), Put(")");
181264ab3302SCarolineConcatto     Walk(" ", std::get<std::optional<Suffix>>(x.t));
181364ab3302SCarolineConcatto   }
181464ab3302SCarolineConcatto   void Unparse(const ReturnStmt &x) { // R1542
181564ab3302SCarolineConcatto     Word("RETURN"), Walk(" ", x.v);
181664ab3302SCarolineConcatto   }
181764ab3302SCarolineConcatto   void Unparse(const ContainsStmt &) { // R1543
181864ab3302SCarolineConcatto     Outdent();
181964ab3302SCarolineConcatto     Word("CONTAINS");
182064ab3302SCarolineConcatto     Indent();
182164ab3302SCarolineConcatto   }
182264ab3302SCarolineConcatto   void Unparse(const StmtFunctionStmt &x) { // R1544
182364ab3302SCarolineConcatto     Walk(std::get<Name>(x.t)), Put('(');
182464ab3302SCarolineConcatto     Walk(std::get<std::list<Name>>(x.t), ", "), Put(") = ");
182564ab3302SCarolineConcatto     Walk(std::get<Scalar<Expr>>(x.t));
182664ab3302SCarolineConcatto   }
182764ab3302SCarolineConcatto 
182864ab3302SCarolineConcatto   // Directives, extensions, and deprecated constructs
182964ab3302SCarolineConcatto   void Unparse(const CompilerDirective &x) {
1830cd03e96fSPeter Klausler     common::visit(
183164ab3302SCarolineConcatto         common::visitors{
183264ab3302SCarolineConcatto             [&](const std::list<CompilerDirective::IgnoreTKR> &tkr) {
183364ab3302SCarolineConcatto               Word("!DIR$ IGNORE_TKR"); // emitted even if tkr list is empty
183464ab3302SCarolineConcatto               Walk(" ", tkr, ", ");
183564ab3302SCarolineConcatto             },
1836c2d8974aSNadeem, Usman             [&](const CompilerDirective::LoopCount &lcount) {
1837c2d8974aSNadeem, Usman               Walk("!DIR$ LOOP COUNT (", lcount.v, ", ", ")");
1838c2d8974aSNadeem, Usman             },
1839601a9587SMats Petersson             [&](const std::list<CompilerDirective::AssumeAligned>
1840601a9587SMats Petersson                     &assumeAligned) {
1841601a9587SMats Petersson               Word("!DIR$ ASSUME_ALIGNED ");
1842601a9587SMats Petersson               Walk(" ", assumeAligned, ", ");
1843601a9587SMats Petersson             },
1844c6b6e18cSDavid Truby             [&](const CompilerDirective::VectorAlways &valways) {
1845c6b6e18cSDavid Truby               Word("!DIR$ VECTOR ALWAYS");
1846c6b6e18cSDavid Truby             },
18478e2b4e50Speter klausler             [&](const std::list<CompilerDirective::NameValue> &names) {
18488e2b4e50Speter klausler               Walk("!DIR$ ", names, " ");
18498e2b4e50Speter klausler             },
1850e811cb00SJean-Didier PAILLEUX             [&](const CompilerDirective::Unroll &unroll) {
1851e811cb00SJean-Didier PAILLEUX               Word("!DIR$ UNROLL");
1852e811cb00SJean-Didier PAILLEUX               Walk(" ", unroll.v);
1853e811cb00SJean-Didier PAILLEUX             },
18546e261d9cSPeter Klausler             [&](const CompilerDirective::Unrecognized &) {
18556e261d9cSPeter Klausler               Word("!DIR$ ");
18566e261d9cSPeter Klausler               Word(x.source.ToString());
18576e261d9cSPeter Klausler             },
185864ab3302SCarolineConcatto         },
185964ab3302SCarolineConcatto         x.u);
186064ab3302SCarolineConcatto     Put('\n');
186164ab3302SCarolineConcatto   }
186264ab3302SCarolineConcatto   void Unparse(const CompilerDirective::IgnoreTKR &x) {
1863864cb2aaSPeter Klausler     if (const auto &maybeList{
1864864cb2aaSPeter Klausler             std::get<std::optional<std::list<const char *>>>(x.t)}) {
186564ab3302SCarolineConcatto       Put("(");
1866864cb2aaSPeter Klausler       for (const char *tkr : *maybeList) {
186764ab3302SCarolineConcatto         Put(*tkr);
186864ab3302SCarolineConcatto       }
186964ab3302SCarolineConcatto       Put(") ");
187064ab3302SCarolineConcatto     }
187164ab3302SCarolineConcatto     Walk(std::get<Name>(x.t));
187264ab3302SCarolineConcatto   }
18738e2b4e50Speter klausler   void Unparse(const CompilerDirective::NameValue &x) {
18748e2b4e50Speter klausler     Walk(std::get<Name>(x.t));
18758e2b4e50Speter klausler     Walk("=", std::get<std::optional<std::uint64_t>>(x.t));
18768e2b4e50Speter klausler   }
1877601a9587SMats Petersson   void Unparse(const CompilerDirective::AssumeAligned &x) {
1878601a9587SMats Petersson     Walk(std::get<common::Indirection<Designator>>(x.t));
1879601a9587SMats Petersson     Put(":");
1880601a9587SMats Petersson     Walk(std::get<uint64_t>(x.t));
1881601a9587SMats Petersson   }
18820a90ffa7SValentin Clement 
18830a90ffa7SValentin Clement   // OpenACC Directives & Clauses
18840a90ffa7SValentin Clement   void Unparse(const AccAtomicCapture &x) {
18850a90ffa7SValentin Clement     BeginOpenACC();
18860a90ffa7SValentin Clement     Word("!$ACC CAPTURE");
18870a90ffa7SValentin Clement     Put("\n");
18880a90ffa7SValentin Clement     EndOpenACC();
18890a90ffa7SValentin Clement     Walk(std::get<AccAtomicCapture::Stmt1>(x.t));
18900a90ffa7SValentin Clement     Put("\n");
18910a90ffa7SValentin Clement     Walk(std::get<AccAtomicCapture::Stmt2>(x.t));
18920a90ffa7SValentin Clement     BeginOpenACC();
18930a90ffa7SValentin Clement     Word("!$ACC END ATOMIC\n");
18940a90ffa7SValentin Clement     EndOpenACC();
18950a90ffa7SValentin Clement   }
18960a90ffa7SValentin Clement   void Unparse(const AccAtomicRead &x) {
18970a90ffa7SValentin Clement     BeginOpenACC();
18980a90ffa7SValentin Clement     Word("!$ACC ATOMIC READ");
18990a90ffa7SValentin Clement     Put("\n");
19000a90ffa7SValentin Clement     EndOpenACC();
19010a90ffa7SValentin Clement     Walk(std::get<Statement<AssignmentStmt>>(x.t));
19020a90ffa7SValentin Clement     BeginOpenACC();
19030a90ffa7SValentin Clement     Walk(std::get<std::optional<AccEndAtomic>>(x.t), "!$ACC END ATOMIC\n");
19040a90ffa7SValentin Clement     EndOpenACC();
19050a90ffa7SValentin Clement   }
19060a90ffa7SValentin Clement   void Unparse(const AccAtomicWrite &x) {
19070a90ffa7SValentin Clement     BeginOpenACC();
19080a90ffa7SValentin Clement     Word("!$ACC ATOMIC WRITE");
19090a90ffa7SValentin Clement     Put("\n");
19100a90ffa7SValentin Clement     EndOpenACC();
19110a90ffa7SValentin Clement     Walk(std::get<Statement<AssignmentStmt>>(x.t));
19120a90ffa7SValentin Clement     BeginOpenACC();
19130a90ffa7SValentin Clement     Walk(std::get<std::optional<AccEndAtomic>>(x.t), "!$ACC END ATOMIC\n");
19140a90ffa7SValentin Clement     EndOpenACC();
19150a90ffa7SValentin Clement   }
19160a90ffa7SValentin Clement   void Unparse(const AccAtomicUpdate &x) {
19170a90ffa7SValentin Clement     BeginOpenACC();
19180a90ffa7SValentin Clement     Word("!$ACC ATOMIC UPDATE");
19190a90ffa7SValentin Clement     Put("\n");
19200a90ffa7SValentin Clement     EndOpenACC();
19210a90ffa7SValentin Clement     Walk(std::get<Statement<AssignmentStmt>>(x.t));
19220a90ffa7SValentin Clement     BeginOpenACC();
19230a90ffa7SValentin Clement     Walk(std::get<std::optional<AccEndAtomic>>(x.t), "!$ACC END ATOMIC\n");
19240a90ffa7SValentin Clement     EndOpenACC();
19250a90ffa7SValentin Clement   }
19260a90ffa7SValentin Clement   void Unparse(const llvm::acc::Directive &x) {
19270a90ffa7SValentin Clement     Word(llvm::acc::getOpenACCDirectiveName(x).str());
19280a90ffa7SValentin Clement   }
19293060894bSValentin Clement #define GEN_FLANG_CLAUSE_UNPARSE
1930ca98baa0SValentin Clement #include "llvm/Frontend/OpenACC/ACC.inc"
19310a90ffa7SValentin Clement   void Unparse(const AccObjectListWithModifier &x) {
19320a90ffa7SValentin Clement     Walk(std::get<std::optional<AccDataModifier>>(x.t), ":");
19330a90ffa7SValentin Clement     Walk(std::get<AccObjectList>(x.t));
19340a90ffa7SValentin Clement   }
193571699a99SValentin Clement   void Unparse(const AccBindClause &x) {
1936cd03e96fSPeter Klausler     common::visit(common::visitors{
19372991c39dSValentin Clement                       [&](const Name &y) { Walk(y); },
19382991c39dSValentin Clement                       [&](const ScalarDefaultCharExpr &y) { Walk(y); },
193971699a99SValentin Clement                   },
194071699a99SValentin Clement         x.u);
194171699a99SValentin Clement   }
19420a90ffa7SValentin Clement   void Unparse(const AccDefaultClause &x) {
19430a90ffa7SValentin Clement     switch (x.v) {
19448f933a4eSValentin Clement     case llvm::acc::DefaultValue::ACC_Default_none:
19450a90ffa7SValentin Clement       Put("NONE");
19460a90ffa7SValentin Clement       break;
19478f933a4eSValentin Clement     case llvm::acc::DefaultValue::ACC_Default_present:
19480a90ffa7SValentin Clement       Put("PRESENT");
19490a90ffa7SValentin Clement       break;
19500a90ffa7SValentin Clement     }
19510a90ffa7SValentin Clement   }
19520a90ffa7SValentin Clement   void Unparse(const AccClauseList &x) { Walk(" ", x.v, " "); }
19535923e46fSValentin Clement   void Unparse(const AccGangArgList &x) { Walk(x.v, ","); }
19545923e46fSValentin Clement   void Before(const AccSizeExpr &x) {
19555923e46fSValentin Clement     if (!x.v)
19565923e46fSValentin Clement       Put("*");
19575923e46fSValentin Clement   }
19585923e46fSValentin Clement   void Before(const AccGangArg &x) {
19595923e46fSValentin Clement     common::visit(common::visitors{
19605923e46fSValentin Clement                       [&](const AccGangArg::Num &) { Word("NUM:"); },
19615923e46fSValentin Clement                       [&](const AccGangArg::Dim &) { Word("DIM:"); },
19625923e46fSValentin Clement                       [&](const AccGangArg::Static &) { Word("STATIC:"); },
19635923e46fSValentin Clement                       [](const StatOrErrmsg &) {},
19645923e46fSValentin Clement                   },
19655923e46fSValentin Clement         x.u);
19660a90ffa7SValentin Clement   }
1967ae86fe85SValentin Clement   void Unparse(const AccCollapseArg &x) {
1968ae86fe85SValentin Clement     const auto &force{std::get<bool>(x.t)};
1969ae86fe85SValentin Clement     const auto &collapseValue{std::get<parser::ScalarIntConstantExpr>(x.t)};
1970ae86fe85SValentin Clement     if (force) {
1971ae86fe85SValentin Clement       Put("FORCE:");
1972ae86fe85SValentin Clement     }
1973ae86fe85SValentin Clement     Walk(collapseValue);
1974ae86fe85SValentin Clement   }
19750a90ffa7SValentin Clement   void Unparse(const OpenACCBlockConstruct &x) {
19760a90ffa7SValentin Clement     BeginOpenACC();
19770a90ffa7SValentin Clement     Word("!$ACC ");
19780a90ffa7SValentin Clement     Walk(std::get<AccBeginBlockDirective>(x.t));
19790a90ffa7SValentin Clement     Put("\n");
19800a90ffa7SValentin Clement     EndOpenACC();
19810a90ffa7SValentin Clement     Walk(std::get<Block>(x.t), "");
19820a90ffa7SValentin Clement     BeginOpenACC();
19830a90ffa7SValentin Clement     Word("!$ACC END ");
19840a90ffa7SValentin Clement     Walk(std::get<AccEndBlockDirective>(x.t));
19850a90ffa7SValentin Clement     Put("\n");
19860a90ffa7SValentin Clement     EndOpenACC();
19870a90ffa7SValentin Clement   }
19880a90ffa7SValentin Clement   void Unparse(const OpenACCLoopConstruct &x) {
19890a90ffa7SValentin Clement     BeginOpenACC();
19900a90ffa7SValentin Clement     Word("!$ACC ");
19910a90ffa7SValentin Clement     Walk(std::get<AccBeginLoopDirective>(x.t));
19920a90ffa7SValentin Clement     Put("\n");
19930a90ffa7SValentin Clement     EndOpenACC();
1994bc323460SValentin Clement (バレンタイン クレメン)     Walk(std::get<std::optional<DoConstruct>>(x.t));
19950a90ffa7SValentin Clement   }
19960a90ffa7SValentin Clement   void Unparse(const AccBeginLoopDirective &x) {
19970a90ffa7SValentin Clement     Walk(std::get<AccLoopDirective>(x.t));
19980a90ffa7SValentin Clement     Walk(std::get<AccClauseList>(x.t));
19990a90ffa7SValentin Clement   }
20000a90ffa7SValentin Clement   void Unparse(const OpenACCStandaloneConstruct &x) {
20010a90ffa7SValentin Clement     BeginOpenACC();
20020a90ffa7SValentin Clement     Word("!$ACC ");
20030a90ffa7SValentin Clement     Walk(std::get<AccStandaloneDirective>(x.t));
20040a90ffa7SValentin Clement     Walk(std::get<AccClauseList>(x.t));
20050a90ffa7SValentin Clement     Put("\n");
20060a90ffa7SValentin Clement     EndOpenACC();
20070a90ffa7SValentin Clement   }
20080a90ffa7SValentin Clement   void Unparse(const OpenACCStandaloneDeclarativeConstruct &x) {
20090a90ffa7SValentin Clement     BeginOpenACC();
20100a90ffa7SValentin Clement     Word("!$ACC ");
20110a90ffa7SValentin Clement     Walk(std::get<AccDeclarativeDirective>(x.t));
20120a90ffa7SValentin Clement     Walk(std::get<AccClauseList>(x.t));
20130a90ffa7SValentin Clement     Put("\n");
20140a90ffa7SValentin Clement     EndOpenACC();
20150a90ffa7SValentin Clement   }
20160a90ffa7SValentin Clement   void Unparse(const OpenACCCombinedConstruct &x) {
20170a90ffa7SValentin Clement     BeginOpenACC();
20180a90ffa7SValentin Clement     Word("!$ACC ");
20190a90ffa7SValentin Clement     Walk(std::get<AccBeginCombinedDirective>(x.t));
20200a90ffa7SValentin Clement     Put("\n");
20210a90ffa7SValentin Clement     EndOpenACC();
202205169af5SValentin Clement     Walk(std::get<std::optional<DoConstruct>>(x.t));
20230a90ffa7SValentin Clement     BeginOpenACC();
202491b49fc2SValentin Clement     Walk("!$ACC END ", std::get<std::optional<AccEndCombinedDirective>>(x.t),
202591b49fc2SValentin Clement         "\n");
20260a90ffa7SValentin Clement     EndOpenACC();
20270a90ffa7SValentin Clement   }
20280a90ffa7SValentin Clement   void Unparse(const OpenACCRoutineConstruct &x) {
20290a90ffa7SValentin Clement     BeginOpenACC();
20300a90ffa7SValentin Clement     Word("!$ACC ROUTINE");
20310a90ffa7SValentin Clement     Walk("(", std::get<std::optional<Name>>(x.t), ")");
20320a90ffa7SValentin Clement     Walk(std::get<AccClauseList>(x.t));
20330a90ffa7SValentin Clement     Put("\n");
20340a90ffa7SValentin Clement     EndOpenACC();
20350a90ffa7SValentin Clement   }
20360a90ffa7SValentin Clement   void Unparse(const AccObject &x) {
2037cd03e96fSPeter Klausler     common::visit(common::visitors{
20380a90ffa7SValentin Clement                       [&](const Designator &y) { Walk(y); },
20390a90ffa7SValentin Clement                       [&](const Name &y) { Put("/"), Walk(y), Put("/"); },
20400a90ffa7SValentin Clement                   },
20410a90ffa7SValentin Clement         x.u);
20420a90ffa7SValentin Clement   }
20430a90ffa7SValentin Clement   void Unparse(const AccObjectList &x) { Walk(x.v, ","); }
20440a90ffa7SValentin Clement   void Unparse(const AccObjectListWithReduction &x) {
20453af717d6Skhaki3     Walk(std::get<ReductionOperator>(x.t));
20460a90ffa7SValentin Clement     Put(":");
20470a90ffa7SValentin Clement     Walk(std::get<AccObjectList>(x.t));
20480a90ffa7SValentin Clement   }
20490a90ffa7SValentin Clement   void Unparse(const OpenACCCacheConstruct &x) {
20500a90ffa7SValentin Clement     BeginOpenACC();
20510a90ffa7SValentin Clement     Word("!$ACC ");
20520a90ffa7SValentin Clement     Word("CACHE(");
20530a90ffa7SValentin Clement     Walk(std::get<AccObjectListWithModifier>(x.t));
20540a90ffa7SValentin Clement     Put(")");
20550a90ffa7SValentin Clement     Put("\n");
20560a90ffa7SValentin Clement     EndOpenACC();
20570a90ffa7SValentin Clement   }
205886bbf8e6SValentin Clement   void Unparse(const AccWaitArgument &x) {
205986bbf8e6SValentin Clement     Walk("DEVNUM:", std::get<std::optional<ScalarIntExpr>>(x.t), ":");
206086bbf8e6SValentin Clement     Walk(std::get<std::list<ScalarIntExpr>>(x.t), ",");
206186bbf8e6SValentin Clement   }
20620a90ffa7SValentin Clement   void Unparse(const OpenACCWaitConstruct &x) {
20630a90ffa7SValentin Clement     BeginOpenACC();
20640a90ffa7SValentin Clement     Word("!$ACC ");
20650a90ffa7SValentin Clement     Word("WAIT(");
20660a90ffa7SValentin Clement     Walk(std::get<std::optional<AccWaitArgument>>(x.t));
20670a90ffa7SValentin Clement     Walk(std::get<AccClauseList>(x.t));
20680a90ffa7SValentin Clement     Put(")");
20690a90ffa7SValentin Clement     Put("\n");
20700a90ffa7SValentin Clement     EndOpenACC();
20710a90ffa7SValentin Clement   }
20720a90ffa7SValentin Clement 
207364ab3302SCarolineConcatto   // OpenMP Clauses & Directives
207470e96dc3SKrzysztof Parzyszek   void Unparse(const llvm::omp::Directive &x) {
207570e96dc3SKrzysztof Parzyszek     Word(llvm::omp::getOpenMPDirectiveName(x).str());
207670e96dc3SKrzysztof Parzyszek   }
2077*15ab7be2SKrzysztof Parzyszek   void Unparse(const OmpDirectiveSpecification &x) {
2078*15ab7be2SKrzysztof Parzyszek     Walk(std::get<llvm::omp::Directive>(x.t));
2079*15ab7be2SKrzysztof Parzyszek     Walk(std::get<std::optional<common::Indirection<OmpClauseList>>>(x.t));
2080*15ab7be2SKrzysztof Parzyszek   }
208170e96dc3SKrzysztof Parzyszek   void Unparse(const OmpTraitScore &x) {
208270e96dc3SKrzysztof Parzyszek     Word("SCORE(");
208370e96dc3SKrzysztof Parzyszek     Walk(x.v);
208470e96dc3SKrzysztof Parzyszek     Put(")");
208570e96dc3SKrzysztof Parzyszek   }
2086c8593239SKrzysztof Parzyszek   void Unparse(const OmpTraitPropertyExtension::Complex &x) {
2087c8593239SKrzysztof Parzyszek     using PropList = std::list<common::Indirection<OmpTraitPropertyExtension>>;
208870e96dc3SKrzysztof Parzyszek     Walk(std::get<OmpTraitPropertyName>(x.t));
208970e96dc3SKrzysztof Parzyszek     Put("(");
2090c8593239SKrzysztof Parzyszek     Walk(std::get<PropList>(x.t), ",");
209170e96dc3SKrzysztof Parzyszek     Put(")");
209270e96dc3SKrzysztof Parzyszek   }
209370e96dc3SKrzysztof Parzyszek   void Unparse(const OmpTraitSelector &x) {
209470e96dc3SKrzysztof Parzyszek     Walk(std::get<OmpTraitSelectorName>(x.t));
209570e96dc3SKrzysztof Parzyszek     Walk(std::get<std::optional<OmpTraitSelector::Properties>>(x.t));
209670e96dc3SKrzysztof Parzyszek   }
209770e96dc3SKrzysztof Parzyszek   void Unparse(const OmpTraitSelector::Properties &x) {
209870e96dc3SKrzysztof Parzyszek     Put("(");
209970e96dc3SKrzysztof Parzyszek     Walk(std::get<std::optional<OmpTraitScore>>(x.t), ": ");
210070e96dc3SKrzysztof Parzyszek     Walk(std::get<std::list<OmpTraitProperty>>(x.t));
210170e96dc3SKrzysztof Parzyszek     Put(")");
210270e96dc3SKrzysztof Parzyszek   }
210370e96dc3SKrzysztof Parzyszek   void Unparse(const OmpTraitSetSelector &x) {
210470e96dc3SKrzysztof Parzyszek     Walk(std::get<OmpTraitSetSelectorName>(x.t));
210570e96dc3SKrzysztof Parzyszek     Put("={");
210670e96dc3SKrzysztof Parzyszek     Walk(std::get<std::list<OmpTraitSelector>>(x.t));
210770e96dc3SKrzysztof Parzyszek     Put("}");
210870e96dc3SKrzysztof Parzyszek   }
210970e96dc3SKrzysztof Parzyszek   void Unparse(const OmpContextSelectorSpecification &x) { Walk(x.v, ", "); }
211070e96dc3SKrzysztof Parzyszek 
211164ab3302SCarolineConcatto   void Unparse(const OmpObject &x) {
2112cd03e96fSPeter Klausler     common::visit(common::visitors{
211364ab3302SCarolineConcatto                       [&](const Designator &y) { Walk(y); },
211464ab3302SCarolineConcatto                       [&](const Name &y) { Put("/"), Walk(y), Put("/"); },
211564ab3302SCarolineConcatto                   },
211664ab3302SCarolineConcatto         x.u);
211764ab3302SCarolineConcatto   }
211833faa828SKrzysztof Parzyszek   void Unparse(const OmpDirectiveNameModifier &x) {
211933faa828SKrzysztof Parzyszek     Word(llvm::omp::getOpenMPDirectiveName(x.v));
212033faa828SKrzysztof Parzyszek   }
2121973fa983SKrzysztof Parzyszek   void Unparse(const OmpIteratorSpecifier &x) {
2122973fa983SKrzysztof Parzyszek     Walk(std::get<TypeDeclarationStmt>(x.t));
2123973fa983SKrzysztof Parzyszek     Put(" = ");
2124973fa983SKrzysztof Parzyszek     Walk(std::get<SubscriptTriplet>(x.t));
2125973fa983SKrzysztof Parzyszek   }
2126cfd67c21SKrzysztof Parzyszek   void Unparse(const OmpIterator &x) {
2127973fa983SKrzysztof Parzyszek     Word("ITERATOR(");
2128973fa983SKrzysztof Parzyszek     Walk(x.v);
2129973fa983SKrzysztof Parzyszek     Put(")");
2130973fa983SKrzysztof Parzyszek   }
213152755ac2SKrzysztof Parzyszek   void Unparse(const OmpMapper &x) {
213252755ac2SKrzysztof Parzyszek     Word("MAPPER(");
213352755ac2SKrzysztof Parzyszek     Walk(x.v);
213452755ac2SKrzysztof Parzyszek     Put(")");
213552755ac2SKrzysztof Parzyszek   }
2136f9824439SKrzysztof Parzyszek   void Unparse(const OmpLastprivateClause &x) {
213733faa828SKrzysztof Parzyszek     using Modifier = OmpLastprivateClause::Modifier;
213833faa828SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
2139f9824439SKrzysztof Parzyszek     Walk(std::get<OmpObjectList>(x.t));
2140f9824439SKrzysztof Parzyszek   }
214164ab3302SCarolineConcatto   void Unparse(const OmpMapClause &x) {
214252755ac2SKrzysztof Parzyszek     using Modifier = OmpMapClause::Modifier;
214352755ac2SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
214464ab3302SCarolineConcatto     Walk(std::get<OmpObjectList>(x.t));
214564ab3302SCarolineConcatto   }
214664ab3302SCarolineConcatto   void Unparse(const OmpScheduleClause &x) {
2147e79cd246SKrzysztof Parzyszek     using Modifier = OmpScheduleClause::Modifier;
2148e79cd246SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
2149e79cd246SKrzysztof Parzyszek     Walk(std::get<OmpScheduleClause::Kind>(x.t));
215064ab3302SCarolineConcatto     Walk(",", std::get<std::optional<ScalarIntExpr>>(x.t));
215164ab3302SCarolineConcatto   }
2152d9ff6703SSesha Kalyur   void Unparse(const OmpDeviceClause &x) {
215305096590SKrzysztof Parzyszek     using Modifier = OmpDeviceClause::Modifier;
215405096590SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
2155d9ff6703SSesha Kalyur     Walk(std::get<ScalarIntExpr>(x.t));
2156d9ff6703SSesha Kalyur   }
2157ea3534b3SKrzysztof Parzyszek   void Unparse(const OmpAffinityClause &x) {
215805096590SKrzysztof Parzyszek     using Modifier = OmpAffinityClause::Modifier;
215905096590SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
2160ea3534b3SKrzysztof Parzyszek     Walk(std::get<OmpObjectList>(x.t));
2161ea3534b3SKrzysztof Parzyszek   }
216264ab3302SCarolineConcatto   void Unparse(const OmpAlignedClause &x) {
216305096590SKrzysztof Parzyszek     using Modifier = OmpAlignedClause::Modifier;
2164f36a2547SRaghu Maddhipatla     Walk(std::get<OmpObjectList>(x.t));
216505096590SKrzysztof Parzyszek     Walk(": ", std::get<std::optional<std::list<Modifier>>>(x.t));
216664ab3302SCarolineConcatto   }
21671c6ec29bSKrzysztof Parzyszek   void Unparse(const OmpFromClause &x) {
216852755ac2SKrzysztof Parzyszek     using Modifier = OmpFromClause::Modifier;
216952755ac2SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21701c6ec29bSKrzysztof Parzyszek     Walk(std::get<OmpObjectList>(x.t));
21711c6ec29bSKrzysztof Parzyszek   }
217264ab3302SCarolineConcatto   void Unparse(const OmpIfClause &x) {
217333faa828SKrzysztof Parzyszek     using Modifier = OmpIfClause::Modifier;
217433faa828SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
217564ab3302SCarolineConcatto     Walk(std::get<ScalarLogicalExpr>(x.t));
217664ab3302SCarolineConcatto   }
217703cbe426SKrzysztof Parzyszek   void Unparse(const OmpStepSimpleModifier &x) { Walk(x.v); }
217803cbe426SKrzysztof Parzyszek   void Unparse(const OmpStepComplexModifier &x) {
217903cbe426SKrzysztof Parzyszek     Word("STEP(");
218003cbe426SKrzysztof Parzyszek     Walk(x.v);
218103cbe426SKrzysztof Parzyszek     Put(")");
218264ab3302SCarolineConcatto   }
218303cbe426SKrzysztof Parzyszek   void Unparse(const OmpLinearClause &x) {
218403cbe426SKrzysztof Parzyszek     using Modifier = OmpLinearClause::Modifier;
218503cbe426SKrzysztof Parzyszek     auto &modifiers{std::get<std::optional<std::list<Modifier>>>(x.t)};
218603cbe426SKrzysztof Parzyszek     if (std::get<bool>(x.t)) { // PostModified
218703cbe426SKrzysztof Parzyszek       Walk(std::get<OmpObjectList>(x.t));
218803cbe426SKrzysztof Parzyszek       Walk(": ", modifiers);
218903cbe426SKrzysztof Parzyszek     } else {
219003cbe426SKrzysztof Parzyszek       // Unparse using pre-5.2 syntax.
219103cbe426SKrzysztof Parzyszek       bool HasStepModifier{false}, HasLinearModifier{false};
219203cbe426SKrzysztof Parzyszek 
219303cbe426SKrzysztof Parzyszek       if (modifiers) {
219403cbe426SKrzysztof Parzyszek         bool NeedComma{false};
219503cbe426SKrzysztof Parzyszek         for (const Modifier &m : *modifiers) {
219603cbe426SKrzysztof Parzyszek           // Print all linear modifiers in case we need to unparse an
219703cbe426SKrzysztof Parzyszek           // incorrect tree.
219803cbe426SKrzysztof Parzyszek           if (auto *lmod{std::get_if<parser::OmpLinearModifier>(&m.u)}) {
219903cbe426SKrzysztof Parzyszek             if (NeedComma) {
220003cbe426SKrzysztof Parzyszek               Put(",");
220103cbe426SKrzysztof Parzyszek             }
220203cbe426SKrzysztof Parzyszek             Walk(*lmod);
220303cbe426SKrzysztof Parzyszek             HasLinearModifier = true;
220403cbe426SKrzysztof Parzyszek             NeedComma = true;
220503cbe426SKrzysztof Parzyszek           } else {
220603cbe426SKrzysztof Parzyszek             // If not linear-modifier, then it has to be step modifier.
220703cbe426SKrzysztof Parzyszek             HasStepModifier = true;
220803cbe426SKrzysztof Parzyszek           }
220903cbe426SKrzysztof Parzyszek         }
221003cbe426SKrzysztof Parzyszek       }
221103cbe426SKrzysztof Parzyszek 
221203cbe426SKrzysztof Parzyszek       if (HasLinearModifier) {
221303cbe426SKrzysztof Parzyszek         Put("(");
221403cbe426SKrzysztof Parzyszek       }
221503cbe426SKrzysztof Parzyszek       Walk(std::get<OmpObjectList>(x.t));
221603cbe426SKrzysztof Parzyszek       if (HasLinearModifier) {
221703cbe426SKrzysztof Parzyszek         Put(")");
221803cbe426SKrzysztof Parzyszek       }
221903cbe426SKrzysztof Parzyszek 
222003cbe426SKrzysztof Parzyszek       if (HasStepModifier) {
222103cbe426SKrzysztof Parzyszek         Put(": ");
222203cbe426SKrzysztof Parzyszek         bool NeedComma{false};
222303cbe426SKrzysztof Parzyszek         for (const Modifier &m : *modifiers) {
222403cbe426SKrzysztof Parzyszek           if (!std::holds_alternative<parser::OmpLinearModifier>(m.u)) {
222503cbe426SKrzysztof Parzyszek             if (NeedComma) {
222603cbe426SKrzysztof Parzyszek               Put(",");
222703cbe426SKrzysztof Parzyszek             }
222803cbe426SKrzysztof Parzyszek             common::visit([&](auto &&s) { Walk(s); }, m.u);
222903cbe426SKrzysztof Parzyszek             NeedComma = true;
223003cbe426SKrzysztof Parzyszek           }
223103cbe426SKrzysztof Parzyszek         }
223203cbe426SKrzysztof Parzyszek       }
223303cbe426SKrzysztof Parzyszek     }
223464ab3302SCarolineConcatto   }
223564ab3302SCarolineConcatto   void Unparse(const OmpReductionClause &x) {
22364fc1141eSKrzysztof Parzyszek     using Modifier = OmpReductionClause::Modifier;
22374fc1141eSKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
22386280bc1cSsameeran joshi     Walk(std::get<OmpObjectList>(x.t));
223964ab3302SCarolineConcatto   }
22400653698dSNimishMishra   void Unparse(const OmpDetachClause &x) { Walk(x.v); }
22416a3c4a40SNimish Mishra   void Unparse(const OmpInReductionClause &x) {
224258f9c4fcSKrzysztof Parzyszek     using Modifier = OmpInReductionClause::Modifier;
224358f9c4fcSKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
224458f9c4fcSKrzysztof Parzyszek     Walk(std::get<OmpObjectList>(x.t));
224558f9c4fcSKrzysztof Parzyszek   }
224658f9c4fcSKrzysztof Parzyszek   void Unparse(const OmpTaskReductionClause &x) {
224758f9c4fcSKrzysztof Parzyszek     using Modifier = OmpTaskReductionClause::Modifier;
224858f9c4fcSKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
22496a3c4a40SNimish Mishra     Walk(std::get<OmpObjectList>(x.t));
22506a3c4a40SNimish Mishra   }
2251e355f85bSIrina Dobrescu   void Unparse(const OmpAllocateClause &x) {
2252cdbd2287SKrzysztof Parzyszek     using Modifier = OmpAllocateClause::Modifier;
2253cdbd2287SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
2254e355f85bSIrina Dobrescu     Walk(std::get<OmpObjectList>(x.t));
2255e355f85bSIrina Dobrescu   }
2256cdbd2287SKrzysztof Parzyszek   void Unparse(const OmpAlignModifier &x) {
22576311ab21SEthan Luis McDonough     Word("ALIGN(");
22586311ab21SEthan Luis McDonough     Walk(x.v);
22596311ab21SEthan Luis McDonough     Put(")");
22606311ab21SEthan Luis McDonough   }
2261cdbd2287SKrzysztof Parzyszek   void Unparse(const OmpAllocatorSimpleModifier &x) { Walk(x.v); }
2262cdbd2287SKrzysztof Parzyszek   void Unparse(const OmpAllocatorComplexModifier &x) {
2263cdbd2287SKrzysztof Parzyszek     Word("ALLOCATOR(");
2264cdbd2287SKrzysztof Parzyszek     Walk(x.v);
2265cdbd2287SKrzysztof Parzyszek     Put(")");
2266cdbd2287SKrzysztof Parzyszek   }
2267a7d352c7SKavitha Natarajan   void Unparse(const OmpOrderClause &x) {
2268e79cd246SKrzysztof Parzyszek     using Modifier = OmpOrderClause::Modifier;
2269e79cd246SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
2270e79cd246SKrzysztof Parzyszek     Walk(std::get<OmpOrderClause::Ordering>(x.t));
2271a7d352c7SKavitha Natarajan   }
22725621929fSKiran Chandramohan   void Unparse(const OmpGrainsizeClause &x) {
2273bde79c0eSKrzysztof Parzyszek     using Modifier = OmpGrainsizeClause::Modifier;
2274bde79c0eSKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
22755621929fSKiran Chandramohan     Walk(std::get<ScalarIntExpr>(x.t));
22765621929fSKiran Chandramohan   }
22775621929fSKiran Chandramohan   void Unparse(const OmpNumTasksClause &x) {
2278bde79c0eSKrzysztof Parzyszek     using Modifier = OmpNumTasksClause::Modifier;
2279bde79c0eSKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
22805621929fSKiran Chandramohan     Walk(std::get<ScalarIntExpr>(x.t));
22815621929fSKiran Chandramohan   }
2282f87737f3SKrzysztof Parzyszek   void Unparse(const OmpDoacross::Sink &x) {
2283f87737f3SKrzysztof Parzyszek     Word("SINK: ");
2284f87737f3SKrzysztof Parzyszek     Walk(x.v.v);
228564ab3302SCarolineConcatto   }
2286f87737f3SKrzysztof Parzyszek   void Unparse(const OmpDoacross::Source &) { Word("SOURCE"); }
2287f87737f3SKrzysztof Parzyszek   void Unparse(const OmpDependClause::TaskDep &x) {
2288bde79c0eSKrzysztof Parzyszek     using Modifier = OmpDependClause::TaskDep::Modifier;
2289bde79c0eSKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
229009a4bcf1SKrzysztof Parzyszek     Walk(std::get<OmpObjectList>(x.t));
229164ab3302SCarolineConcatto   }
229264ab3302SCarolineConcatto   void Unparse(const OmpDefaultmapClause &x) {
22934fc1141eSKrzysztof Parzyszek     using Modifier = OmpDefaultmapClause::Modifier;
229464ab3302SCarolineConcatto     Walk(std::get<OmpDefaultmapClause::ImplicitBehavior>(x.t));
22954fc1141eSKrzysztof Parzyszek     Walk(":", std::get<std::optional<std::list<Modifier>>>(x.t));
229664ab3302SCarolineConcatto   }
22971c6ec29bSKrzysztof Parzyszek   void Unparse(const OmpToClause &x) {
229852755ac2SKrzysztof Parzyszek     using Modifier = OmpToClause::Modifier;
229952755ac2SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
23001c6ec29bSKrzysztof Parzyszek     Walk(std::get<OmpObjectList>(x.t));
23011c6ec29bSKrzysztof Parzyszek   }
2302*15ab7be2SKrzysztof Parzyszek   void Unparse(const OmpWhenClause &x) {
2303*15ab7be2SKrzysztof Parzyszek     using Modifier = OmpWhenClause::Modifier;
2304*15ab7be2SKrzysztof Parzyszek     Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
2305*15ab7be2SKrzysztof Parzyszek     Walk(std::get<std::optional<OmpDirectiveSpecification>>(x.t));
2306*15ab7be2SKrzysztof Parzyszek   }
23073060894bSValentin Clement #define GEN_FLANG_CLAUSE_UNPARSE
2308f4c8b803SValentin Clement #include "llvm/Frontend/OpenMP/OMP.inc"
230964ab3302SCarolineConcatto   void Unparse(const OmpLoopDirective &x) {
231064ab3302SCarolineConcatto     switch (x.v) {
23112ddba308SValentin Clement     case llvm::omp::Directive::OMPD_distribute:
23121f879005STim Keith       Word("DISTRIBUTE ");
23131f879005STim Keith       break;
23142ddba308SValentin Clement     case llvm::omp::Directive::OMPD_distribute_parallel_do:
231564ab3302SCarolineConcatto       Word("DISTRIBUTE PARALLEL DO ");
231664ab3302SCarolineConcatto       break;
23172ddba308SValentin Clement     case llvm::omp::Directive::OMPD_distribute_parallel_do_simd:
231864ab3302SCarolineConcatto       Word("DISTRIBUTE PARALLEL DO SIMD ");
231964ab3302SCarolineConcatto       break;
23202ddba308SValentin Clement     case llvm::omp::Directive::OMPD_distribute_simd:
232164ab3302SCarolineConcatto       Word("DISTRIBUTE SIMD ");
232264ab3302SCarolineConcatto       break;
23232ddba308SValentin Clement     case llvm::omp::Directive::OMPD_do:
23241f879005STim Keith       Word("DO ");
23251f879005STim Keith       break;
23262ddba308SValentin Clement     case llvm::omp::Directive::OMPD_do_simd:
23272ddba308SValentin Clement       Word("DO SIMD ");
23281f879005STim Keith       break;
2329826bde5dSAnchu Rajendran S     case llvm::omp::Directive::OMPD_loop:
2330826bde5dSAnchu Rajendran S       Word("LOOP ");
2331826bde5dSAnchu Rajendran S       break;
23326658e1a3SAnchu Rajendran S     case llvm::omp::Directive::OMPD_masked_taskloop_simd:
23336658e1a3SAnchu Rajendran S       Word("MASKED TASKLOOP SIMD");
23346658e1a3SAnchu Rajendran S       break;
23356658e1a3SAnchu Rajendran S     case llvm::omp::Directive::OMPD_masked_taskloop:
23366658e1a3SAnchu Rajendran S       Word("MASKED TASKLOOP");
23376658e1a3SAnchu Rajendran S       break;
2338092a819eSKiran Chandramohan     case llvm::omp::Directive::OMPD_master_taskloop_simd:
2339092a819eSKiran Chandramohan       Word("MASTER TASKLOOP SIMD");
2340092a819eSKiran Chandramohan       break;
2341092a819eSKiran Chandramohan     case llvm::omp::Directive::OMPD_master_taskloop:
2342092a819eSKiran Chandramohan       Word("MASTER TASKLOOP");
2343092a819eSKiran Chandramohan       break;
23442ddba308SValentin Clement     case llvm::omp::Directive::OMPD_parallel_do:
23451f879005STim Keith       Word("PARALLEL DO ");
23461f879005STim Keith       break;
23472ddba308SValentin Clement     case llvm::omp::Directive::OMPD_parallel_do_simd:
234864ab3302SCarolineConcatto       Word("PARALLEL DO SIMD ");
234964ab3302SCarolineConcatto       break;
23506658e1a3SAnchu Rajendran S     case llvm::omp::Directive::OMPD_parallel_masked_taskloop_simd:
23516658e1a3SAnchu Rajendran S       Word("PARALLEL MASKED TASKLOOP SIMD");
23526658e1a3SAnchu Rajendran S       break;
23536658e1a3SAnchu Rajendran S     case llvm::omp::Directive::OMPD_parallel_masked_taskloop:
23546658e1a3SAnchu Rajendran S       Word("PARALLEL MASKED TASKLOOP");
23556658e1a3SAnchu Rajendran S       break;
2356092a819eSKiran Chandramohan     case llvm::omp::Directive::OMPD_parallel_master_taskloop_simd:
2357092a819eSKiran Chandramohan       Word("PARALLEL MASTER TASKLOOP SIMD");
2358092a819eSKiran Chandramohan       break;
2359092a819eSKiran Chandramohan     case llvm::omp::Directive::OMPD_parallel_master_taskloop:
2360092a819eSKiran Chandramohan       Word("PARALLEL MASTER TASKLOOP");
2361092a819eSKiran Chandramohan       break;
23622ddba308SValentin Clement     case llvm::omp::Directive::OMPD_simd:
23631f879005STim Keith       Word("SIMD ");
23641f879005STim Keith       break;
2365826bde5dSAnchu Rajendran S     case llvm::omp::Directive::OMPD_target_loop:
2366826bde5dSAnchu Rajendran S       Word("TARGET LOOP ");
2367826bde5dSAnchu Rajendran S       break;
23682ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_parallel_do:
236964ab3302SCarolineConcatto       Word("TARGET PARALLEL DO ");
237064ab3302SCarolineConcatto       break;
23712ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_parallel_do_simd:
237264ab3302SCarolineConcatto       Word("TARGET PARALLEL DO SIMD ");
237364ab3302SCarolineConcatto       break;
2374826bde5dSAnchu Rajendran S     case llvm::omp::Directive::OMPD_target_parallel_loop:
2375826bde5dSAnchu Rajendran S       Word("TARGET PARALLEL LOOP ");
2376826bde5dSAnchu Rajendran S       break;
23772ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_teams_distribute:
237864ab3302SCarolineConcatto       Word("TARGET TEAMS DISTRIBUTE ");
237964ab3302SCarolineConcatto       break;
23802ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do:
238164ab3302SCarolineConcatto       Word("TARGET TEAMS DISTRIBUTE PARALLEL DO ");
238264ab3302SCarolineConcatto       break;
23832ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd:
238464ab3302SCarolineConcatto       Word("TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD ");
238564ab3302SCarolineConcatto       break;
23862ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
238764ab3302SCarolineConcatto       Word("TARGET TEAMS DISTRIBUTE SIMD ");
238864ab3302SCarolineConcatto       break;
2389826bde5dSAnchu Rajendran S     case llvm::omp::Directive::OMPD_target_teams_loop:
2390826bde5dSAnchu Rajendran S       Word("TARGET TEAMS LOOP ");
2391826bde5dSAnchu Rajendran S       break;
23922ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_simd:
23931f879005STim Keith       Word("TARGET SIMD ");
23941f879005STim Keith       break;
23952ddba308SValentin Clement     case llvm::omp::Directive::OMPD_taskloop:
23961f879005STim Keith       Word("TASKLOOP ");
23971f879005STim Keith       break;
23982ddba308SValentin Clement     case llvm::omp::Directive::OMPD_taskloop_simd:
239964ab3302SCarolineConcatto       Word("TASKLOOP SIMD ");
240064ab3302SCarolineConcatto       break;
24012ddba308SValentin Clement     case llvm::omp::Directive::OMPD_teams_distribute:
240264ab3302SCarolineConcatto       Word("TEAMS DISTRIBUTE ");
240364ab3302SCarolineConcatto       break;
24042ddba308SValentin Clement     case llvm::omp::Directive::OMPD_teams_distribute_parallel_do:
240564ab3302SCarolineConcatto       Word("TEAMS DISTRIBUTE PARALLEL DO ");
240664ab3302SCarolineConcatto       break;
24072ddba308SValentin Clement     case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd:
240864ab3302SCarolineConcatto       Word("TEAMS DISTRIBUTE PARALLEL DO SIMD ");
240964ab3302SCarolineConcatto       break;
24102ddba308SValentin Clement     case llvm::omp::Directive::OMPD_teams_distribute_simd:
241164ab3302SCarolineConcatto       Word("TEAMS DISTRIBUTE SIMD ");
241264ab3302SCarolineConcatto       break;
24138feb5d41SAbid Malik     case llvm::omp::Directive::OMPD_tile:
24148feb5d41SAbid Malik       Word("TILE ");
24158feb5d41SAbid Malik       break;
241684bf4b7cSAbid Malik     case llvm::omp::Directive::OMPD_unroll:
241784bf4b7cSAbid Malik       Word("UNROLL ");
241884bf4b7cSAbid Malik       break;
24192ddba308SValentin Clement     default:
24202ddba308SValentin Clement       break;
242164ab3302SCarolineConcatto     }
242264ab3302SCarolineConcatto   }
242364ab3302SCarolineConcatto   void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
242464ab3302SCarolineConcatto   void Unparse(const OmpSimpleStandaloneDirective &x) {
242564ab3302SCarolineConcatto     switch (x.v) {
24262ddba308SValentin Clement     case llvm::omp::Directive::OMPD_barrier:
242764ab3302SCarolineConcatto       Word("BARRIER ");
242864ab3302SCarolineConcatto       break;
2429e67e09a7SAnchu Rajendran S     case llvm::omp::Directive::OMPD_scan:
2430e67e09a7SAnchu Rajendran S       Word("SCAN ");
2431e67e09a7SAnchu Rajendran S       break;
24322ddba308SValentin Clement     case llvm::omp::Directive::OMPD_taskwait:
243364ab3302SCarolineConcatto       Word("TASKWAIT ");
243464ab3302SCarolineConcatto       break;
24352ddba308SValentin Clement     case llvm::omp::Directive::OMPD_taskyield:
243664ab3302SCarolineConcatto       Word("TASKYIELD ");
243764ab3302SCarolineConcatto       break;
24382ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_enter_data:
243964ab3302SCarolineConcatto       Word("TARGET ENTER DATA ");
244064ab3302SCarolineConcatto       break;
24412ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_exit_data:
244264ab3302SCarolineConcatto       Word("TARGET EXIT DATA ");
244364ab3302SCarolineConcatto       break;
24442ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_update:
244564ab3302SCarolineConcatto       Word("TARGET UPDATE ");
244664ab3302SCarolineConcatto       break;
24472ddba308SValentin Clement     case llvm::omp::Directive::OMPD_ordered:
244864ab3302SCarolineConcatto       Word("ORDERED ");
244964ab3302SCarolineConcatto       break;
24502ddba308SValentin Clement     default:
24512ddba308SValentin Clement       // Nothing to be done
24522ddba308SValentin Clement       break;
245364ab3302SCarolineConcatto     }
245464ab3302SCarolineConcatto   }
245564ab3302SCarolineConcatto   void Unparse(const OmpBlockDirective &x) {
245664ab3302SCarolineConcatto     switch (x.v) {
24576658e1a3SAnchu Rajendran S     case llvm::omp::Directive::OMPD_masked:
24586658e1a3SAnchu Rajendran S       Word("MASKED");
24596658e1a3SAnchu Rajendran S       break;
24602ddba308SValentin Clement     case llvm::omp::Directive::OMPD_master:
24611f879005STim Keith       Word("MASTER");
24621f879005STim Keith       break;
24632ddba308SValentin Clement     case llvm::omp::Directive::OMPD_ordered:
24641f879005STim Keith       Word("ORDERED ");
24651f879005STim Keith       break;
24666658e1a3SAnchu Rajendran S     case llvm::omp::Directive::OMPD_parallel_masked:
24676658e1a3SAnchu Rajendran S       Word("PARALLEL MASKED");
24686658e1a3SAnchu Rajendran S       break;
2469092a819eSKiran Chandramohan     case llvm::omp::Directive::OMPD_parallel_master:
2470092a819eSKiran Chandramohan       Word("PARALLEL MASTER");
2471092a819eSKiran Chandramohan       break;
24722ddba308SValentin Clement     case llvm::omp::Directive::OMPD_parallel_workshare:
247364ab3302SCarolineConcatto       Word("PARALLEL WORKSHARE ");
247464ab3302SCarolineConcatto       break;
24752ddba308SValentin Clement     case llvm::omp::Directive::OMPD_parallel:
24761f879005STim Keith       Word("PARALLEL ");
24771f879005STim Keith       break;
2478843c2fbeSKiran Chandramohan     case llvm::omp::Directive::OMPD_scope:
2479843c2fbeSKiran Chandramohan       Word("SCOPE ");
2480843c2fbeSKiran Chandramohan       break;
24812ddba308SValentin Clement     case llvm::omp::Directive::OMPD_single:
24821f879005STim Keith       Word("SINGLE ");
24831f879005STim Keith       break;
24842ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_data:
24851f879005STim Keith       Word("TARGET DATA ");
24861f879005STim Keith       break;
24872ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_parallel:
248864ab3302SCarolineConcatto       Word("TARGET PARALLEL ");
248964ab3302SCarolineConcatto       break;
24902ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target_teams:
249164ab3302SCarolineConcatto       Word("TARGET TEAMS ");
249264ab3302SCarolineConcatto       break;
24932ddba308SValentin Clement     case llvm::omp::Directive::OMPD_target:
24941f879005STim Keith       Word("TARGET ");
24951f879005STim Keith       break;
24962ddba308SValentin Clement     case llvm::omp::Directive::OMPD_taskgroup:
24971f879005STim Keith       Word("TASKGROUP ");
24981f879005STim Keith       break;
24992ddba308SValentin Clement     case llvm::omp::Directive::OMPD_task:
25001f879005STim Keith       Word("TASK ");
25011f879005STim Keith       break;
25022ddba308SValentin Clement     case llvm::omp::Directive::OMPD_teams:
25031f879005STim Keith       Word("TEAMS ");
25041f879005STim Keith       break;
25052ddba308SValentin Clement     case llvm::omp::Directive::OMPD_workshare:
25061f879005STim Keith       Word("WORKSHARE ");
25071f879005STim Keith       break;
25082ddba308SValentin Clement     default:
25092ddba308SValentin Clement       // Nothing to be done
25102ddba308SValentin Clement       break;
251164ab3302SCarolineConcatto     }
251264ab3302SCarolineConcatto   }
2513d5fb5960SSergio Afonso 
2514d5fb5960SSergio Afonso   void Unparse(const OmpAtomicDefaultMemOrderClause &x) {
2515edc2fb07SSergio Afonso     Word(ToUpperCaseLetters(common::EnumToString(x.v)));
2516d5fb5960SSergio Afonso   }
2517d5fb5960SSergio Afonso 
2518e43b3b08Ssameeran joshi   void Unparse(const OmpAtomicClauseList &x) { Walk(" ", x.v, " "); }
2519e43b3b08Ssameeran joshi 
252064ab3302SCarolineConcatto   void Unparse(const OmpAtomic &x) {
252164ab3302SCarolineConcatto     BeginOpenMP();
252264ab3302SCarolineConcatto     Word("!$OMP ATOMIC");
2523e43b3b08Ssameeran joshi     Walk(std::get<OmpAtomicClauseList>(x.t));
252464ab3302SCarolineConcatto     Put("\n");
252564ab3302SCarolineConcatto     EndOpenMP();
252664ab3302SCarolineConcatto     Walk(std::get<Statement<AssignmentStmt>>(x.t));
252764ab3302SCarolineConcatto     BeginOpenMP();
252864ab3302SCarolineConcatto     Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
252964ab3302SCarolineConcatto     EndOpenMP();
253064ab3302SCarolineConcatto   }
253164ab3302SCarolineConcatto   void Unparse(const OmpAtomicCapture &x) {
253264ab3302SCarolineConcatto     BeginOpenMP();
253364ab3302SCarolineConcatto     Word("!$OMP ATOMIC");
2534d95d3d2aSsameeran joshi     Walk(std::get<0>(x.t));
253564ab3302SCarolineConcatto     Word(" CAPTURE");
2536d95d3d2aSsameeran joshi     Walk(std::get<2>(x.t));
253764ab3302SCarolineConcatto     Put("\n");
253864ab3302SCarolineConcatto     EndOpenMP();
253964ab3302SCarolineConcatto     Walk(std::get<OmpAtomicCapture::Stmt1>(x.t));
254064ab3302SCarolineConcatto     Put("\n");
254164ab3302SCarolineConcatto     Walk(std::get<OmpAtomicCapture::Stmt2>(x.t));
254264ab3302SCarolineConcatto     BeginOpenMP();
254364ab3302SCarolineConcatto     Word("!$OMP END ATOMIC\n");
254464ab3302SCarolineConcatto     EndOpenMP();
254564ab3302SCarolineConcatto   }
254603b5f8f0SMats Petersson   void Unparse(const OmpAtomicCompare &x) {
254703b5f8f0SMats Petersson     BeginOpenMP();
254803b5f8f0SMats Petersson     Word("!$OMP ATOMIC");
254903b5f8f0SMats Petersson     Walk(std::get<0>(x.t));
255003b5f8f0SMats Petersson     Word(" COMPARE");
255103b5f8f0SMats Petersson     Walk(std::get<2>(x.t));
255203b5f8f0SMats Petersson     Put("\n");
255303b5f8f0SMats Petersson     EndOpenMP();
255403b5f8f0SMats Petersson     Walk(std::get<OmpAtomicCompareIfStmt>(x.t));
255503b5f8f0SMats Petersson   }
255664ab3302SCarolineConcatto   void Unparse(const OmpAtomicRead &x) {
255764ab3302SCarolineConcatto     BeginOpenMP();
255864ab3302SCarolineConcatto     Word("!$OMP ATOMIC");
2559d95d3d2aSsameeran joshi     Walk(std::get<0>(x.t));
256064ab3302SCarolineConcatto     Word(" READ");
2561d95d3d2aSsameeran joshi     Walk(std::get<2>(x.t));
256264ab3302SCarolineConcatto     Put("\n");
256364ab3302SCarolineConcatto     EndOpenMP();
256464ab3302SCarolineConcatto     Walk(std::get<Statement<AssignmentStmt>>(x.t));
256564ab3302SCarolineConcatto     BeginOpenMP();
256664ab3302SCarolineConcatto     Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
256764ab3302SCarolineConcatto     EndOpenMP();
256864ab3302SCarolineConcatto   }
256964ab3302SCarolineConcatto   void Unparse(const OmpAtomicUpdate &x) {
257064ab3302SCarolineConcatto     BeginOpenMP();
257164ab3302SCarolineConcatto     Word("!$OMP ATOMIC");
2572d95d3d2aSsameeran joshi     Walk(std::get<0>(x.t));
257364ab3302SCarolineConcatto     Word(" UPDATE");
2574d95d3d2aSsameeran joshi     Walk(std::get<2>(x.t));
257564ab3302SCarolineConcatto     Put("\n");
257664ab3302SCarolineConcatto     EndOpenMP();
257764ab3302SCarolineConcatto     Walk(std::get<Statement<AssignmentStmt>>(x.t));
257864ab3302SCarolineConcatto     BeginOpenMP();
257964ab3302SCarolineConcatto     Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
258064ab3302SCarolineConcatto     EndOpenMP();
258164ab3302SCarolineConcatto   }
258264ab3302SCarolineConcatto   void Unparse(const OmpAtomicWrite &x) {
258364ab3302SCarolineConcatto     BeginOpenMP();
258464ab3302SCarolineConcatto     Word("!$OMP ATOMIC");
2585d95d3d2aSsameeran joshi     Walk(std::get<0>(x.t));
258664ab3302SCarolineConcatto     Word(" WRITE");
2587d95d3d2aSsameeran joshi     Walk(std::get<2>(x.t));
258864ab3302SCarolineConcatto     Put("\n");
258964ab3302SCarolineConcatto     EndOpenMP();
259064ab3302SCarolineConcatto     Walk(std::get<Statement<AssignmentStmt>>(x.t));
259164ab3302SCarolineConcatto     BeginOpenMP();
259264ab3302SCarolineConcatto     Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
259364ab3302SCarolineConcatto     EndOpenMP();
259464ab3302SCarolineConcatto   }
2595c9e967afSIrina Dobrescu   void Unparse(const OpenMPExecutableAllocate &x) {
259642df4951SEthan Luis McDonough     const auto &fields =
259742df4951SEthan Luis McDonough         std::get<std::optional<std::list<parser::OpenMPDeclarativeAllocate>>>(
259842df4951SEthan Luis McDonough             x.t);
259942df4951SEthan Luis McDonough     if (fields) {
260042df4951SEthan Luis McDonough       for (const auto &decl : *fields) {
260142df4951SEthan Luis McDonough         Walk(decl);
260242df4951SEthan Luis McDonough       }
260342df4951SEthan Luis McDonough     }
2604c9e967afSIrina Dobrescu     BeginOpenMP();
2605c9e967afSIrina Dobrescu     Word("!$OMP ALLOCATE");
2606c9e967afSIrina Dobrescu     Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
2607c9e967afSIrina Dobrescu     Walk(std::get<OmpClauseList>(x.t));
2608c9e967afSIrina Dobrescu     Put("\n");
2609c9e967afSIrina Dobrescu     EndOpenMP();
2610c9e967afSIrina Dobrescu     Walk(std::get<Statement<AllocateStmt>>(x.t));
2611c9e967afSIrina Dobrescu   }
2612c9e967afSIrina Dobrescu   void Unparse(const OpenMPDeclarativeAllocate &x) {
2613c9e967afSIrina Dobrescu     BeginOpenMP();
2614c9e967afSIrina Dobrescu     Word("!$OMP ALLOCATE");
2615c9e967afSIrina Dobrescu     Put(" (");
2616c9e967afSIrina Dobrescu     Walk(std::get<OmpObjectList>(x.t));
2617c9e967afSIrina Dobrescu     Put(")");
2618c9e967afSIrina Dobrescu     Walk(std::get<OmpClauseList>(x.t));
2619c9e967afSIrina Dobrescu     Put("\n");
2620c9e967afSIrina Dobrescu     EndOpenMP();
2621c9e967afSIrina Dobrescu   }
26226311ab21SEthan Luis McDonough   void Unparse(const OmpEndAllocators &x) {
26236311ab21SEthan Luis McDonough     BeginOpenMP();
26246311ab21SEthan Luis McDonough     Word("!$OMP END ALLOCATE");
26256311ab21SEthan Luis McDonough     Put("\n");
26266311ab21SEthan Luis McDonough     EndOpenMP();
26276311ab21SEthan Luis McDonough   }
26286311ab21SEthan Luis McDonough   void Unparse(const OpenMPAllocatorsConstruct &x) {
26296311ab21SEthan Luis McDonough     BeginOpenMP();
26306311ab21SEthan Luis McDonough     Word("!$OMP ALLOCATE");
26316311ab21SEthan Luis McDonough     Walk(std::get<OmpClauseList>(x.t));
26326311ab21SEthan Luis McDonough     Put("\n");
26336311ab21SEthan Luis McDonough     EndOpenMP();
26346311ab21SEthan Luis McDonough     Walk(std::get<Statement<AllocateStmt>>(x.t));
26356311ab21SEthan Luis McDonough     if (const auto &end = std::get<std::optional<OmpEndAllocators>>(x.t)) {
26366311ab21SEthan Luis McDonough       Walk(*end);
26376311ab21SEthan Luis McDonough     }
26386311ab21SEthan Luis McDonough   }
263964ab3302SCarolineConcatto   void Unparse(const OmpCriticalDirective &x) {
264064ab3302SCarolineConcatto     BeginOpenMP();
264164ab3302SCarolineConcatto     Word("!$OMP CRITICAL");
264264ab3302SCarolineConcatto     Walk(" (", std::get<std::optional<Name>>(x.t), ")");
2643fe2d053cSNimish Mishra     Walk(std::get<OmpClauseList>(x.t));
264464ab3302SCarolineConcatto     Put("\n");
264564ab3302SCarolineConcatto     EndOpenMP();
264664ab3302SCarolineConcatto   }
264764ab3302SCarolineConcatto   void Unparse(const OmpEndCriticalDirective &x) {
264864ab3302SCarolineConcatto     BeginOpenMP();
264964ab3302SCarolineConcatto     Word("!$OMP END CRITICAL");
265064ab3302SCarolineConcatto     Walk(" (", std::get<std::optional<Name>>(x.t), ")");
265164ab3302SCarolineConcatto     Put("\n");
265264ab3302SCarolineConcatto     EndOpenMP();
265364ab3302SCarolineConcatto   }
265464ab3302SCarolineConcatto   void Unparse(const OpenMPCriticalConstruct &x) {
265564ab3302SCarolineConcatto     Walk(std::get<OmpCriticalDirective>(x.t));
265664ab3302SCarolineConcatto     Walk(std::get<Block>(x.t), "");
265764ab3302SCarolineConcatto     Walk(std::get<OmpEndCriticalDirective>(x.t));
265864ab3302SCarolineConcatto   }
265964ab3302SCarolineConcatto   void Unparse(const OmpDeclareTargetWithList &x) {
266064ab3302SCarolineConcatto     Put("("), Walk(x.v), Put(")");
266164ab3302SCarolineConcatto   }
266264ab3302SCarolineConcatto   void Unparse(const OmpReductionInitializerClause &x) {
266364ab3302SCarolineConcatto     Word(" INITIALIZER(OMP_PRIV = ");
266464ab3302SCarolineConcatto     Walk(x.v);
266564ab3302SCarolineConcatto     Put(")");
266664ab3302SCarolineConcatto   }
266764ab3302SCarolineConcatto   void Unparse(const OmpReductionCombiner::FunctionCombiner &x) {
266864ab3302SCarolineConcatto     const auto &pd = std::get<ProcedureDesignator>(x.v.t);
266964ab3302SCarolineConcatto     const auto &args = std::get<std::list<ActualArgSpec>>(x.v.t);
267064ab3302SCarolineConcatto     Walk(pd);
267164ab3302SCarolineConcatto     if (args.empty()) {
267264ab3302SCarolineConcatto       if (std::holds_alternative<ProcComponentRef>(pd.u)) {
267364ab3302SCarolineConcatto         Put("()");
267464ab3302SCarolineConcatto       }
267564ab3302SCarolineConcatto     } else {
267664ab3302SCarolineConcatto       Walk("(", args, ", ", ")");
267764ab3302SCarolineConcatto     }
267864ab3302SCarolineConcatto   }
267964ab3302SCarolineConcatto   void Unparse(const OpenMPDeclareReductionConstruct &x) {
2680adeff9f6SKrzysztof Parzyszek     BeginOpenMP();
2681adeff9f6SKrzysztof Parzyszek     Word("!$OMP DECLARE REDUCTION ");
268264ab3302SCarolineConcatto     Put("(");
2683cfd67c21SKrzysztof Parzyszek     Walk(std::get<OmpReductionIdentifier>(x.t)), Put(" : ");
268464ab3302SCarolineConcatto     Walk(std::get<std::list<DeclarationTypeSpec>>(x.t), ","), Put(" : ");
268564ab3302SCarolineConcatto     Walk(std::get<OmpReductionCombiner>(x.t));
268664ab3302SCarolineConcatto     Put(")");
268764ab3302SCarolineConcatto     Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
2688c9e967afSIrina Dobrescu     EndOpenMP();
2689adeff9f6SKrzysztof Parzyszek   }
2690adeff9f6SKrzysztof Parzyszek 
2691adeff9f6SKrzysztof Parzyszek   void Unparse(const OpenMPDeclareMapperConstruct &z) {
2692adeff9f6SKrzysztof Parzyszek     BeginOpenMP();
2693adeff9f6SKrzysztof Parzyszek     Word("!$OMP DECLARE MAPPER (");
2694ec1e0c5eSMats Petersson     const auto &spec{std::get<OmpDeclareMapperSpecifier>(z.t)};
2695ec1e0c5eSMats Petersson     if (auto mapname{std::get<std::optional<Name>>(spec.t)}) {
2696ec1e0c5eSMats Petersson       Walk(mapname);
2697ec1e0c5eSMats Petersson       Put(":");
2698ec1e0c5eSMats Petersson     }
2699ec1e0c5eSMats Petersson     Walk(std::get<TypeSpec>(spec.t));
2700ec1e0c5eSMats Petersson     Put("::");
2701ec1e0c5eSMats Petersson     Walk(std::get<Name>(spec.t));
2702ec1e0c5eSMats Petersson     Put(")");
2703ec1e0c5eSMats Petersson 
2704ec1e0c5eSMats Petersson     Walk(std::get<OmpClauseList>(z.t));
2705ec1e0c5eSMats Petersson     Put("\n");
2706adeff9f6SKrzysztof Parzyszek     EndOpenMP();
2707adeff9f6SKrzysztof Parzyszek   }
2708adeff9f6SKrzysztof Parzyszek   void Unparse(const OpenMPDeclareSimdConstruct &y) {
2709adeff9f6SKrzysztof Parzyszek     BeginOpenMP();
2710adeff9f6SKrzysztof Parzyszek     Word("!$OMP DECLARE SIMD ");
271164ab3302SCarolineConcatto     Walk("(", std::get<std::optional<Name>>(y.t), ")");
271264ab3302SCarolineConcatto     Walk(std::get<OmpClauseList>(y.t));
271364ab3302SCarolineConcatto     Put("\n");
271464ab3302SCarolineConcatto     EndOpenMP();
2715adeff9f6SKrzysztof Parzyszek   }
2716adeff9f6SKrzysztof Parzyszek   void Unparse(const OpenMPDeclareTargetConstruct &x) {
2717adeff9f6SKrzysztof Parzyszek     BeginOpenMP();
2718adeff9f6SKrzysztof Parzyszek     Word("!$OMP DECLARE TARGET ");
2719adeff9f6SKrzysztof Parzyszek     Walk(std::get<parser::OmpDeclareTargetSpecifier>(x.t));
2720adeff9f6SKrzysztof Parzyszek     Put("\n");
2721adeff9f6SKrzysztof Parzyszek     EndOpenMP();
2722adeff9f6SKrzysztof Parzyszek   }
2723adeff9f6SKrzysztof Parzyszek   void Unparse(const OpenMPRequiresConstruct &y) {
2724adeff9f6SKrzysztof Parzyszek     BeginOpenMP();
2725adeff9f6SKrzysztof Parzyszek     Word("!$OMP REQUIRES ");
2726d5fb5960SSergio Afonso     Walk(std::get<OmpClauseList>(y.t));
2727d5fb5960SSergio Afonso     Put("\n");
2728d5fb5960SSergio Afonso     EndOpenMP();
272964ab3302SCarolineConcatto   }
2730adeff9f6SKrzysztof Parzyszek   void Unparse(const OpenMPThreadprivate &x) {
2731adeff9f6SKrzysztof Parzyszek     BeginOpenMP();
2732adeff9f6SKrzysztof Parzyszek     Word("!$OMP THREADPRIVATE (");
2733adeff9f6SKrzysztof Parzyszek     Walk(std::get<parser::OmpObjectList>(x.t));
273464ab3302SCarolineConcatto     Put(")\n");
273564ab3302SCarolineConcatto     EndOpenMP();
273664ab3302SCarolineConcatto   }
2737adeff9f6SKrzysztof Parzyszek 
273875e6d0ebSMats Petersson   bool Pre(const OmpMessageClause &x) {
273975e6d0ebSMats Petersson     Walk(x.v);
274075e6d0ebSMats Petersson     return false;
274175e6d0ebSMats Petersson   }
27428035d38dSMats Petersson   void Unparse(const OmpDispatchDirective &x) {
27438035d38dSMats Petersson     Word("!$OMP DISPATCH");
27448035d38dSMats Petersson     Walk(x.t);
27458035d38dSMats Petersson     Put("\n");
27468035d38dSMats Petersson   }
27478035d38dSMats Petersson   void Unparse(const OmpEndDispatchDirective &) {
27488035d38dSMats Petersson     Word("!$OMP END DISPATCH");
27498035d38dSMats Petersson     Put("\n");
27508035d38dSMats Petersson   }
2751df859f90SKrzysztof Parzyszek   void Unparse(const OmpErrorDirective &x) {
275275e6d0ebSMats Petersson     Word("!$OMP ERROR ");
275375e6d0ebSMats Petersson     Walk(x.t);
275475e6d0ebSMats Petersson     Put("\n");
275575e6d0ebSMats Petersson   }
2756df859f90SKrzysztof Parzyszek   void Unparse(const OmpNothingDirective &x) {
2757df859f90SKrzysztof Parzyszek     Word("!$OMP NOTHING");
2758df859f90SKrzysztof Parzyszek     Put("\n");
2759df859f90SKrzysztof Parzyszek   }
276064ab3302SCarolineConcatto   void Unparse(const OmpSectionsDirective &x) {
276164ab3302SCarolineConcatto     switch (x.v) {
27622ddba308SValentin Clement     case llvm::omp::Directive::OMPD_sections:
27631f879005STim Keith       Word("SECTIONS ");
27641f879005STim Keith       break;
27652ddba308SValentin Clement     case llvm::omp::Directive::OMPD_parallel_sections:
276664ab3302SCarolineConcatto       Word("PARALLEL SECTIONS ");
276764ab3302SCarolineConcatto       break;
27682ddba308SValentin Clement     default:
27692ddba308SValentin Clement       break;
277064ab3302SCarolineConcatto     }
277164ab3302SCarolineConcatto   }
277264ab3302SCarolineConcatto   void Unparse(const OmpSectionBlocks &x) {
277364ab3302SCarolineConcatto     for (const auto &y : x.v) {
277464ab3302SCarolineConcatto       BeginOpenMP();
277564ab3302SCarolineConcatto       Word("!$OMP SECTION");
277664ab3302SCarolineConcatto       Put("\n");
277764ab3302SCarolineConcatto       EndOpenMP();
2778ae1623b3SShraiysh Vaishay       // y.u is an OpenMPSectionConstruct
2779ae1623b3SShraiysh Vaishay       // (y.u).v is Block
2780ae1623b3SShraiysh Vaishay       Walk(std::get<OpenMPSectionConstruct>(y.u).v, "");
278164ab3302SCarolineConcatto     }
278264ab3302SCarolineConcatto   }
278364ab3302SCarolineConcatto   void Unparse(const OpenMPSectionsConstruct &x) {
278464ab3302SCarolineConcatto     BeginOpenMP();
278564ab3302SCarolineConcatto     Word("!$OMP ");
278664ab3302SCarolineConcatto     Walk(std::get<OmpBeginSectionsDirective>(x.t));
278764ab3302SCarolineConcatto     Put("\n");
278864ab3302SCarolineConcatto     EndOpenMP();
278964ab3302SCarolineConcatto     Walk(std::get<OmpSectionBlocks>(x.t));
279064ab3302SCarolineConcatto     BeginOpenMP();
279164ab3302SCarolineConcatto     Word("!$OMP END ");
279264ab3302SCarolineConcatto     Walk(std::get<OmpEndSectionsDirective>(x.t));
279364ab3302SCarolineConcatto     Put("\n");
279464ab3302SCarolineConcatto     EndOpenMP();
279564ab3302SCarolineConcatto   }
279664ab3302SCarolineConcatto   void Unparse(const OpenMPCancellationPointConstruct &x) {
279764ab3302SCarolineConcatto     BeginOpenMP();
279864ab3302SCarolineConcatto     Word("!$OMP CANCELLATION POINT ");
279964ab3302SCarolineConcatto     Walk(std::get<OmpCancelType>(x.t));
280064ab3302SCarolineConcatto     Put("\n");
280164ab3302SCarolineConcatto     EndOpenMP();
280264ab3302SCarolineConcatto   }
280364ab3302SCarolineConcatto   void Unparse(const OpenMPCancelConstruct &x) {
280464ab3302SCarolineConcatto     BeginOpenMP();
280564ab3302SCarolineConcatto     Word("!$OMP CANCEL ");
280664ab3302SCarolineConcatto     Walk(std::get<OmpCancelType>(x.t));
280764ab3302SCarolineConcatto     Walk(std::get<std::optional<OpenMPCancelConstruct::If>>(x.t));
280864ab3302SCarolineConcatto     Put("\n");
280964ab3302SCarolineConcatto     EndOpenMP();
281064ab3302SCarolineConcatto   }
281100e1cc4cSMats Petersson   void Unparse(const OmpFailClause &x) {
281200e1cc4cSMats Petersson     Word("FAIL(");
281300e1cc4cSMats Petersson     Walk(x.v);
281400e1cc4cSMats Petersson     Put(")");
281500e1cc4cSMats Petersson   }
2816aa179d80SValentin Clement   void Unparse(const OmpMemoryOrderClause &x) { Walk(x.v); }
2817e43b3b08Ssameeran joshi   void Unparse(const OmpAtomicClause &x) {
2818cd03e96fSPeter Klausler     common::visit(common::visitors{
2819e43b3b08Ssameeran joshi                       [&](const OmpMemoryOrderClause &y) { Walk(y); },
282000e1cc4cSMats Petersson                       [&](const OmpFailClause &y) { Walk(y); },
2821e43b3b08Ssameeran joshi                       [&](const OmpClause &z) { Walk(z); },
2822e43b3b08Ssameeran joshi                   },
2823e43b3b08Ssameeran joshi         x.u);
2824e43b3b08Ssameeran joshi   }
2825*15ab7be2SKrzysztof Parzyszek   void Unparse(const OmpMetadirectiveDirective &x) {
2826*15ab7be2SKrzysztof Parzyszek     BeginOpenMP();
2827*15ab7be2SKrzysztof Parzyszek     Word("!$OMP METADIRECTIVE ");
2828*15ab7be2SKrzysztof Parzyszek     Walk(std::get<OmpClauseList>(x.t));
2829*15ab7be2SKrzysztof Parzyszek     Put("\n");
2830*15ab7be2SKrzysztof Parzyszek     EndOpenMP();
2831*15ab7be2SKrzysztof Parzyszek   }
2832c478aab6SKrzysztof Parzyszek   void Unparse(const OpenMPDepobjConstruct &x) {
2833c478aab6SKrzysztof Parzyszek     BeginOpenMP();
2834c478aab6SKrzysztof Parzyszek     Word("!$OMP DEPOBJ");
2835c478aab6SKrzysztof Parzyszek     Put("(");
2836c478aab6SKrzysztof Parzyszek     Walk(std::get<OmpObject>(x.t));
2837c478aab6SKrzysztof Parzyszek     Put(") ");
2838c478aab6SKrzysztof Parzyszek     Walk(std::get<OmpClause>(x.t));
2839c478aab6SKrzysztof Parzyszek     Put("\n");
2840c478aab6SKrzysztof Parzyszek     EndOpenMP();
2841c478aab6SKrzysztof Parzyszek   }
284264ab3302SCarolineConcatto   void Unparse(const OpenMPFlushConstruct &x) {
284364ab3302SCarolineConcatto     BeginOpenMP();
284464ab3302SCarolineConcatto     Word("!$OMP FLUSH ");
2845f1569b1eSsameeran joshi     Walk(std::get<std::optional<std::list<OmpMemoryOrderClause>>>(x.t));
284664ab3302SCarolineConcatto     Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
284764ab3302SCarolineConcatto     Put("\n");
284864ab3302SCarolineConcatto     EndOpenMP();
284964ab3302SCarolineConcatto   }
285064ab3302SCarolineConcatto   void Unparse(const OmpEndLoopDirective &x) {
285164ab3302SCarolineConcatto     BeginOpenMP();
285264ab3302SCarolineConcatto     Word("!$OMP END ");
285364ab3302SCarolineConcatto     Walk(std::get<OmpLoopDirective>(x.t));
285464ab3302SCarolineConcatto     Walk(std::get<OmpClauseList>(x.t));
285564ab3302SCarolineConcatto     Put("\n");
285664ab3302SCarolineConcatto     EndOpenMP();
285764ab3302SCarolineConcatto   }
285864ab3302SCarolineConcatto   void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
285964ab3302SCarolineConcatto   void Unparse(const OpenMPSimpleStandaloneConstruct &x) {
286064ab3302SCarolineConcatto     BeginOpenMP();
286164ab3302SCarolineConcatto     Word("!$OMP ");
286264ab3302SCarolineConcatto     Walk(std::get<OmpSimpleStandaloneDirective>(x.t));
286364ab3302SCarolineConcatto     Walk(std::get<OmpClauseList>(x.t));
286464ab3302SCarolineConcatto     Put("\n");
286564ab3302SCarolineConcatto     EndOpenMP();
286664ab3302SCarolineConcatto   }
286764ab3302SCarolineConcatto   void Unparse(const OpenMPBlockConstruct &x) {
286864ab3302SCarolineConcatto     BeginOpenMP();
286964ab3302SCarolineConcatto     Word("!$OMP ");
287064ab3302SCarolineConcatto     Walk(std::get<OmpBeginBlockDirective>(x.t));
287164ab3302SCarolineConcatto     Put("\n");
287264ab3302SCarolineConcatto     EndOpenMP();
287364ab3302SCarolineConcatto     Walk(std::get<Block>(x.t), "");
287464ab3302SCarolineConcatto     BeginOpenMP();
287564ab3302SCarolineConcatto     Word("!$OMP END ");
287664ab3302SCarolineConcatto     Walk(std::get<OmpEndBlockDirective>(x.t));
287764ab3302SCarolineConcatto     Put("\n");
287864ab3302SCarolineConcatto     EndOpenMP();
287964ab3302SCarolineConcatto   }
288064ab3302SCarolineConcatto   void Unparse(const OpenMPLoopConstruct &x) {
288164ab3302SCarolineConcatto     BeginOpenMP();
288264ab3302SCarolineConcatto     Word("!$OMP ");
288364ab3302SCarolineConcatto     Walk(std::get<OmpBeginLoopDirective>(x.t));
288464ab3302SCarolineConcatto     Put("\n");
288564ab3302SCarolineConcatto     EndOpenMP();
288664ab3302SCarolineConcatto     Walk(std::get<std::optional<DoConstruct>>(x.t));
288764ab3302SCarolineConcatto     Walk(std::get<std::optional<OmpEndLoopDirective>>(x.t));
288864ab3302SCarolineConcatto   }
288964ab3302SCarolineConcatto   void Unparse(const BasedPointer &x) {
289064ab3302SCarolineConcatto     Put('('), Walk(std::get<0>(x.t)), Put(","), Walk(std::get<1>(x.t));
289164ab3302SCarolineConcatto     Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")"), Put(')');
289264ab3302SCarolineConcatto   }
289364ab3302SCarolineConcatto   void Unparse(const BasedPointerStmt &x) { Walk("POINTER ", x.v, ","); }
28944ad72793SPeter Klausler   void Unparse(const CUDAAttributesStmt &x) {
28954ad72793SPeter Klausler     Word("ATTRIBUTES("), Walk(std::get<common::CUDADataAttr>(x.t));
28964ad72793SPeter Klausler     Word(") "), Walk(std::get<std::list<Name>>(x.t), ", ");
28974ad72793SPeter Klausler   }
289864ab3302SCarolineConcatto   void Post(const StructureField &x) {
289964ab3302SCarolineConcatto     if (const auto *def{std::get_if<Statement<DataComponentDefStmt>>(&x.u)}) {
2900c14cf92bSPeter Klausler       for (const auto &item :
2901c14cf92bSPeter Klausler           std::get<std::list<ComponentOrFill>>(def->statement.t)) {
2902c14cf92bSPeter Klausler         if (const auto *comp{std::get_if<ComponentDecl>(&item.u)}) {
2903c14cf92bSPeter Klausler           structureComponents_.insert(std::get<Name>(comp->t).source);
2904c14cf92bSPeter Klausler         }
290564ab3302SCarolineConcatto       }
290664ab3302SCarolineConcatto     }
290764ab3302SCarolineConcatto   }
290864ab3302SCarolineConcatto   void Unparse(const StructureStmt &x) {
290964ab3302SCarolineConcatto     Word("STRUCTURE ");
2910c14cf92bSPeter Klausler     // The name, if present, includes the /slashes/
2911c14cf92bSPeter Klausler     Walk(std::get<std::optional<Name>>(x.t));
291264ab3302SCarolineConcatto     Walk(" ", std::get<std::list<EntityDecl>>(x.t), ", ");
291364ab3302SCarolineConcatto     Indent();
291464ab3302SCarolineConcatto   }
291564ab3302SCarolineConcatto   void Post(const Union::UnionStmt &) { Word("UNION"), Indent(); }
291664ab3302SCarolineConcatto   void Post(const Union::EndUnionStmt &) { Outdent(), Word("END UNION"); }
291764ab3302SCarolineConcatto   void Post(const Map::MapStmt &) { Word("MAP"), Indent(); }
291864ab3302SCarolineConcatto   void Post(const Map::EndMapStmt &) { Outdent(), Word("END MAP"); }
291964ab3302SCarolineConcatto   void Post(const StructureDef::EndStructureStmt &) {
292064ab3302SCarolineConcatto     Outdent(), Word("END STRUCTURE");
292164ab3302SCarolineConcatto   }
292264ab3302SCarolineConcatto   void Unparse(const OldParameterStmt &x) {
292364ab3302SCarolineConcatto     Word("PARAMETER "), Walk(x.v, ", ");
292464ab3302SCarolineConcatto   }
292564ab3302SCarolineConcatto   void Unparse(const ArithmeticIfStmt &x) {
292664ab3302SCarolineConcatto     Word("IF ("), Walk(std::get<Expr>(x.t)), Put(") ");
292764ab3302SCarolineConcatto     Walk(std::get<1>(x.t)), Put(", ");
292864ab3302SCarolineConcatto     Walk(std::get<2>(x.t)), Put(", ");
292964ab3302SCarolineConcatto     Walk(std::get<3>(x.t));
293064ab3302SCarolineConcatto   }
293164ab3302SCarolineConcatto   void Unparse(const AssignStmt &x) {
293264ab3302SCarolineConcatto     Word("ASSIGN "), Walk(std::get<Label>(x.t));
293364ab3302SCarolineConcatto     Word(" TO "), Walk(std::get<Name>(x.t));
293464ab3302SCarolineConcatto   }
293564ab3302SCarolineConcatto   void Unparse(const AssignedGotoStmt &x) {
293664ab3302SCarolineConcatto     Word("GO TO "), Walk(std::get<Name>(x.t));
293764ab3302SCarolineConcatto     Walk(", (", std::get<std::list<Label>>(x.t), ", ", ")");
293864ab3302SCarolineConcatto   }
293964ab3302SCarolineConcatto   void Unparse(const PauseStmt &x) { Word("PAUSE"), Walk(" ", x.v); }
294064ab3302SCarolineConcatto 
294164ab3302SCarolineConcatto #define WALK_NESTED_ENUM(CLASS, ENUM) \
294264ab3302SCarolineConcatto   void Unparse(const CLASS::ENUM &x) { Word(CLASS::EnumToString(x)); }
29434ad72793SPeter Klausler   WALK_NESTED_ENUM(AccDataModifier, Modifier)
294464ab3302SCarolineConcatto   WALK_NESTED_ENUM(AccessSpec, Kind) // R807
294564ab3302SCarolineConcatto   WALK_NESTED_ENUM(common, TypeParamAttr) // R734
29464ad72793SPeter Klausler   WALK_NESTED_ENUM(common, CUDADataAttr) // CUDA
29474ad72793SPeter Klausler   WALK_NESTED_ENUM(common, CUDASubprogramAttrs) // CUDA
294864ab3302SCarolineConcatto   WALK_NESTED_ENUM(IntentSpec, Intent) // R826
294964ab3302SCarolineConcatto   WALK_NESTED_ENUM(ImplicitStmt, ImplicitNoneNameSpec) // R866
295064ab3302SCarolineConcatto   WALK_NESTED_ENUM(ConnectSpec::CharExpr, Kind) // R1205
295164ab3302SCarolineConcatto   WALK_NESTED_ENUM(IoControlSpec::CharExpr, Kind)
295264ab3302SCarolineConcatto   WALK_NESTED_ENUM(InquireSpec::CharVar, Kind)
295364ab3302SCarolineConcatto   WALK_NESTED_ENUM(InquireSpec::IntVar, Kind)
295464ab3302SCarolineConcatto   WALK_NESTED_ENUM(InquireSpec::LogVar, Kind)
295564ab3302SCarolineConcatto   WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506
295664ab3302SCarolineConcatto   WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
295775e6d0ebSMats Petersson   WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at
2958608f4ae1SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind
2959608f4ae1SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind
2960608f4ae1SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
2961608f4ae1SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpDefaultmapClause, ImplicitBehavior) // OMP defaultmap
29624fc1141eSKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpVariableCategory, Value) // OMP variable-category
296333faa828SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpLastprivateModifier, Value) // OMP lastprivate-modifier
2964e79cd246SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpChunkModifier, Value) // OMP chunk-modifier
2965cfd67c21SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpLinearModifier, Value) // OMP linear-modifier
2966e79cd246SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier
2967cfd67c21SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type
2968e79cd246SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind
296975e6d0ebSMats Petersson   WALK_NESTED_ENUM(OmpSeverityClause, Severity) // OMP severity
297005096590SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpDeviceModifier, Value) // OMP device modifier
2971608f4ae1SKrzysztof Parzyszek   WALK_NESTED_ENUM(
2972608f4ae1SKrzysztof Parzyszek       OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type
29734fc1141eSKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier
297452755ac2SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation
297564ab3302SCarolineConcatto   WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
2976e79cd246SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering
2977e79cd246SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier
2978bde79c0eSKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness
297952755ac2SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpMapType, Value) // OMP map-type
298052755ac2SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpMapTypeModifier, Value) // OMP map-type-modifier
298170e96dc3SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpTraitSelectorName, Value)
298270e96dc3SKrzysztof Parzyszek   WALK_NESTED_ENUM(OmpTraitSetSelectorName, Value)
298370e96dc3SKrzysztof Parzyszek 
298464ab3302SCarolineConcatto #undef WALK_NESTED_ENUM
29853af717d6Skhaki3   void Unparse(const ReductionOperator::Operator x) {
29865bbb63bdSPeter Klausler     switch (x) {
29873af717d6Skhaki3     case ReductionOperator::Operator::Plus:
29885bbb63bdSPeter Klausler       Word("+");
29895bbb63bdSPeter Klausler       break;
29903af717d6Skhaki3     case ReductionOperator::Operator::Multiply:
29915bbb63bdSPeter Klausler       Word("*");
29925bbb63bdSPeter Klausler       break;
29933af717d6Skhaki3     case ReductionOperator::Operator::And:
29945bbb63bdSPeter Klausler       Word(".AND.");
29955bbb63bdSPeter Klausler       break;
29963af717d6Skhaki3     case ReductionOperator::Operator::Or:
29975bbb63bdSPeter Klausler       Word(".OR.");
29985bbb63bdSPeter Klausler       break;
29993af717d6Skhaki3     case ReductionOperator::Operator::Eqv:
30005bbb63bdSPeter Klausler       Word(".EQV.");
30015bbb63bdSPeter Klausler       break;
30023af717d6Skhaki3     case ReductionOperator::Operator::Neqv:
30035bbb63bdSPeter Klausler       Word(".NEQV.");
30045bbb63bdSPeter Klausler       break;
30055bbb63bdSPeter Klausler     default:
30063af717d6Skhaki3       Word(ReductionOperator::EnumToString(x));
30075bbb63bdSPeter Klausler       break;
30085bbb63bdSPeter Klausler     }
30095bbb63bdSPeter Klausler   }
301064ab3302SCarolineConcatto 
301160fa2b06SPeter Klausler   void Unparse(const CUFKernelDoConstruct::StarOrExpr &x) {
301260fa2b06SPeter Klausler     if (x.v) {
301360fa2b06SPeter Klausler       Walk(*x.v);
301460fa2b06SPeter Klausler     } else {
301560fa2b06SPeter Klausler       Word("*");
301660fa2b06SPeter Klausler     }
301760fa2b06SPeter Klausler   }
301837143fe2SValentin Clement (バレンタイン クレメン)   void Unparse(const CUFKernelDoConstruct::LaunchConfiguration &x) {
30194ad72793SPeter Klausler     Word(" <<<");
302037143fe2SValentin Clement (バレンタイン クレメン)     const auto &grid{std::get<0>(x.t)};
30214ad72793SPeter Klausler     if (grid.empty()) {
30224ad72793SPeter Klausler       Word("*");
30234ad72793SPeter Klausler     } else if (grid.size() == 1) {
30244ad72793SPeter Klausler       Walk(grid.front());
30254ad72793SPeter Klausler     } else {
30264ad72793SPeter Klausler       Walk("(", grid, ",", ")");
30274ad72793SPeter Klausler     }
30284ad72793SPeter Klausler     Word(",");
302937143fe2SValentin Clement (バレンタイン クレメン)     const auto &block{std::get<1>(x.t)};
30304ad72793SPeter Klausler     if (block.empty()) {
30314ad72793SPeter Klausler       Word("*");
30324ad72793SPeter Klausler     } else if (block.size() == 1) {
30334ad72793SPeter Klausler       Walk(block.front());
30344ad72793SPeter Klausler     } else {
30354ad72793SPeter Klausler       Walk("(", block, ",", ")");
30364ad72793SPeter Klausler     }
303737143fe2SValentin Clement (バレンタイン クレメン)     if (const auto &stream{std::get<2>(x.t)}) {
30384ad72793SPeter Klausler       Word(",STREAM="), Walk(*stream);
30394ad72793SPeter Klausler     }
30405bbb63bdSPeter Klausler     Word(">>>");
304137143fe2SValentin Clement (バレンタイン クレメン)   }
304237143fe2SValentin Clement (バレンタイン クレメン)   void Unparse(const CUFKernelDoConstruct::Directive &x) {
304337143fe2SValentin Clement (バレンタイン クレメン)     Word("!$CUF KERNEL DO");
304437143fe2SValentin Clement (バレンタイン クレメン)     Walk(" (", std::get<std::optional<ScalarIntConstantExpr>>(x.t), ")");
304537143fe2SValentin Clement (バレンタイン クレメン)     Walk(std::get<std::optional<CUFKernelDoConstruct::LaunchConfiguration>>(
304637143fe2SValentin Clement (バレンタイン クレメン)         x.t));
30475bbb63bdSPeter Klausler     Walk(" ", std::get<std::list<CUFReduction>>(x.t), " ");
30485bbb63bdSPeter Klausler     Word("\n");
30494ad72793SPeter Klausler   }
30504ad72793SPeter Klausler   void Unparse(const CUFKernelDoConstruct &x) {
30514ad72793SPeter Klausler     Walk(std::get<CUFKernelDoConstruct::Directive>(x.t));
30524ad72793SPeter Klausler     Walk(std::get<std::optional<DoConstruct>>(x.t));
30534ad72793SPeter Klausler   }
30545bbb63bdSPeter Klausler   void Unparse(const CUFReduction &x) {
30555bbb63bdSPeter Klausler     Word("REDUCE(");
30565bbb63bdSPeter Klausler     Walk(std::get<CUFReduction::Operator>(x.t));
30575bbb63bdSPeter Klausler     Walk(":", std::get<std::list<Scalar<Variable>>>(x.t), ",", ")");
30585bbb63bdSPeter Klausler   }
30594ad72793SPeter Klausler 
306064ab3302SCarolineConcatto   void Done() const { CHECK(indent_ == 0); }
306164ab3302SCarolineConcatto 
306264ab3302SCarolineConcatto private:
306364ab3302SCarolineConcatto   void Put(char);
306464ab3302SCarolineConcatto   void Put(const char *);
306564ab3302SCarolineConcatto   void Put(const std::string &);
306664ab3302SCarolineConcatto   void PutNormalized(const std::string &);
306764ab3302SCarolineConcatto   void PutKeywordLetter(char);
306864ab3302SCarolineConcatto   void Word(const char *);
306964ab3302SCarolineConcatto   void Word(const std::string &);
3070bcba39a5SPeter Klausler   void Word(const std::string_view &);
307164ab3302SCarolineConcatto   void Indent() { indent_ += indentationAmount_; }
307264ab3302SCarolineConcatto   void Outdent() {
307364ab3302SCarolineConcatto     CHECK(indent_ >= indentationAmount_);
307464ab3302SCarolineConcatto     indent_ -= indentationAmount_;
307564ab3302SCarolineConcatto   }
307664ab3302SCarolineConcatto   void BeginOpenMP() { openmpDirective_ = true; }
307764ab3302SCarolineConcatto   void EndOpenMP() { openmpDirective_ = false; }
30780a90ffa7SValentin Clement   void BeginOpenACC() { openaccDirective_ = true; }
30790a90ffa7SValentin Clement   void EndOpenACC() { openaccDirective_ = false; }
308064ab3302SCarolineConcatto 
308164ab3302SCarolineConcatto   // Call back to the traversal framework.
308264ab3302SCarolineConcatto   template <typename T> void Walk(const T &x) {
308364ab3302SCarolineConcatto     Fortran::parser::Walk(x, *this);
308464ab3302SCarolineConcatto   }
308564ab3302SCarolineConcatto 
308664ab3302SCarolineConcatto   // Traverse a std::optional<> value.  Emit a prefix and/or a suffix string
308764ab3302SCarolineConcatto   // only when it contains a value.
308864ab3302SCarolineConcatto   template <typename A>
308964ab3302SCarolineConcatto   void Walk(
309064ab3302SCarolineConcatto       const char *prefix, const std::optional<A> &x, const char *suffix = "") {
309164ab3302SCarolineConcatto     if (x) {
309264ab3302SCarolineConcatto       Word(prefix), Walk(*x), Word(suffix);
309364ab3302SCarolineConcatto     }
309464ab3302SCarolineConcatto   }
309564ab3302SCarolineConcatto   template <typename A>
309664ab3302SCarolineConcatto   void Walk(const std::optional<A> &x, const char *suffix = "") {
309764ab3302SCarolineConcatto     return Walk("", x, suffix);
309864ab3302SCarolineConcatto   }
309964ab3302SCarolineConcatto 
310064ab3302SCarolineConcatto   // Traverse a std::list<>.  Separate the elements with an optional string.
310164ab3302SCarolineConcatto   // Emit a prefix and/or a suffix string only when the list is not empty.
310264ab3302SCarolineConcatto   template <typename A>
310364ab3302SCarolineConcatto   void Walk(const char *prefix, const std::list<A> &list,
310464ab3302SCarolineConcatto       const char *comma = ", ", const char *suffix = "") {
310564ab3302SCarolineConcatto     if (!list.empty()) {
310664ab3302SCarolineConcatto       const char *str{prefix};
310764ab3302SCarolineConcatto       for (const auto &x : list) {
310864ab3302SCarolineConcatto         Word(str), Walk(x);
310964ab3302SCarolineConcatto         str = comma;
311064ab3302SCarolineConcatto       }
311164ab3302SCarolineConcatto       Word(suffix);
311264ab3302SCarolineConcatto     }
311364ab3302SCarolineConcatto   }
311464ab3302SCarolineConcatto   template <typename A>
311564ab3302SCarolineConcatto   void Walk(const std::list<A> &list, const char *comma = ", ",
311664ab3302SCarolineConcatto       const char *suffix = "") {
311764ab3302SCarolineConcatto     return Walk("", list, comma, suffix);
311864ab3302SCarolineConcatto   }
311964ab3302SCarolineConcatto 
312064ab3302SCarolineConcatto   // Traverse a std::tuple<>, with an optional separator.
312164ab3302SCarolineConcatto   template <std::size_t J = 0, typename T>
312264ab3302SCarolineConcatto   void WalkTupleElements(const T &tuple, const char *separator) {
312364ab3302SCarolineConcatto     if (J > 0 && J < std::tuple_size_v<T>) {
312464ab3302SCarolineConcatto       Word(separator); // this usage dodges "unused parameter" warning
312564ab3302SCarolineConcatto     }
312664ab3302SCarolineConcatto     if constexpr (J < std::tuple_size_v<T>) {
312764ab3302SCarolineConcatto       Walk(std::get<J>(tuple));
312864ab3302SCarolineConcatto       WalkTupleElements<J + 1>(tuple, separator);
312964ab3302SCarolineConcatto     }
313064ab3302SCarolineConcatto   }
313164ab3302SCarolineConcatto   template <typename... A>
313264ab3302SCarolineConcatto   void Walk(const std::tuple<A...> &tuple, const char *separator = "") {
313364ab3302SCarolineConcatto     WalkTupleElements(tuple, separator);
313464ab3302SCarolineConcatto   }
313564ab3302SCarolineConcatto 
313664ab3302SCarolineConcatto   void EndSubprogram(const char *kind, const std::optional<Name> &name) {
313764ab3302SCarolineConcatto     Outdent(), Word("END "), Word(kind), Walk(" ", name);
313864ab3302SCarolineConcatto     structureComponents_.clear();
313964ab3302SCarolineConcatto   }
314064ab3302SCarolineConcatto 
31418670e499SCaroline Concatto   llvm::raw_ostream &out_;
314264ab3302SCarolineConcatto   int indent_{0};
314364ab3302SCarolineConcatto   const int indentationAmount_{1};
314464ab3302SCarolineConcatto   int column_{1};
314564ab3302SCarolineConcatto   const int maxColumns_{80};
314664ab3302SCarolineConcatto   std::set<CharBlock> structureComponents_;
314764ab3302SCarolineConcatto   Encoding encoding_{Encoding::UTF_8};
314864ab3302SCarolineConcatto   bool capitalizeKeywords_{true};
31490a90ffa7SValentin Clement   bool openaccDirective_{false};
315064ab3302SCarolineConcatto   bool openmpDirective_{false};
315164ab3302SCarolineConcatto   bool backslashEscapes_{false};
315264ab3302SCarolineConcatto   preStatementType *preStatement_{nullptr};
315364ab3302SCarolineConcatto   AnalyzedObjectsAsFortran *asFortran_{nullptr};
315464ab3302SCarolineConcatto };
315564ab3302SCarolineConcatto 
315664ab3302SCarolineConcatto void UnparseVisitor::Put(char ch) {
315764ab3302SCarolineConcatto   int sav = indent_;
31580a90ffa7SValentin Clement   if (openmpDirective_ || openaccDirective_) {
315964ab3302SCarolineConcatto     indent_ = 0;
316064ab3302SCarolineConcatto   }
316164ab3302SCarolineConcatto   if (column_ <= 1) {
316264ab3302SCarolineConcatto     if (ch == '\n') {
316364ab3302SCarolineConcatto       return;
316464ab3302SCarolineConcatto     }
316564ab3302SCarolineConcatto     for (int j{0}; j < indent_; ++j) {
316664ab3302SCarolineConcatto       out_ << ' ';
316764ab3302SCarolineConcatto     }
316864ab3302SCarolineConcatto     column_ = indent_ + 2;
316964ab3302SCarolineConcatto   } else if (ch == '\n') {
317064ab3302SCarolineConcatto     column_ = 1;
317164ab3302SCarolineConcatto   } else if (++column_ >= maxColumns_) {
317264ab3302SCarolineConcatto     out_ << "&\n";
317364ab3302SCarolineConcatto     for (int j{0}; j < indent_; ++j) {
317464ab3302SCarolineConcatto       out_ << ' ';
317564ab3302SCarolineConcatto     }
317664ab3302SCarolineConcatto     if (openmpDirective_) {
317764ab3302SCarolineConcatto       out_ << "!$OMP&";
317864ab3302SCarolineConcatto       column_ = 8;
31790a90ffa7SValentin Clement     } else if (openaccDirective_) {
31800a90ffa7SValentin Clement       out_ << "!$ACC&";
31810a90ffa7SValentin Clement       column_ = 8;
318264ab3302SCarolineConcatto     } else {
318364ab3302SCarolineConcatto       out_ << '&';
318464ab3302SCarolineConcatto       column_ = indent_ + 3;
318564ab3302SCarolineConcatto     }
318664ab3302SCarolineConcatto   }
318764ab3302SCarolineConcatto   out_ << ch;
31880a90ffa7SValentin Clement   if (openmpDirective_ || openaccDirective_) {
318964ab3302SCarolineConcatto     indent_ = sav;
319064ab3302SCarolineConcatto   }
319164ab3302SCarolineConcatto }
319264ab3302SCarolineConcatto 
319364ab3302SCarolineConcatto void UnparseVisitor::Put(const char *str) {
319464ab3302SCarolineConcatto   for (; *str != '\0'; ++str) {
319564ab3302SCarolineConcatto     Put(*str);
319664ab3302SCarolineConcatto   }
319764ab3302SCarolineConcatto }
319864ab3302SCarolineConcatto 
319964ab3302SCarolineConcatto void UnparseVisitor::Put(const std::string &str) {
320064ab3302SCarolineConcatto   for (char ch : str) {
320164ab3302SCarolineConcatto     Put(ch);
320264ab3302SCarolineConcatto   }
320364ab3302SCarolineConcatto }
320464ab3302SCarolineConcatto 
320564ab3302SCarolineConcatto void UnparseVisitor::PutNormalized(const std::string &str) {
320664ab3302SCarolineConcatto   auto decoded{DecodeString<std::string, Encoding::LATIN_1>(str, true)};
320764ab3302SCarolineConcatto   std::string encoded{EncodeString<Encoding::LATIN_1>(decoded)};
320864ab3302SCarolineConcatto   Put(QuoteCharacterLiteral(encoded, backslashEscapes_));
320964ab3302SCarolineConcatto }
321064ab3302SCarolineConcatto 
321164ab3302SCarolineConcatto void UnparseVisitor::PutKeywordLetter(char ch) {
321264ab3302SCarolineConcatto   if (capitalizeKeywords_) {
321364ab3302SCarolineConcatto     Put(ToUpperCaseLetter(ch));
321464ab3302SCarolineConcatto   } else {
321564ab3302SCarolineConcatto     Put(ToLowerCaseLetter(ch));
321664ab3302SCarolineConcatto   }
321764ab3302SCarolineConcatto }
321864ab3302SCarolineConcatto 
321964ab3302SCarolineConcatto void UnparseVisitor::Word(const char *str) {
322064ab3302SCarolineConcatto   for (; *str != '\0'; ++str) {
322164ab3302SCarolineConcatto     PutKeywordLetter(*str);
322264ab3302SCarolineConcatto   }
322364ab3302SCarolineConcatto }
322464ab3302SCarolineConcatto 
322564ab3302SCarolineConcatto void UnparseVisitor::Word(const std::string &str) { Word(str.c_str()); }
322664ab3302SCarolineConcatto 
3227bcba39a5SPeter Klausler void UnparseVisitor::Word(const std::string_view &str) {
3228bcba39a5SPeter Klausler   for (std::size_t j{0}; j < str.length(); ++j) {
3229bcba39a5SPeter Klausler     PutKeywordLetter(str[j]);
3230bcba39a5SPeter Klausler   }
3231bcba39a5SPeter Klausler }
3232bcba39a5SPeter Klausler 
32339e7eef99SPeter Klausler template <typename A>
32349e7eef99SPeter Klausler void Unparse(llvm::raw_ostream &out, const A &root, Encoding encoding,
323564ab3302SCarolineConcatto     bool capitalizeKeywords, bool backslashEscapes,
323664ab3302SCarolineConcatto     preStatementType *preStatement, AnalyzedObjectsAsFortran *asFortran) {
323764ab3302SCarolineConcatto   UnparseVisitor visitor{out, 1, encoding, capitalizeKeywords, backslashEscapes,
323864ab3302SCarolineConcatto       preStatement, asFortran};
32399e7eef99SPeter Klausler   Walk(root, visitor);
324064ab3302SCarolineConcatto   visitor.Done();
324164ab3302SCarolineConcatto }
32429e7eef99SPeter Klausler 
32439e7eef99SPeter Klausler template void Unparse<Program>(llvm::raw_ostream &, const Program &, Encoding,
32449e7eef99SPeter Klausler     bool, bool, preStatementType *, AnalyzedObjectsAsFortran *);
32459e7eef99SPeter Klausler template void Unparse<Expr>(llvm::raw_ostream &, const Expr &, Encoding, bool,
32469e7eef99SPeter Klausler     bool, preStatementType *, AnalyzedObjectsAsFortran *);
32471f879005STim Keith } // namespace Fortran::parser
3248