[flang-commits] [flang] [flang] Migrate away from std::nullopt (NFC) (PR #145928)

Kazu Hirata via flang-commits flang-commits at lists.llvm.org
Thu Jun 26 09:55:59 PDT 2025


https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/145928

ArrayRef has a constructor that accepts std::nullopt.  This
constructor dates back to the days when we still had llvm::Optional.

Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.

This patch replaces std::nullopt with {}.  There are a couple of
places where std::nullopt is replaced with TypeRange() to accommodate
perfect forwarding.


>From 9821fe8dd2b0f3af01f8e2543ab66ee36b938227 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Thu, 26 Jun 2025 08:52:36 -0700
Subject: [PATCH] [flang] Migrate away from std::nullopt (NFC)

ArrayRef has a constructor that accepts std::nullopt.  This
constructor dates back to the days when we still had llvm::Optional.

Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.

This patch replaces std::nullopt with {}.  There are a couple of
places where std::nullopt is replaced with TypeRange() to accommodate
perfect forwarding.
---
 flang/include/flang/Lower/AbstractConverter.h |  2 +-
 .../flang/Optimizer/Builder/FIRBuilder.h      |  4 +--
 .../Optimizer/Dialect/Support/KindMapping.h   |  2 +-
 flang/lib/Lower/Allocatable.cpp               | 25 +++++++++----------
 flang/lib/Lower/Bridge.cpp                    |  3 +--
 flang/lib/Lower/CallInterface.cpp             | 10 +++-----
 flang/lib/Lower/ConvertConstant.cpp           |  7 +++---
 flang/lib/Lower/ConvertExprToHLFIR.cpp        | 14 +++++------
 flang/lib/Lower/ConvertVariable.cpp           | 17 ++++++-------
 flang/lib/Lower/HostAssociations.cpp          |  4 +--
 flang/lib/Lower/Mangler.cpp                   |  6 ++---
 flang/lib/Optimizer/Builder/Character.cpp     |  2 +-
 flang/lib/Optimizer/Builder/MutableBox.cpp    |  2 +-
 flang/lib/Optimizer/CodeGen/TypeConverter.cpp |  4 +--
 14 files changed, 47 insertions(+), 55 deletions(-)

diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h
index de3e833f60699..59f8ba0cffcf0 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -267,7 +267,7 @@ class AbstractConverter {
   /// Generate the type from a category and kind and length parameters.
   virtual mlir::Type
   genType(Fortran::common::TypeCategory tc, int kind,
-          llvm::ArrayRef<std::int64_t> lenParameters = std::nullopt) = 0;
+          llvm::ArrayRef<std::int64_t> lenParameters = {}) = 0;
   /// Generate the type from a DerivedTypeSpec.
   virtual mlir::Type genType(const Fortran::semantics::DerivedTypeSpec &) = 0;
   /// Generate the type from a Variable
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 6e617d50f0be5..e1eaab3346901 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -537,14 +537,14 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
   /// Create an IfOp with no "else" region, and no result values.
   /// Usage: genIfThen(loc, cdt).genThen(lambda).end();
   IfBuilder genIfThen(mlir::Location loc, mlir::Value cdt) {
-    auto op = create<fir::IfOp>(loc, std::nullopt, cdt, false);
+    auto op = create<fir::IfOp>(loc, mlir::TypeRange(), cdt, false);
     return IfBuilder(op, *this);
   }
 
   /// Create an IfOp with an "else" region, and no result values.
   /// Usage: genIfThenElse(loc, cdt).genThen(lambda).genElse(lambda).end();
   IfBuilder genIfThenElse(mlir::Location loc, mlir::Value cdt) {
-    auto op = create<fir::IfOp>(loc, std::nullopt, cdt, true);
+    auto op = create<fir::IfOp>(loc, mlir::TypeRange(), cdt, true);
     return IfBuilder(op, *this);
   }
 
diff --git a/flang/include/flang/Optimizer/Dialect/Support/KindMapping.h b/flang/include/flang/Optimizer/Dialect/Support/KindMapping.h
index 083526fcbac94..28e101a60d1f9 100644
--- a/flang/include/flang/Optimizer/Dialect/Support/KindMapping.h
+++ b/flang/include/flang/Optimizer/Dialect/Support/KindMapping.h
@@ -66,7 +66,7 @@ class KindMapping {
   /// of 6 KindTy must be passed. The kinds must be the given in the following
   /// order: CHARACTER, COMPLEX, DOUBLE PRECISION, INTEGER, LOGICAL, and REAL.
   explicit KindMapping(mlir::MLIRContext *context, llvm::StringRef map,
-                       llvm::ArrayRef<KindTy> defs = std::nullopt);
+                       llvm::ArrayRef<KindTy> defs = {});
   explicit KindMapping(mlir::MLIRContext *context, llvm::StringRef map,
                        llvm::StringRef defs)
       : KindMapping{context, map, toDefaultKinds(defs)} {}
diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp
index dd90e8900704b..5536bfe8d63ca 100644
--- a/flang/lib/Lower/Allocatable.cpp
+++ b/flang/lib/Lower/Allocatable.cpp
@@ -1041,19 +1041,19 @@ createMutableProperties(Fortran::lower::AbstractConverter &converter,
     baseAddrTy = boxType.getEleTy();
   // Allocate and set a variable to hold the address.
   // It will be set to null in setUnallocatedStatus.
-  mutableProperties.addr = builder.allocateLocal(
-      loc, baseAddrTy, name + ".addr", "",
-      /*shape=*/std::nullopt, /*typeparams=*/std::nullopt);
+  mutableProperties.addr =
+      builder.allocateLocal(loc, baseAddrTy, name + ".addr", "",
+                            /*shape=*/{}, /*typeparams=*/{});
   // Allocate variables to hold lower bounds and extents.
   int rank = sym.Rank();
   mlir::Type idxTy = builder.getIndexType();
   for (decltype(rank) i = 0; i < rank; ++i) {
-    mlir::Value lboundVar = builder.allocateLocal(
-        loc, idxTy, name + ".lb" + std::to_string(i), "",
-        /*shape=*/std::nullopt, /*typeparams=*/std::nullopt);
-    mlir::Value extentVar = builder.allocateLocal(
-        loc, idxTy, name + ".ext" + std::to_string(i), "",
-        /*shape=*/std::nullopt, /*typeparams=*/std::nullopt);
+    mlir::Value lboundVar =
+        builder.allocateLocal(loc, idxTy, name + ".lb" + std::to_string(i), "",
+                              /*shape=*/{}, /*typeparams=*/{});
+    mlir::Value extentVar =
+        builder.allocateLocal(loc, idxTy, name + ".ext" + std::to_string(i), "",
+                              /*shape=*/{}, /*typeparams=*/{});
     mutableProperties.lbounds.emplace_back(lboundVar);
     mutableProperties.extents.emplace_back(extentVar);
   }
@@ -1068,10 +1068,9 @@ createMutableProperties(Fortran::lower::AbstractConverter &converter,
     if (record.getNumLenParams() != 0)
       TODO(loc, "deferred length type parameters.");
   if (fir::isa_char(eleTy) && nonDeferredParams.empty()) {
-    mlir::Value lenVar =
-        builder.allocateLocal(loc, builder.getCharacterLengthType(),
-                              name + ".len", "", /*shape=*/std::nullopt,
-                              /*typeparams=*/std::nullopt);
+    mlir::Value lenVar = builder.allocateLocal(
+        loc, builder.getCharacterLengthType(), name + ".len", "", /*shape=*/{},
+        /*typeparams=*/{});
     mutableProperties.deferredParams.emplace_back(lenVar);
   }
   return mutableProperties;
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 8506b9a984e58..7b640dd497af3 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -701,8 +701,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
   }
   mlir::Type genType(Fortran::common::TypeCategory tc) override final {
     return Fortran::lower::getFIRType(
-        &getMLIRContext(), tc, bridge.getDefaultKinds().GetDefaultKind(tc),
-        std::nullopt);
+        &getMLIRContext(), tc, bridge.getDefaultKinds().GetDefaultKind(tc), {});
   }
 
   Fortran::lower::TypeConstructionStack &
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index 676c26dbcdbec..72431a9cfacc4 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -1338,15 +1338,13 @@ class Fortran::lower::CallInterfaceImpl {
           getConverter().getFoldingContext(), toEvExpr(*expr)));
     return std::nullopt;
   }
-  void addFirOperand(
-      mlir::Type type, int entityPosition, Property p,
-      llvm::ArrayRef<mlir::NamedAttribute> attributes = std::nullopt) {
+  void addFirOperand(mlir::Type type, int entityPosition, Property p,
+                     llvm::ArrayRef<mlir::NamedAttribute> attributes = {}) {
     interface.inputs.emplace_back(
         FirPlaceHolder{type, entityPosition, p, attributes});
   }
-  void
-  addFirResult(mlir::Type type, int entityPosition, Property p,
-               llvm::ArrayRef<mlir::NamedAttribute> attributes = std::nullopt) {
+  void addFirResult(mlir::Type type, int entityPosition, Property p,
+                    llvm::ArrayRef<mlir::NamedAttribute> attributes = {}) {
     interface.outputs.emplace_back(
         FirPlaceHolder{type, entityPosition, p, attributes});
   }
diff --git a/flang/lib/Lower/ConvertConstant.cpp b/flang/lib/Lower/ConvertConstant.cpp
index 38f83f1deceb8..1051d50ce8a9a 100644
--- a/flang/lib/Lower/ConvertConstant.cpp
+++ b/flang/lib/Lower/ConvertConstant.cpp
@@ -150,8 +150,8 @@ class DenseGlobalBuilder {
     auto attrTc = TC == Fortran::common::TypeCategory::Logical
                       ? Fortran::common::TypeCategory::Integer
                       : TC;
-    attributeElementType = Fortran::lower::getFIRType(
-        builder.getContext(), attrTc, KIND, std::nullopt);
+    attributeElementType =
+        Fortran::lower::getFIRType(builder.getContext(), attrTc, KIND, {});
     for (auto element : constant.values())
       attributes.push_back(
           convertToAttribute<TC, KIND>(builder, element, attributeElementType));
@@ -230,8 +230,7 @@ static mlir::Value genScalarLit(
                 TC == Fortran::common::TypeCategory::Unsigned) {
     // MLIR requires constants to be signless
     mlir::Type ty = Fortran::lower::getFIRType(
-        builder.getContext(), Fortran::common::TypeCategory::Integer, KIND,
-        std::nullopt);
+        builder.getContext(), Fortran::common::TypeCategory::Integer, KIND, {});
     if (KIND == 16) {
       auto bigInt = llvm::APInt(ty.getIntOrFloatBitWidth(),
                                 TC == Fortran::common::TypeCategory::Unsigned
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 808928bc97adf..df8dfbc72c030 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -1065,7 +1065,7 @@ struct BinaryOp<Fortran::evaluate::Divide<
                                          hlfir::Entity lhs, hlfir::Entity rhs) {
     mlir::Type ty = Fortran::lower::getFIRType(
         builder.getContext(), Fortran::common::TypeCategory::Complex, KIND,
-        /*params=*/std::nullopt);
+        /*params=*/{});
     return hlfir::EntityWithAttributes{
         fir::genDivC(builder, loc, ty, lhs, rhs)};
   }
@@ -1078,7 +1078,7 @@ struct BinaryOp<Fortran::evaluate::Power<Fortran::evaluate::Type<TC, KIND>>> {
                                          fir::FirOpBuilder &builder, const Op &,
                                          hlfir::Entity lhs, hlfir::Entity rhs) {
     mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, KIND,
-                                               /*params=*/std::nullopt);
+                                               /*params=*/{});
     return hlfir::EntityWithAttributes{fir::genPow(builder, loc, ty, lhs, rhs)};
   }
 };
@@ -1092,7 +1092,7 @@ struct BinaryOp<
                                          fir::FirOpBuilder &builder, const Op &,
                                          hlfir::Entity lhs, hlfir::Entity rhs) {
     mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, KIND,
-                                               /*params=*/std::nullopt);
+                                               /*params=*/{});
     return hlfir::EntityWithAttributes{fir::genPow(builder, loc, ty, lhs, rhs)};
   }
 };
@@ -1416,7 +1416,7 @@ struct UnaryOp<Fortran::evaluate::Negate<
     // Like LLVM, integer negation is the binary op "0 - value"
     mlir::Type type = Fortran::lower::getFIRType(
         builder.getContext(), Fortran::common::TypeCategory::Integer, KIND,
-        /*params=*/std::nullopt);
+        /*params=*/{});
     mlir::Value zero = builder.createIntegerConstant(loc, type, 0);
     return hlfir::EntityWithAttributes{
         builder.create<mlir::arith::SubIOp>(loc, zero, lhs)};
@@ -1517,7 +1517,7 @@ struct UnaryOp<
       return hlfir::convertCharacterKind(loc, builder, lhs, KIND);
     }
     mlir::Type type = Fortran::lower::getFIRType(builder.getContext(), TC1,
-                                                 KIND, /*params=*/std::nullopt);
+                                                 KIND, /*params=*/{});
     mlir::Value res = builder.convertWithSemantics(loc, type, lhs);
     return hlfir::EntityWithAttributes{res};
   }
@@ -1661,7 +1661,7 @@ class HlfirBuilder {
     } else {
       elementType =
           Fortran::lower::getFIRType(builder.getContext(), R::category, R::kind,
-                                     /*params=*/std::nullopt);
+                                     /*params=*/{});
     }
     mlir::Value shape = hlfir::genShape(loc, builder, left);
     auto genKernel = [&op, &left, &unaryOp](
@@ -1699,7 +1699,7 @@ class HlfirBuilder {
     // Elemental expression.
     mlir::Type elementType =
         Fortran::lower::getFIRType(builder.getContext(), R::category, R::kind,
-                                   /*params=*/std::nullopt);
+                                   /*params=*/{});
     // TODO: "merge" shape, get cst shape from front-end if possible.
     mlir::Value shape;
     if (left.isArray()) {
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 6f818cd7dc303..49e6ea02d51a7 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1289,9 +1289,8 @@ instantiateAggregateStore(Fortran::lower::AbstractConverter &converter,
   auto size = std::get<1>(var.getInterval());
   fir::SequenceType::Shape shape(1, size);
   auto seqTy = fir::SequenceType::get(shape, i8Ty);
-  mlir::Value local =
-      builder.allocateLocal(loc, seqTy, aggName, "", std::nullopt, std::nullopt,
-                            /*target=*/false);
+  mlir::Value local = builder.allocateLocal(loc, seqTy, aggName, "", {}, {},
+                                            /*target=*/false);
   insertAggregateStore(storeMap, var, local);
 }
 
@@ -1839,8 +1838,8 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
                              Fortran::lower::SymMap &symMap,
                              const Fortran::semantics::Symbol &sym,
                              mlir::Value base, mlir::Value len = {},
-                             llvm::ArrayRef<mlir::Value> shape = std::nullopt,
-                             llvm::ArrayRef<mlir::Value> lbounds = std::nullopt,
+                             llvm::ArrayRef<mlir::Value> shape = {},
+                             llvm::ArrayRef<mlir::Value> lbounds = {},
                              bool force = false) {
   // In HLFIR, procedure dummy symbols are not added with an hlfir.declare
   // because they are "values", and hlfir.declare is intended for variables. It
@@ -2008,8 +2007,8 @@ genAllocatableOrPointerDeclare(Fortran::lower::AbstractConverter &converter,
     explictLength = box.nonDeferredLenParams()[0];
   }
   genDeclareSymbol(converter, symMap, sym, base, explictLength,
-                   /*shape=*/std::nullopt,
-                   /*lbounds=*/std::nullopt, force);
+                   /*shape=*/{},
+                   /*lbounds=*/{}, force);
 }
 
 /// Map a procedure pointer
@@ -2018,8 +2017,8 @@ static void genProcPointer(Fortran::lower::AbstractConverter &converter,
                            const Fortran::semantics::Symbol &sym,
                            mlir::Value addr, bool force = false) {
   genDeclareSymbol(converter, symMap, sym, addr, mlir::Value{},
-                   /*shape=*/std::nullopt,
-                   /*lbounds=*/std::nullopt, force);
+                   /*shape=*/{},
+                   /*lbounds=*/{}, force);
 }
 
 /// Map a symbol represented with a runtime descriptor to its FIR fir.box and
diff --git a/flang/lib/Lower/HostAssociations.cpp b/flang/lib/Lower/HostAssociations.cpp
index e58dc827652ec..6a44be65a6cde 100644
--- a/flang/lib/Lower/HostAssociations.cpp
+++ b/flang/lib/Lower/HostAssociations.cpp
@@ -449,7 +449,7 @@ class CapturedArrays : public CapturedSymbols<CapturedArrays> {
     }
 
     if (canReadCapturedBoxValue(converter, sym)) {
-      fir::BoxValue boxValue(box, lbounds, /*explicitParams=*/std::nullopt);
+      fir::BoxValue boxValue(box, lbounds, /*explicitParams=*/{});
       bindCapturedSymbol(sym,
                          fir::factory::readBoxValue(builder, loc, boxValue),
                          converter, args.symMap);
@@ -470,7 +470,7 @@ class CapturedArrays : public CapturedSymbols<CapturedArrays> {
         box = builder.create<mlir::arith::SelectOp>(loc, isPresent, box,
                                                     absentBox);
       }
-      fir::BoxValue boxValue(box, lbounds, /*explicitParams=*/std::nullopt);
+      fir::BoxValue boxValue(box, lbounds, /*explicitParams=*/{});
       bindCapturedSymbol(sym, boxValue, converter, args.symMap);
     }
   }
diff --git a/flang/lib/Lower/Mangler.cpp b/flang/lib/Lower/Mangler.cpp
index 1165417ef89a2..1333e3fe349d1 100644
--- a/flang/lib/Lower/Mangler.cpp
+++ b/flang/lib/Lower/Mangler.cpp
@@ -119,8 +119,7 @@ std::string Fortran::lower::mangle::mangleName(
             // Mangle external procedure without any scope prefix.
             if (!keepExternalInScope &&
                 Fortran::semantics::IsExternal(ultimateSymbol))
-              return fir::NameUniquer::doProcedure(std::nullopt, std::nullopt,
-                                                   symbolName);
+              return fir::NameUniquer::doProcedure({}, {}, symbolName);
             // A separate module procedure must be mangled according to its
             // declaration scope, not its definition scope.
             const Fortran::semantics::Symbol *interface = &ultimateSymbol;
@@ -142,8 +141,7 @@ std::string Fortran::lower::mangle::mangleName(
             }
             // Otherwise, this is an external procedure, with or without an
             // explicit EXTERNAL attribute. Mangle it without any prefix.
-            return fir::NameUniquer::doProcedure(std::nullopt, std::nullopt,
-                                                 symbolName);
+            return fir::NameUniquer::doProcedure({}, {}, symbolName);
           },
           [&](const Fortran::semantics::ObjectEntityDetails &) {
             return mangleObject();
diff --git a/flang/lib/Optimizer/Builder/Character.cpp b/flang/lib/Optimizer/Builder/Character.cpp
index cd7ffd27117d3..61428ac490a46 100644
--- a/flang/lib/Optimizer/Builder/Character.cpp
+++ b/flang/lib/Optimizer/Builder/Character.cpp
@@ -380,7 +380,7 @@ fir::factory::CharacterExprHelper::createCharacterTemp(mlir::Type type,
   if (typeLen == fir::CharacterType::unknownLen())
     lenParams.push_back(len);
   auto ref = builder.allocateLocal(loc, charTy, "", ".chrtmp",
-                                   /*shape=*/std::nullopt, lenParams);
+                                   /*shape=*/{}, lenParams);
   return {ref, len};
 }
 
diff --git a/flang/lib/Optimizer/Builder/MutableBox.cpp b/flang/lib/Optimizer/Builder/MutableBox.cpp
index f20b5e37dffd8..d944a4c98473e 100644
--- a/flang/lib/Optimizer/Builder/MutableBox.cpp
+++ b/flang/lib/Optimizer/Builder/MutableBox.cpp
@@ -362,7 +362,7 @@ mlir::Value fir::factory::createUnallocatedBox(
     auto zero = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
     llvm::SmallVector<mlir::Value> extents(seqTy.getDimension(), zero);
     shape = builder.createShape(
-        loc, fir::ArrayBoxValue{nullAddr, extents, /*lbounds=*/std::nullopt});
+        loc, fir::ArrayBoxValue{nullAddr, extents, /*lbounds=*/{}});
   }
   // Provide dummy length parameters if they are dynamic. If a length parameter
   // is deferred. It is set to zero here and will be set on allocation.
diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
index 1a1d3a8cfb870..22835605ba9db 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
@@ -128,8 +128,8 @@ LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
                                                   /*isPacked=*/false);
   });
   addConversion([&](mlir::NoneType none) {
-    return mlir::LLVM::LLVMStructType::getLiteral(
-        none.getContext(), std::nullopt, /*isPacked=*/false);
+    return mlir::LLVM::LLVMStructType::getLiteral(none.getContext(), {},
+                                                  /*isPacked=*/false);
   });
   addConversion([&](fir::DummyScopeType dscope) {
     // DummyScopeType values must not have any uses after PreCGRewrite.



More information about the flang-commits mailing list