[flang] start refactoring of Constant and Fold
authorpeter klausler <pklausler@nvidia.com>
Mon, 22 Oct 2018 22:20:42 +0000 (15:20 -0700)
committerpeter klausler <pklausler@nvidia.com>
Fri, 26 Oct 2018 22:19:07 +0000 (15:19 -0700)
Original-commit: flang-compiler/f18@53f7174c3dddd743146e1cff9ffcde0db4c89b6b
Reviewed-on: https://github.com/flang-compiler/f18/pull/219
Tree-same-pre-rewrite: false

flang/lib/evaluate/expression.h
flang/lib/evaluate/tools.h
flang/lib/evaluate/type.h

index 9f7e621..c592004 100644 (file)
@@ -669,46 +669,6 @@ struct GenericExprWrapper {
   Expr<SomeType> v;
 };
 
-// When an Expr holds something that is a Variable (i.e., a Designator
-// or pointer-valued FunctionRef), return a copy of its contents in
-// a Variable.
-template<typename A>
-std::optional<Variable<A>> AsVariable(const Expr<A> &expr) {
-  using Variant = decltype(Variable<A>::u);
-  return std::visit(
-      [](const auto &x) -> std::optional<Variable<A>> {
-        if constexpr (common::HasMember<std::decay_t<decltype(x)>, Variant>) {
-          return std::make_optional<Variable<A>>(x);
-        }
-        return std::nullopt;
-      },
-      expr.u);
-}
-
-// Predicate: true when an expression is a variable reference
-template<typename A> bool IsVariable(const Expr<A> &expr) {
-  return AsVariable(expr).has_value();
-}
-
-template<TypeCategory CATEGORY>
-bool IsVariable(const Expr<SomeKind<CATEGORY>> &expr) {
-  return std::visit([](const auto &x) { return IsVariable(x); }, expr.u);
-}
-
-template<> inline bool IsVariable(const Expr<SomeDerived> &) { return true; }
-
-template<> inline bool IsVariable(const Expr<SomeType> &expr) {
-  return std::visit(
-      [](const auto &x) {
-        if constexpr (!std::is_same_v<BOZLiteralConstant,
-                          std::decay_t<decltype(x)>>) {
-          return IsVariable(x);
-        }
-        return false;
-      },
-      expr.u);
-}
-
 FOR_EACH_CATEGORY_TYPE(extern template class Expr)
 FOR_EACH_TYPE_AND_KIND(extern template struct ExpressionBase)
 }
index a206e8a..4e1898f 100644 (file)
 
 namespace Fortran::evaluate {
 
+// Some expression predicates and extractors.
+
+// When an Expr holds something that is a Variable (i.e., a Designator
+// or pointer-valued FunctionRef), return a copy of its contents in
+// a Variable.
+template<typename A>
+std::optional<Variable<A>> AsVariable(const Expr<A> &expr) {
+  using Variant = decltype(Variable<A>::u);
+  return std::visit(
+      [](const auto &x) -> std::optional<Variable<A>> {
+        if constexpr (common::HasMember<std::decay_t<decltype(x)>, Variant>) {
+          return std::make_optional<Variable<A>>(x);
+        }
+        return std::nullopt;
+      },
+      expr.u);
+}
+
+// Predicate: true when an expression is a variable reference
+template<typename A> bool IsVariable(const A &) { return false; }
+template<typename A> bool IsVariable(const Designator<A> &) { return true; }
+template<typename A> bool IsVariable(const FunctionRef<A> &) { return true; }
+template<typename A> bool IsVariable(const Expr<A> &expr) {
+  return std::visit([](const auto &x) { return IsVariable(x); }, expr.u);
+}
+
+// Predicate: true when an expression is a constant value
+template<typename A> bool IsConstant(const A &) { return false; }
+template<typename A> bool IsConstant(const Constant<A> &) { return true; }
+template<typename A> bool IsConstant(const Expr<A> &expr) {
+  return std::visit([](const auto &x) { return IsConstant(x); }, expr.u);
+}
+
 // Generalizing packagers: these take operations and expressions of more
 // specific types and wrap them in Expr<> containers of more abstract types.
 
index 95ade4a..229e640 100644 (file)
@@ -383,8 +383,13 @@ struct SomeType {
   FOR_EACH_SPECIFIC_TYPE(PREFIX) \
   FOR_EACH_CATEGORY_TYPE(PREFIX)
 
-// Wraps a constant value in a class with its resolved type.
+// Wraps a constant scalar value of a specific intrinsic type
+// in a class with its resolved type.
+// N.B. Array constants are represented as array constructors
+// and derived type constants are structure constructors; generic
+// constants are generic expressions wrapping these constants.
 template<typename T> struct Constant {
+  // TODO: static_assert(T::isSpecificIntrinsicType);
   using Result = T;
   using Value = Scalar<Result>;
   CLASS_BOILERPLATE(Constant)
@@ -399,7 +404,7 @@ template<typename T> struct Constant {
       return value.GetType();
     }
   }
-  int Rank() const { return 0; }  // TODO: array constants
+  int Rank() const { return 0; }
   std::ostream &Dump(std::ostream &) const;
   Value value;
 };