[flang-commits] [flang] [flang] Enumeration Type: (PR 2/5) Name Resolution + Expression + Relational + SELECT CASE (PR #193028)

via flang-commits flang-commits at lists.llvm.org
Thu Jun 25 08:25:18 PDT 2026


================
@@ -755,6 +755,79 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
                 },
                 std::move(cx.u), std::move(cy.u));
           },
+          [&](Expr<SomeDerived> &&dx,
+              Expr<SomeDerived> &&dy) -> std::optional<Expr<LogicalResult>> {
+            // Enumeration type comparison: extract __ordinal and delegate
+            // to integer comparison
+            auto xType{dx.GetType()};
+            auto yType{dy.GetType()};
+            if (xType && yType) {
+              const auto *xDerived{GetDerivedTypeSpec(*xType)};
+              const auto *yDerived{GetDerivedTypeSpec(*yType)};
+              if (xDerived && yDerived && xDerived->IsEnumerationType() &&
+                  yDerived->IsEnumerationType() &&
+                  &xDerived->typeSymbol() == &yDerived->typeSymbol()) {
+                if (const auto *scope{xDerived->GetScope()}) {
+                  auto ordIter{
+                      scope->find(semantics::SourceName{"__ordinal", 9})};
+                  if (ordIter != scope->end()) {
+                    const semantics::Symbol &ordSym{*ordIter->second};
+                    // Try to extract from Constant<SomeDerived>
+                    auto extractOrdinal = [&](Expr<SomeDerived> &expr)
+                        -> std::optional<Expr<SomeType>> {
+                      if (auto *constant{
+                              UnwrapConstantValue<SomeDerived>(expr)}) {
+                        if (auto sc{constant->GetScalarValue()}) {
+                          return sc->Find(ordSym);
+                        }
+                      } else if (auto *sc{
+                                     UnwrapExpr<StructureConstructor>(expr)}) {
+                        return sc->Find(ordSym);
+                      }
+                      return std::nullopt;
+                    };
+                    auto xOrd{extractOrdinal(dx)};
+                    auto yOrd{extractOrdinal(dy)};
+                    if (xOrd && yOrd) {
+                      return Relate(
+                          messages, opr, std::move(*xOrd), std::move(*yOrd));
+                    }
+                    // Non-constant operands: wrap in INT() to convert to
+                    // integer comparison. Build FunctionRef<Int4> for each
+                    // operand representing INT(enumExpr).
+                    auto makeIntCall =
+                        [&](Expr<SomeDerived> &&operand) -> Expr<SomeType> {
+                      using IntType = Type<TypeCategory::Integer, 4>;
+                      DynamicType enumType{*xDerived};
+                      DynamicType intResultType{TypeCategory::Integer, 4};
+                      characteristics::DummyDataObject ddo{
+                          characteristics::TypeAndShape{enumType}};
+                      ddo.intent = common::Intent::In;
+                      characteristics::Procedure::Attrs attrs;
+                      attrs.set(characteristics::Procedure::Attr::Pure);
+                      attrs.set(characteristics::Procedure::Attr::Elemental);
----------------
kwyatt-ext wrote:

Done.

https://github.com/llvm/llvm-project/pull/193028


More information about the flang-commits mailing list