[clang] [flang] [flang] Add UNSIGNED (PR #113504)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 23 16:12:01 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
Implement the UNSIGNED extension type and operations under control of a language feature flag (-funsigned).
This is nearly identical to the UNSIGNED feature that has been available in Sun Fortran for years, and now implemented in GNU Fortran for gfortran 15, and proposed for ISO standardization in J3/24-116.txt.
See the new documentation for details; but in short, this is C's unsigned type, with guaranteed modular arithmetic for +, -, and *, and the related transformational intrinsic functions SUM & al.
More tests to come.
---
Patch is 239.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113504.diff
71 Files Affected:
- (modified) clang/include/clang/Driver/Options.td (+1)
- (modified) clang/lib/Driver/ToolChains/Flang.cpp (+2-1)
- (modified) flang/docs/Extensions.md (+1)
- (added) flang/docs/Unsigned.md (+109)
- (modified) flang/include/flang/Common/Fortran-features.h (+1-1)
- (modified) flang/include/flang/Common/Fortran.h (+6-3)
- (modified) flang/include/flang/Evaluate/expression.h (+39-8)
- (modified) flang/include/flang/Evaluate/integer.h (+8-3)
- (modified) flang/include/flang/Evaluate/tools.h (+7-3)
- (modified) flang/include/flang/Evaluate/type.h (+30-10)
- (modified) flang/include/flang/ISO_Fortran_binding.h (+6-1)
- (modified) flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h (+74)
- (modified) flang/include/flang/Optimizer/Dialect/FIROps.td (+3-2)
- (modified) flang/include/flang/Optimizer/Dialect/FIRTypes.td (+18-1)
- (modified) flang/include/flang/Optimizer/Support/Utils.h (+15-5)
- (modified) flang/include/flang/Parser/dump-parse-tree.h (+3-1)
- (modified) flang/include/flang/Parser/parse-tree.h (+14-6)
- (modified) flang/include/flang/Runtime/cpp-type.h (+4)
- (modified) flang/include/flang/Runtime/numeric.h (+1-1)
- (modified) flang/include/flang/Runtime/reduce.h (+83)
- (modified) flang/include/flang/Runtime/reduction.h (+93)
- (modified) flang/include/flang/Semantics/expression.h (+3-2)
- (modified) flang/lib/Common/default-kinds.cpp (+1)
- (modified) flang/lib/Evaluate/expression.cpp (+6)
- (modified) flang/lib/Evaluate/fold-implementation.h (+33)
- (modified) flang/lib/Evaluate/fold-integer.cpp (+407-327)
- (modified) flang/lib/Evaluate/fold-logical.cpp (+4)
- (modified) flang/lib/Evaluate/fold-matmul.h (+2-2)
- (modified) flang/lib/Evaluate/fold-reduction.h (+17-2)
- (modified) flang/lib/Evaluate/formatting.cpp (+7-2)
- (modified) flang/lib/Evaluate/intrinsics.cpp (+124-64)
- (modified) flang/lib/Evaluate/target.cpp (+2)
- (modified) flang/lib/Evaluate/tools.cpp (+45-9)
- (modified) flang/lib/Evaluate/type.cpp (+9)
- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+6)
- (modified) flang/lib/Lower/ConvertConstant.cpp (+11-5)
- (modified) flang/lib/Lower/ConvertExpr.cpp (+109-19)
- (modified) flang/lib/Lower/ConvertExprToHLFIR.cpp (+81-5)
- (modified) flang/lib/Lower/ConvertType.cpp (+5-3)
- (modified) flang/lib/Lower/IO.cpp (+16-14)
- (modified) flang/lib/Lower/Mangler.cpp (+2)
- (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+4)
- (modified) flang/lib/Optimizer/Builder/Runtime/Reduction.cpp (+191)
- (modified) flang/lib/Optimizer/Dialect/FIRType.cpp (+41-12)
- (modified) flang/lib/Parser/Fortran-parsers.cpp (+18-7)
- (modified) flang/lib/Parser/type-parsers.h (+1)
- (modified) flang/lib/Semantics/check-arithmeticif.cpp (+3)
- (modified) flang/lib/Semantics/check-case.cpp (+7-1)
- (modified) flang/lib/Semantics/expression.cpp (+46-33)
- (modified) flang/lib/Semantics/resolve-names.cpp (+6)
- (modified) flang/lib/Semantics/scope.cpp (+1)
- (modified) flang/lib/Semantics/tools.cpp (+3-1)
- (modified) flang/module/iso_c_binding.f90 (+29)
- (modified) flang/module/iso_fortran_env.f90 (+3)
- (modified) flang/module/iso_fortran_env_impl.f90 (+30)
- (modified) flang/runtime/descriptor-io.h (+26-9)
- (modified) flang/runtime/dot-product.cpp (+23)
- (modified) flang/runtime/edit-output.cpp (+7-7)
- (modified) flang/runtime/edit-output.h (+7-7)
- (modified) flang/runtime/extrema.cpp (+133-1)
- (modified) flang/runtime/io-api-minimal.cpp (+1-1)
- (modified) flang/runtime/numeric.cpp (+2-2)
- (modified) flang/runtime/reduce.cpp (+214)
- (modified) flang/runtime/tools.h (+1-1)
- (modified) flang/runtime/type-code.cpp (+29)
- (modified) flang/runtime/type-info.cpp (+1)
- (added) flang/test/Lower/Unsigned/unsigned-ops.f90 (+26)
- (modified) flang/test/Lower/allocatable-polymorphic.f90 (+1-1)
- (modified) flang/test/Semantics/typeinfo01.f90 (+4-4)
- (modified) flang/test/Semantics/typeinfo08.f90 (+1-1)
- (added) flang/test/Semantics/unsigned-errors.f90 (+77)
``````````diff
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6491e9ac73ce99..881a6b8386209a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6831,6 +6831,7 @@ defm underscoring : OptInFC1FFlag<"underscoring", "Appends one trailing undersco
defm ppc_native_vec_elem_order: BoolOptionWithoutMarshalling<"f", "ppc-native-vector-element-order",
PosFlag<SetTrue, [], [ClangOption], "Specifies PowerPC native vector element order (default)">,
NegFlag<SetFalse, [], [ClangOption], "Specifies PowerPC non-native vector element order">>;
+defm unsigned : OptInFC1FFlag<"unsigned", "Enables UNSIGNED type">;
def fno_automatic : Flag<["-"], "fno-automatic">, Group<f_Group>,
HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">;
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index e2f8f6e0cca1c6..89f0110c94d44c 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -120,7 +120,8 @@ void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
options::OPT_std_EQ, options::OPT_W_Joined,
options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ,
- options::OPT_funderscoring, options::OPT_fno_underscoring});
+ options::OPT_funderscoring, options::OPT_fno_underscoring,
+ options::OPT_funsigned, options::OPT_fno_unsigned});
llvm::codegenoptions::DebugInfoKind DebugInfoKind;
if (Args.hasArg(options::OPT_gN_Group)) {
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index f85a3eb39ed191..5867d9a14c084c 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -417,6 +417,7 @@ end
[-fimplicit-none-type-never]
* Old-style `PARAMETER pi=3.14` statement without parentheses
[-falternative-parameter-statement]
+* `UNSIGNED` type (-funsigned)
### Extensions and legacy features deliberately not supported
diff --git a/flang/docs/Unsigned.md b/flang/docs/Unsigned.md
new file mode 100644
index 00000000000000..d9f8b78507dd3f
--- /dev/null
+++ b/flang/docs/Unsigned.md
@@ -0,0 +1,109 @@
+<!--===- docs/Unsigned.md
+
+ Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ See https://llvm.org/LICENSE.txt for license information.
+ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+-->
+
+# Fortran Extensions supported by Flang
+
+```{contents}
+---
+local:
+---
+```
+
+For better compatibility with GNU Fortran and Sun Fortran,
+this compiler supports an option (`-funsigned`) that enables
+the `UNSIGNED` data type, constants, intrinsic functions,
+its use with intrinsic operations and `SELECT CASE`, and C
+language interoperability.
+
+## `UNSIGNED` type
+
+`UNSIGNED` is a numeric with the same kinds as `INTEGER`.
+It may appear as a type-spec in any context, including
+a type declaration statement, a type-decl in an array
+constructor or `ALLOCATE` statement, `IMPLICIT`, or a
+function statement's prefix.
+
+`UNSIGNED` constants are nonempty strings of decimal digits
+followed by the letter `U` and optionally a kind suffix with
+an underscore.
+
+## `UNSIGNED` operations
+
+`UNSIGNED` operands are accepted for unary negation (`-`),
+the basic four binary arithmetic intrinsic operations `+`, `-`, `*`, and `/`,
+and for numeric relational operators.
+The power operator `**` does not accept `UNSIGNED` operands.
+
+Mixed operations with other types are not allowed.
+Mixed operations with one `UNSIGNED` operand and one BOZ literal
+constant operand are allowed.
+When the operands' kinds differ, the smaller operand is zero-extended
+to the size of the larger.
+
+The arithmetic operations `u+v`, `-u`, `u-v`, and `u*v` are implemented
+modulo `MAX(HUGE(u),HUGE(v))+1`;
+informally speaking, they always truncate their results, or are
+guaranteed to "wrap".
+
+## `UNSIGNED` intrinsic functions
+
+`UNSIGNED` operands are accepted as operands to,
+or may be returned as results from,
+several intrinsic procedures.
+
+Bitwise operations:
+* `NOT`
+* `IAND`, `IOR`, `IEOR`, `IBCLR`, `IBSET`, `IBITS`, `MERGE_BITS`
+* `BTEST`
+* `ISHFT`, `ISHFTC`
+* `SHIFTA`, `SHIFTL`, `SHIFTR`
+* `TRANSFER`
+* `MVBITS`
+
+The existing unsigned comparisons `BLT`, `BLE`, `BGE`, and `BGT`.
+
+The inquiries `BIT_SIZE`, `DIGITS`, `HUGE`, and `RANGE`.
+
+Homogeneous `MAX` and `MIN`.
+
+The reducing transformationals:
+* `MAXVAL`, `MINVAL`
+* `SUM`, `PRODUCT`
+* `IALL`, `IANY`, `IPARITY`
+* `DOT_PRODUCT`, `MATMUL`
+
+All of the restructuring array transformational intrinsics: `CSHIFT`, `EOSHIFT`,
+ `PACK`, `RESHAPE`, `SPREAD`, `TRANSPOSE`, and `UNPACK`.
+
+The location transformationals `FINDLOC`, `MAXLOC`, and `MINLOC`.
+
+Support for `UNSIGNED` in the `OUT_OF_RANGE` predicate and `RANDOM_NUMBER`
+remains to be implemented.
+
+## Other usage
+
+`UNSIGNED` is allowed in `SELECT CASE`, but not in `DO` loop indices or
+limits, or an arithmetic `IF` expression.
+
+`UNSIGNED` array indices are not allowed.
+
+`UNSIGNED` data may be used as data items in I/O statements, including
+list-directed and `NAMELIST` I/O.
+Format-directed I/O may edit `UNSIGNED` data with `I`, `G`, `B`, `O`, and `Z`
+edit descriptors.
+
+## C interoperability
+
+`UNSIGNED` data map to type codes for C's `unsigned` types in the
+`type` member of a `cdesc_t` descriptor in the `ISO_Fortran_binding.h`
+header file.
+
+## Standard modules
+
+New definitions (`C_UNSIGNED`, `C_UINT8_T`, &c.) were added to ISO_C_BINDING
+and new constants (`UINT8`, `UINT16`, &c.) to ISO_FORTRAN_ENV.
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 2b57c7ae50642c..bd8f922cf3d440 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -53,7 +53,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
NonBindCInteroperability, CudaManaged, CudaUnified,
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
- SavedLocalInSpecExpr, PrintNamelist)
+ SavedLocalInSpecExpr, PrintNamelist, Unsigned)
// Portability and suspicious usage warnings
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
diff --git a/flang/include/flang/Common/Fortran.h b/flang/include/flang/Common/Fortran.h
index 5b2ed43a8f99c0..a4c20854eb7516 100644
--- a/flang/include/flang/Common/Fortran.h
+++ b/flang/include/flang/Common/Fortran.h
@@ -21,12 +21,15 @@
namespace Fortran::common {
class LanguageFeatureControl;
-// Fortran has five kinds of intrinsic data types, plus the derived types.
-ENUM_CLASS(TypeCategory, Integer, Real, Complex, Character, Logical, Derived)
+// Fortran has five kinds of standard intrinsic data types, the Unsigned
+// extension, and derived types.
+ENUM_CLASS(
+ TypeCategory, Integer, Unsigned, Real, Complex, Character, Logical, Derived)
ENUM_CLASS(VectorElementCategory, Integer, Unsigned, Real)
constexpr bool IsNumericTypeCategory(TypeCategory category) {
- return category == TypeCategory::Integer || category == TypeCategory::Real ||
+ return category == TypeCategory::Integer ||
+ category == TypeCategory::Unsigned || category == TypeCategory::Real ||
category == TypeCategory::Complex;
}
diff --git a/flang/include/flang/Evaluate/expression.h b/flang/include/flang/Evaluate/expression.h
index 2a40193e32306b..9ea037a2f7c429 100644
--- a/flang/include/flang/Evaluate/expression.h
+++ b/flang/include/flang/Evaluate/expression.h
@@ -209,10 +209,12 @@ template <typename TO, TypeCategory FROMCAT = TO::category>
struct Convert : public Operation<Convert<TO, FROMCAT>, TO, SomeKind<FROMCAT>> {
// Fortran doesn't have conversions between kinds of CHARACTER apart from
// assignments, and in those the data must be convertible to/from 7-bit ASCII.
- static_assert(((TO::category == TypeCategory::Integer ||
- TO::category == TypeCategory::Real) &&
- (FROMCAT == TypeCategory::Integer ||
- FROMCAT == TypeCategory::Real)) ||
+ static_assert(
+ ((TO::category == TypeCategory::Integer ||
+ TO::category == TypeCategory::Real ||
+ TO::category == TypeCategory::Unsigned) &&
+ (FROMCAT == TypeCategory::Integer || FROMCAT == TypeCategory::Real ||
+ FROMCAT == TypeCategory::Unsigned)) ||
TO::category == FROMCAT);
using Result = TO;
using Operand = SomeKind<FROMCAT>;
@@ -526,7 +528,8 @@ class Expr<Type<TypeCategory::Integer, KIND>>
private:
using Conversions = std::tuple<Convert<Result, TypeCategory::Integer>,
- Convert<Result, TypeCategory::Real>>;
+ Convert<Result, TypeCategory::Real>,
+ Convert<Result, TypeCategory::Unsigned>>;
using Operations = std::tuple<Parentheses<Result>, Negate<Result>,
Add<Result>, Subtract<Result>, Multiply<Result>, Divide<Result>,
Power<Result>, Extremum<Result>>;
@@ -547,6 +550,29 @@ class Expr<Type<TypeCategory::Integer, KIND>>
u;
};
+template <int KIND>
+class Expr<Type<TypeCategory::Unsigned, KIND>>
+ : public ExpressionBase<Type<TypeCategory::Unsigned, KIND>> {
+public:
+ using Result = Type<TypeCategory::Unsigned, KIND>;
+
+ EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
+
+private:
+ using Conversions = std::tuple<Convert<Result, TypeCategory::Integer>,
+ Convert<Result, TypeCategory::Real>,
+ Convert<Result, TypeCategory::Unsigned>>;
+ using Operations =
+ std::tuple<Parentheses<Result>, Negate<Result>, Add<Result>,
+ Subtract<Result>, Multiply<Result>, Divide<Result>, Extremum<Result>>;
+ using Others = std::tuple<Constant<Result>, ArrayConstructor<Result>,
+ Designator<Result>, FunctionRef<Result>>;
+
+public:
+ common::TupleToVariant<common::CombineTuples<Operations, Conversions, Others>>
+ u;
+};
+
template <int KIND>
class Expr<Type<TypeCategory::Real, KIND>>
: public ExpressionBase<Type<TypeCategory::Real, KIND>> {
@@ -560,7 +586,8 @@ class Expr<Type<TypeCategory::Real, KIND>>
// N.B. Real->Complex and Complex->Real conversions are done with CMPLX
// and part access operations (resp.).
using Conversions = std::variant<Convert<Result, TypeCategory::Integer>,
- Convert<Result, TypeCategory::Real>>;
+ Convert<Result, TypeCategory::Real>,
+ Convert<Result, TypeCategory::Unsigned>>;
using Operations = std::variant<ComplexComponent<KIND>, Parentheses<Result>,
Negate<Result>, Add<Result>, Subtract<Result>, Multiply<Result>,
Divide<Result>, Power<Result>, RealToIntPower<Result>, Extremum<Result>>;
@@ -590,6 +617,7 @@ class Expr<Type<TypeCategory::Complex, KIND>>
};
FOR_EACH_INTEGER_KIND(extern template class Expr, )
+FOR_EACH_UNSIGNED_KIND(extern template class Expr, )
FOR_EACH_REAL_KIND(extern template class Expr, )
FOR_EACH_COMPLEX_KIND(extern template class Expr, )
@@ -629,7 +657,8 @@ class Relational : public Operation<Relational<T>, LogicalResult, T, T> {
static_assert(Operand::category == TypeCategory::Integer ||
Operand::category == TypeCategory::Real ||
Operand::category == TypeCategory::Complex ||
- Operand::category == TypeCategory::Character);
+ Operand::category == TypeCategory::Character ||
+ Operand::category == TypeCategory::Unsigned);
CLASS_BOILERPLATE(Relational)
Relational(
RelationalOperator r, const Expr<Operand> &a, const Expr<Operand> &b)
@@ -642,7 +671,7 @@ class Relational : public Operation<Relational<T>, LogicalResult, T, T> {
template <> class Relational<SomeType> {
using DirectlyComparableTypes = common::CombineTuples<IntegerTypes, RealTypes,
- ComplexTypes, CharacterTypes>;
+ ComplexTypes, CharacterTypes, UnsignedTypes>;
public:
using Result = LogicalResult;
@@ -656,6 +685,7 @@ template <> class Relational<SomeType> {
};
FOR_EACH_INTEGER_KIND(extern template class Relational, )
+FOR_EACH_UNSIGNED_KIND(extern template class Relational, )
FOR_EACH_REAL_KIND(extern template class Relational, )
FOR_EACH_CHARACTER_KIND(extern template class Relational, )
extern template class Relational<SomeType>;
@@ -886,6 +916,7 @@ FOR_EACH_INTRINSIC_KIND(extern template class ArrayConstructor, )
FOR_EACH_INTRINSIC_KIND(template class Expr, ) \
FOR_EACH_CATEGORY_TYPE(template class Expr, ) \
FOR_EACH_INTEGER_KIND(template class Relational, ) \
+ FOR_EACH_UNSIGNED_KIND(template class Relational, ) \
FOR_EACH_REAL_KIND(template class Relational, ) \
FOR_EACH_CHARACTER_KIND(template class Relational, ) \
template class Relational<SomeType>; \
diff --git a/flang/include/flang/Evaluate/integer.h b/flang/include/flang/Evaluate/integer.h
index e420eb75e3dff0..fccc2ad774a8fc 100644
--- a/flang/include/flang/Evaluate/integer.h
+++ b/flang/include/flang/Evaluate/integer.h
@@ -33,6 +33,12 @@
namespace Fortran::evaluate::value {
+// Computes decimal range in the sense of SELECTED_INT_KIND
+static constexpr int DecimalRange(int bits) {
+ // This magic value is LOG10(2.)*1E12.
+ return static_cast<int>((bits * 301029995664) / 1000000000000);
+}
+
// Implements an integer as an assembly of smaller host integer parts
// that constitute the digits of a large-radix fixed-point number.
// For best performance, the type of these parts should be half of the
@@ -367,9 +373,8 @@ class Integer {
static constexpr int DIGITS{bits - 1}; // don't count the sign bit
static constexpr Integer HUGE() { return MASKR(bits - 1); }
static constexpr Integer Least() { return MASKL(1); }
- static constexpr int RANGE{// in the sense of SELECTED_INT_KIND
- // This magic value is LOG10(2.)*1E12.
- static_cast<int>(((bits - 1) * 301029995664) / 1000000000000)};
+ static constexpr int RANGE{DecimalRange(bits - 1)};
+ static constexpr int UnsignedRANGE{DecimalRange(bits)};
constexpr bool IsZero() const {
for (int j{0}; j < parts; ++j) {
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index f547138f5a116c..7a97a56b020ad9 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -582,7 +582,8 @@ Expr<TO> ConvertToType(Expr<Type<FROMCAT, FROMKIND>> &&x) {
template <typename TO> Expr<TO> ConvertToType(BOZLiteralConstant &&x) {
static_assert(IsSpecificIntrinsicType<TO>);
- if constexpr (TO::category == TypeCategory::Integer) {
+ if constexpr (TO::category == TypeCategory::Integer ||
+ TO::category == TypeCategory::Unsigned) {
return Expr<TO>{
Constant<TO>{Scalar<TO>::ConvertUnsigned(std::move(x)).value}};
} else {
@@ -754,11 +755,11 @@ Expr<SomeKind<CAT>> PromoteAndCombine(
// one of the operands to the type of the other. Handles special cases with
// typeless literal operands and with REAL/COMPLEX exponentiation to INTEGER
// powers.
-template <template <typename> class OPR>
+template <template <typename> class OPR, bool CAN_BE_UNSIGNED = true>
std::optional<Expr<SomeType>> NumericOperation(parser::ContextualMessages &,
Expr<SomeType> &&, Expr<SomeType> &&, int defaultRealKind);
-extern template std::optional<Expr<SomeType>> NumericOperation<Power>(
+extern template std::optional<Expr<SomeType>> NumericOperation<Power, false>(
parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
int defaultRealKind);
extern template std::optional<Expr<SomeType>> NumericOperation<Multiply>(
@@ -910,6 +911,9 @@ common::IfNoLvalue<std::optional<Expr<SomeType>>, WRAPPED> TypedWrapper(
case TypeCategory::Integer:
return WrapperHelper<TypeCategory::Integer, WRAPPER, WRAPPED>(
dyType.kind(), std::move(x));
+ case TypeCategory::Unsigned:
+ return WrapperHelper<TypeCategory::Unsigned, WRAPPER, WRAPPED>(
+ dyType.kind(), std::move(x));
case TypeCategory::Real:
return WrapperHelper<TypeCategory::Real, WRAPPER, WRAPPED>(
dyType.kind(), std::move(x));
diff --git a/flang/include/flang/Evaluate/type.h b/flang/include/flang/Evaluate/type.h
index bd8887dbce4e82..1f9296ac4fea75 100644
--- a/flang/include/flang/Evaluate/type.h
+++ b/flang/include/flang/Evaluate/type.h
@@ -69,6 +69,7 @@ static constexpr bool IsValidKindOfIntrinsicType(
TypeCategory category, std::int64_t kind) {
switch (category) {
case TypeCategory::Integer:
+ case TypeCategory::Unsigned:
return kind == 1 || kind == 2 || kind == 4 || kind == 8 || kind == 16;
case TypeCategory::Real:
case TypeCategory::Complex:
@@ -287,6 +288,13 @@ class Type<TypeCategory::Integer, KIND>
using Scalar = value::Integer<8 * KIND>;
};
+template <int KIND>
+class Type<TypeCategory::Unsigned, KIND>
+ : public TypeBase<TypeCategory::Unsigned, KIND> {
+public:
+ using Scalar = value::Integer<8 * KIND>;
+};
+
template <int KIND>
class Type<TypeCategory::Real, KIND>
: public TypeBase<TypeCategory::Real, KIND> {
@@ -367,11 +375,13 @@ using RealTypes = CategoryTypes<TypeCategory::Real>;
using ComplexTypes = CategoryTypes<TypeCategory::Complex>;
using CharacterTypes = CategoryTypes<TypeCategory::Character>;
using LogicalTypes = CategoryTypes<TypeCategory::Logical>;
+using UnsignedTypes = CategoryTypes<TypeCategory::Unsigned>;
using FloatingTypes = common::CombineTuples<RealTypes, ComplexTypes>;
-using NumericTypes = common::CombineTuples<IntegerTypes, FloatingTypes>;
-using RelationalTypes =
- common::CombineTuples<IntegerTypes, RealTypes, CharacterTypes>;
+using NumericTypes =
+ common::CombineTuples<IntegerTypes, FloatingTypes, UnsignedTypes>;
+using RelationalTypes = common::CombineTuples<IntegerTypes, RealTypes,
+ CharacterTypes, UnsignedTypes>;
using AllIntrinsicTypes =
common::CombineTuples<NumericTypes, CharacterTypes, LogicalTypes>;
using LengthlessIntrinsicTypes =
@@ -397,11 +407,13 @@ template <TypeCategory CATEGORY> struct SomeKind {
}
};
-using NumericCategoryTypes = std::tuple<SomeKind<TypeCategory::Integer>,
- SomeKind<TypeCategory::Real>, SomeKind<TypeCategory::Complex>>;
-using AllIntrinsicCategoryTypes = std::tuple<SomeKind<TypeCategory::Integer>,
- SomeKind<TypeCategory::Real>, SomeKind<TypeCategory::Complex>,
- SomeKind<TypeCategory::Character>, SomeKind<TypeCategory::Logical>>;
+using NumericCategoryTypes =
+ std::tuple<SomeKind<TypeCategory::Integer>, SomeKind<TypeCategory::Real>,
+ SomeKind<TypeCategory::Complex>, SomeKind<TypeCategory::Unsigned>>;
+using AllIntrinsicCategoryTypes =
+ std::tuple<SomeKind<TypeCategory::Integer>, SomeKind<TypeCategory::Real>,
+ SomeKind<TypeCategory::Complex>, SomeKind<TypeCategory::Character>,
+ SomeKind<TypeCategory::Logical>, SomeKind<TypeCategory::Unsigned>>;
// Represents a completely generic type (or, for Expr<SomeType>, a typeless
// value like a BOZ literal or NULL() pointer).
@@ -448,9 +460,10 @@ using SomeReal = SomeKind<TypeCategory::Real>;
using SomeComplex = SomeKind<TypeCategory::Complex>;
using SomeCharacter = SomeKind<TypeCategory::Character>;
using SomeLogical = SomeKind<TypeCategory::Logical>;
+using SomeUnsigned = SomeKind<TypeCategory::Unsigned>;
using SomeDerived = SomeKind<TypeCategory::Derived>;
using SomeCategory = std::tuple<SomeInteger, SomeReal, SomeComplex,
- SomeCharacter, SomeLogical, SomeDerived>;
+ SomeCharacter, SomeLogical, SomeUnsigned, SomeDerived>;
using AllTypes =
common::CombineTuples<AllIntrinsicTypes, std::tuple<SomeDerived>>;
@@ -507,6 +520,7 @@ bool AreSameDerivedTypeIgnoringTypeParameters(
#define EXPAND_FOR_EACH_CHARACTER_KIND(M, P, S) M(P, S, 1) M(P, S, 2) M(P, S, 4)
#define EXPAND_FOR_EACH_LOGICAL_KIND(M, P, S) \
M(P, S, 1) M(P, S, 2) M(P, S, 4) M(P, S, 8)
+#define EXPAND_FOR_EACH_UNSIGNED_KIND EXPAND_FOR_EACH_INTEGER_KIND
#define FOR_EACH_INTEGER_KIND_HELP(PREFIX, SUFFIX, K) \
PREFIX<Type<TypeCategory::Integer, K>> SUFFIX;
@@ -518,6 +532,8 @@ bool AreSameDerivedTypeIgnoringTypeParameters(
PREFIX<Type<TypeCategory::Character, K>> SUFFIX;
#define FOR_EACH_LOGICAL_KIND_HELP(PREFIX, SUFFIX, K) \
PREFIX<Type<TypeCategory::Logical, K>> SUFFIX;
+#define FOR_EACH_UNSIGNED_KIND_HELP(PREFIX, SUFFIX, K) \
+ PREFIX<Type<TypeCategory::Unsigned, K>> SUFFIX;
...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/113504
More information about the cfe-commits
mailing list