diff options
Diffstat (limited to 'flang/lib/Evaluate/tools.cpp')
| -rw-r--r-- | flang/lib/Evaluate/tools.cpp | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index 3b2c4f9f5601..1f3cbbf6a0c3 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -495,7 +495,7 @@ Expr<SomeComplex> PromoteMixedComplexReal( // N.B. When a "typeless" BOZ literal constant appears as one (not both!) of // the operands to a dyadic operation where one is permitted, it assumes the // type and kind of the other operand. -template <template <typename> class OPR, bool CAN_BE_UNSIGNED> +template <template <typename> class OPR> std::optional<Expr<SomeType>> NumericOperation( parser::ContextualMessages &messages, Expr<SomeType> &&x, Expr<SomeType> &&y, int defaultRealKind) { @@ -510,13 +510,8 @@ std::optional<Expr<SomeType>> NumericOperation( std::move(rx), std::move(ry))); }, [&](Expr<SomeUnsigned> &&ix, Expr<SomeUnsigned> &&iy) { - if constexpr (CAN_BE_UNSIGNED) { - return Package(PromoteAndCombine<OPR, TypeCategory::Unsigned>( - std::move(ix), std::move(iy))); - } else { - messages.Say("Operands must not be UNSIGNED"_err_en_US); - return NoExpr(); - } + return Package(PromoteAndCombine<OPR, TypeCategory::Unsigned>( + std::move(ix), std::move(iy))); }, // Mixed REAL/INTEGER operations [](Expr<SomeReal> &&rx, Expr<SomeInteger> &&iy) { @@ -575,34 +570,31 @@ std::optional<Expr<SomeType>> NumericOperation( }, // Operations with one typeless operand [&](BOZLiteralConstant &&bx, Expr<SomeInteger> &&iy) { - return NumericOperation<OPR, CAN_BE_UNSIGNED>(messages, + return NumericOperation<OPR>(messages, AsGenericExpr(ConvertTo(iy, std::move(bx))), std::move(y), defaultRealKind); }, [&](BOZLiteralConstant &&bx, Expr<SomeUnsigned> &&iy) { - return NumericOperation<OPR, CAN_BE_UNSIGNED>(messages, + return NumericOperation<OPR>(messages, AsGenericExpr(ConvertTo(iy, std::move(bx))), std::move(y), defaultRealKind); }, [&](BOZLiteralConstant &&bx, Expr<SomeReal> &&ry) { - return NumericOperation<OPR, CAN_BE_UNSIGNED>(messages, + return NumericOperation<OPR>(messages, AsGenericExpr(ConvertTo(ry, std::move(bx))), std::move(y), defaultRealKind); }, [&](Expr<SomeInteger> &&ix, BOZLiteralConstant &&by) { - return NumericOperation<OPR, CAN_BE_UNSIGNED>(messages, - std::move(x), AsGenericExpr(ConvertTo(ix, std::move(by))), - defaultRealKind); + return NumericOperation<OPR>(messages, std::move(x), + AsGenericExpr(ConvertTo(ix, std::move(by))), defaultRealKind); }, [&](Expr<SomeUnsigned> &&ix, BOZLiteralConstant &&by) { - return NumericOperation<OPR, CAN_BE_UNSIGNED>(messages, - std::move(x), AsGenericExpr(ConvertTo(ix, std::move(by))), - defaultRealKind); + return NumericOperation<OPR>(messages, std::move(x), + AsGenericExpr(ConvertTo(ix, std::move(by))), defaultRealKind); }, [&](Expr<SomeReal> &&rx, BOZLiteralConstant &&by) { - return NumericOperation<OPR, CAN_BE_UNSIGNED>(messages, - std::move(x), AsGenericExpr(ConvertTo(rx, std::move(by))), - defaultRealKind); + return NumericOperation<OPR>(messages, std::move(x), + AsGenericExpr(ConvertTo(rx, std::move(by))), defaultRealKind); }, // Error cases [&](Expr<SomeUnsigned> &&, auto &&) { @@ -621,7 +613,7 @@ std::optional<Expr<SomeType>> NumericOperation( std::move(x.u), std::move(y.u)); } -template std::optional<Expr<SomeType>> NumericOperation<Power, false>( +template std::optional<Expr<SomeType>> NumericOperation<Power>( parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&, int defaultRealKind); template std::optional<Expr<SomeType>> NumericOperation<Multiply>( @@ -890,29 +882,6 @@ std::optional<Expr<SomeType>> ConvertToType( } } -bool IsAssumedRank(const Symbol &original) { - if (const auto *assoc{original.detailsIf<semantics::AssocEntityDetails>()}) { - if (assoc->rank()) { - return false; // in RANK(n) or RANK(*) - } else if (assoc->IsAssumedRank()) { - return true; // RANK DEFAULT - } - } - const Symbol &symbol{semantics::ResolveAssociations(original)}; - const auto *object{symbol.detailsIf<semantics::ObjectEntityDetails>()}; - return object && object->IsAssumedRank(); -} - -bool IsAssumedRank(const ActualArgument &arg) { - if (const auto *expr{arg.UnwrapExpr()}) { - return IsAssumedRank(*expr); - } else { - const Symbol *assumedTypeDummy{arg.GetAssumedTypeDummy()}; - CHECK(assumedTypeDummy); - return IsAssumedRank(*assumedTypeDummy); - } -} - int GetCorank(const ActualArgument &arg) { const auto *expr{arg.UnwrapExpr()}; return GetCorank(*expr); @@ -1203,6 +1172,15 @@ bool HasVectorSubscript(const Expr<SomeType> &expr) { return HasVectorSubscriptHelper{}(expr); } +bool HasVectorSubscript(const ActualArgument &actual) { + auto expr{actual.UnwrapExpr()}; + return expr && HasVectorSubscript(*expr); +} + +bool IsArraySection(const Expr<SomeType> &expr) { + return expr.Rank() > 0 && IsVariable(expr) && !UnwrapWholeSymbolDataRef(expr); +} + // HasConstant() struct HasConstantHelper : public AnyTraverse<HasConstantHelper, bool, /*TraverseAssocEntityDetails=*/false> { @@ -2312,9 +2290,22 @@ bool IsDummy(const Symbol &symbol) { ResolveAssociations(symbol).details()); } +bool IsAssumedRank(const Symbol &original) { + if (const auto *assoc{original.detailsIf<semantics::AssocEntityDetails>()}) { + if (assoc->rank()) { + return false; // in RANK(n) or RANK(*) + } else if (assoc->IsAssumedRank()) { + return true; // RANK DEFAULT + } + } + const Symbol &symbol{semantics::ResolveAssociations(original)}; + const auto *object{symbol.detailsIf<semantics::ObjectEntityDetails>()}; + return object && object->IsAssumedRank(); +} + bool IsAssumedShape(const Symbol &symbol) { const Symbol &ultimate{ResolveAssociations(symbol)}; - const auto *object{ultimate.detailsIf<ObjectEntityDetails>()}; + const auto *object{ultimate.detailsIf<semantics::ObjectEntityDetails>()}; return object && object->IsAssumedShape() && !semantics::IsAllocatableOrObjectPointer(&ultimate); } |
