From: peter klausler Date: Mon, 22 Oct 2018 22:20:42 +0000 (-0700) Subject: [flang] start refactoring of Constant and Fold X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=43a0a63441b81533aa74dd8c779c4873da39403e;p=platform%2Fupstream%2Fllvm.git [flang] start refactoring of Constant and Fold Original-commit: flang-compiler/f18@53f7174c3dddd743146e1cff9ffcde0db4c89b6b Reviewed-on: https://github.com/flang-compiler/f18/pull/219 Tree-same-pre-rewrite: false --- diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 9f7e621..c592004 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -669,46 +669,6 @@ struct GenericExprWrapper { Expr 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 -std::optional> AsVariable(const Expr &expr) { - using Variant = decltype(Variable::u); - return std::visit( - [](const auto &x) -> std::optional> { - if constexpr (common::HasMember, Variant>) { - return std::make_optional>(x); - } - return std::nullopt; - }, - expr.u); -} - -// Predicate: true when an expression is a variable reference -template bool IsVariable(const Expr &expr) { - return AsVariable(expr).has_value(); -} - -template -bool IsVariable(const Expr> &expr) { - return std::visit([](const auto &x) { return IsVariable(x); }, expr.u); -} - -template<> inline bool IsVariable(const Expr &) { return true; } - -template<> inline bool IsVariable(const Expr &expr) { - return std::visit( - [](const auto &x) { - if constexpr (!std::is_same_v>) { - return IsVariable(x); - } - return false; - }, - expr.u); -} - FOR_EACH_CATEGORY_TYPE(extern template class Expr) FOR_EACH_TYPE_AND_KIND(extern template struct ExpressionBase) } diff --git a/flang/lib/evaluate/tools.h b/flang/lib/evaluate/tools.h index a206e8a..4e1898f 100644 --- a/flang/lib/evaluate/tools.h +++ b/flang/lib/evaluate/tools.h @@ -24,6 +24,39 @@ 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 +std::optional> AsVariable(const Expr &expr) { + using Variant = decltype(Variable::u); + return std::visit( + [](const auto &x) -> std::optional> { + if constexpr (common::HasMember, Variant>) { + return std::make_optional>(x); + } + return std::nullopt; + }, + expr.u); +} + +// Predicate: true when an expression is a variable reference +template bool IsVariable(const A &) { return false; } +template bool IsVariable(const Designator &) { return true; } +template bool IsVariable(const FunctionRef &) { return true; } +template bool IsVariable(const Expr &expr) { + return std::visit([](const auto &x) { return IsVariable(x); }, expr.u); +} + +// Predicate: true when an expression is a constant value +template bool IsConstant(const A &) { return false; } +template bool IsConstant(const Constant &) { return true; } +template bool IsConstant(const Expr &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. diff --git a/flang/lib/evaluate/type.h b/flang/lib/evaluate/type.h index 95ade4a..229e640 100644 --- a/flang/lib/evaluate/type.h +++ b/flang/lib/evaluate/type.h @@ -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 struct Constant { + // TODO: static_assert(T::isSpecificIntrinsicType); using Result = T; using Value = Scalar; CLASS_BOILERPLATE(Constant) @@ -399,7 +404,7 @@ template 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; };