From b60fd092f52757a7b2cc6f22cdd75f3dba361163 Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Tue, 12 Feb 2019 16:13:58 -0800 Subject: [PATCH] [flang] Simplify CommonStmt in parse tree The grammar requires parsing the first common block in a common stmt differently from the others: the '//' is optional for the blank common. But once it's parsed, it is easier to work with if each is represented as a `parser::CommonStmt::Block`. This is achieved by using the same constructor for `CommonStmt` but then including the first block in the list of blocks. Original-commit: flang-compiler/f18@dd46afd6b5607ec61ea9b2e97efa16deda31441b Reviewed-on: https://github.com/flang-compiler/f18/pull/284 --- flang/lib/parser/parse-tree-visitor.h | 12 ++++++++++++ flang/lib/parser/parse-tree.cc | 7 +++++++ flang/lib/parser/parse-tree.h | 8 ++++---- flang/lib/parser/unparse.cc | 4 +--- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/flang/lib/parser/parse-tree-visitor.h b/flang/lib/parser/parse-tree-visitor.h index fc7a918..ae1181f 100644 --- a/flang/lib/parser/parse-tree-visitor.h +++ b/flang/lib/parser/parse-tree-visitor.h @@ -498,6 +498,18 @@ template void Walk(LoopBounds &x, M &mutator) { mutator.Post(x); } } +template void Walk(const CommonStmt &x, V &visitor) { + if (visitor.Pre(x)) { + Walk(x.blocks, visitor); + visitor.Post(x); + } +} +template void Walk(CommonStmt &x, M &mutator) { + if (mutator.Pre(x)) { + Walk(x.blocks, mutator); + mutator.Post(x); + } +} template void Walk(const Expr &x, V &visitor) { if (visitor.Pre(x)) { Walk(x.source, visitor); diff --git a/flang/lib/parser/parse-tree.cc b/flang/lib/parser/parse-tree.cc index ec8c393..efa0ece 100644 --- a/flang/lib/parser/parse-tree.cc +++ b/flang/lib/parser/parse-tree.cc @@ -27,6 +27,13 @@ ImportStmt::ImportStmt(common::ImportKind &&k, std::list &&n) kind == common::ImportKind::Only || names.empty()); } +// R873 +CommonStmt::CommonStmt(std::optional &&name, + std::list &&objects, std::list &&others) { + blocks.emplace_front(std::move(name), std::move(objects)); + blocks.splice(blocks.end(), std::move(others)); +} + // R901 designator bool Designator::EndsInBareName() const { return std::visit( diff --git a/flang/lib/parser/parse-tree.h b/flang/lib/parser/parse-tree.h index e3e409b..00af09d 100644 --- a/flang/lib/parser/parse-tree.h +++ b/flang/lib/parser/parse-tree.h @@ -1535,10 +1535,10 @@ struct CommonStmt { TUPLE_CLASS_BOILERPLATE(Block); std::tuple, std::list> t; }; - TUPLE_CLASS_BOILERPLATE(CommonStmt); - std::tuple, std::list, - std::list> - t; + BOILERPLATE(CommonStmt); + CommonStmt(std::optional &&, std::list &&, + std::list &&); + std::list blocks; }; // R872 equivalence-object -> variable-name | array-element | substring diff --git a/flang/lib/parser/unparse.cc b/flang/lib/parser/unparse.cc index 2ffd9a5..891f5c3 100644 --- a/flang/lib/parser/unparse.cc +++ b/flang/lib/parser/unparse.cc @@ -703,9 +703,7 @@ public: } void Unparse(const CommonStmt &x) { // R873 Word("COMMON "); - Walk("/", std::get>(x.t), "/"); - Walk(std::get>(x.t), ", "); - Walk(", ", std::get>(x.t), ", "); + Walk(x.blocks); } void Unparse(const CommonBlockObject &x) { // R874 Walk(std::get(x.t)); -- 2.7.4