[flang] Incorporate suggestions from code review.
authorpeter klausler <pklausler@nvidia.com>
Fri, 22 Jun 2018 23:44:23 +0000 (16:44 -0700)
committerpeter klausler <pklausler@nvidia.com>
Fri, 22 Jun 2018 23:44:23 +0000 (16:44 -0700)
Original-commit: flang-compiler/f18@c66bd9ab15846afcaed129764b8c958f277e071f
Reviewed-on: https://github.com/flang-compiler/f18/pull/111

flang/documentation/ControlFlowGraph.md
flang/documentation/parsing.md
flang/lib/evaluate/expression.cc
flang/lib/evaluate/expression.h

index f3f695a..b551ca1 100644 (file)
@@ -74,15 +74,15 @@ resolved function references, constant literals, and
 data designators.
 
 Expression nodes are represented in the compiler in a type-safe manner.
-There is a general `Expression` class template that is parameterized
-over type classification (e.g., `INTEGER`, `REAL`, &c.) and, for intrinsic
-types, kind type parameter values.
-The `Expression` class template is specialized for each type classification
-with a representation the admits only the operations that are valid
-for that type.
-Operands are non-nullable storage-owning indirections to other instances
+There is a distinct class or class template for every category of
+intrinsic type, templatized over its supported kind type parameter values.
+
+Operands are storage-owning indirections to other instances
 of `Expression`, instances of constant values, and to representations
 of data and function references.
+These indirections are not nullable apart from the situation in which
+the operands of an expression are being removed for use elsewhere before
+the expression is destructed.
 
 The ranks and the extents of the shapes of the results of expressions
 are explicit for constant arrays and recoverable by analysis otherwise.
index 75594e6..716a1e8 100644 (file)
@@ -75,7 +75,7 @@ source; the parser proper does not have a tokenizer.  The prescanner
 builds these token sequences out of source lines and supplies them
 to the preprocessor, which interprets directives and expands macro
 invocations.  The token sequences returned by the preprocessor are then
-marshaled to constitue the cooked character stream that is the output of
+marshaled to constitute the cooked character stream that is the output of
 the prescanner.
 
 The preprocessor and prescanner can both instantiate new temporary
@@ -122,7 +122,7 @@ Messages
 --------
 Message texts, and snprintf-like formatting strings for constructing
 messages, are instantiated in the various components of the parser with
-C++ user defined character literals tagged with `err_en_US` and `_en_US`
+C++ user defined character literals tagged with `_err_en_US` and `_en_US`
 (signifying fatality and language, with the default being the dialect of
 English used in the United States) so that they may be easily identified
 for localization.  As described above, messages are associated with
index 4b1a297..d50e8ff 100644 (file)
@@ -48,26 +48,28 @@ std::ostream &AnyIntegerOrRealExpr::Dump(std::ostream &o) const {
   return o;
 }
 
+template<typename A>
+std::ostream &Unary<A>::Dump(std::ostream &o, const char *opr) const {
+  return x->Dump(o << opr) << ')';
+}
+
+template<typename A, typename B>
+std::ostream &Binary<A, B>::Dump(std::ostream &o, const char *opr) const {
+  return y->Dump(x->Dump(o << '(') << opr) << ')';
+}
+
 template<int KIND>
 std::ostream &IntegerExpr<KIND>::Dump(std::ostream &o) const {
   std::visit(
       common::visitors{[&](const Constant &n) { o << n.SignedDecimal(); },
           [&](const Convert &c) { c.x->Dump(o); },
-          [&](const Parentheses &p) { p.x->Dump(o << '(') << ')'; },
-          [&](const Negate &n) { n.x->Dump(o << "(-") << ')'; },
-          [&](const Add &a) { a.y->Dump(a.x->Dump(o << '(') << '+') << ')'; },
-          [&](const Subtract &s) {
-            s.y->Dump(s.x->Dump(o << '(') << '-') << ')';
-          },
-          [&](const Multiply &m) {
-            m.y->Dump(m.x->Dump(o << '(') << '*') << ')';
-          },
-          [&](const Divide &d) {
-            d.y->Dump(d.x->Dump(o << '(') << '/') << ')';
-          },
-          [&](const Power &p) {
-            p.y->Dump(p.x->Dump(o << '(') << "**") << ')';
-          }},
+          [&](const Parentheses &p) { p.Dump(o, "("); },
+          [&](const Negate &n) { n.Dump(o, "(-"); },
+          [&](const Add &a) { a.Dump(o, "+"); },
+          [&](const Subtract &s) { s.Dump(o, "-"); },
+          [&](const Multiply &m) { m.Dump(o, "*"); },
+          [&](const Divide &d) { d.Dump(o, "/"); },
+          [&](const Power &p) { p.Dump(o, "**"); }},
       u);
   return o;
 }
@@ -132,26 +134,16 @@ template<int KIND> std::ostream &RealExpr<KIND>::Dump(std::ostream &o) const {
   std::visit(
       common::visitors{[&](const Constant &n) { o << n.DumpHexadecimal(); },
           [&](const Convert &c) { c.x->Dump(o); },
-          [&](const Parentheses &p) { p.x->Dump(o << '(') << ')'; },
-          [&](const Negate &n) { n.x->Dump(o << "(-") << ')'; },
-          [&](const Add &a) { a.y->Dump(a.x->Dump(o << '(') << '+') << ')'; },
-          [&](const Subtract &s) {
-            s.y->Dump(s.x->Dump(o << '(') << '-') << ')';
-          },
-          [&](const Multiply &m) {
-            m.y->Dump(m.x->Dump(o << '(') << '*') << ')';
-          },
-          [&](const Divide &d) {
-            d.y->Dump(d.x->Dump(o << '(') << '/') << ')';
-          },
-          [&](const Power &p) {
-            p.y->Dump(p.x->Dump(o << '(') << "**") << ')';
-          },
-          [&](const IntPower &p) {
-            p.y->Dump(p.x->Dump(o << '(') << "**") << ')';
-          },
-          [&](const RealPart &z) { z.x->Dump(o << "REAL(") << ')'; },
-          [&](const AIMAG &z) { z.x->Dump(o << "AIMAG(") << ')'; }},
+          [&](const Parentheses &p) { p.Dump(o, "("); },
+          [&](const Negate &n) { n.Dump(o, "(-"); },
+          [&](const Add &a) { a.Dump(o, "+"); },
+          [&](const Subtract &s) { s.Dump(o, "-"); },
+          [&](const Multiply &m) { m.Dump(o, "*"); },
+          [&](const Divide &d) { d.Dump(o, "/"); },
+          [&](const Power &p) { p.Dump(o, "**"); },
+          [&](const IntPower &p) { p.Dump(o, "**"); },
+          [&](const RealPart &z) { z.Dump(o, "REAL("); },
+          [&](const AIMAG &p) { p.Dump(o, "AIMAG("); }},
       u);
   return o;
 }
@@ -160,27 +152,15 @@ template<int KIND>
 std::ostream &ComplexExpr<KIND>::Dump(std::ostream &o) const {
   std::visit(
       common::visitors{[&](const Constant &n) { o << n.DumpHexadecimal(); },
-          [&](const Parentheses &p) { p.x->Dump(o << '(') << ')'; },
-          [&](const Negate &n) { n.x->Dump(o << "(-") << ')'; },
-          [&](const Add &a) { a.y->Dump(a.x->Dump(o << '(') << '+') << ')'; },
-          [&](const Subtract &s) {
-            s.y->Dump(s.x->Dump(o << '(') << '-') << ')';
-          },
-          [&](const Multiply &m) {
-            m.y->Dump(m.x->Dump(o << '(') << '*') << ')';
-          },
-          [&](const Divide &d) {
-            d.y->Dump(d.x->Dump(o << '(') << '/') << ')';
-          },
-          [&](const Power &p) {
-            p.y->Dump(p.x->Dump(o << '(') << "**") << ')';
-          },
-          [&](const IntPower &p) {
-            p.y->Dump(p.x->Dump(o << '(') << "**") << ')';
-          },
-          [&](const CMPLX &c) {
-            c.y->Dump(c.x->Dump(o << '(') << ',') << ')';
-          }},
+          [&](const Parentheses &p) { p.Dump(o, "("); },
+          [&](const Negate &n) { n.Dump(o, "(-"); },
+          [&](const Add &a) { a.Dump(o, "+"); },
+          [&](const Subtract &s) { s.Dump(o, "-"); },
+          [&](const Multiply &m) { m.Dump(o, "*"); },
+          [&](const Divide &d) { d.Dump(o, "/"); },
+          [&](const Power &p) { p.Dump(o, "**"); },
+          [&](const IntPower &p) { p.Dump(o, "**"); },
+          [&](const CMPLX &c) { c.Dump(o, ","); }},
       u);
   return o;
 }
@@ -205,28 +185,20 @@ std::ostream &CharacterExpr<KIND>::Dump(std::ostream &o) const {
 }
 
 template<typename T> std::ostream &Comparison<T>::Dump(std::ostream &o) const {
-  std::visit(
-      common::visitors{
-          [&](const LT &c) { c.y->Dump(c.x->Dump(o << '(') << ".LT.") << ')'; },
-          [&](const LE &c) { c.y->Dump(c.x->Dump(o << '(') << ".LE.") << ')'; },
-          [&](const EQ &c) { c.y->Dump(c.x->Dump(o << '(') << ".EQ.") << ')'; },
-          [&](const NE &c) { c.y->Dump(c.x->Dump(o << '(') << ".NE.") << ')'; },
-          [&](const GE &c) { c.y->Dump(c.x->Dump(o << '(') << ".GE.") << ')'; },
-          [&](const GT &c) {
-            c.y->Dump(c.x->Dump(o << '(') << ".GT.") << ')';
-          }},
+  std::visit(common::visitors{[&](const LT &c) { c.Dump(o, ".LT."); },
+                 [&](const LE &c) { c.Dump(o, ".LE."); },
+                 [&](const EQ &c) { c.Dump(o, ".EQ."); },
+                 [&](const NE &c) { c.Dump(o, ".NE."); },
+                 [&](const GE &c) { c.Dump(o, ".GE."); },
+                 [&](const GT &c) { c.Dump(o, ".GT."); }},
       u);
   return o;
 }
 
 template<int KIND>
 std::ostream &Comparison<ComplexExpr<KIND>>::Dump(std::ostream &o) const {
-  std::visit(common::visitors{[&](const EQ &c) {
-                                c.y->Dump(c.x->Dump(o << '(') << ".EQ.") << ')';
-                              },
-                 [&](const NE &c) {
-                   c.y->Dump(c.x->Dump(o << '(') << ".NE.") << ')';
-                 }},
+  std::visit(common::visitors{[&](const EQ &c) { c.Dump(o, ".EQ."); },
+                 [&](const NE &c) { c.Dump(o, ".NE."); }},
       u);
   return o;
 }
@@ -254,17 +226,11 @@ std::ostream &CharacterComparison::Dump(std::ostream &o) const {
 std::ostream &LogicalExpr::Dump(std::ostream &o) const {
   std::visit(
       common::visitors{[&](const bool &tf) { o << (tf ? ".T." : ".F."); },
-          [&](const Not &n) { n.x->Dump(o << "(.NOT.") << ')'; },
-          [&](const And &a) {
-            a.y->Dump(a.x->Dump(o << '(') << ".AND.") << ')';
-          },
-          [&](const Or &a) { a.y->Dump(a.x->Dump(o << '(') << ".OR.") << ')'; },
-          [&](const Eqv &a) {
-            a.y->Dump(a.x->Dump(o << '(') << ".EQV.") << ')';
-          },
-          [&](const Neqv &a) {
-            a.y->Dump(a.x->Dump(o << '(') << ".NEQV.") << ')';
-          },
+          [&](const Not &n) { n.Dump(o, "(.NOT."); },
+          [&](const And &a) { a.Dump(o, ".AND."); },
+          [&](const Or &a) { a.Dump(o, ".OR."); },
+          [&](const Eqv &a) { a.Dump(o, ".EQV."); },
+          [&](const Neqv &a) { a.Dump(o, ".NEQV."); },
           [&](const auto &comparison) { comparison.Dump(o); }},
       u);
   return o;
index f53d5a4..5550e20 100644 (file)
@@ -59,6 +59,7 @@ template<typename A> struct Unary {
   }
   Unary &operator=(Unary &&) = default;
   A *Mutable() const { return const_cast<A *>(x.get()); }
+  std::ostream &Dump(std::ostream &, const char *opr) const;
   std::unique_ptr<const A> x;
 };
 
@@ -81,6 +82,7 @@ template<typename A, typename B> struct Binary {
   Binary &operator=(Binary &&) = default;
   A *MutableX() const { return const_cast<A *>(x.get()); }
   B *MutableY() const { return const_cast<B *>(y.get()); }
+  std::ostream &Dump(std::ostream &, const char *opr) const;
   std::unique_ptr<const A> x;
   std::unique_ptr<const B> y;
 };