forked from OSchip/llvm-project
[flang] Rewrite read-stmt/write-stmt parse trees for misparsed namelist group names
Original-commit: flang-compiler/f18@e0f1b1c469 Reviewed-on: https://github.com/flang-compiler/f18/pull/394 Tree-same-pre-rewrite: false
This commit is contained in:
parent
798e5544b0
commit
0e55f2463b
|
@ -2613,7 +2613,7 @@ struct ReadStmt {
|
|||
std::optional<IoUnit> iounit; // if first in controls without UNIT=
|
||||
std::optional<Format> format; // if second in controls without FMT=, or
|
||||
// no (io-control-spec-list); might be
|
||||
// an untagged namelist group name (TODO)
|
||||
// an untagged namelist group name, too
|
||||
std::list<IoControlSpec> controls;
|
||||
std::list<InputItem> items;
|
||||
};
|
||||
|
@ -2633,7 +2633,7 @@ struct WriteStmt {
|
|||
items(std::move(its)) {}
|
||||
std::optional<IoUnit> iounit; // if first in controls without UNIT=
|
||||
std::optional<Format> format; // if second in controls without FMT=;
|
||||
// might be an untagged namelist group (TODO)
|
||||
// might be an untagged namelist group, too
|
||||
std::list<IoControlSpec> controls;
|
||||
std::list<OutputItem> items;
|
||||
};
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Fortran::semantics {
|
|||
using namespace parser::literals;
|
||||
|
||||
/// Convert mis-identified statement functions to array element assignments.
|
||||
/// Convert mis-identified format expressions to namelist group names.
|
||||
class RewriteMutator {
|
||||
public:
|
||||
RewriteMutator(parser::Messages &messages) : messages_{messages} {}
|
||||
|
@ -37,6 +38,8 @@ public:
|
|||
void Post(parser::Name &);
|
||||
void Post(parser::SpecificationPart &);
|
||||
bool Pre(parser::ExecutionPart &);
|
||||
void Post(parser::ReadStmt &);
|
||||
void Post(parser::WriteStmt &);
|
||||
|
||||
// Name resolution yet implemented:
|
||||
bool Pre(parser::EquivalenceStmt &) { return false; }
|
||||
|
@ -101,6 +104,41 @@ bool RewriteMutator::Pre(parser::ExecutionPart &x) {
|
|||
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
|
||||
// name had appeared with NML=.
|
||||
template<typename READ_OR_WRITE>
|
||||
void FixMisparsedUntaggedNamelistName(READ_OR_WRITE &x) {
|
||||
if (x.format.has_value()) {
|
||||
if (auto *charExpr{
|
||||
std::get_if<parser::DefaultCharExpr>(&x.format.value().u)}) {
|
||||
parser::Expr &expr{charExpr->thing.value()};
|
||||
if (auto *designator{
|
||||
std::get_if<common::Indirection<parser::Designator>>(&expr.u)}) {
|
||||
parser::Name *name{
|
||||
std::get_if<parser::ObjectName>(&designator->value().u)};
|
||||
if (auto *dr{std::get_if<parser::DataRef>(&designator->value().u)}) {
|
||||
name = std::get_if<parser::Name>(&dr->u);
|
||||
}
|
||||
if (name != nullptr && name->symbol != nullptr &&
|
||||
name->symbol->has<NamelistDetails>()) {
|
||||
x.controls.emplace_front(parser::IoControlSpec{std::move(*name)});
|
||||
x.format.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RewriteMutator::Post(parser::ReadStmt &x) {
|
||||
FixMisparsedUntaggedNamelistName(x);
|
||||
}
|
||||
|
||||
void RewriteMutator::Post(parser::WriteStmt &x) {
|
||||
FixMisparsedUntaggedNamelistName(x);
|
||||
}
|
||||
|
||||
bool RewriteParseTree(SemanticsContext &context, parser::Program &program) {
|
||||
RewriteMutator mutator{context.messages()};
|
||||
parser::Walk(program, mutator);
|
||||
|
|
Loading…
Reference in New Issue