From 55763194f1ae90ee9fc7e03dcafc178e5d3ce71e Mon Sep 17 00:00:00 2001 From: peter klausler Date: Wed, 12 Sep 2018 13:53:14 -0700 Subject: [PATCH] [flang] Merge with current master, address early review comments. Original-commit: flang-compiler/f18@d1f981ddb431fedcc6aba5e33465ebe85fdf66dc Reviewed-on: https://github.com/flang-compiler/f18/pull/183 Tree-same-pre-rewrite: false --- flang/lib/common/template.h | 35 ++++-------- flang/lib/evaluate/expression.cc | 4 +- flang/lib/evaluate/tools.h | 2 +- flang/lib/evaluate/type.h | 10 ++-- flang/lib/semantics/expression.cc | 90 ++++++++++++------------------- 5 files changed, 49 insertions(+), 92 deletions(-) diff --git a/flang/lib/common/template.h b/flang/lib/common/template.h index 28f5e6da9bc2..572c0b58b6ef 100644 --- a/flang/lib/common/template.h +++ b/flang/lib/common/template.h @@ -78,8 +78,9 @@ struct OverMembersHelper> { using type = T; }; -template class T, typename TorV> -using OverMembers = typename OverMembersHelper>::type; +template class T, typename TUPLEorVARIANT> +using OverMembers = + typename OverMembersHelper>::type; // SearchMembers scans the types that constitute the alternatives // of a std::variant instantiation or elements of a std::tuple. @@ -92,31 +93,14 @@ template class PREDICATE> struct SearchMembersHelper { }; }; -template class PREDICATE, typename TorV> +template class PREDICATE, typename TUPLEorVARIANT> constexpr int SearchMembers{ OverMembers::template Scanner, - TorV>::value()}; + TUPLEorVARIANT>::value()}; -template +template constexpr bool HasMember{ - SearchMembers::template Match, TorV> >= 0}; - -// const A * -> std::optional -template std::optional GetIfNonNull(const A *p) { - if (p) { - return {*p}; - } - return std::nullopt; -} - -// const std::variant<..., A, ...> -> std::optional -// i.e., when a variant holds a value of a particular type, return a copy -// of that value in a std::optional<>. The type A must be a valid -// alternative for the variant. -template -std::optional GetIf(const VARIANT &u) { - return GetIfNonNull(std::get_if(&u)); -} + SearchMembers::template Match, TUPLEorVARIANT> >= 0}; // std::optional> -> std::optional template @@ -209,9 +193,10 @@ template class F, template class PACKAGE, struct MapTemplateHelper> { using type = PACKAGE...>; }; -template class F, typename TorV, +template class F, typename TUPLEorVARIANT, template class PACKAGE = std::variant> -using MapTemplate = typename MapTemplateHelper::type; +using MapTemplate = + typename MapTemplateHelper::type; // std::tuple...> -> std::optional> // i.e., inverts a tuple of optional values into an optional tuple that has diff --git a/flang/lib/evaluate/expression.cc b/flang/lib/evaluate/expression.cc index 977e7494e680..1f2decab8f87 100644 --- a/flang/lib/evaluate/expression.cc +++ b/flang/lib/evaluate/expression.cc @@ -503,13 +503,13 @@ template auto ExpressionBase::ScalarValue() const -> std::optional> { if constexpr (Result::isSpecificType) { - if (auto c{common::GetIf>(derived().u)}) { + if (auto *c{std::get_if>(&derived().u)}) { return {c->value}; } // TODO: every specifically-typed Expr should support Parentheses if constexpr (common::HasMember, decltype(derived().u)>) { - if (auto p{common::GetIf>(derived().u)}) { + if (auto *p{std::get_if>(&derived().u)}) { return p->left().ScalarValue(); } } diff --git a/flang/lib/evaluate/tools.h b/flang/lib/evaluate/tools.h index 29186e42f642..fa331bf8e6de 100644 --- a/flang/lib/evaluate/tools.h +++ b/flang/lib/evaluate/tools.h @@ -103,7 +103,7 @@ Expr ConvertToType(Expr> &&x) { } } else { // Same type category - if (auto already{common::GetIf>(x.u)}) { + if (auto *already{std::get_if>(&x.u)}) { return std::move(*already); } if constexpr (TO::category == TypeCategory::Complex) { diff --git a/flang/lib/evaluate/type.h b/flang/lib/evaluate/type.h index de34d1e2676e..889c89798aa5 100644 --- a/flang/lib/evaluate/type.h +++ b/flang/lib/evaluate/type.h @@ -210,7 +210,7 @@ template struct SomeScalar { SomeScalar(std::enable_if_t, A> &&x) : u{std::move(x)} {} - auto ToInt64() const { + std::optional ToInt64() const { return std::visit( [](const auto &x) -> std::optional { if constexpr (TypeOf::category == @@ -222,7 +222,7 @@ template struct SomeScalar { u); } - auto ToString() const { + std::optional ToString() const { return std::visit( [](const auto &x) -> std::optional { if constexpr (std::is_same_v struct SomeScalar { u); } - auto IsTrue() const { + std::optional IsTrue() const { return std::visit( [](const auto &x) -> std::optional { if constexpr (TypeOf::category == @@ -246,10 +246,6 @@ template struct SomeScalar { u); } - template auto GetIf() const { - return common::GetIf>(u); - } - common::MapTemplate u; }; diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc index 416f45a4f4f1..b0800a3a041d 100644 --- a/flang/lib/semantics/expression.cc +++ b/flang/lib/semantics/expression.cc @@ -323,9 +323,11 @@ MaybeExpr ExprAnalyzer::Analyze(const parser::RealLiteralConstant &x) { MaybeExpr ExprAnalyzer::Analyze(const parser::SignedRealLiteralConstant &x) { if (MaybeExpr result{Analyze(std::get(x.t))}) { + auto *realExpr{std::get_if>(&result->u)}; + CHECK(realExpr != nullptr); if (auto sign{std::get>(x.t)}) { if (sign == parser::Sign::Negative) { - return {AsGenericExpr(-*common::GetIf>(result->u))}; + return {AsGenericExpr(-std::move(*realExpr))}; } } return result; @@ -397,32 +399,38 @@ MaybeExpr ExprAnalyzer::Analyze(const parser::BOZLiteralConstant &x) { return {AsGenericExpr(value.value)}; } -template -MaybeExpr DataRefIfType( - const semantics::Symbol &symbol, int defaultKind, DataRef &&dataRef) { +template +MaybeExpr TypedDataRefHelper(int kind, DataRef &&dataRef) { + return common::SearchDynamicTypes( + TypeKindVisitor{ + kind, std::move(dataRef)}); +} + +static MaybeExpr TypedDataRef( + const semantics::Symbol &symbol, DataRef &&dataRef) { if (auto *details{symbol.detailsIf()}) { if (details->type().has_value()) { if (details->type()->category() == semantics::DeclTypeSpec::Category::Intrinsic) { - std::uint64_t kindParam{ - details->type()->intrinsicTypeSpec().kind().value().value()}; - int kind = static_cast(kindParam); - if (static_cast(kind) == kindParam) { - // TODO: Inspection of semantics::IntrinsicTypeSpec requires the use - // of forbidden RTTI via dynamic_cast<>. See whether - // semantics::IntrinsicTypeSpec can be augmented with query - // interfaces instead. - if (dynamic_cast( - &details->type()->intrinsicTypeSpec()) != nullptr) { - if (kind == 0) { // TODO: resolve default kinds in semantics - kind = defaultKind; - } - if (MaybeExpr result{common::SearchDynamicTypes( - TypeKindVisitor{ - kind, std::move(dataRef)})}) { - return result; - } - } + TypeCategory category{details->type()->intrinsicTypeSpec().category()}; + int kind{details->type()->intrinsicTypeSpec().kind()}; + switch (category) { + case TypeCategory::Integer: + return TypedDataRefHelper( + kind, std::move(dataRef)); + case TypeCategory::Real: + return TypedDataRefHelper( + kind, std::move(dataRef)); + case TypeCategory::Complex: + return TypedDataRefHelper( + kind, std::move(dataRef)); + case TypeCategory::Character: + return TypedDataRefHelper( + kind, std::move(dataRef)); + case TypeCategory::Logical: + return TypedDataRefHelper( + kind, std::move(dataRef)); + default: CRASH_NO_CASE; } } } @@ -430,36 +438,6 @@ MaybeExpr DataRefIfType( return std::nullopt; } -static MaybeExpr TypedDataRef(const semantics::Symbol &symbol, - const semantics::IntrinsicTypeDefaultKinds &defaults, DataRef &&dataRef) { - if (MaybeExpr result{ - DataRefIfType( - symbol, defaults.defaultIntegerKind, std::move(dataRef))}) { - return result; - } - if (MaybeExpr result{ - DataRefIfType( - symbol, defaults.defaultRealKind, std::move(dataRef))}) { - return result; - } - if (MaybeExpr result{ - DataRefIfType( - symbol, defaults.defaultRealKind, std::move(dataRef))}) { - return result; - } - if (MaybeExpr result{ - DataRefIfType( - symbol, defaults.defaultCharacterKind, std::move(dataRef))}) { - return result; - } - if (MaybeExpr result{ - DataRefIfType( - symbol, defaults.defaultLogicalKind, std::move(dataRef))}) { - return result; - } - return std::nullopt; -} - MaybeExpr ExprAnalyzer::Analyze(const parser::Name &n) { if (n.symbol == nullptr) { // TODO: convert this to a CHECK later @@ -471,8 +449,7 @@ MaybeExpr ExprAnalyzer::Analyze(const parser::Name &n) { "TODO: PARAMETER references not yet implemented"_err_en_US); // TODO: enumerators, do they have the PARAMETER attribute? } else { - if (MaybeExpr result{ - TypedDataRef(*n.symbol, defaults, DataRef{*n.symbol})}) { + if (MaybeExpr result{TypedDataRef(*n.symbol, DataRef{*n.symbol})}) { return result; } context.messages.Say("'%s' is not of a supported type and kind"_err_en_US, @@ -562,8 +539,7 @@ MaybeExpr ExprAnalyzer::Analyze(const parser::ArrayElement &ae) { name->ToString().data()); } else { ArrayRef arrayRef{*name->symbol, std::move(subscripts)}; - return TypedDataRef( - *name->symbol, defaults, DataRef{std::move(arrayRef)}); + return TypedDataRef(*name->symbol, DataRef{std::move(arrayRef)}); } } else if (const auto *component{ std::get_if>(