[flang-commits] [flang] [flang] Enumeration Type: (PR 4/5) Lowering (PR #193571)
via flang-commits
flang-commits at lists.llvm.org
Thu Oct 1 19:49:58 PDT 2026
================
@@ -2074,6 +2379,69 @@ class HlfirBuilder {
mlir::Location loc = getLoc();
fir::FirOpBuilder &builder = getBuilder();
mlir::Type ty = translateSomeExprToFIRType(converter, toEvExpr(ctor));
+
+ // Enumeration types lower to i32 — extract the __ordinal value.
+ // Check via the type symbol's DerivedTypeDetails rather than
+ // DerivedTypeSpec::IsEnumerationType(), which may not be set on
+ // all DerivedTypeSpec instances.
+ if (const auto *dtDetails =
+ ctor.derivedTypeSpec()
+ .typeSymbol()
+ .detailsIf<Fortran::semantics::DerivedTypeDetails>()) {
+ if (dtDetails->isEnumerationType()) {
+ if (const auto *scope = ctor.derivedTypeSpec().GetScope()) {
+ auto it = scope->find(Fortran::parser::CharBlock{"__ordinal", 9});
+ if (it != scope->end()) {
+ if (auto val = ctor.Find(it->second.get())) {
+ if (auto ordinal = Fortran::evaluate::ToInt64(*val)) {
+ mlir::Value result =
+ builder.createIntegerConstant(loc, ty, *ordinal);
+ return hlfir::EntityWithAttributes{result};
+ }
+ // Non-constant ordinal (e.g. color(i) with variable i): lower
+ // the __ordinal component expression to a runtime scalar value.
+ hlfir::Entity ordinalEntity = gen(*val);
+ mlir::Value ordinal =
+ hlfir::loadTrivialScalar(loc, builder, ordinalEntity);
+ if (ordinal.getType() != ty)
+ ordinal = builder.createConvert(loc, ty, ordinal);
+ // F2023 7.6.2 para 5 requires the constructor value to be
+ // positive and <= the number of enumerators. We choose to always
+ // emit a runtime range check with error termination. This block
+ // could be placed behind an -fcheck=enum style flag if the
+ // community prefers an opt-in implementation like gfortran's
+ // -fcheck=bounds.
+ int count = ctor.derivedTypeSpec()
+ .typeSymbol()
+ .GetUltimate()
+ .get<Fortran::semantics::DerivedTypeDetails>()
+ .enumeratorCount();
+ mlir::Value one = builder.createIntegerConstant(loc, ty, 1);
+ mlir::Value maxVal =
+ builder.createIntegerConstant(loc, ty, count);
+ mlir::Value tooLow = mlir::arith::CmpIOp::create(
+ builder, loc, mlir::arith::CmpIPredicate::slt, ordinal, one);
----------------
MattPD wrote:
The constructor now rejects `4294967297_8` as out of range.
https://github.com/llvm/llvm-project/pull/193571
More information about the flang-commits
mailing list