-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Support "PRINT namelistname" #112024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesNearly every Fortran compiler supports "PRINT namelistname" as a synonym for "WRITE (*, NML=namelistname)". Implement this extension via parse tree rewriting. Full diff: https://github.com/llvm/llvm-project/pull/112024.diff 4 Files Affected:
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 3ffd2949e45bf4..f85a3eb39ed191 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -389,6 +389,8 @@ end
* A local data object may appear in a specification expression, even
when it is not a dummy argument or in COMMON, so long as it is
has the SAVE attribute and was initialized.
+* `PRINT namelistname` is accepted and interpreted as
+ `WRITE(*,NML=namelistname)`, a near-universal extension.
### Extensions supported when enabled by options
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 3942a792628645..648f5b0798fa48 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -53,7 +53,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
NonBindCInteroperability, CudaManaged, CudaUnified,
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
- SavedLocalInSpecExpr)
+ SavedLocalInSpecExpr, PrintNamelist)
// Portability and suspicious usage warnings
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
diff --git a/flang/lib/Semantics/rewrite-parse-tree.cpp b/flang/lib/Semantics/rewrite-parse-tree.cpp
index b4fb72ce213017..c90ae66342840e 100644
--- a/flang/lib/Semantics/rewrite-parse-tree.cpp
+++ b/flang/lib/Semantics/rewrite-parse-tree.cpp
@@ -32,7 +32,7 @@ using namespace parser::literals;
class RewriteMutator {
public:
RewriteMutator(SemanticsContext &context)
- : errorOnUnresolvedName_{!context.AnyFatalError()},
+ : context_{context}, errorOnUnresolvedName_{!context.AnyFatalError()},
messages_{context.messages()} {}
// Default action for a parse tree node is to visit children.
@@ -42,6 +42,7 @@ class RewriteMutator {
void Post(parser::Name &);
void Post(parser::SpecificationPart &);
bool Pre(parser::ExecutionPart &);
+ bool Pre(parser::ActionStmt &);
void Post(parser::ReadStmt &);
void Post(parser::WriteStmt &);
@@ -66,6 +67,7 @@ class RewriteMutator {
private:
using stmtFuncType =
parser::Statement<common::Indirection<parser::StmtFunctionStmt>>;
+ SemanticsContext &context_;
bool errorOnUnresolvedName_{true};
parser::Messages &messages_;
std::list<stmtFuncType> stmtFuncsToConvert_;
@@ -130,6 +132,29 @@ bool RewriteMutator::Pre(parser::ExecutionPart &x) {
return true;
}
+// Rewrite PRINT NML -> WRITE(*,NML=NML)
+bool RewriteMutator::Pre(parser::ActionStmt &x) {
+ if (auto *print{std::get_if<common::Indirection<parser::PrintStmt>>(&x.u)};
+ print &&
+ std::get<std::list<parser::OutputItem>>(print->value().t).empty()) {
+ auto &format{std::get<parser::Format>(print->value().t)};
+ if (std::holds_alternative<parser::Expr>(format.u)) {
+ if (auto *name{parser::Unwrap<parser::Name>(format)}; name &&
+ name->symbol && name->symbol->GetUltimate().has<NamelistDetails>() &&
+ context_.IsEnabled(common::LanguageFeature::PrintNamelist)) {
+ context_.Warn(common::LanguageFeature::PrintNamelist, name->source,
+ "nonstandard: namelist in PRINT statement"_port_en_US);
+ std::list<parser::IoControlSpec> controls;
+ controls.emplace_back(std::move(*name));
+ x.u = common::Indirection<parser::WriteStmt>::Make(
+ parser::IoUnit{parser::Star{}}, std::optional<parser::Format>{},
+ std::move(controls), std::list<parser::OutputItem>{});
+ }
+ }
+ }
+ return true;
+}
+
// When a namelist group name appears (without NML=) in a READ or WRITE
// statement in such a way that it can be misparsed as a format expression,
// rewrite the I/O statement's parse tree node as if the namelist group
diff --git a/flang/test/Semantics/rewrite02.f90 b/flang/test/Semantics/rewrite02.f90
new file mode 100644
index 00000000000000..2393498e65d291
--- /dev/null
+++ b/flang/test/Semantics/rewrite02.f90
@@ -0,0 +1,8 @@
+!RUN: %flang_fc1 -fdebug-unparse -pedantic %s 2>&1 | FileCheck %s
+!Test rewrite of "PRINT namelistname" into "WRITE(*,NML=namelistname)"
+!CHECK: nonstandard: namelist in PRINT statement
+namelist /nml/x
+x = 123.
+!CHECK: WRITE (*, NML=nml)
+print nml
+end
|
Nearly every Fortran compiler supports "PRINT namelistname" as a synonym for "WRITE (*, NML=namelistname)". Implement this extension via parse tree rewriting. Fixes llvm#111738.
An upcoming PR to flang (llvm/llvm-project#112024) will soon allow two gfortran tests to compile and run successfully.
llvm-test-suite PR llvm/llvm-test-suite#171 will need to be merged shortly after this one is merged into llvm-project. |
An upcoming PR to flang (llvm/llvm-project#112024) will soon allow two gfortran tests to compile and run successfully, which will come as a fatal surprise because they're marked "xfail".
An upcoming PR to flang (llvm/llvm-project#112024) will soon allow two gfortran tests to compile and run successfully, which will come as a fatal surprise because they're marked "xfail".
Nearly every Fortran compiler supports "PRINT namelistname" as a synonym for "WRITE (*, NML=namelistname)". Implement this extension via parse tree rewriting. Fixes llvm#111738.
Nearly every Fortran compiler supports "PRINT namelistname" as a synonym for "WRITE (*, NML=namelistname)". Implement this extension via parse tree rewriting.
Fixes #111738.