blob: 740615c34b7576ca7aeaa94538a647e0519fe63c [file] [log] [blame]
peter klausler204a50d2019-02-27 20:30:571// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
Tim Keith18cee3e2018-05-01 19:50:342//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
peter klausler79d044e2018-03-01 00:56:1015// Generates Fortran from the content of a parse tree, using the
16// traversal templates in parse-tree-visitor.h.
17
Tim Keith2af29bc2018-02-26 22:28:3218#include "unparse.h"
peter klausler79d044e2018-03-01 00:56:1019#include "characters.h"
Tim Keith2af29bc2018-02-26 22:28:3220#include "parse-tree-visitor.h"
21#include "parse-tree.h"
peter klauslerab74d1a2019-02-28 18:48:4122#include "../common/Fortran.h"
peter klauslerb23701f2018-06-18 18:03:4323#include "../common/idioms.h"
24#include "../common/indirection.h"
peter klausler79d044e2018-03-01 00:56:1025#include <algorithm>
peter klausler424ec7b2018-03-20 17:59:0726#include <cinttypes>
27#include <cstddef>
peter klausler4e354d82018-03-30 22:23:3728#include <set>
Tim Keith2af29bc2018-02-26 22:28:3229
Tim Keith7f66c0a2018-05-02 20:48:1230namespace Fortran::parser {
Tim Keith2af29bc2018-02-26 22:28:3231
32class UnparseVisitor {
33public:
peter klauslerb7cf5122018-03-14 22:31:1634 UnparseVisitor(std::ostream &out, int indentationAmount, Encoding encoding,
peter klausler888786b2018-07-19 22:35:5535 bool capitalize, bool backslashEscapes, preStatementType *preStatement)
peter klauslerb7cf5122018-03-14 22:31:1636 : out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding},
peter klausler888786b2018-07-19 22:35:5537 capitalizeKeywords_{capitalize}, backslashEscapes_{backslashEscapes},
38 preStatement_{preStatement} {}
Tim Keith2af29bc2018-02-26 22:28:3239
peter klausler8ea4a0a2018-04-06 20:13:2040 // In nearly all cases, this code avoids defining Boolean-valued Pre()
41 // callbacks for the parse tree walking framework in favor of two void
42 // functions, Before() and Unparse(), which imply true and false return
43 // values for Pre() respectively.
44 template<typename T> void Before(const T &) {}
45 template<typename T> double Unparse(const T &); // not void, never used
46
peter klausler022a91b2018-04-26 22:44:2947 template<typename T> bool Pre(const T &x) {
48 if constexpr (std::is_void_v<decltype(Unparse(x))>) {
49 // There is a local definition of Unparse() for this type. It
50 // overrides the parse tree walker's default Walk() over the descendents.
51 Before(x);
52 Unparse(x);
53 Post(x);
54 return false; // Walk() does not visit descendents
55 } else {
56 Before(x);
57 return true; // there's no Unparse() defined here, Walk() the descendents
58 }
peter klausler8ea4a0a2018-04-06 20:13:2059 }
Tim Keith2af29bc2018-02-26 22:28:3260 template<typename T> void Post(const T &) {}
61
Tim Keith2af29bc2018-02-26 22:28:3262 // Emit simple types as-is.
peter klausler8ea4a0a2018-04-06 20:13:2063 void Unparse(const std::string &x) { Put(x); }
64 void Unparse(int x) { Put(std::to_string(x)); }
Tim Keith03435d92018-10-10 14:24:2765 void Unparse(unsigned int x) { Put(std::to_string(x)); }
66 void Unparse(long x) { Put(std::to_string(x)); }
67 void Unparse(unsigned long x) { Put(std::to_string(x)); }
68 void Unparse(long long x) { Put(std::to_string(x)); }
69 void Unparse(unsigned long long x) { Put(std::to_string(x)); }
peter klausler8ea4a0a2018-04-06 20:13:2070 void Unparse(char x) { Put(x); }
Tim Keith2af29bc2018-02-26 22:28:3271
peter klausler79d044e2018-03-01 00:56:1072 // Statement labels and ends of lines
peter klausler8ea4a0a2018-04-06 20:13:2073 template<typename T> void Before(const Statement<T> &x) {
Tim Keith89840b52018-06-26 22:01:4274 if (preStatement_) {
75 (*preStatement_)(x.source, out_, indent_);
76 }
peter klausler79d044e2018-03-01 00:56:1077 Walk(x.label, " ");
Tim Keith2af29bc2018-02-26 22:28:3278 }
peter klausler79d044e2018-03-01 00:56:1079 template<typename T> void Post(const Statement<T> &) { Put('\n'); }
80
81 // The special-case formatting functions for these productions are
82 // ordered to correspond roughly to their order of appearance in
83 // the Fortran 2018 standard (and parse-tree.h).
84
peter klausler8ea4a0a2018-04-06 20:13:2085 void Unparse(const Program &x) { // R501
86 Walk("", x.v, "\n"); // put blank lines between ProgramUnits
Tim Keith2af29bc2018-02-26 22:28:3287 }
peter klausler424ec7b2018-03-20 17:59:0788
peter klausler8ea4a0a2018-04-06 20:13:2089 void Unparse(const Name &x) { // R603
peter klausler938d1eb2018-03-23 21:18:5990 Put(x.ToString());
peter klausler424ec7b2018-03-20 17:59:0791 }
peter klausler8ea4a0a2018-04-06 20:13:2092 void Unparse(const DefinedOperator::IntrinsicOperator &x) { // R608
peter klausler79d044e2018-03-01 00:56:1093 switch (x) {
94 case DefinedOperator::IntrinsicOperator::Power: Put("**"); break;
95 case DefinedOperator::IntrinsicOperator::Multiply: Put('*'); break;
96 case DefinedOperator::IntrinsicOperator::Divide: Put('/'); break;
97 case DefinedOperator::IntrinsicOperator::Add: Put('+'); break;
98 case DefinedOperator::IntrinsicOperator::Subtract: Put('-'); break;
99 case DefinedOperator::IntrinsicOperator::Concat: Put("//"); break;
100 case DefinedOperator::IntrinsicOperator::LT: Put('<'); break;
101 case DefinedOperator::IntrinsicOperator::LE: Put("<="); break;
102 case DefinedOperator::IntrinsicOperator::EQ: Put("=="); break;
103 case DefinedOperator::IntrinsicOperator::NE: Put("/="); break;
104 case DefinedOperator::IntrinsicOperator::GE: Put(">="); break;
105 case DefinedOperator::IntrinsicOperator::GT: Put('>'); break;
peter klausler8ea4a0a2018-04-06 20:13:20106 default: Put('.'), Word(DefinedOperator::EnumToString(x)), Put('.');
Tim Keith2af29bc2018-02-26 22:28:32107 }
Tim Keith2af29bc2018-02-26 22:28:32108 }
peter klausler79d044e2018-03-01 00:56:10109 void Post(const Star &) { Put('*'); } // R701 &c.
110 void Post(const TypeParamValue::Deferred &) { Put(':'); } // R701
peter klausler8ea4a0a2018-04-06 20:13:20111 void Unparse(const DeclarationTypeSpec::Type &x) { // R703
peter klauslerb7cf5122018-03-14 22:31:16112 Word("TYPE("), Walk(x.derived), Put(')');
Tim Keith2af29bc2018-02-26 22:28:32113 }
peter klausler8ea4a0a2018-04-06 20:13:20114 void Unparse(const DeclarationTypeSpec::Class &x) {
peter klauslerb7cf5122018-03-14 22:31:16115 Word("CLASS("), Walk(x.derived), Put(')');
Tim Keith2af29bc2018-02-26 22:28:32116 }
peter klauslerb7cf5122018-03-14 22:31:16117 void Post(const DeclarationTypeSpec::ClassStar &) { Word("CLASS(*)"); }
118 void Post(const DeclarationTypeSpec::TypeStar &) { Word("TYPE(*)"); }
peter klausler8ea4a0a2018-04-06 20:13:20119 void Unparse(const DeclarationTypeSpec::Record &x) {
peter klauslerb7cf5122018-03-14 22:31:16120 Word("RECORD/"), Walk(x.v), Put('/');
Tim Keith2af29bc2018-02-26 22:28:32121 }
peter klausler8ea4a0a2018-04-06 20:13:20122 void Before(const IntrinsicTypeSpec::Real &x) { // R704
peter klauslerb7cf5122018-03-14 22:31:16123 Word("REAL");
Tim Keith2af29bc2018-02-26 22:28:32124 }
peter klausler8ea4a0a2018-04-06 20:13:20125 void Before(const IntrinsicTypeSpec::Complex &x) { Word("COMPLEX"); }
peter klausler79d044e2018-03-01 00:56:10126 void Post(const IntrinsicTypeSpec::DoublePrecision &) {
peter klauslerb7cf5122018-03-14 22:31:16127 Word("DOUBLE PRECISION");
peter klausler79d044e2018-03-01 00:56:10128 }
peter klausler8ea4a0a2018-04-06 20:13:20129 void Before(const IntrinsicTypeSpec::Character &x) { Word("CHARACTER"); }
130 void Before(const IntrinsicTypeSpec::Logical &x) { Word("LOGICAL"); }
peter klauslerb7cf5122018-03-14 22:31:16131 void Post(const IntrinsicTypeSpec::DoubleComplex &) {
132 Word("DOUBLE COMPLEX");
133 }
peter klausler8ea4a0a2018-04-06 20:13:20134 void Before(const IntrinsicTypeSpec::NCharacter &x) { Word("NCHARACTER"); }
135 void Before(const IntegerTypeSpec &x) { // R705
peter klauslerb7cf5122018-03-14 22:31:16136 Word("INTEGER");
Tim Keith2af29bc2018-02-26 22:28:32137 }
peter klausler8ea4a0a2018-04-06 20:13:20138 void Unparse(const KindSelector &x) { // R706
peter klausler79d044e2018-03-01 00:56:10139 std::visit(
Tim Keithdaa0b052018-11-29 17:27:34140 common::visitors{
141 [&](const ScalarIntConstantExpr &y) {
142 Put('('), Word("KIND="), Walk(y), Put(')');
143 },
144 [&](const KindSelector::StarSize &y) { Put('*'), Walk(y.v); },
145 },
peter klausler79d044e2018-03-01 00:56:10146 x.u);
peter klausler79d044e2018-03-01 00:56:10147 }
peter klausler8ea4a0a2018-04-06 20:13:20148 void Unparse(const SignedIntLiteralConstant &x) { // R707
peter klausler822810f2019-03-22 21:27:18149 Put(std::get<CharBlock>(x.t).ToString());
peter klausler79d044e2018-03-01 00:56:10150 Walk("_", std::get<std::optional<KindParam>>(x.t));
peter klausler79d044e2018-03-01 00:56:10151 }
peter klausler8ea4a0a2018-04-06 20:13:20152 void Unparse(const IntLiteralConstant &x) { // R708
peter klausler822810f2019-03-22 21:27:18153 Put(std::get<CharBlock>(x.t).ToString());
peter klausler79d044e2018-03-01 00:56:10154 Walk("_", std::get<std::optional<KindParam>>(x.t));
peter klausler79d044e2018-03-01 00:56:10155 }
peter klausler8ea4a0a2018-04-06 20:13:20156 void Unparse(const Sign &x) { // R712
peter klausler79d044e2018-03-01 00:56:10157 Put(x == Sign::Negative ? '-' : '+');
peter klausler79d044e2018-03-01 00:56:10158 }
peter klausler8ea4a0a2018-04-06 20:13:20159 void Unparse(const RealLiteralConstant &x) { // R714, R715
peter klausler424ec7b2018-03-20 17:59:07160 Put(x.real.source.ToString()), Walk("_", x.kind);
peter klausler79d044e2018-03-01 00:56:10161 }
peter klausler8ea4a0a2018-04-06 20:13:20162 void Unparse(const ComplexLiteralConstant &x) { // R718 - R720
peter klausler79d044e2018-03-01 00:56:10163 Put('('), Walk(x.t, ","), Put(')');
peter klausler79d044e2018-03-01 00:56:10164 }
peter klausler8ea4a0a2018-04-06 20:13:20165 void Unparse(const CharSelector::LengthAndKind &x) { // R721
peter klauslerb7cf5122018-03-14 22:31:16166 Put('('), Word("KIND="), Walk(x.kind);
167 Walk(", LEN=", x.length), Put(')');
peter klausler79d044e2018-03-01 00:56:10168 }
peter klausler8ea4a0a2018-04-06 20:13:20169 void Unparse(const LengthSelector &x) { // R722
Tim Keithdaa0b052018-11-29 17:27:34170 std::visit(
171 common::visitors{
172 [&](const TypeParamValue &y) {
173 Put('('), Word("LEN="), Walk(y), Put(')');
174 },
175 [&](const CharLength &y) { Put('*'), Walk(y); },
176 },
peter klausler79d044e2018-03-01 00:56:10177 x.u);
peter klausler79d044e2018-03-01 00:56:10178 }
peter klausler8ea4a0a2018-04-06 20:13:20179 void Unparse(const CharLength &x) { // R723
Tim Keithdaa0b052018-11-29 17:27:34180 std::visit(
181 common::visitors{
182 [&](const TypeParamValue &y) { Put('('), Walk(y), Put(')'); },
183 [&](const std::int64_t &y) { Walk(y); },
184 },
peter klausler79d044e2018-03-01 00:56:10185 x.u);
peter klausler79d044e2018-03-01 00:56:10186 }
peter klausler8ea4a0a2018-04-06 20:13:20187 void Unparse(const CharLiteralConstant &x) { // R724
peter klauslerf147abd2018-07-11 00:09:07188 if (const auto &k{std::get<std::optional<KindParam>>(x.t)}) {
peter klausler79d044e2018-03-01 00:56:10189 if (std::holds_alternative<KindParam::Kanji>(k->u)) {
peter klauslerb7cf5122018-03-14 22:31:16190 Word("NC");
peter klausler79d044e2018-03-01 00:56:10191 } else {
192 Walk(*k), Put('_');
193 }
194 }
peter klausler888786b2018-07-19 22:35:55195 Put(QuoteCharacterLiteral(
196 std::get<std::string>(x.t), true, backslashEscapes_));
peter klausler79d044e2018-03-01 00:56:10197 }
peter klausler8ea4a0a2018-04-06 20:13:20198 void Before(const HollerithLiteralConstant &x) {
peter klausler424ec7b2018-03-20 17:59:07199 std::optional<std::size_t> chars{CountCharacters(x.v.data(), x.v.size(),
peter klausler79d044e2018-03-01 00:56:10200 encoding_ == Encoding::EUC_JP ? EUC_JPCharacterBytes
201 : UTF8CharacterBytes)};
202 if (chars.has_value()) {
peter klausler81b92ae2018-07-31 19:32:09203 Unparse(*chars);
peter klausler79d044e2018-03-01 00:56:10204 } else {
peter klausler81b92ae2018-07-31 19:32:09205 Unparse(x.v.size());
peter klausler79d044e2018-03-01 00:56:10206 }
207 Put('H');
Tim Keith2af29bc2018-02-26 22:28:32208 }
peter klausler8ea4a0a2018-04-06 20:13:20209 void Unparse(const LogicalLiteralConstant &x) { // R725
peter klausler42b72c42018-03-15 17:59:46210 Put(std::get<bool>(x.t) ? ".TRUE." : ".FALSE.");
211 Walk("_", std::get<std::optional<KindParam>>(x.t));
Tim Keith2af29bc2018-02-26 22:28:32212 }
peter klausler8ea4a0a2018-04-06 20:13:20213 void Unparse(const DerivedTypeStmt &x) { // R727
peter klauslerb7cf5122018-03-14 22:31:16214 Word("TYPE"), Walk(", ", std::get<std::list<TypeAttrSpec>>(x.t), ", ");
peter klausler424ec7b2018-03-20 17:59:07215 Put(" :: "), Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:10216 Walk("(", std::get<std::list<Name>>(x.t), ", ", ")");
Tim Keith2af29bc2018-02-26 22:28:32217 Indent();
Tim Keith2af29bc2018-02-26 22:28:32218 }
peter klausler8ea4a0a2018-04-06 20:13:20219 void Unparse(const Abstract &x) { // R728, &c.
peter klauslerb7cf5122018-03-14 22:31:16220 Word("ABSTRACT");
Tim Keith2af29bc2018-02-26 22:28:32221 }
peter klauslerd71f3cf2018-03-14 23:31:41222 void Post(const TypeAttrSpec::BindC &) { Word("BIND(C)"); }
peter klausler8ea4a0a2018-04-06 20:13:20223 void Unparse(const TypeAttrSpec::Extends &x) {
peter klauslerb7cf5122018-03-14 22:31:16224 Word("EXTENDS("), Walk(x.v), Put(')');
Tim Keith2af29bc2018-02-26 22:28:32225 }
peter klausler8ea4a0a2018-04-06 20:13:20226 void Unparse(const EndTypeStmt &x) { // R730
peter klauslerb7cf5122018-03-14 22:31:16227 Outdent(), Word("END TYPE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10228 }
peter klausler8ea4a0a2018-04-06 20:13:20229 void Unparse(const SequenceStmt &x) { // R731
peter klauslerb7cf5122018-03-14 22:31:16230 Word("SEQUENCE");
Tim Keith2af29bc2018-02-26 22:28:32231 }
peter klausler8ea4a0a2018-04-06 20:13:20232 void Unparse(const TypeParamDefStmt &x) { // R732
peter klausler79d044e2018-03-01 00:56:10233 Walk(std::get<IntegerTypeSpec>(x.t));
Tim Keith90373072018-09-05 23:02:41234 Put(", "), Walk(std::get<common::TypeParamAttr>(x.t));
peter klausler79d044e2018-03-01 00:56:10235 Put(" :: "), Walk(std::get<std::list<TypeParamDecl>>(x.t), ", ");
Tim Keith2af29bc2018-02-26 22:28:32236 }
peter klausler8ea4a0a2018-04-06 20:13:20237 void Unparse(const TypeParamDecl &x) { // R733
peter klausler424ec7b2018-03-20 17:59:07238 Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:10239 Walk("=", std::get<std::optional<ScalarIntConstantExpr>>(x.t));
Tim Keith2af29bc2018-02-26 22:28:32240 }
peter klausler8ea4a0a2018-04-06 20:13:20241 void Unparse(const DataComponentDefStmt &x) { // R737
peter klauslerf147abd2018-07-11 00:09:07242 const auto &dts{std::get<DeclarationTypeSpec>(x.t)};
243 const auto &attrs{std::get<std::list<ComponentAttrSpec>>(x.t)};
244 const auto &decls{std::get<std::list<ComponentDecl>>(x.t)};
peter klausler79d044e2018-03-01 00:56:10245 Walk(dts), Walk(", ", attrs, ", ");
246 if (!attrs.empty() ||
247 (!std::holds_alternative<DeclarationTypeSpec::Record>(dts.u) &&
248 std::none_of(
249 decls.begin(), decls.end(), [](const ComponentDecl &d) {
peter klauslerf147abd2018-07-11 00:09:07250 const auto &init{
251 std::get<std::optional<Initialization>>(d.t)};
peter klausler79d044e2018-03-01 00:56:10252 return init.has_value() &&
253 std::holds_alternative<
peter klauslerb23701f2018-06-18 18:03:43254 std::list<common::Indirection<DataStmtValue>>>(
255 init->u);
peter klausler79d044e2018-03-01 00:56:10256 }))) {
257 Put(" ::");
258 }
259 Put(' '), Walk(decls, ", ");
Tim Keith2af29bc2018-02-26 22:28:32260 }
peter klausler8ea4a0a2018-04-06 20:13:20261 void Unparse(const Allocatable &x) { // R738
peter klauslerb7cf5122018-03-14 22:31:16262 Word("ALLOCATABLE");
Tim Keith2af29bc2018-02-26 22:28:32263 }
peter klausler8ea4a0a2018-04-06 20:13:20264 void Unparse(const Pointer &x) { Word("POINTER"); }
265 void Unparse(const Contiguous &x) { Word("CONTIGUOUS"); }
266 void Before(const ComponentAttrSpec &x) {
peter klauslerb23701f2018-06-18 18:03:43267 std::visit(
Tim Keithdaa0b052018-11-29 17:27:34268 common::visitors{
269 [&](const CoarraySpec &) { Word("CODIMENSION["); },
peter klauslerb23701f2018-06-18 18:03:43270 [&](const ComponentArraySpec &) { Word("DIMENSION("); },
Tim Keithdaa0b052018-11-29 17:27:34271 [](const auto &) {},
272 },
peter klausler79d044e2018-03-01 00:56:10273 x.u);
Tim Keith2af29bc2018-02-26 22:28:32274 }
peter klausler79d044e2018-03-01 00:56:10275 void Post(const ComponentAttrSpec &x) {
peter klauslerd71f3cf2018-03-14 23:31:41276 std::visit(
Tim Keithdaa0b052018-11-29 17:27:34277 common::visitors{
278 [&](const CoarraySpec &) { Put(']'); },
279 [&](const ComponentArraySpec &) { Put(')'); },
280 [](const auto &) {},
281 },
peter klausler79d044e2018-03-01 00:56:10282 x.u);
283 }
peter klausler8ea4a0a2018-04-06 20:13:20284 void Unparse(const ComponentDecl &x) { // R739
peter klausler79d044e2018-03-01 00:56:10285 Walk(std::get<ObjectName>(x.t));
286 Walk("(", std::get<std::optional<ComponentArraySpec>>(x.t), ")");
287 Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
288 Walk("*", std::get<std::optional<CharLength>>(x.t));
289 Walk(std::get<std::optional<Initialization>>(x.t));
peter klausler79d044e2018-03-01 00:56:10290 }
peter klausler8ea4a0a2018-04-06 20:13:20291 void Unparse(const ComponentArraySpec &x) { // R740
Tim Keithdaa0b052018-11-29 17:27:34292 std::visit(
293 common::visitors{
294 [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
295 [&](const DeferredShapeSpecList &y) { Walk(y); },
296 },
peter klausler79d044e2018-03-01 00:56:10297 x.u);
peter klausler79d044e2018-03-01 00:56:10298 }
peter klausler8ea4a0a2018-04-06 20:13:20299 void Unparse(const ProcComponentDefStmt &x) { // R741
peter klauslerb7cf5122018-03-14 22:31:16300 Word("PROCEDURE(");
peter klausler79d044e2018-03-01 00:56:10301 Walk(std::get<std::optional<ProcInterface>>(x.t)), Put(')');
302 Walk(", ", std::get<std::list<ProcComponentAttrSpec>>(x.t), ", ");
303 Put(" :: "), Walk(std::get<std::list<ProcDecl>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10304 }
peter klausler8ea4a0a2018-04-06 20:13:20305 void Unparse(const NoPass &x) { // R742
peter klauslerb7cf5122018-03-14 22:31:16306 Word("NOPASS");
peter klausler79d044e2018-03-01 00:56:10307 }
peter klausler8ea4a0a2018-04-06 20:13:20308 void Unparse(const Pass &x) { Word("PASS"), Walk("(", x.v, ")"); }
309 void Unparse(const Initialization &x) { // R743 & R805
peter klauslerb23701f2018-06-18 18:03:43310 std::visit(
Tim Keithdaa0b052018-11-29 17:27:34311 common::visitors{
312 [&](const ConstantExpr &y) { Put(" = "), Walk(y); },
peter klauslerb23701f2018-06-18 18:03:43313 [&](const NullInit &y) { Put(" => "), Walk(y); },
314 [&](const InitialDataTarget &y) { Put(" => "), Walk(y); },
315 [&](const std::list<common::Indirection<DataStmtValue>> &y) {
316 Walk("/", y, ", ", "/");
Tim Keithdaa0b052018-11-29 17:27:34317 },
318 },
peter klausler79d044e2018-03-01 00:56:10319 x.u);
peter klausler79d044e2018-03-01 00:56:10320 }
peter klausler8ea4a0a2018-04-06 20:13:20321 void Unparse(const PrivateStmt &x) { // R745
peter klauslerb7cf5122018-03-14 22:31:16322 Word("PRIVATE");
peter klausler79d044e2018-03-01 00:56:10323 }
peter klausler8ea4a0a2018-04-06 20:13:20324 void Unparse(const TypeBoundProcedureStmt::WithoutInterface &x) { // R749
peter klauslerb7cf5122018-03-14 22:31:16325 Word("PROCEDURE"), Walk(", ", x.attributes, ", ");
peter klauslerdcd09422018-03-15 23:03:28326 Put(" :: "), Walk(x.declarations, ", ");
peter klausler79d044e2018-03-01 00:56:10327 }
peter klausler8ea4a0a2018-04-06 20:13:20328 void Unparse(const TypeBoundProcedureStmt::WithInterface &x) {
peter klauslerb7cf5122018-03-14 22:31:16329 Word("PROCEDURE("), Walk(x.interfaceName), Put("), ");
peter klausler79d044e2018-03-01 00:56:10330 Walk(x.attributes);
peter klauslerdcd09422018-03-15 23:03:28331 Put(" :: "), Walk(x.bindingNames, ", ");
peter klausler79d044e2018-03-01 00:56:10332 }
peter klausler8ea4a0a2018-04-06 20:13:20333 void Unparse(const TypeBoundProcDecl &x) { // R750
peter klausler79d044e2018-03-01 00:56:10334 Walk(std::get<Name>(x.t));
335 Walk(" => ", std::get<std::optional<Name>>(x.t));
peter klausler79d044e2018-03-01 00:56:10336 }
peter klausler8ea4a0a2018-04-06 20:13:20337 void Unparse(const TypeBoundGenericStmt &x) { // R751
peter klauslerb7cf5122018-03-14 22:31:16338 Word("GENERIC"), Walk(", ", std::get<std::optional<AccessSpec>>(x.t));
peter klauslerb23701f2018-06-18 18:03:43339 Put(" :: "), Walk(std::get<common::Indirection<GenericSpec>>(x.t));
peter klausler79d044e2018-03-01 00:56:10340 Put(" => "), Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10341 }
peter klauslerb7cf5122018-03-14 22:31:16342 void Post(const BindAttr::Deferred &) { Word("DEFERRED"); } // R752
343 void Post(const BindAttr::Non_Overridable &) { Word("NON_OVERRIDABLE"); }
peter klausler8ea4a0a2018-04-06 20:13:20344 void Unparse(const FinalProcedureStmt &x) { // R753
peter klausler62d9cdd2018-03-15 00:02:21345 Word("FINAL :: "), Walk(x.v, ", ");
peter klauslerb7cf5122018-03-14 22:31:16346 }
peter klausler8ea4a0a2018-04-06 20:13:20347 void Unparse(const DerivedTypeSpec &x) { // R754
peter klausler79d044e2018-03-01 00:56:10348 Walk(std::get<Name>(x.t));
349 Walk("(", std::get<std::list<TypeParamSpec>>(x.t), ",", ")");
peter klausler79d044e2018-03-01 00:56:10350 }
peter klausler8ea4a0a2018-04-06 20:13:20351 void Unparse(const TypeParamSpec &x) { // R755
peter klausler79d044e2018-03-01 00:56:10352 Walk(std::get<std::optional<Keyword>>(x.t), "=");
353 Walk(std::get<TypeParamValue>(x.t));
peter klausler79d044e2018-03-01 00:56:10354 }
peter klausler8ea4a0a2018-04-06 20:13:20355 void Unparse(const StructureConstructor &x) { // R756
peter klausler79d044e2018-03-01 00:56:10356 Walk(std::get<DerivedTypeSpec>(x.t));
357 Put('('), Walk(std::get<std::list<ComponentSpec>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10358 }
peter klausler8ea4a0a2018-04-06 20:13:20359 void Unparse(const ComponentSpec &x) { // R757
peter klausler79d044e2018-03-01 00:56:10360 Walk(std::get<std::optional<Keyword>>(x.t), "=");
361 Walk(std::get<ComponentDataSource>(x.t));
peter klausler79d044e2018-03-01 00:56:10362 }
peter klausler8ea4a0a2018-04-06 20:13:20363 void Unparse(const EnumDefStmt &) { // R760
peter klausler62d9cdd2018-03-15 00:02:21364 Word("ENUM, BIND(C)"), Indent();
peter klausler79d044e2018-03-01 00:56:10365 }
peter klausler8ea4a0a2018-04-06 20:13:20366 void Unparse(const EnumeratorDefStmt &x) { // R761
peter klausler62d9cdd2018-03-15 00:02:21367 Word("ENUMERATOR :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10368 }
peter klausler8ea4a0a2018-04-06 20:13:20369 void Unparse(const Enumerator &x) { // R762
peter klausler79d044e2018-03-01 00:56:10370 Walk(std::get<NamedConstant>(x.t));
371 Walk(" = ", std::get<std::optional<ScalarIntConstantExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:10372 }
373 void Post(const EndEnumStmt &) { // R763
peter klausler62d9cdd2018-03-15 00:02:21374 Outdent(), Word("END ENUM");
peter klausler79d044e2018-03-01 00:56:10375 }
peter klausler8ea4a0a2018-04-06 20:13:20376 void Unparse(const BOZLiteralConstant &x) { // R764 - R767
peter klausler9e90c992018-08-08 23:30:58377 Put(x.v);
peter klausler79d044e2018-03-01 00:56:10378 }
peter klausler8ea4a0a2018-04-06 20:13:20379 void Unparse(const AcValue::Triplet &x) { // R773
peter klausler79d044e2018-03-01 00:56:10380 Walk(std::get<0>(x.t)), Put(':'), Walk(std::get<1>(x.t));
381 Walk(":", std::get<std::optional<ScalarIntExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:10382 }
peter klausler8ea4a0a2018-04-06 20:13:20383 void Unparse(const ArrayConstructor &x) { // R769
peter klausler79d044e2018-03-01 00:56:10384 Put('['), Walk(x.v), Put(']');
peter klausler79d044e2018-03-01 00:56:10385 }
peter klausler8ea4a0a2018-04-06 20:13:20386 void Unparse(const AcSpec &x) { // R770
peter klausler79d044e2018-03-01 00:56:10387 Walk(x.type, "::"), Walk(x.values, ", ");
peter klausler79d044e2018-03-01 00:56:10388 }
peter klausler8ea4a0a2018-04-06 20:13:20389 template<typename A> void Unparse(const LoopBounds<A> &x) {
peter klausler79d044e2018-03-01 00:56:10390 Walk(x.name), Put('='), Walk(x.lower), Put(','), Walk(x.upper);
391 Walk(",", x.step);
peter klausler79d044e2018-03-01 00:56:10392 }
peter klausler8ea4a0a2018-04-06 20:13:20393 void Unparse(const AcImpliedDo &x) { // R774
peter klausler46c35382018-03-14 00:11:26394 Put('('), Walk(std::get<std::list<AcValue>>(x.t), ", ");
395 Put(", "), Walk(std::get<AcImpliedDoControl>(x.t)), Put(')');
peter klausler46c35382018-03-14 00:11:26396 }
peter klausler8ea4a0a2018-04-06 20:13:20397 void Unparse(const AcImpliedDoControl &x) { // R775
peter klausler79d044e2018-03-01 00:56:10398 Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
399 Walk(std::get<LoopBounds<ScalarIntExpr>>(x.t));
Tim Keith2af29bc2018-02-26 22:28:32400 }
401
peter klausler8ea4a0a2018-04-06 20:13:20402 void Unparse(const TypeDeclarationStmt &x) { // R801
peter klauslerf147abd2018-07-11 00:09:07403 const auto &dts{std::get<DeclarationTypeSpec>(x.t)};
404 const auto &attrs{std::get<std::list<AttrSpec>>(x.t)};
405 const auto &decls{std::get<std::list<EntityDecl>>(x.t)};
peter klausler79d044e2018-03-01 00:56:10406 Walk(dts), Walk(", ", attrs, ", ");
peter klausler92bcb7ce2018-03-19 23:17:23407
peter klauslerf147abd2018-07-11 00:09:07408 static const auto isInitializerOldStyle{[](const Initialization &i) {
peter klauslerb23701f2018-06-18 18:03:43409 return std::holds_alternative<
410 std::list<common::Indirection<DataStmtValue>>>(i.u);
peter klauslerf147abd2018-07-11 00:09:07411 }};
412 static const auto hasAssignmentInitializer{[](const EntityDecl &d) {
peter klausler92bcb7ce2018-03-19 23:17:23413 // Does a declaration have a new-style =x initializer?
peter klauslerf147abd2018-07-11 00:09:07414 const auto &init{std::get<std::optional<Initialization>>(d.t)};
peter klausler92bcb7ce2018-03-19 23:17:23415 return init.has_value() && !isInitializerOldStyle(*init);
peter klauslerf147abd2018-07-11 00:09:07416 }};
417 static const auto hasSlashDelimitedInitializer{[](const EntityDecl &d) {
peter klausler92bcb7ce2018-03-19 23:17:23418 // Does a declaration have an old-style /x/ initializer?
peter klauslerf147abd2018-07-11 00:09:07419 const auto &init{std::get<std::optional<Initialization>>(d.t)};
peter klausler92bcb7ce2018-03-19 23:17:23420 return init.has_value() && isInitializerOldStyle(*init);
peter klauslerf147abd2018-07-11 00:09:07421 }};
422 const auto useDoubledColons{[&]() {
peter klausler92bcb7ce2018-03-19 23:17:23423 bool isRecord{std::holds_alternative<DeclarationTypeSpec::Record>(dts.u)};
424 if (!attrs.empty()) {
425 // Attributes after the type require :: before the entities.
426 CHECK(!isRecord);
427 return true;
428 }
429 if (std::any_of(decls.begin(), decls.end(), hasAssignmentInitializer)) {
430 // Always use :: with new style standard initializers (=x),
431 // since the standard requires them to appear (even in free form,
432 // where mandatory spaces already disambiguate INTEGER J=666).
433 CHECK(!isRecord);
434 return true;
435 }
436 if (isRecord) {
437 // Never put :: in a legacy extension RECORD// statement.
438 return false;
439 }
440 // The :: is optional for this declaration. Avoid usage that can
441 // crash the pgf90 compiler.
442 if (std::any_of(
443 decls.begin(), decls.end(), hasSlashDelimitedInitializer)) {
444 // Don't use :: when a declaration uses legacy DATA-statement-like
445 // /x/ initialization.
446 return false;
447 }
448 // Don't use :: with intrinsic types. Otherwise, use it.
449 return !std::holds_alternative<IntrinsicTypeSpec>(dts.u);
peter klauslerf147abd2018-07-11 00:09:07450 }};
peter klausler92bcb7ce2018-03-19 23:17:23451
452 if (useDoubledColons()) {
453 Put(" ::");
Tim Keith2af29bc2018-02-26 22:28:32454 }
peter klausler79d044e2018-03-01 00:56:10455 Put(' '), Walk(std::get<std::list<EntityDecl>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10456 }
peter klausler8ea4a0a2018-04-06 20:13:20457 void Before(const AttrSpec &x) { // R802
peter klauslerb23701f2018-06-18 18:03:43458 std::visit(
Tim Keithdaa0b052018-11-29 17:27:34459 common::visitors{
460 [&](const CoarraySpec &y) { Word("CODIMENSION["); },
peter klauslerb23701f2018-06-18 18:03:43461 [&](const ArraySpec &y) { Word("DIMENSION("); },
Tim Keithdaa0b052018-11-29 17:27:34462 [](const auto &) {},
463 },
peter klauslerd39a33f2018-03-13 23:59:30464 x.u);
peter klauslerd39a33f2018-03-13 23:59:30465 }
466 void Post(const AttrSpec &x) {
Tim Keithdaa0b052018-11-29 17:27:34467 std::visit(
468 common::visitors{
469 [&](const CoarraySpec &y) { Put(']'); },
470 [&](const ArraySpec &y) { Put(')'); },
471 [](const auto &) {},
472 },
peter klauslerd39a33f2018-03-13 23:59:30473 x.u);
474 }
peter klausler8ea4a0a2018-04-06 20:13:20475 void Unparse(const EntityDecl &x) { // R803
peter klausler79d044e2018-03-01 00:56:10476 Walk(std::get<ObjectName>(x.t));
477 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
478 Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
479 Walk("*", std::get<std::optional<CharLength>>(x.t));
480 Walk(std::get<std::optional<Initialization>>(x.t));
peter klausler79d044e2018-03-01 00:56:10481 }
peter klausler8ea4a0a2018-04-06 20:13:20482 void Unparse(const NullInit &x) { // R806
peter klauslerb7cf5122018-03-14 22:31:16483 Word("NULL()");
peter klausler79d044e2018-03-01 00:56:10484 }
peter klausler8ea4a0a2018-04-06 20:13:20485 void Unparse(const LanguageBindingSpec &x) { // R808 & R1528
peter klauslerb7cf5122018-03-14 22:31:16486 Word("BIND(C"), Walk(", NAME=", x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:10487 }
peter klausler8ea4a0a2018-04-06 20:13:20488 void Unparse(const CoarraySpec &x) { // R809
peter klauslerb23701f2018-06-18 18:03:43489 std::visit(
Tim Keithdaa0b052018-11-29 17:27:34490 common::visitors{
491 [&](const DeferredCoshapeSpecList &y) { Walk(y); },
492 [&](const ExplicitCoshapeSpec &y) { Walk(y); },
493 },
peter klausler79d044e2018-03-01 00:56:10494 x.u);
peter klausler79d044e2018-03-01 00:56:10495 }
peter klausler8ea4a0a2018-04-06 20:13:20496 void Unparse(const DeferredCoshapeSpecList &x) { // R810
peter klauslerf147abd2018-07-11 00:09:07497 for (auto j{x.v}; j > 0; --j) {
peter klausler79d044e2018-03-01 00:56:10498 Put(':');
499 if (j > 1) {
500 Put(',');
Tim Keith2af29bc2018-02-26 22:28:32501 }
502 }
Tim Keith2af29bc2018-02-26 22:28:32503 }
peter klausler8ea4a0a2018-04-06 20:13:20504 void Unparse(const ExplicitCoshapeSpec &x) { // R811
peter klausler79d044e2018-03-01 00:56:10505 Walk(std::get<std::list<ExplicitShapeSpec>>(x.t), ",", ",");
506 Walk(std::get<std::optional<SpecificationExpr>>(x.t), ":"), Put('*');
Tim Keith2af29bc2018-02-26 22:28:32507 }
peter klausler8ea4a0a2018-04-06 20:13:20508 void Unparse(const ExplicitShapeSpec &x) { // R812 - R813 & R816 - R818
peter klausler79d044e2018-03-01 00:56:10509 Walk(std::get<std::optional<SpecificationExpr>>(x.t), ":");
510 Walk(std::get<SpecificationExpr>(x.t));
peter klausler79d044e2018-03-01 00:56:10511 }
peter klausler8ea4a0a2018-04-06 20:13:20512 void Unparse(const ArraySpec &x) { // R815
Tim Keithdaa0b052018-11-29 17:27:34513 std::visit(
514 common::visitors{
515 [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
516 [&](const std::list<AssumedShapeSpec> &y) { Walk(y, ","); },
517 [&](const DeferredShapeSpecList &y) { Walk(y); },
518 [&](const AssumedSizeSpec &y) { Walk(y); },
519 [&](const ImpliedShapeSpec &y) { Walk(y); },
520 [&](const AssumedRankSpec &y) { Walk(y); },
521 },
peter klausler79d044e2018-03-01 00:56:10522 x.u);
peter klausler79d044e2018-03-01 00:56:10523 }
524 void Post(const AssumedShapeSpec &) { Put(':'); } // R819
peter klausler8ea4a0a2018-04-06 20:13:20525 void Unparse(const DeferredShapeSpecList &x) { // R820
peter klauslerf147abd2018-07-11 00:09:07526 for (auto j{x.v}; j > 0; --j) {
peter klausler79d044e2018-03-01 00:56:10527 Put(':');
528 if (j > 1) {
529 Put(',');
530 }
531 }
peter klausler79d044e2018-03-01 00:56:10532 }
peter klausler8ea4a0a2018-04-06 20:13:20533 void Unparse(const AssumedImpliedSpec &x) { // R821
peter klausler79d044e2018-03-01 00:56:10534 Walk(x.v, ":");
535 Put('*');
peter klausler79d044e2018-03-01 00:56:10536 }
peter klausler8ea4a0a2018-04-06 20:13:20537 void Unparse(const AssumedSizeSpec &x) { // R822
peter klausler79d044e2018-03-01 00:56:10538 Walk(std::get<std::list<ExplicitShapeSpec>>(x.t), ",", ",");
539 Walk(std::get<AssumedImpliedSpec>(x.t));
peter klausler79d044e2018-03-01 00:56:10540 }
peter klausler8ea4a0a2018-04-06 20:13:20541 void Unparse(const ImpliedShapeSpec &x) { // R823
peter klausler79d044e2018-03-01 00:56:10542 Walk(x.v, ",");
peter klausler79d044e2018-03-01 00:56:10543 }
544 void Post(const AssumedRankSpec &) { Put(".."); } // R825
peter klauslerb7cf5122018-03-14 22:31:16545 void Post(const Asynchronous &) { Word("ASYNCHRONOUS"); }
546 void Post(const External &) { Word("EXTERNAL"); }
547 void Post(const Intrinsic &) { Word("INTRINSIC"); }
548 void Post(const Optional &) { Word("OPTIONAL"); }
549 void Post(const Parameter &) { Word("PARAMETER"); }
550 void Post(const Protected &) { Word("PROTECTED"); }
551 void Post(const Save &) { Word("SAVE"); }
552 void Post(const Target &) { Word("TARGET"); }
553 void Post(const Value &) { Word("VALUE"); }
554 void Post(const Volatile &) { Word("VOLATILE"); }
peter klausler8ea4a0a2018-04-06 20:13:20555 void Unparse(const IntentSpec &x) { // R826
peter klauslerb7cf5122018-03-14 22:31:16556 Word("INTENT("), Walk(x.v), Put(")");
peter klausler79d044e2018-03-01 00:56:10557 }
peter klausler8ea4a0a2018-04-06 20:13:20558 void Unparse(const AccessStmt &x) { // R827
peter klausler79d044e2018-03-01 00:56:10559 Walk(std::get<AccessSpec>(x.t));
560 Walk(" :: ", std::get<std::list<AccessId>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10561 }
peter klausler8ea4a0a2018-04-06 20:13:20562 void Unparse(const AllocatableStmt &x) { // R829
peter klauslerb7cf5122018-03-14 22:31:16563 Word("ALLOCATABLE :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10564 }
peter klausler8ea4a0a2018-04-06 20:13:20565 void Unparse(const ObjectDecl &x) { // R830 & R860
peter klausler79d044e2018-03-01 00:56:10566 Walk(std::get<ObjectName>(x.t));
567 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
568 Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
peter klausler79d044e2018-03-01 00:56:10569 }
peter klausler8ea4a0a2018-04-06 20:13:20570 void Unparse(const AsynchronousStmt &x) { // R831
peter klauslerb7cf5122018-03-14 22:31:16571 Word("ASYNCHRONOUS :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10572 }
peter klausler8ea4a0a2018-04-06 20:13:20573 void Unparse(const BindStmt &x) { // R832
peter klausler79d044e2018-03-01 00:56:10574 Walk(x.t, " :: ");
peter klausler79d044e2018-03-01 00:56:10575 }
peter klausler8ea4a0a2018-04-06 20:13:20576 void Unparse(const BindEntity &x) { // R833
peter klausler79d044e2018-03-01 00:56:10577 bool isCommon{std::get<BindEntity::Kind>(x.t) == BindEntity::Kind::Common};
578 const char *slash{isCommon ? "/" : ""};
579 Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
peter klausler79d044e2018-03-01 00:56:10580 }
peter klausler8ea4a0a2018-04-06 20:13:20581 void Unparse(const CodimensionStmt &x) { // R834
peter klauslerb7cf5122018-03-14 22:31:16582 Word("CODIMENSION :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10583 }
peter klausler8ea4a0a2018-04-06 20:13:20584 void Unparse(const CodimensionDecl &x) { // R835
peter klausler79d044e2018-03-01 00:56:10585 Walk(std::get<Name>(x.t));
586 Put('['), Walk(std::get<CoarraySpec>(x.t)), Put(']');
peter klausler79d044e2018-03-01 00:56:10587 }
peter klausler8ea4a0a2018-04-06 20:13:20588 void Unparse(const ContiguousStmt &x) { // R836
peter klauslerb7cf5122018-03-14 22:31:16589 Word("CONTIGUOUS :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10590 }
peter klausler8ea4a0a2018-04-06 20:13:20591 void Unparse(const DataStmt &x) { // R837
peter klauslerb7cf5122018-03-14 22:31:16592 Word("DATA "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10593 }
peter klausler8ea4a0a2018-04-06 20:13:20594 void Unparse(const DataStmtSet &x) { // R838
peter klausler79d044e2018-03-01 00:56:10595 Walk(std::get<std::list<DataStmtObject>>(x.t), ", ");
596 Put('/'), Walk(std::get<std::list<DataStmtValue>>(x.t), ", "), Put('/');
peter klausler79d044e2018-03-01 00:56:10597 }
peter klausler8ea4a0a2018-04-06 20:13:20598 void Unparse(const DataImpliedDo &x) { // R840, R842
peter klauslerb7cf5122018-03-14 22:31:16599 Put('('), Walk(std::get<std::list<DataIDoObject>>(x.t), ", "), Put(',');
peter klausler79d044e2018-03-01 00:56:10600 Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
601 Walk(std::get<LoopBounds<ScalarIntConstantExpr>>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10602 }
peter klausler8ea4a0a2018-04-06 20:13:20603 void Unparse(const DataStmtValue &x) { // R843
peter klausler79d044e2018-03-01 00:56:10604 Walk(std::get<std::optional<DataStmtRepeat>>(x.t), "*");
605 Walk(std::get<DataStmtConstant>(x.t));
peter klausler79d044e2018-03-01 00:56:10606 }
peter klausler8ea4a0a2018-04-06 20:13:20607 void Unparse(const DimensionStmt &x) { // R848
peter klauslerb7cf5122018-03-14 22:31:16608 Word("DIMENSION :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10609 }
peter klausler8ea4a0a2018-04-06 20:13:20610 void Unparse(const DimensionStmt::Declaration &x) {
peter klausler79d044e2018-03-01 00:56:10611 Walk(std::get<Name>(x.t));
612 Put('('), Walk(std::get<ArraySpec>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10613 }
peter klausler8ea4a0a2018-04-06 20:13:20614 void Unparse(const IntentStmt &x) { // R849
peter klausler79d044e2018-03-01 00:56:10615 Walk(x.t, " :: ");
peter klausler79d044e2018-03-01 00:56:10616 }
peter klausler8ea4a0a2018-04-06 20:13:20617 void Unparse(const OptionalStmt &x) { // R850
peter klauslerb7cf5122018-03-14 22:31:16618 Word("OPTIONAL :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10619 }
peter klausler8ea4a0a2018-04-06 20:13:20620 void Unparse(const ParameterStmt &x) { // R851
peter klauslerb7cf5122018-03-14 22:31:16621 Word("PARAMETER("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10622 }
peter klausler8ea4a0a2018-04-06 20:13:20623 void Unparse(const NamedConstantDef &x) { // R852
peter klausler79d044e2018-03-01 00:56:10624 Walk(x.t, "=");
peter klausler79d044e2018-03-01 00:56:10625 }
peter klausler8ea4a0a2018-04-06 20:13:20626 void Unparse(const PointerStmt &x) { // R853
peter klausler26b5f572018-04-09 20:40:20627 Word("POINTER :: "), Walk(x.v, ", ");
628 }
629 void Unparse(const PointerDecl &x) { // R854
630 Walk(std::get<Name>(x.t));
631 Walk("(", std::get<std::optional<DeferredShapeSpecList>>(x.t), ")");
peter klausler79d044e2018-03-01 00:56:10632 }
peter klausler8ea4a0a2018-04-06 20:13:20633 void Unparse(const ProtectedStmt &x) { // R855
peter klauslerb7cf5122018-03-14 22:31:16634 Word("PROTECTED :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10635 }
peter klausler8ea4a0a2018-04-06 20:13:20636 void Unparse(const SaveStmt &x) { // R856
peter klauslerb7cf5122018-03-14 22:31:16637 Word("SAVE"), Walk(" :: ", x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10638 }
peter klausler8ea4a0a2018-04-06 20:13:20639 void Unparse(const SavedEntity &x) { // R857, R858
peter klausler79d044e2018-03-01 00:56:10640 bool isCommon{
641 std::get<SavedEntity::Kind>(x.t) == SavedEntity::Kind::Common};
642 const char *slash{isCommon ? "/" : ""};
643 Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
peter klausler79d044e2018-03-01 00:56:10644 }
peter klausler8ea4a0a2018-04-06 20:13:20645 void Unparse(const TargetStmt &x) { // R859
peter klauslerb7cf5122018-03-14 22:31:16646 Word("TARGET :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10647 }
peter klausler8ea4a0a2018-04-06 20:13:20648 void Unparse(const ValueStmt &x) { // R861
peter klauslerb7cf5122018-03-14 22:31:16649 Word("VALUE :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10650 }
peter klausler8ea4a0a2018-04-06 20:13:20651 void Unparse(const VolatileStmt &x) { // R862
peter klauslerb7cf5122018-03-14 22:31:16652 Word("VOLATILE :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10653 }
peter klausler8ea4a0a2018-04-06 20:13:20654 void Unparse(const ImplicitStmt &x) { // R863
peter klauslerb7cf5122018-03-14 22:31:16655 Word("IMPLICIT ");
Tim Keithdaa0b052018-11-29 17:27:34656 std::visit(
657 common::visitors{
658 [&](const std::list<ImplicitSpec> &y) { Walk(y, ", "); },
659 [&](const std::list<ImplicitStmt::ImplicitNoneNameSpec> &y) {
660 Word("NONE"), Walk(" (", y, ", ", ")");
661 },
662 },
peter klausler79d044e2018-03-01 00:56:10663 x.u);
peter klausler79d044e2018-03-01 00:56:10664 }
peter klausler8ea4a0a2018-04-06 20:13:20665 void Unparse(const ImplicitSpec &x) { // R864
peter klausler79d044e2018-03-01 00:56:10666 Walk(std::get<DeclarationTypeSpec>(x.t));
667 Put('('), Walk(std::get<std::list<LetterSpec>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10668 }
peter klausler8ea4a0a2018-04-06 20:13:20669 void Unparse(const LetterSpec &x) { // R865
peter klausler424ec7b2018-03-20 17:59:07670 Put(*std::get<const char *>(x.t));
peter klauslerf147abd2018-07-11 00:09:07671 auto second{std::get<std::optional<const char *>>(x.t)};
peter klausler424ec7b2018-03-20 17:59:07672 if (second.has_value()) {
673 Put('-'), Put(**second);
674 }
peter klausler79d044e2018-03-01 00:56:10675 }
peter klausler8ea4a0a2018-04-06 20:13:20676 void Unparse(const ImportStmt &x) { // R867
peter klauslerb7cf5122018-03-14 22:31:16677 Word("IMPORT");
peter klausler79d044e2018-03-01 00:56:10678 switch (x.kind) {
Tim Keith37476ee2018-08-23 18:45:49679 case common::ImportKind::Default: Walk(" :: ", x.names, ", "); break;
680 case common::ImportKind::Only:
peter klauslerb7cf5122018-03-14 22:31:16681 Put(", "), Word("ONLY: ");
peter klauslerdcd09422018-03-15 23:03:28682 Walk(x.names, ", ");
peter klausler79d044e2018-03-01 00:56:10683 break;
Tim Keith37476ee2018-08-23 18:45:49684 case common::ImportKind::None: Word(", NONE"); break;
685 case common::ImportKind::All: Word(", ALL"); break;
peter klausler79d044e2018-03-01 00:56:10686 default: CRASH_NO_CASE;
687 }
peter klausler79d044e2018-03-01 00:56:10688 }
peter klausler8ea4a0a2018-04-06 20:13:20689 void Unparse(const NamelistStmt &x) { // R868
peter klauslerb7cf5122018-03-14 22:31:16690 Word("NAMELIST"), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10691 }
peter klausler8ea4a0a2018-04-06 20:13:20692 void Unparse(const NamelistStmt::Group &x) {
peter klausler424ec7b2018-03-20 17:59:07693 Put('/'), Walk(std::get<Name>(x.t)), Put('/');
peter klausler79d044e2018-03-01 00:56:10694 Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10695 }
peter klausler8ea4a0a2018-04-06 20:13:20696 void Unparse(const EquivalenceStmt &x) { // R870, R871
peter klauslerb7cf5122018-03-14 22:31:16697 Word("EQUIVALENCE");
peter klausler79d044e2018-03-01 00:56:10698 const char *separator{" "};
699 for (const std::list<EquivalenceObject> &y : x.v) {
700 Put(separator), Put('('), Walk(y), Put(')');
701 separator = ", ";
702 }
peter klausler79d044e2018-03-01 00:56:10703 }
peter klausler8ea4a0a2018-04-06 20:13:20704 void Unparse(const CommonStmt &x) { // R873
peter klauslerb7cf5122018-03-14 22:31:16705 Word("COMMON ");
Tim Keithb60fd0922019-02-13 00:13:58706 Walk(x.blocks);
peter klausler79d044e2018-03-01 00:56:10707 }
peter klausler8ea4a0a2018-04-06 20:13:20708 void Unparse(const CommonBlockObject &x) { // R874
peter klausler79d044e2018-03-01 00:56:10709 Walk(std::get<Name>(x.t));
710 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
peter klausler79d044e2018-03-01 00:56:10711 }
peter klausler8ea4a0a2018-04-06 20:13:20712 void Unparse(const CommonStmt::Block &x) {
peter klausler79d044e2018-03-01 00:56:10713 Walk("/", std::get<std::optional<Name>>(x.t), "/");
714 Walk(std::get<std::list<CommonBlockObject>>(x.t));
peter klausler79d044e2018-03-01 00:56:10715 }
Tim Keith2af29bc2018-02-26 22:28:32716
peter klausler8ea4a0a2018-04-06 20:13:20717 void Unparse(const Substring &x) { // R908, R909
peter klausler2884b2e2018-04-13 21:21:13718 Walk(std::get<DataRef>(x.t));
peter klausler79d044e2018-03-01 00:56:10719 Put('('), Walk(std::get<SubstringRange>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10720 }
peter klausler8ea4a0a2018-04-06 20:13:20721 void Unparse(const CharLiteralConstantSubstring &x) {
peter klausler79d044e2018-03-01 00:56:10722 Walk(std::get<CharLiteralConstant>(x.t));
723 Put('('), Walk(std::get<SubstringRange>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10724 }
peter klausler8ea4a0a2018-04-06 20:13:20725 void Unparse(const SubstringRange &x) { // R910
peter klausler79d044e2018-03-01 00:56:10726 Walk(x.t, ":");
peter klausler79d044e2018-03-01 00:56:10727 }
peter klausler8ea4a0a2018-04-06 20:13:20728 void Unparse(const PartRef &x) { // R912
peter klausler79d044e2018-03-01 00:56:10729 Walk(x.name);
730 Walk("(", x.subscripts, ",", ")");
731 Walk(x.imageSelector);
peter klausler79d044e2018-03-01 00:56:10732 }
peter klausler8ea4a0a2018-04-06 20:13:20733 void Unparse(const StructureComponent &x) { // R913
peter klausler4e354d82018-03-30 22:23:37734 Walk(x.base);
735 if (structureComponents_.find(x.component.source) !=
736 structureComponents_.end()) {
737 Put('.');
738 } else {
739 Put('%');
740 }
741 Walk(x.component);
peter klausler79d044e2018-03-01 00:56:10742 }
peter klausler8ea4a0a2018-04-06 20:13:20743 void Unparse(const ArrayElement &x) { // R917
peter klausler79d044e2018-03-01 00:56:10744 Walk(x.base);
745 Put('('), Walk(x.subscripts, ","), Put(')');
peter klausler79d044e2018-03-01 00:56:10746 }
peter klausler8ea4a0a2018-04-06 20:13:20747 void Unparse(const SubscriptTriplet &x) { // R921
peter klausler79d044e2018-03-01 00:56:10748 Walk(std::get<0>(x.t)), Put(':'), Walk(std::get<1>(x.t));
749 Walk(":", std::get<2>(x.t));
peter klausler79d044e2018-03-01 00:56:10750 }
peter klausler8ea4a0a2018-04-06 20:13:20751 void Unparse(const ImageSelector &x) { // R924
peter klausler79d044e2018-03-01 00:56:10752 Put('['), Walk(std::get<std::list<Cosubscript>>(x.t), ",");
753 Walk(",", std::get<std::list<ImageSelectorSpec>>(x.t), ","), Put(']');
peter klausler79d044e2018-03-01 00:56:10754 }
peter klausler8ea4a0a2018-04-06 20:13:20755 void Before(const ImageSelectorSpec::Stat &) { // R926
peter klauslerb7cf5122018-03-14 22:31:16756 Word("STAT=");
peter klausler79d044e2018-03-01 00:56:10757 }
peter klausler8ea4a0a2018-04-06 20:13:20758 void Before(const ImageSelectorSpec::Team &) { Word("TEAM="); }
759 void Before(const ImageSelectorSpec::Team_Number &) { Word("TEAM_NUMBER="); }
760 void Unparse(const AllocateStmt &x) { // R927
peter klauslerb7cf5122018-03-14 22:31:16761 Word("ALLOCATE(");
762 Walk(std::get<std::optional<TypeSpec>>(x.t), "::");
peter klausler79d044e2018-03-01 00:56:10763 Walk(std::get<std::list<Allocation>>(x.t), ", ");
764 Walk(", ", std::get<std::list<AllocOpt>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10765 }
peter klausler8ea4a0a2018-04-06 20:13:20766 void Before(const AllocOpt &x) { // R928, R931
Tim Keithdaa0b052018-11-29 17:27:34767 std::visit(
768 common::visitors{
769 [&](const AllocOpt::Mold &) { Word("MOLD="); },
770 [&](const AllocOpt::Source &) { Word("SOURCE="); },
771 [](const StatOrErrmsg &) {},
772 },
peter klausler79d044e2018-03-01 00:56:10773 x.u);
peter klausler79d044e2018-03-01 00:56:10774 }
peter klausler8ea4a0a2018-04-06 20:13:20775 void Unparse(const Allocation &x) { // R932
peter klausler79d044e2018-03-01 00:56:10776 Walk(std::get<AllocateObject>(x.t));
777 Walk("(", std::get<std::list<AllocateShapeSpec>>(x.t), ",", ")");
778 Walk("[", std::get<std::optional<AllocateCoarraySpec>>(x.t), "]");
peter klausler79d044e2018-03-01 00:56:10779 }
peter klausler8ea4a0a2018-04-06 20:13:20780 void Unparse(const AllocateShapeSpec &x) { // R934 & R938
peter klausler79d044e2018-03-01 00:56:10781 Walk(std::get<std::optional<BoundExpr>>(x.t), ":");
782 Walk(std::get<BoundExpr>(x.t));
peter klausler79d044e2018-03-01 00:56:10783 }
peter klausler8ea4a0a2018-04-06 20:13:20784 void Unparse(const AllocateCoarraySpec &x) { // R937
peter klausler79d044e2018-03-01 00:56:10785 Walk(std::get<std::list<AllocateCoshapeSpec>>(x.t), ",", ",");
786 Walk(std::get<std::optional<BoundExpr>>(x.t), ":"), Put('*');
peter klausler79d044e2018-03-01 00:56:10787 }
peter klausler8ea4a0a2018-04-06 20:13:20788 void Unparse(const NullifyStmt &x) { // R939
peter klauslerb7cf5122018-03-14 22:31:16789 Word("NULLIFY("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10790 }
peter klausler8ea4a0a2018-04-06 20:13:20791 void Unparse(const DeallocateStmt &x) { // R941
peter klauslerb7cf5122018-03-14 22:31:16792 Word("DEALLOCATE(");
793 Walk(std::get<std::list<AllocateObject>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10794 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10795 }
peter klausler8ea4a0a2018-04-06 20:13:20796 void Before(const StatOrErrmsg &x) { // R942 & R1165
Tim Keithdaa0b052018-11-29 17:27:34797 std::visit(
798 common::visitors{
799 [&](const StatVariable &) { Word("STAT="); },
800 [&](const MsgVariable &) { Word("ERRMSG="); },
801 },
peter klausler79d044e2018-03-01 00:56:10802 x.u);
peter klausler79d044e2018-03-01 00:56:10803 }
804
805 // R1001 - R1022
peter klausler8ea4a0a2018-04-06 20:13:20806 void Unparse(const Expr::Parentheses &x) { Put('('), Walk(x.v), Put(')'); }
807 void Before(const Expr::UnaryPlus &x) { Put("+"); }
808 void Before(const Expr::Negate &x) { Put("-"); }
809 void Before(const Expr::NOT &x) { Word(".NOT."); }
810 void Unparse(const Expr::PercentLoc &x) {
peter klauslerb7cf5122018-03-14 22:31:16811 Word("%LOC("), Walk(x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:10812 }
peter klausler8ea4a0a2018-04-06 20:13:20813 void Unparse(const Expr::Power &x) { Walk(x.t, "**"); }
814 void Unparse(const Expr::Multiply &x) { Walk(x.t, "*"); }
815 void Unparse(const Expr::Divide &x) { Walk(x.t, "/"); }
816 void Unparse(const Expr::Add &x) { Walk(x.t, "+"); }
817 void Unparse(const Expr::Subtract &x) { Walk(x.t, "-"); }
818 void Unparse(const Expr::Concat &x) { Walk(x.t, "//"); }
819 void Unparse(const Expr::LT &x) { Walk(x.t, "<"); }
820 void Unparse(const Expr::LE &x) { Walk(x.t, "<="); }
821 void Unparse(const Expr::EQ &x) { Walk(x.t, "=="); }
822 void Unparse(const Expr::NE &x) { Walk(x.t, "/="); }
823 void Unparse(const Expr::GE &x) { Walk(x.t, ">="); }
824 void Unparse(const Expr::GT &x) { Walk(x.t, ">"); }
825 void Unparse(const Expr::AND &x) { Walk(x.t, ".AND."); }
826 void Unparse(const Expr::OR &x) { Walk(x.t, ".OR."); }
827 void Unparse(const Expr::EQV &x) { Walk(x.t, ".EQV."); }
828 void Unparse(const Expr::NEQV &x) { Walk(x.t, ".NEQV."); }
829 void Unparse(const Expr::XOR &x) { Walk(x.t, ".XOR."); }
830 void Unparse(const Expr::ComplexConstructor &x) {
peter klausler79d044e2018-03-01 00:56:10831 Put('('), Walk(x.t, ","), Put(')');
peter klausler79d044e2018-03-01 00:56:10832 }
peter klausler8ea4a0a2018-04-06 20:13:20833 void Unparse(const Expr::DefinedBinary &x) {
peter klausler79d044e2018-03-01 00:56:10834 Walk(std::get<1>(x.t)); // left
835 Walk(std::get<DefinedOpName>(x.t));
836 Walk(std::get<2>(x.t)); // right
peter klausler79d044e2018-03-01 00:56:10837 }
peter klausler8ea4a0a2018-04-06 20:13:20838 void Unparse(const DefinedOpName &x) { // R1003, R1023, R1414, & R1415
peter klausler0c78d8b2019-03-20 21:17:12839 Walk(x.v);
peter klausler79d044e2018-03-01 00:56:10840 }
peter klausler8ea4a0a2018-04-06 20:13:20841 void Unparse(const AssignmentStmt &x) { // R1032
peter klausler79d044e2018-03-01 00:56:10842 Walk(x.t, " = ");
peter klausler79d044e2018-03-01 00:56:10843 }
peter klausler8ea4a0a2018-04-06 20:13:20844 void Unparse(const PointerAssignmentStmt &x) { // R1033, R1034, R1038
peter klausler2884b2e2018-04-13 21:21:13845 Walk(std::get<DataRef>(x.t));
peter klausler79d044e2018-03-01 00:56:10846 std::visit(
Tim Keithdaa0b052018-11-29 17:27:34847 common::visitors{
848 [&](const std::list<BoundsRemapping> &y) {
849 Put('('), Walk(y), Put(')');
850 },
851 [&](const std::list<BoundsSpec> &y) { Walk("(", y, ", ", ")"); },
852 },
peter klausler79d044e2018-03-01 00:56:10853 std::get<PointerAssignmentStmt::Bounds>(x.t).u);
854 Put(" => "), Walk(std::get<Expr>(x.t));
peter klausler79d044e2018-03-01 00:56:10855 }
856 void Post(const BoundsSpec &) { // R1035
857 Put(':');
858 }
peter klausler8ea4a0a2018-04-06 20:13:20859 void Unparse(const BoundsRemapping &x) { // R1036
peter klausler79d044e2018-03-01 00:56:10860 Walk(x.t, ":");
peter klausler79d044e2018-03-01 00:56:10861 }
peter klausler8ea4a0a2018-04-06 20:13:20862 void Unparse(const WhereStmt &x) { // R1041, R1045, R1046
peter klauslerb7cf5122018-03-14 22:31:16863 Word("WHERE ("), Walk(x.t, ") ");
peter klausler79d044e2018-03-01 00:56:10864 }
peter klausler8ea4a0a2018-04-06 20:13:20865 void Unparse(const WhereConstructStmt &x) { // R1043
peter klausler79d044e2018-03-01 00:56:10866 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16867 Word("WHERE ("), Walk(std::get<LogicalExpr>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10868 Indent();
peter klausler79d044e2018-03-01 00:56:10869 }
peter klausler8ea4a0a2018-04-06 20:13:20870 void Unparse(const MaskedElsewhereStmt &x) { // R1047
peter klausler79d044e2018-03-01 00:56:10871 Outdent();
peter klauslerb7cf5122018-03-14 22:31:16872 Word("ELSEWHERE ("), Walk(std::get<LogicalExpr>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10873 Walk(" ", std::get<std::optional<Name>>(x.t));
874 Indent();
peter klausler79d044e2018-03-01 00:56:10875 }
peter klausler8ea4a0a2018-04-06 20:13:20876 void Unparse(const ElsewhereStmt &x) { // R1048
peter klauslerb7cf5122018-03-14 22:31:16877 Outdent(), Word("ELSEWHERE"), Walk(" ", x.v), Indent();
peter klausler79d044e2018-03-01 00:56:10878 }
peter klausler8ea4a0a2018-04-06 20:13:20879 void Unparse(const EndWhereStmt &x) { // R1049
peter klauslerb7cf5122018-03-14 22:31:16880 Outdent(), Word("END WHERE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10881 }
peter klausler8ea4a0a2018-04-06 20:13:20882 void Unparse(const ForallConstructStmt &x) { // R1051
peter klausler79d044e2018-03-01 00:56:10883 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb23701f2018-06-18 18:03:43884 Word("FORALL"), Walk(std::get<common::Indirection<ConcurrentHeader>>(x.t));
peter klausler79d044e2018-03-01 00:56:10885 Indent();
peter klausler79d044e2018-03-01 00:56:10886 }
peter klausler8ea4a0a2018-04-06 20:13:20887 void Unparse(const EndForallStmt &x) { // R1054
peter klauslerb7cf5122018-03-14 22:31:16888 Outdent(), Word("END FORALL"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10889 }
peter klausler8ea4a0a2018-04-06 20:13:20890 void Before(const ForallStmt &) { // R1055
peter klauslerb7cf5122018-03-14 22:31:16891 Word("FORALL");
peter klausler79d044e2018-03-01 00:56:10892 }
893
peter klausler8ea4a0a2018-04-06 20:13:20894 void Unparse(const AssociateStmt &x) { // R1103
peter klausler79d044e2018-03-01 00:56:10895 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16896 Word("ASSOCIATE (");
897 Walk(std::get<std::list<Association>>(x.t), ", "), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:10898 }
peter klausler8ea4a0a2018-04-06 20:13:20899 void Unparse(const Association &x) { // R1104
peter klausler79d044e2018-03-01 00:56:10900 Walk(x.t, " => ");
peter klausler79d044e2018-03-01 00:56:10901 }
peter klausler8ea4a0a2018-04-06 20:13:20902 void Unparse(const EndAssociateStmt &x) { // R1106
peter klauslerb7cf5122018-03-14 22:31:16903 Outdent(), Word("END ASSOCIATE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10904 }
peter klausler8ea4a0a2018-04-06 20:13:20905 void Unparse(const BlockStmt &x) { // R1108
peter klauslerb7cf5122018-03-14 22:31:16906 Walk(x.v, ": "), Word("BLOCK"), Indent();
peter klausler79d044e2018-03-01 00:56:10907 }
peter klausler8ea4a0a2018-04-06 20:13:20908 void Unparse(const EndBlockStmt &x) { // R1110
peter klauslerb7cf5122018-03-14 22:31:16909 Outdent(), Word("END BLOCK"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10910 }
peter klausler8ea4a0a2018-04-06 20:13:20911 void Unparse(const ChangeTeamStmt &x) { // R1112
peter klausler79d044e2018-03-01 00:56:10912 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16913 Word("CHANGE TEAM ("), Walk(std::get<TeamVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:10914 Walk(", ", std::get<std::list<CoarrayAssociation>>(x.t), ", ");
915 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
916 Indent();
peter klausler79d044e2018-03-01 00:56:10917 }
peter klausler8ea4a0a2018-04-06 20:13:20918 void Unparse(const CoarrayAssociation &x) { // R1113
peter klausler79d044e2018-03-01 00:56:10919 Walk(x.t, " => ");
peter klausler79d044e2018-03-01 00:56:10920 }
peter klausler8ea4a0a2018-04-06 20:13:20921 void Unparse(const EndChangeTeamStmt &x) { // R1114
peter klauslerb7cf5122018-03-14 22:31:16922 Outdent(), Word("END TEAM (");
peter klausler79d044e2018-03-01 00:56:10923 Walk(std::get<std::list<StatOrErrmsg>>(x.t), ", ");
924 Put(')'), Walk(" ", std::get<std::optional<Name>>(x.t));
peter klausler79d044e2018-03-01 00:56:10925 }
peter klausler8ea4a0a2018-04-06 20:13:20926 void Unparse(const CriticalStmt &x) { // R1117
peter klausler79d044e2018-03-01 00:56:10927 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16928 Word("CRITICAL ("), Walk(std::get<std::list<StatOrErrmsg>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10929 Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:10930 }
peter klausler8ea4a0a2018-04-06 20:13:20931 void Unparse(const EndCriticalStmt &x) { // R1118
peter klauslerb7cf5122018-03-14 22:31:16932 Outdent(), Word("END CRITICAL"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10933 }
peter klausler8ea4a0a2018-04-06 20:13:20934 void Unparse(const DoConstruct &x) { // R1119, R1120
peter klausler79d044e2018-03-01 00:56:10935 Walk(std::get<Statement<NonLabelDoStmt>>(x.t));
936 Indent(), Walk(std::get<Block>(x.t), ""), Outdent();
937 Walk(std::get<Statement<EndDoStmt>>(x.t));
peter klausler79d044e2018-03-01 00:56:10938 }
peter klausler8ea4a0a2018-04-06 20:13:20939 void Unparse(const LabelDoStmt &x) { // R1121
peter klausler79d044e2018-03-01 00:56:10940 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16941 Word("DO "), Walk(std::get<Label>(x.t));
peter klausler79d044e2018-03-01 00:56:10942 Walk(" ", std::get<std::optional<LoopControl>>(x.t));
peter klausler79d044e2018-03-01 00:56:10943 }
peter klausler8ea4a0a2018-04-06 20:13:20944 void Unparse(const NonLabelDoStmt &x) { // R1122
peter klausler79d044e2018-03-01 00:56:10945 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16946 Word("DO "), Walk(std::get<std::optional<LoopControl>>(x.t));
peter klausler79d044e2018-03-01 00:56:10947 }
peter klausler8ea4a0a2018-04-06 20:13:20948 void Unparse(const LoopControl &x) { // R1123
Tim Keithdaa0b052018-11-29 17:27:34949 std::visit(
950 common::visitors{
951 [&](const ScalarLogicalExpr &y) {
952 Word("WHILE ("), Walk(y), Put(')');
953 },
954 [&](const auto &y) { Walk(y); },
955 },
peter klausler79d044e2018-03-01 00:56:10956 x.u);
peter klausler79d044e2018-03-01 00:56:10957 }
peter klausler8ea4a0a2018-04-06 20:13:20958 void Unparse(const ConcurrentHeader &x) { // R1125
peter klausler79d044e2018-03-01 00:56:10959 Put('('), Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
960 Walk(std::get<std::list<ConcurrentControl>>(x.t), ", ");
961 Walk(", ", std::get<std::optional<ScalarLogicalExpr>>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10962 }
peter klausler8ea4a0a2018-04-06 20:13:20963 void Unparse(const ConcurrentControl &x) { // R1126 - R1128
peter klausler79d044e2018-03-01 00:56:10964 Walk(std::get<Name>(x.t)), Put('='), Walk(std::get<1>(x.t));
965 Put(':'), Walk(std::get<2>(x.t));
966 Walk(":", std::get<std::optional<ScalarIntExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:10967 }
peter klausler8ea4a0a2018-04-06 20:13:20968 void Before(const LoopControl::Concurrent &x) { // R1129
peter klauslerb7cf5122018-03-14 22:31:16969 Word("CONCURRENT");
peter klausler79d044e2018-03-01 00:56:10970 }
peter klausler8ea4a0a2018-04-06 20:13:20971 void Unparse(const LocalitySpec::Local &x) {
peter klauslerb7cf5122018-03-14 22:31:16972 Word("LOCAL("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10973 }
peter klausler8ea4a0a2018-04-06 20:13:20974 void Unparse(const LocalitySpec::LocalInit &x) {
peter klauslerc71aecb2018-10-01 22:00:09975 Word("LOCAL_INIT("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10976 }
peter klausler8ea4a0a2018-04-06 20:13:20977 void Unparse(const LocalitySpec::Shared &x) {
peter klauslerb7cf5122018-03-14 22:31:16978 Word("SHARED("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10979 }
peter klauslerb7cf5122018-03-14 22:31:16980 void Post(const LocalitySpec::DefaultNone &x) { Word("DEFAULT(NONE)"); }
peter klausler8ea4a0a2018-04-06 20:13:20981 void Unparse(const EndDoStmt &x) { // R1132
peter klauslerb7cf5122018-03-14 22:31:16982 Word("END DO"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10983 }
peter klausler8ea4a0a2018-04-06 20:13:20984 void Unparse(const CycleStmt &x) { // R1133
peter klauslerb7cf5122018-03-14 22:31:16985 Word("CYCLE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10986 }
peter klausler8ea4a0a2018-04-06 20:13:20987 void Unparse(const IfThenStmt &x) { // R1135
peter klausler79d044e2018-03-01 00:56:10988 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16989 Word("IF ("), Walk(std::get<ScalarLogicalExpr>(x.t));
990 Put(") "), Word("THEN"), Indent();
peter klausler79d044e2018-03-01 00:56:10991 }
peter klausler8ea4a0a2018-04-06 20:13:20992 void Unparse(const ElseIfStmt &x) { // R1136
peter klauslerb7cf5122018-03-14 22:31:16993 Outdent(), Word("ELSE IF (");
994 Walk(std::get<ScalarLogicalExpr>(x.t)), Put(") "), Word("THEN");
995 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:10996 }
peter klausler8ea4a0a2018-04-06 20:13:20997 void Unparse(const ElseStmt &x) { // R1137
peter klauslerb7cf5122018-03-14 22:31:16998 Outdent(), Word("ELSE"), Walk(" ", x.v), Indent();
peter klausler79d044e2018-03-01 00:56:10999 }
peter klausler8ea4a0a2018-04-06 20:13:201000 void Unparse(const EndIfStmt &x) { // R1138
peter klauslerb7cf5122018-03-14 22:31:161001 Outdent(), Word("END IF"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101002 }
peter klausler8ea4a0a2018-04-06 20:13:201003 void Unparse(const IfStmt &x) { // R1139
peter klauslerb7cf5122018-03-14 22:31:161004 Word("IF ("), Walk(x.t, ") ");
peter klausler79d044e2018-03-01 00:56:101005 }
peter klausler8ea4a0a2018-04-06 20:13:201006 void Unparse(const SelectCaseStmt &x) { // R1141, R1144
peter klausler79d044e2018-03-01 00:56:101007 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:161008 Word("SELECT CASE (");
1009 Walk(std::get<Scalar<Expr>>(x.t)), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:101010 }
peter klausler8ea4a0a2018-04-06 20:13:201011 void Unparse(const CaseStmt &x) { // R1142
peter klauslerb7cf5122018-03-14 22:31:161012 Outdent(), Word("CASE "), Walk(std::get<CaseSelector>(x.t));
peter klausler79d044e2018-03-01 00:56:101013 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:101014 }
peter klausler8ea4a0a2018-04-06 20:13:201015 void Unparse(const EndSelectStmt &x) { // R1143 & R1151 & R1155
peter klauslerb7cf5122018-03-14 22:31:161016 Outdent(), Word("END SELECT"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101017 }
peter klausler8ea4a0a2018-04-06 20:13:201018 void Unparse(const CaseSelector &x) { // R1145
Tim Keithdaa0b052018-11-29 17:27:341019 std::visit(
1020 common::visitors{
1021 [&](const std::list<CaseValueRange> &y) {
1022 Put('('), Walk(y), Put(')');
1023 },
1024 [&](const Default &) { Word("DEFAULT"); },
1025 },
peter klausler79d044e2018-03-01 00:56:101026 x.u);
peter klausler79d044e2018-03-01 00:56:101027 }
peter klausler8ea4a0a2018-04-06 20:13:201028 void Unparse(const CaseValueRange::Range &x) { // R1146
peter klausler79d044e2018-03-01 00:56:101029 Walk(x.lower), Put(':'), Walk(x.upper);
peter klausler79d044e2018-03-01 00:56:101030 }
peter klausler8ea4a0a2018-04-06 20:13:201031 void Unparse(const SelectRankStmt &x) { // R1149
peter klausler79d044e2018-03-01 00:56:101032 Walk(std::get<0>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:161033 Word("SELECT RANK ("), Walk(std::get<1>(x.t), " => ");
peter klausler79d044e2018-03-01 00:56:101034 Walk(std::get<Selector>(x.t)), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:101035 }
peter klausler8ea4a0a2018-04-06 20:13:201036 void Unparse(const SelectRankCaseStmt &x) { // R1150
peter klauslerb7cf5122018-03-14 22:31:161037 Outdent(), Word("RANK ");
Tim Keithdaa0b052018-11-29 17:27:341038 std::visit(
1039 common::visitors{
1040 [&](const ScalarIntConstantExpr &y) {
1041 Put('('), Walk(y), Put(')');
1042 },
1043 [&](const Star &) { Put("(*)"); },
1044 [&](const Default &) { Word("DEFAULT"); },
1045 },
peter klausler79d044e2018-03-01 00:56:101046 std::get<SelectRankCaseStmt::Rank>(x.t).u);
1047 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:101048 }
peter klausler8ea4a0a2018-04-06 20:13:201049 void Unparse(const SelectTypeStmt &x) { // R1153
peter klausler79d044e2018-03-01 00:56:101050 Walk(std::get<0>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:161051 Word("SELECT TYPE ("), Walk(std::get<1>(x.t), " => ");
peter klausler79d044e2018-03-01 00:56:101052 Walk(std::get<Selector>(x.t)), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:101053 }
peter klausler8ea4a0a2018-04-06 20:13:201054 void Unparse(const TypeGuardStmt &x) { // R1154
peter klausler79d044e2018-03-01 00:56:101055 Outdent(), Walk(std::get<TypeGuardStmt::Guard>(x.t));
1056 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:101057 }
peter klausler8ea4a0a2018-04-06 20:13:201058 void Unparse(const TypeGuardStmt::Guard &x) {
Tim Keithdaa0b052018-11-29 17:27:341059 std::visit(
1060 common::visitors{
1061 [&](const TypeSpec &y) { Word("TYPE IS ("), Walk(y), Put(')'); },
1062 [&](const DerivedTypeSpec &y) {
1063 Word("CLASS IS ("), Walk(y), Put(')');
1064 },
1065 [&](const Default &) { Word("CLASS DEFAULT"); },
1066 },
peter klausler79d044e2018-03-01 00:56:101067 x.u);
peter klausler79d044e2018-03-01 00:56:101068 }
peter klausler8ea4a0a2018-04-06 20:13:201069 void Unparse(const ExitStmt &x) { // R1156
peter klauslerb7cf5122018-03-14 22:31:161070 Word("EXIT"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101071 }
peter klausler8ea4a0a2018-04-06 20:13:201072 void Before(const GotoStmt &x) { // R1157
peter klauslerb7cf5122018-03-14 22:31:161073 Word("GO TO ");
peter klausler79d044e2018-03-01 00:56:101074 }
peter klausler8ea4a0a2018-04-06 20:13:201075 void Unparse(const ComputedGotoStmt &x) { // R1158
peter klauslerb7cf5122018-03-14 22:31:161076 Word("GO TO ("), Walk(x.t, "), ");
peter klausler79d044e2018-03-01 00:56:101077 }
peter klausler8ea4a0a2018-04-06 20:13:201078 void Unparse(const ContinueStmt &x) { // R1159
peter klauslerb7cf5122018-03-14 22:31:161079 Word("CONTINUE");
peter klausler79d044e2018-03-01 00:56:101080 }
peter klausler8ea4a0a2018-04-06 20:13:201081 void Unparse(const StopStmt &x) { // R1160, R1161
peter klausler79d044e2018-03-01 00:56:101082 if (std::get<StopStmt::Kind>(x.t) == StopStmt::Kind::ErrorStop) {
peter klauslerb7cf5122018-03-14 22:31:161083 Word("ERROR ");
peter klausler79d044e2018-03-01 00:56:101084 }
peter klauslerb7cf5122018-03-14 22:31:161085 Word("STOP"), Walk(" ", std::get<std::optional<StopCode>>(x.t));
peter klausler79d044e2018-03-01 00:56:101086 Walk(", QUIET=", std::get<std::optional<ScalarLogicalExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:101087 }
peter klausler8ea4a0a2018-04-06 20:13:201088 void Unparse(const FailImageStmt &x) { // R1163
peter klauslerb7cf5122018-03-14 22:31:161089 Word("FAIL IMAGE");
peter klausler79d044e2018-03-01 00:56:101090 }
peter klausler8ea4a0a2018-04-06 20:13:201091 void Unparse(const SyncAllStmt &x) { // R1164
peter klauslerb7cf5122018-03-14 22:31:161092 Word("SYNC ALL ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101093 }
peter klausler8ea4a0a2018-04-06 20:13:201094 void Unparse(const SyncImagesStmt &x) { // R1166
peter klauslerb7cf5122018-03-14 22:31:161095 Word("SYNC IMAGES (");
1096 Walk(std::get<SyncImagesStmt::ImageSet>(x.t));
peter klausler79d044e2018-03-01 00:56:101097 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101098 }
peter klausler8ea4a0a2018-04-06 20:13:201099 void Unparse(const SyncMemoryStmt &x) { // R1168
peter klauslerb7cf5122018-03-14 22:31:161100 Word("SYNC MEMORY ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101101 }
peter klausler8ea4a0a2018-04-06 20:13:201102 void Unparse(const SyncTeamStmt &x) { // R1169
peter klauslerb7cf5122018-03-14 22:31:161103 Word("SYNC TEAM ("), Walk(std::get<TeamVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101104 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101105 }
peter klausler8ea4a0a2018-04-06 20:13:201106 void Unparse(const EventPostStmt &x) { // R1170
peter klauslerb7cf5122018-03-14 22:31:161107 Word("EVENT POST ("), Walk(std::get<EventVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101108 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101109 }
peter klausler8ea4a0a2018-04-06 20:13:201110 void Before(const EventWaitStmt::EventWaitSpec &x) { // R1173, R1174
peter klauslerb23701f2018-06-18 18:03:431111 std::visit(
Tim Keithdaa0b052018-11-29 17:27:341112 common::visitors{
1113 [&](const ScalarIntExpr &x) { Word("UNTIL_COUNT="); },
1114 [](const StatOrErrmsg &) {},
1115 },
peter klausler79d044e2018-03-01 00:56:101116 x.u);
peter klausler79d044e2018-03-01 00:56:101117 }
peter klausler8ea4a0a2018-04-06 20:13:201118 void Unparse(const EventWaitStmt &x) { // R1170
peter klauslerb7cf5122018-03-14 22:31:161119 Word("EVENT WAIT ("), Walk(std::get<EventVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101120 Walk(", ", std::get<std::list<EventWaitStmt::EventWaitSpec>>(x.t), ", ");
1121 Put(')');
peter klausler79d044e2018-03-01 00:56:101122 }
peter klausler8ea4a0a2018-04-06 20:13:201123 void Unparse(const FormTeamStmt &x) { // R1175
peter klauslerb7cf5122018-03-14 22:31:161124 Word("FORM TEAM ("), Walk(std::get<ScalarIntExpr>(x.t));
peter klausler79d044e2018-03-01 00:56:101125 Put(','), Walk(std::get<TeamVariable>(x.t));
1126 Walk(", ", std::get<std::list<FormTeamStmt::FormTeamSpec>>(x.t), ", ");
1127 Put(')');
peter klausler79d044e2018-03-01 00:56:101128 }
peter klausler8ea4a0a2018-04-06 20:13:201129 void Before(const FormTeamStmt::FormTeamSpec &x) { // R1176, R1177
peter klauslerb23701f2018-06-18 18:03:431130 std::visit(
Tim Keithdaa0b052018-11-29 17:27:341131 common::visitors{
1132 [&](const ScalarIntExpr &x) { Word("NEW_INDEX="); },
1133 [](const StatOrErrmsg &) {},
1134 },
peter klausler79d044e2018-03-01 00:56:101135 x.u);
peter klausler79d044e2018-03-01 00:56:101136 }
peter klausler8ea4a0a2018-04-06 20:13:201137 void Unparse(const LockStmt &x) { // R1178
peter klauslerb7cf5122018-03-14 22:31:161138 Word("LOCK ("), Walk(std::get<LockVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101139 Walk(", ", std::get<std::list<LockStmt::LockStat>>(x.t), ", ");
1140 Put(')');
peter klausler79d044e2018-03-01 00:56:101141 }
peter klausler8ea4a0a2018-04-06 20:13:201142 void Before(const LockStmt::LockStat &x) { // R1179
Tim Keithdaa0b052018-11-29 17:27:341143 std::visit(
1144 common::visitors{
1145 [&](const ScalarLogicalVariable &) { Word("ACQUIRED_LOCK="); },
1146 [](const StatOrErrmsg &y) {},
1147 },
peter klausler79d044e2018-03-01 00:56:101148 x.u);
peter klausler79d044e2018-03-01 00:56:101149 }
peter klausler8ea4a0a2018-04-06 20:13:201150 void Unparse(const UnlockStmt &x) { // R1180
peter klauslerb7cf5122018-03-14 22:31:161151 Word("UNLOCK ("), Walk(std::get<LockVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101152 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", ");
1153 Put(')');
peter klausler79d044e2018-03-01 00:56:101154 }
1155
peter klausler8ea4a0a2018-04-06 20:13:201156 void Unparse(const OpenStmt &x) { // R1204
peter klauslerb7cf5122018-03-14 22:31:161157 Word("OPEN ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101158 }
1159 bool Pre(const ConnectSpec &x) { // R1205
Tim Keithdaa0b052018-11-29 17:27:341160 return std::visit(
1161 common::visitors{
1162 [&](const FileUnitNumber &) {
1163 Word("UNIT=");
1164 return true;
1165 },
1166 [&](const FileNameExpr &) {
1167 Word("FILE=");
1168 return true;
1169 },
1170 [&](const ConnectSpec::CharExpr &y) {
1171 Walk(y.t, "=");
1172 return false;
1173 },
1174 [&](const MsgVariable &) {
1175 Word("IOMSG=");
1176 return true;
1177 },
1178 [&](const StatVariable &) {
1179 Word("IOSTAT=");
1180 return true;
1181 },
1182 [&](const ConnectSpec::Recl &) {
1183 Word("RECL=");
1184 return true;
1185 },
1186 [&](const ConnectSpec::Newunit &) {
1187 Word("NEWUNIT=");
1188 return true;
1189 },
1190 [&](const ErrLabel &) {
1191 Word("ERR=");
1192 return true;
1193 },
1194 [&](const StatusExpr &) {
1195 Word("STATUS=");
1196 return true;
1197 },
1198 },
peter klausler79d044e2018-03-01 00:56:101199 x.u);
1200 }
peter klausler8ea4a0a2018-04-06 20:13:201201 void Unparse(const CloseStmt &x) { // R1208
peter klauslerb7cf5122018-03-14 22:31:161202 Word("CLOSE ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101203 }
peter klausler8ea4a0a2018-04-06 20:13:201204 void Before(const CloseStmt::CloseSpec &x) { // R1209
Tim Keithdaa0b052018-11-29 17:27:341205 std::visit(
1206 common::visitors{
1207 [&](const FileUnitNumber &) { Word("UNIT="); },
1208 [&](const StatVariable &) { Word("IOSTAT="); },
1209 [&](const MsgVariable &) { Word("IOMSG="); },
1210 [&](const ErrLabel &) { Word("ERR="); },
1211 [&](const StatusExpr &) { Word("STATUS="); },
1212 },
peter klausler79d044e2018-03-01 00:56:101213 x.u);
peter klausler79d044e2018-03-01 00:56:101214 }
peter klausler8ea4a0a2018-04-06 20:13:201215 void Unparse(const ReadStmt &x) { // R1210
peter klauslerb7cf5122018-03-14 22:31:161216 Word("READ ");
peter klausler79d044e2018-03-01 00:56:101217 if (x.iounit) {
1218 Put('('), Walk(x.iounit);
1219 if (x.format) {
1220 Put(", "), Walk(x.format);
1221 }
peter klauslerdcd09422018-03-15 23:03:281222 Walk(", ", x.controls, ", ");
peter klausler79d044e2018-03-01 00:56:101223 Put(')');
1224 } else if (x.format) {
1225 Walk(x.format);
1226 if (!x.items.empty()) {
1227 Put(", ");
1228 }
1229 } else {
peter klauslerdcd09422018-03-15 23:03:281230 Put('('), Walk(x.controls, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101231 }
1232 Walk(" ", x.items, ", ");
peter klausler79d044e2018-03-01 00:56:101233 }
peter klausler8ea4a0a2018-04-06 20:13:201234 void Unparse(const WriteStmt &x) { // R1211
peter klauslerb7cf5122018-03-14 22:31:161235 Word("WRITE (");
peter klausler79d044e2018-03-01 00:56:101236 if (x.iounit) {
1237 Walk(x.iounit);
1238 if (x.format) {
1239 Put(", "), Walk(x.format);
1240 }
peter klauslerdcd09422018-03-15 23:03:281241 Walk(", ", x.controls, ", ");
peter klausler79d044e2018-03-01 00:56:101242 } else {
peter klauslerdcd09422018-03-15 23:03:281243 Walk(x.controls, ", ");
peter klausler79d044e2018-03-01 00:56:101244 }
1245 Put(')'), Walk(" ", x.items, ", ");
peter klausler79d044e2018-03-01 00:56:101246 }
peter klausler8ea4a0a2018-04-06 20:13:201247 void Unparse(const PrintStmt &x) { // R1212
peter klauslerb7cf5122018-03-14 22:31:161248 Word("PRINT "), Walk(std::get<Format>(x.t));
peter klausler79d044e2018-03-01 00:56:101249 Walk(", ", std::get<std::list<OutputItem>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101250 }
1251 bool Pre(const IoControlSpec &x) { // R1213
Tim Keithdaa0b052018-11-29 17:27:341252 return std::visit(
1253 common::visitors{
1254 [&](const IoUnit &) {
1255 Word("UNIT=");
1256 return true;
1257 },
1258 [&](const Format &) {
1259 Word("FMT=");
1260 return true;
1261 },
1262 [&](const Name &) {
1263 Word("NML=");
1264 return true;
1265 },
1266 [&](const IoControlSpec::CharExpr &y) {
1267 Walk(y.t, "=");
1268 return false;
1269 },
1270 [&](const IoControlSpec::Asynchronous &) {
1271 Word("ASYNCHRONOUS=");
1272 return true;
1273 },
1274 [&](const EndLabel &) {
1275 Word("END=");
1276 return true;
1277 },
1278 [&](const EorLabel &) {
1279 Word("EOR=");
1280 return true;
1281 },
1282 [&](const ErrLabel &) {
1283 Word("ERR=");
1284 return true;
1285 },
1286 [&](const IdVariable &) {
1287 Word("ID=");
1288 return true;
1289 },
1290 [&](const MsgVariable &) {
1291 Word("IOMSG=");
1292 return true;
1293 },
1294 [&](const StatVariable &) {
1295 Word("IOSTAT=");
1296 return true;
1297 },
1298 [&](const IoControlSpec::Pos &) {
1299 Word("POS=");
1300 return true;
1301 },
1302 [&](const IoControlSpec::Rec &) {
1303 Word("REC=");
1304 return true;
1305 },
1306 [&](const IoControlSpec::Size &) {
1307 Word("SIZE=");
1308 return true;
1309 },
1310 },
peter klausler79d044e2018-03-01 00:56:101311 x.u);
1312 }
peter klausler8ea4a0a2018-04-06 20:13:201313 void Unparse(const InputImpliedDo &x) { // R1218
peter klausler79d044e2018-03-01 00:56:101314 Put('('), Walk(std::get<std::list<InputItem>>(x.t), ", "), Put(", ");
1315 Walk(std::get<IoImpliedDoControl>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:101316 }
peter klausler8ea4a0a2018-04-06 20:13:201317 void Unparse(const OutputImpliedDo &x) { // R1219
peter klausler79d044e2018-03-01 00:56:101318 Put('('), Walk(std::get<std::list<OutputItem>>(x.t), ", "), Put(", ");
1319 Walk(std::get<IoImpliedDoControl>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:101320 }
peter klausler8ea4a0a2018-04-06 20:13:201321 void Unparse(const WaitStmt &x) { // R1222
peter klauslerb7cf5122018-03-14 22:31:161322 Word("WAIT ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101323 }
peter klausler8ea4a0a2018-04-06 20:13:201324 void Before(const WaitSpec &x) { // R1223
Tim Keithdaa0b052018-11-29 17:27:341325 std::visit(
1326 common::visitors{
1327 [&](const FileUnitNumber &) { Word("UNIT="); },
1328 [&](const EndLabel &) { Word("END="); },
1329 [&](const EorLabel &) { Word("EOR="); },
1330 [&](const ErrLabel &) { Word("ERR="); },
1331 [&](const IdExpr &) { Word("ID="); },
1332 [&](const MsgVariable &) { Word("IOMSG="); },
1333 [&](const StatVariable &) { Word("IOSTAT="); },
1334 },
peter klausler79d044e2018-03-01 00:56:101335 x.u);
peter klausler79d044e2018-03-01 00:56:101336 }
peter klausler8ea4a0a2018-04-06 20:13:201337 void Unparse(const BackspaceStmt &x) { // R1224
peter klauslerb7cf5122018-03-14 22:31:161338 Word("BACKSPACE ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101339 }
peter klausler8ea4a0a2018-04-06 20:13:201340 void Unparse(const EndfileStmt &x) { // R1225
peter klauslerb7cf5122018-03-14 22:31:161341 Word("ENDFILE ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101342 }
peter klausler8ea4a0a2018-04-06 20:13:201343 void Unparse(const RewindStmt &x) { // R1226
peter klauslerb7cf5122018-03-14 22:31:161344 Word("REWIND ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101345 }
peter klausler8ea4a0a2018-04-06 20:13:201346 void Before(const PositionOrFlushSpec &x) { // R1227 & R1229
Tim Keithdaa0b052018-11-29 17:27:341347 std::visit(
1348 common::visitors{
1349 [&](const FileUnitNumber &) { Word("UNIT="); },
1350 [&](const MsgVariable &) { Word("IOMSG="); },
1351 [&](const StatVariable &) { Word("IOSTAT="); },
1352 [&](const ErrLabel &) { Word("ERR="); },
1353 },
peter klauslerad4adc22018-03-16 00:09:271354 x.u);
peter klauslerad4adc22018-03-16 00:09:271355 }
peter klausler8ea4a0a2018-04-06 20:13:201356 void Unparse(const FlushStmt &x) { // R1228
peter klauslerb7cf5122018-03-14 22:31:161357 Word("FLUSH ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101358 }
peter klausler8ea4a0a2018-04-06 20:13:201359 void Unparse(const InquireStmt &x) { // R1230
peter klauslerb7cf5122018-03-14 22:31:161360 Word("INQUIRE (");
peter klausler79d044e2018-03-01 00:56:101361 std::visit(
Tim Keithdaa0b052018-11-29 17:27:341362 common::visitors{
1363 [&](const InquireStmt::Iolength &y) {
1364 Word("IOLENGTH="), Walk(y.t, ") ");
1365 },
1366 [&](const std::list<InquireSpec> &y) { Walk(y, ", "), Put(')'); },
1367 },
peter klausler79d044e2018-03-01 00:56:101368 x.u);
peter klausler79d044e2018-03-01 00:56:101369 }
1370 bool Pre(const InquireSpec &x) { // R1231
Tim Keithdaa0b052018-11-29 17:27:341371 return std::visit(
1372 common::visitors{
1373 [&](const FileUnitNumber &) {
1374 Word("UNIT=");
1375 return true;
1376 },
1377 [&](const FileNameExpr &) {
1378 Word("FILE=");
1379 return true;
1380 },
1381 [&](const InquireSpec::CharVar &y) {
1382 Walk(y.t, "=");
1383 return false;
1384 },
1385 [&](const InquireSpec::IntVar &y) {
1386 Walk(y.t, "=");
1387 return false;
1388 },
1389 [&](const InquireSpec::LogVar &y) {
1390 Walk(y.t, "=");
1391 return false;
1392 },
1393 [&](const IdExpr &) {
1394 Word("ID=");
1395 return true;
1396 },
1397 [&](const ErrLabel &) {
1398 Word("ERR=");
1399 return true;
1400 },
1401 },
peter klausler79d044e2018-03-01 00:56:101402 x.u);
1403 }
1404
peter klausler8ea4a0a2018-04-06 20:13:201405 void Before(const FormatStmt &) { // R1301
peter klauslerb7cf5122018-03-14 22:31:161406 Word("FORMAT");
peter klausler79d044e2018-03-01 00:56:101407 }
peter klausler8ea4a0a2018-04-06 20:13:201408 void Unparse(const format::FormatSpecification &x) { // R1302, R1303, R1305
peter klausler79d044e2018-03-01 00:56:101409 Put('('), Walk("", x.items, ",", x.unlimitedItems.empty() ? "" : ",");
1410 Walk("*(", x.unlimitedItems, ",", ")"), Put(')');
peter klausler79d044e2018-03-01 00:56:101411 }
peter klausler8ea4a0a2018-04-06 20:13:201412 void Unparse(const format::FormatItem &x) { // R1304, R1306, R1321
peter klausler79d044e2018-03-01 00:56:101413 if (x.repeatCount.has_value()) {
1414 Walk(*x.repeatCount);
1415 }
Tim Keithdaa0b052018-11-29 17:27:341416 std::visit(
1417 common::visitors{
1418 [&](const std::string &y) {
1419 Put(QuoteCharacterLiteral(y, true, backslashEscapes_));
1420 },
1421 [&](const std::list<format::FormatItem> &y) {
1422 Walk("(", y, ",", ")");
1423 },
1424 [&](const auto &y) { Walk(y); },
1425 },
peter klausler79d044e2018-03-01 00:56:101426 x.u);
peter klausler79d044e2018-03-01 00:56:101427 }
peter klausler8ea4a0a2018-04-06 20:13:201428 void Unparse(
1429 const format::IntrinsicTypeDataEditDesc &x) { // R1307(1/2) - R1311
peter klausler79d044e2018-03-01 00:56:101430 switch (x.kind) {
1431#define FMT(x) \
1432 case format::IntrinsicTypeDataEditDesc::Kind::x: Put(#x); break
1433 FMT(I);
1434 FMT(B);
1435 FMT(O);
1436 FMT(Z);
1437 FMT(F);
1438 FMT(E);
1439 FMT(EN);
1440 FMT(ES);
1441 FMT(EX);
1442 FMT(G);
1443 FMT(L);
1444 FMT(A);
1445 FMT(D);
1446#undef FMT
1447 default: CRASH_NO_CASE;
1448 }
1449 Walk(x.width), Walk(".", x.digits), Walk("E", x.exponentWidth);
peter klausler79d044e2018-03-01 00:56:101450 }
peter klausler8ea4a0a2018-04-06 20:13:201451 void Unparse(const format::DerivedTypeDataEditDesc &x) { // R1307(2/2), R1312
peter klauslerb7cf5122018-03-14 22:31:161452 Word("DT");
peter klausler79d044e2018-03-01 00:56:101453 if (!x.type.empty()) {
1454 Put('"'), Put(x.type), Put('"');
1455 }
1456 Walk("(", x.parameters, ",", ")");
peter klausler79d044e2018-03-01 00:56:101457 }
peter klausler8ea4a0a2018-04-06 20:13:201458 void Unparse(const format::ControlEditDesc &x) { // R1313, R1315-R1320
peter klausler79d044e2018-03-01 00:56:101459 switch (x.kind) {
1460 case format::ControlEditDesc::Kind::T:
peter klauslerb7cf5122018-03-14 22:31:161461 Word("T");
peter klausler79d044e2018-03-01 00:56:101462 Walk(x.count);
1463 break;
1464 case format::ControlEditDesc::Kind::TL:
peter klauslerb7cf5122018-03-14 22:31:161465 Word("TL");
peter klausler79d044e2018-03-01 00:56:101466 Walk(x.count);
1467 break;
1468 case format::ControlEditDesc::Kind::TR:
peter klauslerb7cf5122018-03-14 22:31:161469 Word("TR");
peter klausler79d044e2018-03-01 00:56:101470 Walk(x.count);
1471 break;
1472 case format::ControlEditDesc::Kind::X:
1473 if (x.count != 1) {
1474 Walk(x.count);
1475 }
peter klauslerb7cf5122018-03-14 22:31:161476 Word("X");
peter klausler79d044e2018-03-01 00:56:101477 break;
1478 case format::ControlEditDesc::Kind::Slash:
1479 if (x.count != 1) {
1480 Walk(x.count);
1481 }
1482 Put('/');
1483 break;
1484 case format::ControlEditDesc::Kind::Colon: Put(':'); break;
1485 case format::ControlEditDesc::Kind::P:
1486 Walk(x.count);
peter klauslerb7cf5122018-03-14 22:31:161487 Word("P");
peter klausler79d044e2018-03-01 00:56:101488 break;
1489#define FMT(x) \
1490 case format::ControlEditDesc::Kind::x: Put(#x); break
1491 FMT(SS);
1492 FMT(SP);
1493 FMT(S);
1494 FMT(BN);
1495 FMT(BZ);
1496 FMT(RU);
1497 FMT(RD);
1498 FMT(RZ);
1499 FMT(RN);
1500 FMT(RC);
1501 FMT(RP);
1502 FMT(DC);
1503 FMT(DP);
1504#undef FMT
1505 default: CRASH_NO_CASE;
1506 }
peter klausler79d044e2018-03-01 00:56:101507 }
1508
peter klausler8ea4a0a2018-04-06 20:13:201509 void Before(const MainProgram &x) { // R1401
peter klausler79d044e2018-03-01 00:56:101510 if (!std::get<std::optional<Statement<ProgramStmt>>>(x.t)) {
1511 Indent();
1512 }
peter klausler79d044e2018-03-01 00:56:101513 }
peter klausler8ea4a0a2018-04-06 20:13:201514 void Before(const ProgramStmt &x) { // R1402
peter klauslerb7cf5122018-03-14 22:31:161515 Word("PROGRAM "), Indent();
peter klausler79d044e2018-03-01 00:56:101516 }
peter klausler8ea4a0a2018-04-06 20:13:201517 void Unparse(const EndProgramStmt &x) { // R1403
peter klausler41d9cfd2018-04-03 17:29:041518 EndSubprogram("PROGRAM", x.v);
peter klausler79d044e2018-03-01 00:56:101519 }
peter klausler8ea4a0a2018-04-06 20:13:201520 void Before(const ModuleStmt &) { // R1405
peter klauslerb7cf5122018-03-14 22:31:161521 Word("MODULE "), Indent();
peter klausler79d044e2018-03-01 00:56:101522 }
peter klausler8ea4a0a2018-04-06 20:13:201523 void Unparse(const EndModuleStmt &x) { // R1406
peter klausler41d9cfd2018-04-03 17:29:041524 EndSubprogram("MODULE", x.v);
peter klausler79d044e2018-03-01 00:56:101525 }
peter klausler8ea4a0a2018-04-06 20:13:201526 void Unparse(const UseStmt &x) { // R1409
peter klauslerb7cf5122018-03-14 22:31:161527 Word("USE"), Walk(", ", x.nature), Put(" :: "), Walk(x.moduleName);
peter klausler79d044e2018-03-01 00:56:101528 std::visit(
peter klauslerb23701f2018-06-18 18:03:431529 common::visitors{
1530 [&](const std::list<Rename> &y) { Walk(", ", y, ", "); },
Tim Keithdaa0b052018-11-29 17:27:341531 [&](const std::list<Only> &y) { Walk(", ONLY: ", y, ", "); },
1532 },
peter klausler79d044e2018-03-01 00:56:101533 x.u);
peter klausler79d044e2018-03-01 00:56:101534 }
peter klausler8ea4a0a2018-04-06 20:13:201535 void Unparse(const Rename &x) { // R1411
peter klauslerb23701f2018-06-18 18:03:431536 std::visit(
Tim Keithdaa0b052018-11-29 17:27:341537 common::visitors{
1538 [&](const Rename::Names &y) { Walk(y.t, " => "); },
peter klauslerb23701f2018-06-18 18:03:431539 [&](const Rename::Operators &y) {
1540 Word("OPERATOR("), Walk(y.t, ") => OPERATOR("), Put(")");
Tim Keithdaa0b052018-11-29 17:27:341541 },
1542 },
peter klausler79d044e2018-03-01 00:56:101543 x.u);
peter klausler79d044e2018-03-01 00:56:101544 }
peter klausler31cfbea2018-07-17 20:35:411545 void Unparse(const SubmoduleStmt &x) { // R1417
peter klausler1732d042018-07-17 19:51:541546 Word("SUBMODULE ("), WalkTupleElements(x.t, ")"), Indent();
peter klausler79d044e2018-03-01 00:56:101547 }
peter klausler8ea4a0a2018-04-06 20:13:201548 void Unparse(const ParentIdentifier &x) { // R1418
peter klausler79d044e2018-03-01 00:56:101549 Walk(std::get<Name>(x.t)), Walk(":", std::get<std::optional<Name>>(x.t));
peter klausler79d044e2018-03-01 00:56:101550 }
peter klausler8ea4a0a2018-04-06 20:13:201551 void Unparse(const EndSubmoduleStmt &x) { // R1419
peter klausler41d9cfd2018-04-03 17:29:041552 EndSubprogram("SUBMODULE", x.v);
peter klausler79d044e2018-03-01 00:56:101553 }
peter klausler8ea4a0a2018-04-06 20:13:201554 void Unparse(const BlockDataStmt &x) { // R1421
peter klauslerb7cf5122018-03-14 22:31:161555 Word("BLOCK DATA"), Walk(" ", x.v), Indent();
peter klausler79d044e2018-03-01 00:56:101556 }
peter klausler8ea4a0a2018-04-06 20:13:201557 void Unparse(const EndBlockDataStmt &x) { // R1422
peter klausler41d9cfd2018-04-03 17:29:041558 EndSubprogram("BLOCK DATA", x.v);
peter klausler79d044e2018-03-01 00:56:101559 }
1560
peter klausler8ea4a0a2018-04-06 20:13:201561 void Unparse(const InterfaceStmt &x) { // R1503
Tim Keithdaa0b052018-11-29 17:27:341562 std::visit(
1563 common::visitors{
1564 [&](const std::optional<GenericSpec> &y) {
1565 Word("INTERFACE"), Walk(" ", y);
1566 },
1567 [&](const Abstract &) { Word("ABSTRACT INTERFACE"); },
1568 },
peter klausler79d044e2018-03-01 00:56:101569 x.u);
1570 Indent();
peter klausler79d044e2018-03-01 00:56:101571 }
peter klausler8ea4a0a2018-04-06 20:13:201572 void Unparse(const EndInterfaceStmt &x) { // R1504
peter klauslerb7cf5122018-03-14 22:31:161573 Outdent(), Word("END INTERFACE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101574 }
peter klausler8ea4a0a2018-04-06 20:13:201575 void Unparse(const ProcedureStmt &x) { // R1506
peter klausler79d044e2018-03-01 00:56:101576 if (std::get<ProcedureStmt::Kind>(x.t) ==
1577 ProcedureStmt::Kind::ModuleProcedure) {
peter klauslerb7cf5122018-03-14 22:31:161578 Word("MODULE ");
peter klausler79d044e2018-03-01 00:56:101579 }
peter klauslerb7cf5122018-03-14 22:31:161580 Word("PROCEDURE :: ");
peter klausler79d044e2018-03-01 00:56:101581 Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101582 }
peter klausler8ea4a0a2018-04-06 20:13:201583 void Before(const GenericSpec &x) { // R1508, R1509
peter klauslerd71f3cf2018-03-14 23:31:411584 std::visit(
Tim Keithdaa0b052018-11-29 17:27:341585 common::visitors{
1586 [&](const DefinedOperator &x) { Word("OPERATOR("); },
peter klauslerd71f3cf2018-03-14 23:31:411587 [&](const GenericSpec::Assignment &) { Word("ASSIGNMENT(=)"); },
1588 [&](const GenericSpec::ReadFormatted &) {
1589 Word("READ(FORMATTED)");
1590 },
1591 [&](const GenericSpec::ReadUnformatted &) {
1592 Word("READ(UNFORMATTED)");
1593 },
1594 [&](const GenericSpec::WriteFormatted &) {
1595 Word("WRITE(FORMATTED)");
1596 },
1597 [&](const GenericSpec::WriteUnformatted &) {
1598 Word("WRITE(UNFORMATTED)");
1599 },
Tim Keithdaa0b052018-11-29 17:27:341600 [](const auto &) {},
1601 },
peter klausler79d044e2018-03-01 00:56:101602 x.u);
peter klausler79d044e2018-03-01 00:56:101603 }
peter klauslerd71f3cf2018-03-14 23:31:411604 void Post(const GenericSpec &x) {
Tim Keithdaa0b052018-11-29 17:27:341605 std::visit(
1606 common::visitors{
1607 [&](const DefinedOperator &x) { Put(')'); },
1608 [](const auto &) {},
1609 },
peter klauslerd71f3cf2018-03-14 23:31:411610 x.u);
1611 }
peter klausler8ea4a0a2018-04-06 20:13:201612 void Unparse(const GenericStmt &x) { // R1510
peter klauslerb7cf5122018-03-14 22:31:161613 Word("GENERIC"), Walk(", ", std::get<std::optional<AccessSpec>>(x.t));
peter klausler79d044e2018-03-01 00:56:101614 Put(" :: "), Walk(std::get<GenericSpec>(x.t)), Put(" => ");
1615 Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101616 }
peter klausler8ea4a0a2018-04-06 20:13:201617 void Unparse(const ExternalStmt &x) { // R1511
peter klauslerb7cf5122018-03-14 22:31:161618 Word("EXTERNAL :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:101619 }
peter klausler8ea4a0a2018-04-06 20:13:201620 void Unparse(const ProcedureDeclarationStmt &x) { // R1512
peter klauslerb7cf5122018-03-14 22:31:161621 Word("PROCEDURE ("), Walk(std::get<std::optional<ProcInterface>>(x.t));
peter klausler79d044e2018-03-01 00:56:101622 Put(')'), Walk(", ", std::get<std::list<ProcAttrSpec>>(x.t), ", ");
1623 Put(" :: "), Walk(std::get<std::list<ProcDecl>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101624 }
peter klausler204a50d2019-02-27 20:30:571625 void Unparse(const ProcInterface &x) { // R1513
1626 std::visit(
1627 common::visitors{
1628 [&](const DeclarationTypeSpec &d) {
1629 std::visit(
1630 common::visitors{
1631 [&](const IntrinsicTypeSpec &t) {
1632 // Emit TYPE(REAL) to ensure no conflict with a symbol
1633 // REAL
1634 Word("TYPE("), Walk(t), Word(")");
1635 },
1636 [&](const auto &t) { Walk(t); },
1637 },
1638 d.u);
1639 },
1640 [&](const Name &n) { Walk(n); },
1641 },
1642 x.u);
1643 }
peter klausler8ea4a0a2018-04-06 20:13:201644 void Unparse(const ProcDecl &x) { // R1515
peter klausler79d044e2018-03-01 00:56:101645 Walk(std::get<Name>(x.t));
1646 Walk(" => ", std::get<std::optional<ProcPointerInit>>(x.t));
peter klausler79d044e2018-03-01 00:56:101647 }
peter klausler8ea4a0a2018-04-06 20:13:201648 void Unparse(const IntrinsicStmt &x) { // R1519
peter klauslerb7cf5122018-03-14 22:31:161649 Word("INTRINSIC :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:101650 }
peter klausler8ea4a0a2018-04-06 20:13:201651 void Unparse(const FunctionReference &x) { // R1520
peter klausler79d044e2018-03-01 00:56:101652 Walk(std::get<ProcedureDesignator>(x.v.t));
1653 Put('('), Walk(std::get<std::list<ActualArgSpec>>(x.v.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101654 }
peter klausler8ea4a0a2018-04-06 20:13:201655 void Unparse(const CallStmt &x) { // R1521
peter klauslerf147abd2018-07-11 00:09:071656 const auto &pd{std::get<ProcedureDesignator>(x.v.t)};
1657 const auto &args{std::get<std::list<ActualArgSpec>>(x.v.t)};
peter klauslerad4adc22018-03-16 00:09:271658 Word("CALL "), Walk(pd);
1659 if (args.empty()) {
1660 if (std::holds_alternative<ProcComponentRef>(pd.u)) {
1661 Put("()"); // pgf90 crashes on CALL to tbp without parentheses
1662 }
1663 } else {
1664 Walk("(", args, ", ", ")");
1665 }
peter klausler79d044e2018-03-01 00:56:101666 }
peter klausler8ea4a0a2018-04-06 20:13:201667 void Unparse(const ActualArgSpec &x) { // R1523
peter klausler79d044e2018-03-01 00:56:101668 Walk(std::get<std::optional<Keyword>>(x.t), "=");
1669 Walk(std::get<ActualArg>(x.t));
peter klausler79d044e2018-03-01 00:56:101670 }
peter klausler8ea4a0a2018-04-06 20:13:201671 void Unparse(const ActualArg::PercentRef &x) { // R1524
peter klauslerb7cf5122018-03-14 22:31:161672 Word("%REF("), Walk(x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:101673 }
peter klausler8ea4a0a2018-04-06 20:13:201674 void Unparse(const ActualArg::PercentVal &x) {
peter klauslerb7cf5122018-03-14 22:31:161675 Word("%VAL("), Walk(x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:101676 }
peter klausler8ea4a0a2018-04-06 20:13:201677 void Before(const AltReturnSpec &) { // R1525
peter klauslerb7cf5122018-03-14 22:31:161678 Put('*');
peter klausler79d044e2018-03-01 00:56:101679 }
peter klauslerd71f3cf2018-03-14 23:31:411680 void Post(const PrefixSpec::Elemental) { Word("ELEMENTAL"); } // R1527
1681 void Post(const PrefixSpec::Impure) { Word("IMPURE"); }
1682 void Post(const PrefixSpec::Module) { Word("MODULE"); }
1683 void Post(const PrefixSpec::Non_Recursive) { Word("NON_RECURSIVE"); }
1684 void Post(const PrefixSpec::Pure) { Word("PURE"); }
1685 void Post(const PrefixSpec::Recursive) { Word("RECURSIVE"); }
peter klausler8ea4a0a2018-04-06 20:13:201686 void Unparse(const FunctionStmt &x) { // R1530
peter klausler79d044e2018-03-01 00:56:101687 Walk("", std::get<std::list<PrefixSpec>>(x.t), " ", " ");
peter klausler62d9cdd2018-03-15 00:02:211688 Word("FUNCTION "), Walk(std::get<Name>(x.t)), Put("(");
peter klausler79d044e2018-03-01 00:56:101689 Walk(std::get<std::list<Name>>(x.t), ", "), Put(')');
1690 Walk(" ", std::get<std::optional<Suffix>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:101691 }
peter klausler8ea4a0a2018-04-06 20:13:201692 void Unparse(const Suffix &x) { // R1532
peter klausler79d044e2018-03-01 00:56:101693 if (x.resultName) {
peter klauslerb7cf5122018-03-14 22:31:161694 Word("RESULT("), Walk(x.resultName), Put(')');
peter klausler79d044e2018-03-01 00:56:101695 Walk(" ", x.binding);
1696 } else {
1697 Walk(x.binding);
1698 }
peter klausler79d044e2018-03-01 00:56:101699 }
peter klausler8ea4a0a2018-04-06 20:13:201700 void Unparse(const EndFunctionStmt &x) { // R1533
peter klausler41d9cfd2018-04-03 17:29:041701 EndSubprogram("FUNCTION", x.v);
peter klausler79d044e2018-03-01 00:56:101702 }
peter klausler8ea4a0a2018-04-06 20:13:201703 void Unparse(const SubroutineStmt &x) { // R1535
peter klausler79d044e2018-03-01 00:56:101704 Walk("", std::get<std::list<PrefixSpec>>(x.t), " ", " ");
peter klauslerb7cf5122018-03-14 22:31:161705 Word("SUBROUTINE "), Walk(std::get<Name>(x.t));
peter klauslerf147abd2018-07-11 00:09:071706 const auto &args{std::get<std::list<DummyArg>>(x.t)};
1707 const auto &bind{std::get<std::optional<LanguageBindingSpec>>(x.t)};
peter klauslerd71f3cf2018-03-14 23:31:411708 if (args.empty()) {
1709 Walk(" () ", bind);
1710 } else {
1711 Walk(" (", args, ", ", ")");
1712 Walk(" ", bind);
1713 }
peter klausler79d044e2018-03-01 00:56:101714 Indent();
peter klausler79d044e2018-03-01 00:56:101715 }
peter klausler8ea4a0a2018-04-06 20:13:201716 void Unparse(const EndSubroutineStmt &x) { // R1537
peter klausler41d9cfd2018-04-03 17:29:041717 EndSubprogram("SUBROUTINE", x.v);
peter klausler79d044e2018-03-01 00:56:101718 }
peter klausler8ea4a0a2018-04-06 20:13:201719 void Before(const MpSubprogramStmt &) { // R1539
peter klauslerb7cf5122018-03-14 22:31:161720 Word("MODULE PROCEDURE "), Indent();
peter klausler79d044e2018-03-01 00:56:101721 }
peter klausler8ea4a0a2018-04-06 20:13:201722 void Unparse(const EndMpSubprogramStmt &x) { // R1540
peter klausler41d9cfd2018-04-03 17:29:041723 EndSubprogram("PROCEDURE", x.v);
peter klausler79d044e2018-03-01 00:56:101724 }
peter klausler8ea4a0a2018-04-06 20:13:201725 void Unparse(const EntryStmt &x) { // R1541
peter klauslerbdd93dd2018-04-09 20:45:301726 Word("ENTRY "), Walk(std::get<Name>(x.t)), Put("(");
1727 Walk(std::get<std::list<DummyArg>>(x.t), ", "), Put(")");
peter klausler79d044e2018-03-01 00:56:101728 Walk(" ", std::get<std::optional<Suffix>>(x.t));
peter klausler79d044e2018-03-01 00:56:101729 }
peter klausler8ea4a0a2018-04-06 20:13:201730 void Unparse(const ReturnStmt &x) { // R1542
peter klauslerb7cf5122018-03-14 22:31:161731 Word("RETURN"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101732 }
peter klausler8ea4a0a2018-04-06 20:13:201733 void Unparse(const ContainsStmt &x) { // R1543
peter klausler79d044e2018-03-01 00:56:101734 Outdent();
peter klauslerb7cf5122018-03-14 22:31:161735 Word("CONTAINS");
peter klausler79d044e2018-03-01 00:56:101736 Indent();
peter klausler79d044e2018-03-01 00:56:101737 }
peter klausler8ea4a0a2018-04-06 20:13:201738 void Unparse(const StmtFunctionStmt &x) { // R1544
peter klausler79d044e2018-03-01 00:56:101739 Walk(std::get<Name>(x.t)), Put('(');
1740 Walk(std::get<std::list<Name>>(x.t), ", "), Put(") = ");
1741 Walk(std::get<Scalar<Expr>>(x.t));
peter klausler79d044e2018-03-01 00:56:101742 }
1743
peter klausler75b29332018-03-23 22:14:521744 // Directives, extensions, and deprecated constructs
peter klausler8ea4a0a2018-04-06 20:13:201745 void Unparse(const CompilerDirective &x) {
peter klausler75b29332018-03-23 22:14:521746 std::visit(
peter klauslerb23701f2018-06-18 18:03:431747 common::visitors{
1748 [&](const std::list<CompilerDirective::IgnoreTKR> &tkr) {
peter klausler3204a1c2019-03-14 19:19:261749 Word("!DIR$ IGNORE_TKR"); // emitted even if tkr list is empty
peter klauslerb23701f2018-06-18 18:03:431750 Walk(" ", tkr, ", ");
1751 },
peter klausler3204a1c2019-03-14 19:19:261752 [&](const std::list<Name> &names) { Walk("!DIR$ ", names, " "); },
Tim Keithdaa0b052018-11-29 17:27:341753 },
peter klausler75b29332018-03-23 22:14:521754 x.u);
1755 Put('\n');
peter klausler75b29332018-03-23 22:14:521756 }
peter klausler8ea4a0a2018-04-06 20:13:201757 void Unparse(const CompilerDirective::IgnoreTKR &x) {
peter klauslerf147abd2018-07-11 00:09:071758 const auto &list{std::get<std::list<const char *>>(x.t)};
peter klausler75b29332018-03-23 22:14:521759 if (!list.empty()) {
1760 Put("(");
1761 for (const char *tkr : list) {
1762 Put(*tkr);
1763 }
1764 Put(") ");
1765 }
1766 Walk(std::get<Name>(x.t));
peter klausler75b29332018-03-23 22:14:521767 }
Hongyon Suauthai1bfb8432018-06-01 17:40:131768 // OpenMP Clauses & Directives
hsuauthai08b26842018-07-20 22:49:191769 void Unparse(const OmpObject &x) {
1770 bool isCommon{std::get<OmpObject::Kind>(x.t) == OmpObject::Kind::Common};
Hongyon Suauthai1bfb8432018-06-01 17:40:131771 const char *slash{isCommon ? "/" : ""};
hsuauthai08b26842018-07-20 22:49:191772 Put(slash), Walk(std::get<Designator>(x.t)), Put(slash);
Hongyon Suauthai1bfb8432018-06-01 17:40:131773 }
hsuauthai08b26842018-07-20 22:49:191774 void Unparse(const OmpMapType::Always &x) { Word("ALWAYS,"); }
Hongyon Suauthai1bfb8432018-06-01 17:40:131775 void Unparse(const OmpMapClause &x) {
hsuauthai08b26842018-07-20 22:49:191776 Word("MAP(");
1777 Walk(std::get<std::optional<OmpMapType>>(x.t), ":");
1778 Walk(std::get<OmpObjectList>(x.t));
Hongyon Suauthai1bfb8432018-06-01 17:40:131779 Put(") ");
1780 }
1781 void Unparse(const OmpScheduleModifier &x) {
1782 Walk(std::get<OmpScheduleModifier::Modifier1>(x.t));
1783 Walk(",", std::get<std::optional<OmpScheduleModifier::Modifier2>>(x.t));
1784 }
1785 void Unparse(const OmpScheduleClause &x) {
hsuauthai08b26842018-07-20 22:49:191786 Word("SCHEDULE(");
Hongyon Suauthai1bfb8432018-06-01 17:40:131787 Walk(std::get<std::optional<OmpScheduleModifier>>(x.t));
1788 Walk(std::get<OmpScheduleClause::ScheduleType>(x.t));
Hongyon Suauthai90aca332018-06-01 21:36:511789 Walk(",", std::get<std::optional<ScalarIntExpr>>(x.t));
Hongyon Suauthai1bfb8432018-06-01 17:40:131790 Put(")");
1791 }
1792 void Unparse(const OmpAlignedClause &x) {
hsuauthai08b26842018-07-20 22:49:191793 Word("ALIGNED("), Walk(std::get<std::list<Name>>(x.t), ",");
Hongyon Suauthai1bfb8432018-06-01 17:40:131794 Walk(std::get<std::optional<ScalarIntConstantExpr>>(x.t));
1795 Put(") ");
1796 }
1797 void Unparse(const OmpIfClause &x) {
hsuauthai08b26842018-07-20 22:49:191798 Word("IF("),
Hongyon Suauthai9914f222018-06-01 18:15:321799 Walk(std::get<std::optional<OmpIfClause::DirectiveNameModifier>>(x.t),
1800 ":");
Hongyon Suauthai1bfb8432018-06-01 17:40:131801 Walk(std::get<ScalarLogicalExpr>(x.t));
1802 Put(") ");
1803 }
1804 void Unparse(const OmpLinearClause::WithoutModifier &x) {
hsuauthai08b26842018-07-20 22:49:191805 Word("LINEAR("), Walk(x.names, ", ");
Hongyon Suauthai1bfb8432018-06-01 17:40:131806 Walk(":", x.step);
1807 Put(")");
1808 }
1809 void Unparse(const OmpLinearClause::WithModifier &x) {
hsuauthai08b26842018-07-20 22:49:191810 Word("LINEAR("), Walk(x.modifier), Put("("), Walk(x.names, ","), Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131811 Walk(":", x.step);
1812 Put(")");
1813 }
1814 void Unparse(const OmpReductionClause &x) {
hsuauthai08b26842018-07-20 22:49:191815 Word("REDUCTION(");
Hongyon Suauthai1bfb8432018-06-01 17:40:131816 Walk(std::get<OmpReductionOperator>(x.t));
1817 Put(":");
1818 Walk(std::get<std::list<Designator>>(x.t), ",");
1819 Put(")");
1820 }
1821 void Unparse(const OmpDependSinkVecLength &x) {
peter klauslerb23701f2018-06-18 18:03:431822 Walk(std::get<common::Indirection<DefinedOperator>>(x.t));
Hongyon Suauthai1bfb8432018-06-01 17:40:131823 Walk(std::get<ScalarIntConstantExpr>(x.t));
1824 }
1825 void Unparse(const OmpDependSinkVec &x) {
1826 Walk(std::get<Name>(x.t));
1827 Walk(std::get<std::optional<OmpDependSinkVecLength>>(x.t));
1828 }
1829 void Unparse(const OmpDependClause::InOut &x) {
hsuauthai08b26842018-07-20 22:49:191830 Put("(");
Hongyon Suauthai1bfb8432018-06-01 17:40:131831 Walk(std::get<OmpDependenceType>(x.t));
1832 Put(":");
1833 Walk(std::get<std::list<Designator>>(x.t), ",");
hsuauthai08b26842018-07-20 22:49:191834 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131835 }
hsuauthai08b26842018-07-20 22:49:191836 bool Pre(const OmpDependClause &x) {
Tim Keithdaa0b052018-11-29 17:27:341837 return std::visit(
1838 common::visitors{
1839 [&](const OmpDependClause::Source &y) {
1840 Word("DEPEND(SOURCE)");
1841 return false;
1842 },
1843 [&](const OmpDependClause::Sink &y) {
1844 Word("DEPEND(SINK:");
1845 Walk(y.v);
1846 Put(")");
1847 return false;
1848 },
1849 [&](const OmpDependClause::InOut &y) {
1850 Word("DEPEND");
1851 return true;
1852 },
1853 },
Hongyon Suauthai1bfb8432018-06-01 17:40:131854 x.u);
1855 }
hsuauthai08b26842018-07-20 22:49:191856 bool Pre(const OmpDefaultClause &x) {
1857 Word("DEFAULT(");
1858 return true;
1859 }
1860 void Post(const OmpDefaultClause &x) { Put(")"); }
1861 bool Pre(const OmpProcBindClause &x) {
1862 Word("PROC_BIND(");
1863 return true;
1864 }
1865 void Post(const OmpProcBindClause &x) { Put(")"); }
Hongyon Suauthai1bfb8432018-06-01 17:40:131866 void Before(const OmpClause::Defaultmap &x) {
hsuauthai08b26842018-07-20 22:49:191867 Word("DEFAULTMAP(TOFROM:SCALAR)");
Hongyon Suauthai1bfb8432018-06-01 17:40:131868 }
Hongyon Suauthaie2c8c212018-06-01 18:47:241869 void Before(const OmpClause::Inbranch &x) { Word("INBRANCH"); }
1870 void Before(const OmpClause::Mergeable &x) { Word("MERGEABLE"); }
1871 void Before(const OmpClause::Nogroup &x) { Word("NOGROUP"); }
1872 void Before(const OmpClause::Notinbranch &x) { Word("NOTINBRANCH"); }
Hongyon Suauthaie2c8c212018-06-01 18:47:241873 void Before(const OmpClause::Untied &x) { Word("UNTIED"); }
hsuauthai08b26842018-07-20 22:49:191874 void Unparse(const OmpNowait &) { Word("NOWAIT"); }
Hongyon Suauthai9914f222018-06-01 18:15:321875 void Unparse(const OmpClause::Collapse &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241876 Word("COLLAPSE(");
Hongyon Suauthai9914f222018-06-01 18:15:321877 Walk(x.v);
1878 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131879 }
Hongyon Suauthai9914f222018-06-01 18:15:321880 void Unparse(const OmpClause::Copyin &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241881 Word("COPYIN(");
hsuauthai08b26842018-07-20 22:49:191882 Walk(x.v);
Hongyon Suauthai9914f222018-06-01 18:15:321883 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131884 }
Hongyon Suauthai9914f222018-06-01 18:15:321885 void Unparse(const OmpClause::Copyprivate &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241886 Word("COPYPRIVATE(");
hsuauthai08b26842018-07-20 22:49:191887 Walk(x.v);
Hongyon Suauthai9914f222018-06-01 18:15:321888 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131889 }
Hongyon Suauthai9914f222018-06-01 18:15:321890 void Unparse(const OmpClause::Device &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241891 Word("DEVICE(");
Hongyon Suauthai9914f222018-06-01 18:15:321892 Walk(x.v);
1893 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131894 }
Hongyon Suauthai9914f222018-06-01 18:15:321895 void Unparse(const OmpClause::DistSchedule &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241896 Word("DIST_SCHEDULE(STATIC,");
Hongyon Suauthai9914f222018-06-01 18:15:321897 Walk(x.v);
1898 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131899 }
Hongyon Suauthai9914f222018-06-01 18:15:321900 void Unparse(const OmpClause::Final &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241901 Word("FINAL(");
Hongyon Suauthai9914f222018-06-01 18:15:321902 Walk(x.v);
1903 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131904 }
Hongyon Suauthai9914f222018-06-01 18:15:321905 void Unparse(const OmpClause::Firstprivate &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241906 Word("FIRSTPRIVATE(");
hsuauthai08b26842018-07-20 22:49:191907 Walk(x.v);
Hongyon Suauthai9914f222018-06-01 18:15:321908 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131909 }
Hongyon Suauthai9914f222018-06-01 18:15:321910 void Unparse(const OmpClause::From &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241911 Word("FROM(");
Hongyon Suauthai9914f222018-06-01 18:15:321912 Walk(x.v, ",");
1913 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131914 }
Hongyon Suauthai9914f222018-06-01 18:15:321915 void Unparse(const OmpClause::Grainsize &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241916 Word("GRAINSIZE(");
Hongyon Suauthai9914f222018-06-01 18:15:321917 Walk(x.v);
1918 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131919 }
Hongyon Suauthai9914f222018-06-01 18:15:321920 void Unparse(const OmpClause::Lastprivate &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241921 Word("LASTPRIVATE(");
hsuauthai08b26842018-07-20 22:49:191922 Walk(x.v);
Hongyon Suauthai9914f222018-06-01 18:15:321923 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131924 }
Hongyon Suauthai9914f222018-06-01 18:15:321925 void Unparse(const OmpClause::NumTasks &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241926 Word("NUM_TASKS(");
Hongyon Suauthai9914f222018-06-01 18:15:321927 Walk(x.v);
1928 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131929 }
Hongyon Suauthai9914f222018-06-01 18:15:321930 void Unparse(const OmpClause::NumTeams &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241931 Word("NUM_TEAMS(");
Hongyon Suauthai9914f222018-06-01 18:15:321932 Walk(x.v);
1933 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131934 }
Hongyon Suauthai9914f222018-06-01 18:15:321935 void Unparse(const OmpClause::NumThreads &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241936 Word("NUM_THREADS(");
Hongyon Suauthai9914f222018-06-01 18:15:321937 Walk(x.v);
1938 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131939 }
Hongyon Suauthai9914f222018-06-01 18:15:321940 void Unparse(const OmpClause::Ordered &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241941 Word("ORDERED");
Hongyon Suauthai9914f222018-06-01 18:15:321942 Walk("(", x.v, ")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131943 }
Hongyon Suauthai9914f222018-06-01 18:15:321944 void Unparse(const OmpClause::Priority &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241945 Word("PRIORITY(");
Hongyon Suauthai9914f222018-06-01 18:15:321946 Walk(x.v);
1947 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131948 }
Hongyon Suauthai9914f222018-06-01 18:15:321949 void Unparse(const OmpClause::Private &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241950 Word("PRIVATE(");
hsuauthai08b26842018-07-20 22:49:191951 Walk(x.v);
Hongyon Suauthai9914f222018-06-01 18:15:321952 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131953 }
Hongyon Suauthai9914f222018-06-01 18:15:321954 void Unparse(const OmpClause::Safelen &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241955 Word("SAFELEN(");
1956 Walk(x.v);
1957 Put(")");
1958 }
1959 void Unparse(const OmpClause::Simdlen &x) {
1960 Word("SIMDLEN(");
Hongyon Suauthai9914f222018-06-01 18:15:321961 Walk(x.v);
1962 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131963 }
Hongyon Suauthai9914f222018-06-01 18:15:321964 void Unparse(const OmpClause::ThreadLimit &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241965 Word("THREADLIMIT(");
Hongyon Suauthai9914f222018-06-01 18:15:321966 Walk(x.v);
1967 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131968 }
Hongyon Suauthai9914f222018-06-01 18:15:321969 void Unparse(const OmpClause::Shared &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241970 Word("SHARED(");
hsuauthai08b26842018-07-20 22:49:191971 Walk(x.v);
Hongyon Suauthai9914f222018-06-01 18:15:321972 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131973 }
Hongyon Suauthai9914f222018-06-01 18:15:321974 void Unparse(const OmpClause::To &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241975 Word("TO(");
Hongyon Suauthai9914f222018-06-01 18:15:321976 Walk(x.v, ",");
1977 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131978 }
Hongyon Suauthai9914f222018-06-01 18:15:321979 void Unparse(const OmpClause::Uniform &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241980 Word("UNIFORM(");
Hongyon Suauthai9914f222018-06-01 18:15:321981 Walk(x.v, ",");
1982 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131983 }
Hongyon Suauthai9914f222018-06-01 18:15:321984 void Unparse(const OmpClause::UseDevicePtr &x) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241985 Word("USE_DEVICE_PTR(");
Hongyon Suauthai9914f222018-06-01 18:15:321986 Walk(x.v, ",");
1987 Put(")");
Hongyon Suauthai1bfb8432018-06-01 17:40:131988 }
1989 void Unparse(const OmpLoopDirective &x) {
1990 std::visit(
peter klauslerb23701f2018-06-18 18:03:431991 common::visitors{
hsuauthai08b26842018-07-20 22:49:191992 [&](const OmpLoopDirective::DistributeParallelDoSimd &) {
peter klauslerb23701f2018-06-18 18:03:431993 Word("DISTRIBUTE PARALLEL DO SIMD ");
peter klauslerb23701f2018-06-18 18:03:431994 },
hsuauthai08b26842018-07-20 22:49:191995 [&](const OmpLoopDirective::DistributeParallelDo &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241996 Word("DISTRIBUTE PARALLEL DO ");
Hongyon Suauthai9914f222018-06-01 18:15:321997 },
hsuauthai08b26842018-07-20 22:49:191998 [&](const OmpLoopDirective::DistributeSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:241999 Word("DISTRIBUTE SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322000 },
hsuauthai08b26842018-07-20 22:49:192001 [&](const OmpLoopDirective::Distribute &) { Word("DISTRIBUTE "); },
2002 [&](const OmpLoopDirective::ParallelDoSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242003 Word("PARALLEL DO SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322004 },
hsuauthai08b26842018-07-20 22:49:192005 [&](const OmpLoopDirective::ParallelDo &) { Word("PARALLEL DO "); },
2006 [&](const OmpLoopDirective::Do &) { Word("DO "); },
2007 [&](const OmpLoopDirective::DoSimd &) { Word("Do SIMD "); },
2008 [&](const OmpLoopDirective::Simd &) { Word("SIMD "); },
2009 [&](const OmpLoopDirective::TargetParallelDoSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242010 Word("TARGET PARALLEL DO SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322011 },
hsuauthai08b26842018-07-20 22:49:192012 [&](const OmpLoopDirective::TargetParallelDo &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242013 Word("TARGET PARALLEL DO ");
Hongyon Suauthai9914f222018-06-01 18:15:322014 },
hsuauthai08b26842018-07-20 22:49:192015 [&](const OmpLoopDirective::TargetTeamsDistributeParallelDoSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242016 Word("TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322017 },
hsuauthai08b26842018-07-20 22:49:192018 [&](const OmpLoopDirective::TargetTeamsDistributeParallelDo &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242019 Word("TARGET TEAMS DISTRIBUTE PARALLEL DO ");
Hongyon Suauthai9914f222018-06-01 18:15:322020 },
hsuauthai08b26842018-07-20 22:49:192021 [&](const OmpLoopDirective::TargetTeamsDistributeSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242022 Word("TARGET TEAMS DISTRIBUTE SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322023 },
hsuauthai08b26842018-07-20 22:49:192024 [&](const OmpLoopDirective::TargetTeamsDistribute &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242025 Word("TARGET TEAMS DISTRIBUTE ");
Hongyon Suauthai9914f222018-06-01 18:15:322026 },
hsuauthai08b26842018-07-20 22:49:192027 [&](const OmpLoopDirective::TargetSimd &) { Word("TARGET SIMD "); },
2028 [&](const OmpLoopDirective::TaskloopSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242029 Word("TASKLOOP SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322030 },
hsuauthai08b26842018-07-20 22:49:192031 [&](const OmpLoopDirective::Taskloop &) { Word("TASKLOOP "); },
2032 [&](const OmpLoopDirective::TeamsDistributeParallelDoSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242033 Word("TEAMS DISTRIBUTE PARALLEL DO SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322034 },
hsuauthai08b26842018-07-20 22:49:192035 [&](const OmpLoopDirective::TeamsDistributeParallelDo &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242036 Word("TEAMS DISTRIBUTE PARALLEL DO ");
Hongyon Suauthai9914f222018-06-01 18:15:322037 },
hsuauthai08b26842018-07-20 22:49:192038 [&](const OmpLoopDirective::TeamsDistributeSimd &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242039 Word("TEAMS DISTRIBUTE SIMD ");
Hongyon Suauthai9914f222018-06-01 18:15:322040 },
hsuauthai08b26842018-07-20 22:49:192041 [&](const OmpLoopDirective::TeamsDistribute &) {
Hongyon Suauthaie2c8c212018-06-01 18:47:242042 Word("TEAMS DISTRIBUTE ");
Tim Keithdaa0b052018-11-29 17:27:342043 },
2044 },
Hongyon Suauthai1bfb8432018-06-01 17:40:132045 x.u);
Hongyon Suauthai1bfb8432018-06-01 17:40:132046 }
hsuauthai08b26842018-07-20 22:49:192047 void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
Hongyon Suauthai1bfb8432018-06-01 17:40:132048 void Unparse(const OmpStandaloneDirective &x) {
hsuauthai08b26842018-07-20 22:49:192049 std::visit(
Tim Keithdaa0b052018-11-29 17:27:342050 common::visitors{
2051 [&](const OmpStandaloneDirective::TargetEnterData &) {
2052 Word("TARGET ENTER DATA ");
2053 },
hsuauthai08b26842018-07-20 22:49:192054 [&](const OmpStandaloneDirective::TargetExitData &) {
2055 Word("TARGET EXIT DATA ");
2056 },
2057 [&](const OmpStandaloneDirective::TargetUpdate &) {
2058 Word("TARGET UPDATE ");
Tim Keithdaa0b052018-11-29 17:27:342059 },
2060 },
Hongyon Suauthai1bfb8432018-06-01 17:40:132061 x.u);
hsuauthai08b26842018-07-20 22:49:192062 }
2063 void Unparse(const OmpBlockDirective &x) {
2064 std::visit(
2065 common::visitors{
2066 [&](const OmpBlockDirective::Master &y) { Word("MASTER"); },
2067 [&](const OmpBlockDirective::Ordered &) { Word("ORDERED "); },
2068 [&](const OmpBlockDirective::ParallelWorkshare &) {
2069 Word("PARALLEL WORKSHARE ");
2070 },
2071 [&](const OmpBlockDirective::Parallel &) { Word("PARALLEL "); },
2072 [&](const OmpBlockDirective::TargetData &) {
2073 Word("TARGET DATA ");
2074 },
2075 [&](const OmpBlockDirective::TargetParallel &) {
2076 Word("TARGET PARALLEL ");
2077 },
2078 [&](const OmpBlockDirective::TargetTeams &) {
2079 Word("TARGET TEAMS ");
2080 },
2081 [&](const OmpBlockDirective::Target &) { Word("TARGET "); },
2082 [&](const OmpBlockDirective::Taskgroup &) { Word("TASKGROUP "); },
2083 [&](const OmpBlockDirective::Task &) { Word("TASK "); },
Tim Keithdaa0b052018-11-29 17:27:342084 [&](const OmpBlockDirective::Teams &) { Word("TEAMS "); },
2085 },
hsuauthai08b26842018-07-20 22:49:192086 x.u);
2087 }
2088 void Unparse(const OmpAtomic &x) {
2089 BeginOpenMP();
2090 Word("!$OMP ATOMIC");
2091 Walk(std::get<std::optional<OmpAtomic::SeqCst>>(x.t), " SEQ_CST");
Hongyon Suauthai1bfb8432018-06-01 17:40:132092 Put("\n");
hsuauthai08b26842018-07-20 22:49:192093 EndOpenMP();
2094 Walk(std::get<Statement<AssignmentStmt>>(x.t));
2095 BeginOpenMP();
2096 Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
2097 EndOpenMP();
Hongyon Suauthai1bfb8432018-06-01 17:40:132098 }
hsuauthai08b26842018-07-20 22:49:192099 void Unparse(const OmpAtomicCapture &x) {
2100 BeginOpenMP();
2101 Word("!$OMP ATOMIC");
2102 Walk(std::get<std::optional<OmpAtomicCapture::SeqCst1>>(x.t), " SEQ_CST,");
2103 Word(" CAPTURE");
2104 Walk(std::get<std::optional<OmpAtomicCapture::SeqCst2>>(x.t), " ,SEQ_CST");
2105 Put("\n");
2106 EndOpenMP();
2107 Walk(std::get<OmpAtomicCapture::Stmt1>(x.t));
2108 Put("\n");
2109 Walk(std::get<OmpAtomicCapture::Stmt2>(x.t));
2110 BeginOpenMP();
2111 Word("!$OMP END ATOMIC\n");
2112 EndOpenMP();
2113 }
2114 void Unparse(const OmpAtomicRead &x) {
2115 BeginOpenMP();
2116 Word("!$OMP ATOMIC");
2117 Walk(std::get<std::optional<OmpAtomicRead::SeqCst1>>(x.t), " SEQ_CST,");
2118 Word(" READ");
2119 Walk(std::get<std::optional<OmpAtomicRead::SeqCst2>>(x.t), " ,SEQ_CST");
2120 Put("\n");
2121 EndOpenMP();
2122 Walk(std::get<Statement<AssignmentStmt>>(x.t));
2123 BeginOpenMP();
2124 Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
2125 EndOpenMP();
2126 }
2127 void Unparse(const OmpAtomicUpdate &x) {
2128 BeginOpenMP();
2129 Word("!$OMP ATOMIC");
2130 Walk(std::get<std::optional<OmpAtomicUpdate::SeqCst1>>(x.t), " SEQ_CST,");
2131 Word(" UPDATE");
2132 Walk(std::get<std::optional<OmpAtomicUpdate::SeqCst2>>(x.t), " ,SEQ_CST");
2133 Put("\n");
2134 EndOpenMP();
2135 Walk(std::get<Statement<AssignmentStmt>>(x.t));
2136 BeginOpenMP();
2137 Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
2138 EndOpenMP();
2139 }
2140 void Unparse(const OmpAtomicWrite &x) {
2141 BeginOpenMP();
2142 Word("!$OMP ATOMIC");
2143 Walk(std::get<std::optional<OmpAtomicWrite::SeqCst1>>(x.t), " SEQ_CST,");
2144 Word(" WRITE");
2145 Walk(std::get<std::optional<OmpAtomicWrite::SeqCst2>>(x.t), " ,SEQ_CST");
2146 Put("\n");
2147 EndOpenMP();
2148 Walk(std::get<Statement<AssignmentStmt>>(x.t));
2149 BeginOpenMP();
2150 Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
2151 EndOpenMP();
2152 }
2153 void Unparse(const OmpEndCritical &x) {
2154 Walk(" (", x.v, ")");
2155 EndOpenMP();
2156 }
2157 void Unparse(const OpenMPCriticalConstruct &x) {
2158 BeginOpenMP();
2159 Word("!$OMP CRITICAL");
2160 Walk(" (", std::get<std::optional<Name>>(x.t), ")");
2161 Walk(" HINT(", std::get<std::optional<OpenMPCriticalConstruct::Hint>>(x.t),
2162 ")");
2163 Put("\n");
2164 EndOpenMP();
2165 Walk(std::get<Block>(x.t), "");
2166 BeginOpenMP();
2167 Word("!$OMP END CRITICAL");
2168 Walk(std::get<OmpEndCritical>(x.t));
2169 Put("\n");
2170 EndOpenMP();
2171 }
2172 void Unparse(const OpenMPDeclareTargetConstruct::WithClause &x) {
2173 Walk(x.maptype), Put("("), Walk(x.names), Put(")");
2174 }
2175 void Unparse(const OpenMPDeclareTargetConstruct::WithExtendedList &x) {
2176 Put("("), Walk(x.names), Put(")");
2177 }
2178 void Unparse(const OmpReductionInitializerClause &x) {
2179 Word(" INITIALIZER(OMP_PRIV = ");
2180 Walk(x.v);
2181 Put(")");
2182 }
2183 void Unparse(const OmpReductionCombiner::FunctionCombiner &x) {
2184 const auto &pd = std::get<ProcedureDesignator>(x.v.t);
2185 const auto &args = std::get<std::list<ActualArgSpec>>(x.v.t);
2186 Walk(pd);
2187 if (args.empty()) {
2188 if (std::holds_alternative<ProcComponentRef>(pd.u)) {
2189 Put("()");
2190 }
2191 } else {
2192 Walk("(", args, ", ", ")");
2193 }
2194 }
2195 void Unparse(const OpenMPDeclareReductionConstruct &x) {
2196 Put("(");
2197 Walk(std::get<OmpReductionOperator>(x.t)), Put(" : ");
2198 Walk(std::get<std::list<DeclarationTypeSpec>>(x.t), ","), Put(" : ");
2199 Walk(std::get<OmpReductionCombiner>(x.t));
2200 Put(")");
2201 Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
2202 }
2203 bool Pre(const OpenMPDeclarativeConstruct &x) {
2204 BeginOpenMP();
2205 Word("!$OMP ");
2206 return std::visit(
Tim Keithdaa0b052018-11-29 17:27:342207 common::visitors{
2208 [&](const OpenMPDeclareReductionConstruct &y) {
2209 Word("DECLARE REDUCTION ");
2210 return true;
2211 },
hsuauthai08b26842018-07-20 22:49:192212 [&](const OpenMPDeclareSimdConstruct &y) {
2213 Word("DECLARE SIMD ");
2214 Walk("(", std::get<std::optional<Name>>(y.t), ")");
2215 Walk(std::get<OmpClauseList>(y.t));
2216 Put("\n");
2217 EndOpenMP();
2218 return false;
2219 },
2220 [&](const OpenMPDeclareTargetConstruct &y) {
2221 Word("DECLARE TARGET ");
2222 return true;
2223 },
2224 [&](const OpenMPDeclarativeConstruct::Threadprivate &y) {
2225 Word("THREADPRIVATE (");
2226 return true;
Tim Keithdaa0b052018-11-29 17:27:342227 },
2228 },
Hongyon Suauthai1bfb8432018-06-01 17:40:132229 x.u);
2230 }
hsuauthai08b26842018-07-20 22:49:192231 void Post(const OpenMPDeclarativeConstruct &x) {
2232 Put("\n");
2233 EndOpenMP();
Hongyon Suauthai1bfb8432018-06-01 17:40:132234 }
hsuauthai08b26842018-07-20 22:49:192235 void Post(const OpenMPDeclarativeConstruct::Threadprivate &x) {
2236 Put(")\n");
2237 EndOpenMP();
2238 }
2239 void Unparse(const OmpEndDoSimd &x) {
2240 BeginOpenMP();
2241 Word("DO SIMD ");
2242 Walk(x.v);
2243 EndOpenMP();
2244 }
2245 void Unparse(const OmpEndDo &x) {
2246 BeginOpenMP();
2247 Word("DO ");
2248 Walk(x.v);
2249 EndOpenMP();
2250 }
2251 bool Pre(const OpenMPBarrierConstruct &x) {
2252 BeginOpenMP();
2253 Word("!$OMP BARRIER");
2254 Put("\n");
2255 EndOpenMP();
2256 return false;
2257 }
2258 void Unparse(const OpenMPSingleConstruct &x) {
2259 BeginOpenMP();
2260 Word("!$OMP SINGLE");
2261 Walk(std::get<OmpClauseList>(x.t));
2262 EndOpenMP();
2263 Put("\n");
2264 Walk(std::get<Block>(x.t), "");
2265 BeginOpenMP();
2266 Word("!$OMP END SINGLE ");
2267 Walk(std::get<OmpEndSingle>(x.t));
2268 Put("\n");
2269 EndOpenMP();
2270 }
2271 void Unparse(const OmpSection &x) {
2272 BeginOpenMP();
2273 Word("!$OMP SECTION");
2274 Put("\n");
2275 EndOpenMP();
2276 }
2277 void Unparse(const OpenMPSectionsConstruct &x) {
2278 BeginOpenMP();
2279 Word("!$OMP SECTIONS");
2280 Walk(std::get<OmpClauseList>(x.t));
2281 Put("\n");
2282 EndOpenMP();
2283 Walk(std::get<Block>(x.t), "");
2284 BeginOpenMP();
2285 Word("!$OMP END SECTIONS");
2286 Put("\n");
2287 EndOpenMP();
2288 }
2289 void Unparse(const OpenMPParallelSectionsConstruct &x) {
2290 BeginOpenMP();
2291 Word("!$OMP PARALLEL SECTIONS");
2292 Walk(std::get<OmpClauseList>(x.t));
2293 Put("\n");
2294 EndOpenMP();
2295 Walk(std::get<Block>(x.t), "");
2296 BeginOpenMP();
2297 Word("!$OMP END PARALLEL SECTIONS");
2298 Put("\n");
2299 EndOpenMP();
2300 }
2301 void Unparse(const OpenMPWorkshareConstruct &x) {
2302 BeginOpenMP();
2303 Word("!$OMP WORKSHARE");
2304 Put("\n");
2305 EndOpenMP();
2306 Walk(std::get<Block>(x.t), "");
2307 BeginOpenMP();
2308 Word("!$OMP END WORKSHARE ");
2309 Walk(std::get<std::optional<OmpNowait>>(x.t));
2310 Put("\n");
2311 EndOpenMP();
2312 }
2313 bool Pre(const OpenMPTaskyieldConstruct &x) {
2314 BeginOpenMP();
2315 Word("!$OMP TASKYIELD");
2316 Put("\n");
2317 EndOpenMP();
2318 return false;
2319 }
2320 bool Pre(const OpenMPTaskwaitConstruct &x) {
2321 BeginOpenMP();
2322 Word("!$OMP TASKWAIT");
2323 Put("\n");
2324 EndOpenMP();
2325 return false;
2326 }
2327 void Unparse(const OpenMPCancellationPointConstruct &x) {
2328 BeginOpenMP();
2329 Word("!$OMP CANCELLATION POINT ");
2330 Walk(x.v);
2331 Put("\n");
2332 EndOpenMP();
2333 }
2334 void Unparse(const OpenMPCancelConstruct &x) {
2335 BeginOpenMP();
2336 Word("!$OMP CANCEL ");
2337 Walk(std::get<OmpCancelType>(x.t));
2338 Walk(std::get<std::optional<OpenMPCancelConstruct::If>>(x.t));
2339 Put("\n");
2340 EndOpenMP();
2341 }
2342 void Unparse(const OpenMPFlushConstruct &x) {
2343 BeginOpenMP();
2344 Word("!$OMP FLUSH");
2345 if ((x.v).has_value()) {
2346 Put("(");
2347 Walk(x.v);
2348 Put(")");
2349 }
2350 Put("\n");
2351 EndOpenMP();
2352 }
2353 bool Pre(const OpenMPEndLoopDirective &x) {
2354 BeginOpenMP();
2355 Word("!$OMP END ");
Hongyon Suauthai1bfb8432018-06-01 17:40:132356 return true;
2357 }
hsuauthai08b26842018-07-20 22:49:192358 void Post(const OpenMPEndLoopDirective &x) {
2359 Put("\n");
2360 EndOpenMP();
2361 }
2362 void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
2363 void Unparse(const OpenMPStandaloneConstruct &x) {
2364 BeginOpenMP();
2365 Word("!$OMP ");
2366 Walk(std::get<OmpStandaloneDirective>(x.t));
2367 Walk(std::get<OmpClauseList>(x.t));
2368 Put("\n");
2369 EndOpenMP();
2370 }
2371 void Unparse(const OpenMPBlockConstruct &x) {
2372 BeginOpenMP();
2373 Word("!$OMP ");
2374 Walk(std::get<OmpBlockDirective>(x.t));
2375 Walk(std::get<OmpClauseList>(x.t));
2376 Put("\n");
2377 EndOpenMP();
2378 Walk(std::get<Block>(x.t), "");
2379 BeginOpenMP();
2380 Word("!$OMP END ");
2381 Walk(std::get<OmpEndBlockDirective>(x.t));
2382 Put("\n");
2383 EndOpenMP();
2384 }
2385 void Unparse(const OpenMPLoopConstruct &x) {
2386 BeginOpenMP();
2387 Word("!$OMP ");
2388 Walk(std::get<OmpLoopDirective>(x.t));
2389 Walk(std::get<OmpClauseList>(x.t));
2390 Put("\n");
2391 EndOpenMP();
2392 }
peter klausler5b0e18b2019-03-21 23:29:502393 void Unparse(const BasedPointer &x) {
2394 Put('('), Walk(std::get<0>(x.t)), Put(","), Walk(std::get<1>(x.t));
peter klausler79d044e2018-03-01 00:56:102395 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")"), Put(')');
peter klausler79d044e2018-03-01 00:56:102396 }
peter klausler5b0e18b2019-03-21 23:29:502397 void Unparse(const BasedPointerStmt &x) { Walk("POINTER ", x.v, ","); }
peter klausler4e354d82018-03-30 22:23:372398 void Post(const StructureField &x) {
peter klauslerf147abd2018-07-11 00:09:072399 if (const auto *def{std::get_if<Statement<DataComponentDefStmt>>(&x.u)}) {
peter klausler4e354d82018-03-30 22:23:372400 for (const auto &decl :
2401 std::get<std::list<ComponentDecl>>(def->statement.t)) {
2402 structureComponents_.insert(std::get<Name>(decl.t).source);
2403 }
2404 }
2405 }
peter klausler8ea4a0a2018-04-06 20:13:202406 void Unparse(const StructureStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:162407 Word("STRUCTURE ");
peter klausler79d044e2018-03-01 00:56:102408 if (std::get<bool>(x.t)) { // slashes around name
2409 Put('/'), Walk(std::get<Name>(x.t)), Put('/');
2410 Walk(" ", std::get<std::list<EntityDecl>>(x.t), ", ");
2411 } else {
2412 CHECK(std::get<std::list<EntityDecl>>(x.t).empty());
2413 Walk(std::get<Name>(x.t));
2414 }
2415 Indent();
peter klausler79d044e2018-03-01 00:56:102416 }
peter klauslerb7cf5122018-03-14 22:31:162417 void Post(const Union::UnionStmt &) { Word("UNION"), Indent(); }
2418 void Post(const Union::EndUnionStmt &) { Outdent(), Word("END UNION"); }
2419 void Post(const Map::MapStmt &) { Word("MAP"), Indent(); }
2420 void Post(const Map::EndMapStmt &) { Outdent(), Word("END MAP"); }
peter klausler79d044e2018-03-01 00:56:102421 void Post(const StructureDef::EndStructureStmt &) {
peter klauslerb7cf5122018-03-14 22:31:162422 Outdent(), Word("END STRUCTURE");
peter klausler79d044e2018-03-01 00:56:102423 }
peter klausler8ea4a0a2018-04-06 20:13:202424 void Unparse(const OldParameterStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:162425 Word("PARAMETER "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:102426 }
peter klausler8ea4a0a2018-04-06 20:13:202427 void Unparse(const ArithmeticIfStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:162428 Word("IF ("), Walk(std::get<Expr>(x.t)), Put(") ");
peter klausler79d044e2018-03-01 00:56:102429 Walk(std::get<1>(x.t)), Put(", ");
2430 Walk(std::get<2>(x.t)), Put(", ");
2431 Walk(std::get<3>(x.t));
peter klausler79d044e2018-03-01 00:56:102432 }
peter klausler8ea4a0a2018-04-06 20:13:202433 void Unparse(const AssignStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:162434 Word("ASSIGN "), Walk(std::get<Label>(x.t));
2435 Word(" TO "), Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:102436 }
peter klausler8ea4a0a2018-04-06 20:13:202437 void Unparse(const AssignedGotoStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:162438 Word("GO TO "), Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:102439 Walk(", (", std::get<std::list<Label>>(x.t), ", ", ")");
peter klausler79d044e2018-03-01 00:56:102440 }
peter klausler8ea4a0a2018-04-06 20:13:202441 void Unparse(const PauseStmt &x) { Word("PAUSE"), Walk(" ", x.v); }
peter klausler79d044e2018-03-01 00:56:102442
Tim Keith9f755662018-03-23 21:31:142443#define WALK_NESTED_ENUM(CLASS, ENUM) \
peter klausler8ea4a0a2018-04-06 20:13:202444 void Unparse(const CLASS::ENUM &x) { Word(CLASS::EnumToString(x)); }
Tim Keith9f755662018-03-23 21:31:142445 WALK_NESTED_ENUM(AccessSpec, Kind) // R807
Tim Keith90373072018-09-05 23:02:412446 WALK_NESTED_ENUM(common, TypeParamAttr) // R734
Tim Keith9f755662018-03-23 21:31:142447 WALK_NESTED_ENUM(IntentSpec, Intent) // R826
2448 WALK_NESTED_ENUM(ImplicitStmt, ImplicitNoneNameSpec) // R866
2449 WALK_NESTED_ENUM(ConnectSpec::CharExpr, Kind) // R1205
2450 WALK_NESTED_ENUM(IoControlSpec::CharExpr, Kind)
2451 WALK_NESTED_ENUM(InquireSpec::CharVar, Kind)
2452 WALK_NESTED_ENUM(InquireSpec::IntVar, Kind)
2453 WALK_NESTED_ENUM(InquireSpec::LogVar, Kind)
2454 WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506
2455 WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
Hongyon Suauthai1bfb8432018-06-01 17:40:132456 WALK_NESTED_ENUM(OmpProcBindClause, Type) // OMP PROC_BIND
2457 WALK_NESTED_ENUM(OmpDefaultClause, Type) // OMP DEFAULT
2458 WALK_NESTED_ENUM(OmpScheduleModifierType, ModType) // OMP schedule-modifier
2459 WALK_NESTED_ENUM(OmpLinearModifier, Type) // OMP linear-modifier
Hongyon Suauthai1bfb8432018-06-01 17:40:132460 WALK_NESTED_ENUM(OmpDependenceType, Type) // OMP dependence-type
hsuauthai08b26842018-07-20 22:49:192461 WALK_NESTED_ENUM(OmpMapType, Type) // OMP map-type
Hongyon Suauthai1bfb8432018-06-01 17:40:132462 WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type
Hongyon Suauthai9914f222018-06-01 18:15:322463 WALK_NESTED_ENUM(
2464 OmpIfClause, DirectiveNameModifier) // OMP directive-modifier
hsuauthai08b26842018-07-20 22:49:192465 WALK_NESTED_ENUM(OmpDeclareTargetMapType, Type) // OMP DeclareTarget map-type
2466 WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
peter klausler79d044e2018-03-01 00:56:102467#undef WALK_NESTED_ENUM
2468
2469 void Done() const { CHECK(indent_ == 0); }
2470
2471private:
2472 void Put(char);
2473 void Put(const char *);
2474 void Put(const std::string &);
peter klauslerb7cf5122018-03-14 22:31:162475 void PutKeywordLetter(char);
peter klauslerb7cf5122018-03-14 22:31:162476 void Word(const char *);
Tim Keith9f755662018-03-23 21:31:142477 void Word(const std::string &);
peter klausler79d044e2018-03-01 00:56:102478 void Indent() { indent_ += indentationAmount_; }
2479 void Outdent() {
2480 CHECK(indent_ >= indentationAmount_);
2481 indent_ -= indentationAmount_;
2482 }
hsuauthai08b26842018-07-20 22:49:192483 void BeginOpenMP() { openmpDirective_ = true; }
2484 void EndOpenMP() { openmpDirective_ = false; }
peter klausler79d044e2018-03-01 00:56:102485
2486 // Call back to the traversal framework.
Tim Keith2af29bc2018-02-26 22:28:322487 template<typename T> void Walk(const T &x) {
2488 Fortran::parser::Walk(x, *this);
2489 }
2490
peter klausler79d044e2018-03-01 00:56:102491 // Traverse a std::optional<> value. Emit a prefix and/or a suffix string
2492 // only when it contains a value.
2493 template<typename A>
2494 void Walk(
2495 const char *prefix, const std::optional<A> &x, const char *suffix = "") {
2496 if (x.has_value()) {
peter klauslerb7cf5122018-03-14 22:31:162497 Word(prefix), Walk(*x), Word(suffix);
Tim Keith2af29bc2018-02-26 22:28:322498 }
2499 }
peter klausler79d044e2018-03-01 00:56:102500 template<typename A>
2501 void Walk(const std::optional<A> &x, const char *suffix = "") {
2502 return Walk("", x, suffix);
2503 }
2504
2505 // Traverse a std::list<>. Separate the elements with an optional string.
2506 // Emit a prefix and/or a suffix string only when the list is not empty.
2507 template<typename A>
2508 void Walk(const char *prefix, const std::list<A> &list,
2509 const char *comma = ", ", const char *suffix = "") {
2510 if (!list.empty()) {
2511 const char *str{prefix};
2512 for (const auto &x : list) {
peter klauslerb7cf5122018-03-14 22:31:162513 Word(str), Walk(x);
peter klausler79d044e2018-03-01 00:56:102514 str = comma;
2515 }
peter klauslerb7cf5122018-03-14 22:31:162516 Word(suffix);
peter klausler79d044e2018-03-01 00:56:102517 }
2518 }
2519 template<typename A>
2520 void Walk(const std::list<A> &list, const char *comma = ", ",
2521 const char *suffix = "") {
2522 return Walk("", list, comma, suffix);
2523 }
2524
2525 // Traverse a std::tuple<>, with an optional separator.
peter klausler424ec7b2018-03-20 17:59:072526 template<std::size_t J = 0, typename T>
peter klausler79d044e2018-03-01 00:56:102527 void WalkTupleElements(const T &tuple, const char *separator) {
2528 if constexpr (J < std::tuple_size_v<T>) {
2529 if (J > 0) {
peter klauslerb7cf5122018-03-14 22:31:162530 Word(separator);
peter klausler79d044e2018-03-01 00:56:102531 }
2532 Walk(std::get<J>(tuple));
2533 WalkTupleElements<J + 1>(tuple, separator);
2534 }
2535 }
2536 template<typename... A>
2537 void Walk(const std::tuple<A...> &tuple, const char *separator = "") {
2538 WalkTupleElements(tuple, separator);
2539 }
2540
peter klausler41d9cfd2018-04-03 17:29:042541 void EndSubprogram(const char *kind, const std::optional<Name> &name) {
2542 Outdent(), Word("END "), Word(kind), Walk(" ", name);
2543 structureComponents_.clear();
2544 }
peter klausler4e354d82018-03-30 22:23:372545
peter klausler79d044e2018-03-01 00:56:102546 std::ostream &out_;
2547 int indent_{0};
2548 const int indentationAmount_{1};
2549 int column_{1};
2550 const int maxColumns_{80};
peter klausler4e354d82018-03-30 22:23:372551 std::set<CharBlock> structureComponents_;
peter klausler79d044e2018-03-01 00:56:102552 Encoding encoding_{Encoding::UTF8};
peter klauslerb7cf5122018-03-14 22:31:162553 bool capitalizeKeywords_{true};
hsuauthai08b26842018-07-20 22:49:192554 bool openmpDirective_{false};
peter klausler888786b2018-07-19 22:35:552555 bool backslashEscapes_{false};
Tim Keith89840b52018-06-26 22:01:422556 preStatementType *preStatement_{nullptr};
Tim Keith2af29bc2018-02-26 22:28:322557};
2558
peter klausler79d044e2018-03-01 00:56:102559void UnparseVisitor::Put(char ch) {
hsuauthai08b26842018-07-20 22:49:192560 int sav = indent_;
2561 if (openmpDirective_) {
2562 indent_ = 0;
2563 }
peter klausler79d044e2018-03-01 00:56:102564 if (column_ <= 1) {
2565 if (ch == '\n') {
2566 return;
2567 }
2568 for (int j{0}; j < indent_; ++j) {
2569 out_ << ' ';
2570 }
2571 column_ = indent_ + 2;
2572 } else if (ch == '\n') {
2573 column_ = 1;
2574 } else if (++column_ >= maxColumns_) {
2575 out_ << "&\n";
2576 for (int j{0}; j < indent_; ++j) {
2577 out_ << ' ';
2578 }
hsuauthai08b26842018-07-20 22:49:192579 if (openmpDirective_) {
2580 out_ << "!$OMP&";
2581 column_ = 8;
2582 } else {
2583 out_ << '&';
2584 column_ = indent_ + 3;
2585 }
peter klausler79d044e2018-03-01 00:56:102586 }
2587 out_ << ch;
hsuauthai08b26842018-07-20 22:49:192588 if (openmpDirective_) {
2589 indent_ = sav;
2590 }
Tim Keith2af29bc2018-02-26 22:28:322591}
2592
peter klausler79d044e2018-03-01 00:56:102593void UnparseVisitor::Put(const char *str) {
2594 for (; *str != '\0'; ++str) {
2595 Put(*str);
2596 }
2597}
2598
2599void UnparseVisitor::Put(const std::string &str) {
2600 for (char ch : str) {
2601 Put(ch);
2602 }
2603}
2604
peter klauslerb7cf5122018-03-14 22:31:162605void UnparseVisitor::PutKeywordLetter(char ch) {
2606 if (capitalizeKeywords_) {
peter klausler79d044e2018-03-01 00:56:102607 Put(ToUpperCaseLetter(ch));
peter klauslerb7cf5122018-03-14 22:31:162608 } else {
2609 Put(ToLowerCaseLetter(ch));
peter klausler79d044e2018-03-01 00:56:102610 }
2611}
2612
peter klauslerb7cf5122018-03-14 22:31:162613void UnparseVisitor::Word(const char *str) {
2614 for (; *str != '\0'; ++str) {
2615 PutKeywordLetter(*str);
2616 }
2617}
2618
peter klausler75b29332018-03-23 22:14:522619void UnparseVisitor::Word(const std::string &str) { Word(str.c_str()); }
Tim Keith9f755662018-03-23 21:31:142620
peter klauslerb7cf5122018-03-14 22:31:162621void Unparse(std::ostream &out, const Program &program, Encoding encoding,
peter klausler888786b2018-07-19 22:35:552622 bool capitalizeKeywords, bool backslashEscapes,
2623 preStatementType *preStatement) {
2624 UnparseVisitor visitor{
2625 out, 1, encoding, capitalizeKeywords, backslashEscapes, preStatement};
peter klausler79d044e2018-03-01 00:56:102626 Walk(program, visitor);
2627 visitor.Done();
2628}
Jean Perierf7e7cb32018-10-25 12:55:232629}