From 4e354d85ae9f758cbb047ebc4c0275441f4471f7 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Fri, 30 Mar 2018 15:23:37 -0700 Subject: [PATCH] [flang] Debugging, and resolve another TODO in unparse.cc. Original-commit: flang-compiler/f18@edeb283cd5bd730e7284e3d894c1e1ffa8d1c313 Reviewed-on: https://github.com/flang-compiler/f18/pull/37 Tree-same-pre-rewrite: false --- flang/lib/parser/grammar.h | 17 ++++----------- flang/lib/parser/unparse.cc | 41 +++++++++++++++++++++++++++-------- flang/lib/parser/user-state.h | 12 +++++----- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index 84f562f4e771..c0538482ad7b 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -1651,16 +1651,8 @@ constexpr auto percentOrDot = "%"_tok || // legacy VAX extension for RECORD field access extension("."_tok / lookAhead(structureComponentName)); -// TODO - why is this not a TYPE_PARSER? -template<> -std::optional Parser::Parse(ParseState *state) { - static constexpr auto partRefs = - nonemptySeparated(Parser{}, percentOrDot); - if (auto parts = partRefs.Parse(state)) { - return {DataReference(std::move(*parts))}; - } - return {}; -} +TYPE_PARSER(construct{}( + nonemptySeparated(Parser{}, percentOrDot))) // R912 part-ref -> part-name [( section-subscript-list )] [image-selector] TYPE_PARSER(construct{}(name, @@ -3386,7 +3378,7 @@ TYPE_PARSER(construct{}("MODULE PROCEDURE"_sptok >> // READ ( FORMATTED ) | READ ( UNFORMATTED ) | // WRITE ( FORMATTED ) | WRITE ( UNFORMATTED ) TYPE_PARSER(construct{}( - "OPERATOR" >> parenthesized(definedOperator)) || + "OPERATOR" >> parenthesized(Parser{})) || construct{}( "ASSIGNMENT ( = )" >> construct{}) || construct{}( @@ -3663,8 +3655,7 @@ constexpr struct StructureComponents { } } structureComponents; -TYPE_PARSER( - construct{}(statement(structureComponents)) || +TYPE_PARSER(construct{}(statement(structureComponents)) || construct{}(indirect(Parser{})) || construct{}(indirect(Parser{}))) diff --git a/flang/lib/parser/unparse.cc b/flang/lib/parser/unparse.cc index 2243d2e49c3f..8859585c250a 100644 --- a/flang/lib/parser/unparse.cc +++ b/flang/lib/parser/unparse.cc @@ -10,6 +10,7 @@ #include #include #include +#include namespace Fortran { namespace parser { @@ -804,7 +805,14 @@ public: return false; } bool Pre(const StructureComponent &x) { // R913 - Walk(x.base), Put(percentOrDot_), Walk(x.component); + Walk(x.base); + if (structureComponents_.find(x.component.source) != + structureComponents_.end()) { + Put('.'); + } else { + Put('%'); + } + Walk(x.component); return false; } bool Pre(const ArrayElement &x) { // R917 @@ -1007,8 +1015,7 @@ public: return false; } bool Pre(const ProcComponentRef &x) { // R1039 - Walk(std::get>(x.t)), Put(percentOrDot_); - Walk(std::get(x.t)); + Walk(std::get>(x.t)), Put('%'), Walk(std::get(x.t)); return false; } bool Pre(const WhereStmt &x) { // R1041, R1045, R1046 @@ -1710,7 +1717,8 @@ public: return true; } bool Pre(const EndProgramStmt &x) { // R1403 - Outdent(), Word("END PROGRAM"), Walk(" ", x.v); + Word("END PROGRAM"), Walk(" ", x.v); + EndSubprogram(); return false; } bool Pre(const ModuleStmt &) { // R1405 @@ -1889,7 +1897,8 @@ public: return false; } bool Pre(const EndFunctionStmt &x) { // R1533 - Outdent(), Word("END FUNCTION"), Walk(" ", x.v); + Word("END FUNCTION"), Walk(" ", x.v); + EndSubprogram(); return false; } bool Pre(const SubroutineStmt &x) { // R1535 @@ -1907,7 +1916,8 @@ public: return false; } bool Pre(const EndSubroutineStmt &x) { // R1537 - Outdent(), Word("END SUBROUTINE"), Walk(" ", x.v); + Word("END SUBROUTINE"), Walk(" ", x.v); + EndSubprogram(); return false; } bool Pre(const MpSubprogramStmt &) { // R1539 @@ -1915,7 +1925,8 @@ public: return true; } bool Pre(const EndMpSubprogramStmt &x) { // R1540 - Outdent(), Word("END PROCEDURE"), Walk(" ", x.v); + Word("END PROCEDURE"), Walk(" ", x.v); + EndSubprogram(); return false; } bool Pre(const EntryStmt &x) { // R1541 @@ -1971,6 +1982,14 @@ public: Walk("(", std::get>(x.t), ")"), Put(')'); return false; } + void Post(const StructureField &x) { + if (const auto *def = std::get_if>(&x.u)) { + for (const auto &decl : + std::get>(def->statement.t)) { + structureComponents_.insert(std::get(decl.t).source); + } + } + } bool Pre(const StructureStmt &x) { Word("STRUCTURE "); if (std::get(x.t)) { // slashes around name @@ -1981,7 +2000,6 @@ public: Walk(std::get(x.t)); } Indent(); - percentOrDot_ = '.'; // TODO: this is so lame return false; } void Post(const Union::UnionStmt &) { Word("UNION"), Indent(); } @@ -2106,12 +2124,17 @@ private: WalkTupleElements(tuple, separator); } + void EndSubprogram() { + Outdent(); + structureComponents_.clear(); + } + std::ostream &out_; int indent_{0}; const int indentationAmount_{1}; int column_{1}; const int maxColumns_{80}; - char percentOrDot_{'%'}; + std::set structureComponents_; Encoding encoding_{Encoding::UTF8}; bool capitalizeKeywords_{true}; }; diff --git a/flang/lib/parser/user-state.h b/flang/lib/parser/user-state.h index 50e37cd9e459..e6565f3c377d 100644 --- a/flang/lib/parser/user-state.h +++ b/flang/lib/parser/user-state.h @@ -16,6 +16,12 @@ namespace parser { class UserState { public: + void NewSubprogram() { + doLabels_.clear(); + nonlabelDoConstructNestingDepth_ = 0; + structureComponents_.clear(); + } + using Label = std::uint64_t; bool IsDoLabel(Label label) const { return doLabels_.find(label) != doLabels_.end(); @@ -24,11 +30,6 @@ public: return nonlabelDoConstructNestingDepth_ > 0; } void NewDoLabel(Label label) { doLabels_.insert(label); } - void NewSubprogram() { - doLabels_.clear(); - nonlabelDoConstructNestingDepth_ = 0; - structureComponents_.clear(); - } void EnterNonlabelDoConstruct() { ++nonlabelDoConstructNestingDepth_; } void LeaveDoConstruct() { if (nonlabelDoConstructNestingDepth_ > 0) { @@ -46,7 +47,6 @@ public: private: std::unordered_set