diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -90,12 +90,8 @@ def fir_BoxCharType : Type()">, "box character type">; -// PROCEDURE POINTER descriptor. A pair that can capture a host closure. -def fir_BoxProcType : Type()">, - "box procedure type">; - def AnyBoxLike : TypeConstraint, "any box">; + fir_BoxCharType.predicate, BoxProcType.predicate]>, "any box">; def AnyRefOrBox : TypeConstraint, @@ -1179,7 +1175,7 @@ let arguments = (ins SymbolRefAttr:$funcname, AnyReferenceLike:$host); - let results = (outs fir_BoxProcType); + let results = (outs BoxProcType); let parser = [{ mlir::SymbolRefAttr procRef; @@ -1307,7 +1303,7 @@ return emitOpError("second output argument has bad type"); }]; - let arguments = (ins fir_BoxProcType:$boxproc); + let arguments = (ins BoxProcType:$boxproc); let results = (outs FunctionType, fir_ReferenceType:$refTuple); } @@ -1485,7 +1481,7 @@ the host and the internal procedure. }]; - let arguments = (ins fir_BoxProcType:$val); + let arguments = (ins BoxProcType:$val); let results = (outs fir_ReferenceType); } diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -44,7 +44,6 @@ namespace detail { struct BoxTypeStorage; struct BoxCharTypeStorage; -struct BoxProcTypeStorage; struct CharacterTypeStorage; struct ComplexTypeStorage; struct FieldTypeStorage; @@ -206,20 +205,6 @@ CharacterType getEleTy() const; }; -/// The type of a pair that describes a PROCEDURE reference. Pointers to -/// internal procedures must carry an additional reference to the host's -/// variables that are referenced. -class BoxProcType : public mlir::Type::TypeBase { -public: - using Base::Base; - static BoxProcType get(mlir::Type eleTy); - mlir::Type getEleTy() const; - - static mlir::LogicalResult verifyConstructionInvariants(mlir::Location, - mlir::Type eleTy); -}; - /// Type of a vector that represents an array slice operation on an array. /// Fortran slices are triples of lower bound, upper bound, and stride. The rank /// of a SliceType must be at least 1. diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td --- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td +++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td @@ -21,6 +21,28 @@ let mnemonic = typeMnemonic; } +def BoxProcType : FIR_Type<"BoxProc", "boxproc"> { + let summary = ""; + + let description = [{ + The type of a pair that describes a PROCEDURE reference. Pointers to + internal procedures must carry an additional reference to the host's + variables that are referenced. + }]; + + let parameters = (ins "mlir::Type":$eleTy); + + let printer = [{ + $_printer << "boxproc<"; + $_printer.printType(getEleTy()); + $_printer << '>'; + }]; + + let genAccessors = 1; + + let genVerifyInvariantsDecl = 1; +} + def ShapeType : FIR_Type<"Shape", "shape"> { let summary = "shape of a multidimensional array object"; diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -84,11 +84,6 @@ return parseKindSingleton(parser); } -// `boxproc` `<` return-type `>` -BoxProcType parseBoxProc(mlir::DialectAsmParser &parser, mlir::Location loc) { - return parseTypeSingleton(parser, loc); -} - // `char` `<` kind [`,` `len`] `>` CharacterType parseCharacter(mlir::DialectAsmParser &parser) { int kind = 0; @@ -359,7 +354,7 @@ if (typeNameLit == "boxchar") return parseBoxChar(parser); if (typeNameLit == "boxproc") - return parseBoxProc(parser, loc); + return generatedTypeParser(dialect->getContext(), parser, typeNameLit); if (typeNameLit == "char") return parseCharacter(parser); if (typeNameLit == "complex") @@ -658,31 +653,6 @@ explicit BoxCharTypeStorage(KindTy kind) : kind{kind} {} }; -/// Boxed PROCEDURE POINTER object type -struct BoxProcTypeStorage : public mlir::TypeStorage { - using KeyTy = mlir::Type; - - static unsigned hashKey(const KeyTy &key) { return llvm::hash_combine(key); } - - bool operator==(const KeyTy &key) const { return key == getElementType(); } - - static BoxProcTypeStorage *construct(mlir::TypeStorageAllocator &allocator, - mlir::Type eleTy) { - assert(eleTy && "element type is null"); - auto *storage = allocator.allocate(); - return new (storage) BoxProcTypeStorage{eleTy}; - } - - mlir::Type getElementType() const { return eleTy; } - -protected: - mlir::Type eleTy; - -private: - BoxProcTypeStorage() = delete; - explicit BoxProcTypeStorage(mlir::Type eleTy) : eleTy{eleTy} {} -}; - /// Pointer-like object storage struct ReferenceTypeStorage : public mlir::TypeStorage { using KeyTy = mlir::Type; @@ -1044,27 +1014,6 @@ return getImpl()->getElementType(getContext()); } -// BoxProc - -BoxProcType fir::BoxProcType::get(mlir::Type elementType) { - return Base::get(elementType.getContext(), elementType); -} - -mlir::Type fir::BoxProcType::getEleTy() const { - return getImpl()->getElementType(); -} - -mlir::LogicalResult -fir::BoxProcType::verifyConstructionInvariants(mlir::Location loc, - mlir::Type eleTy) { - if (eleTy.isa()) - return mlir::success(); - if (auto refTy = eleTy.dyn_cast()) - if (refTy.isa()) - return mlir::success(); - return mlir::emitError(loc, "invalid type for boxproc") << eleTy << '\n'; -} - // Reference ReferenceType fir::ReferenceType::get(mlir::Type elementType) { @@ -1355,12 +1304,6 @@ << '>'; return; } - if (auto type = ty.dyn_cast()) { - os << "boxproc<"; - p.printType(type.getEleTy()); - os << '>'; - return; - } if (auto chTy = ty.dyn_cast()) { // Fortran intrinsic type CHARACTER os << "char<" << chTy.getFKind(); @@ -1500,3 +1443,33 @@ } return false; } + +namespace fir { + +//===----------------------------------------------------------------------===// +// BoxProcType +//===----------------------------------------------------------------------===// + +// `boxproc` `<` return-type `>` +mlir::Type BoxProcType::parse(mlir::MLIRContext *context, + mlir::DialectAsmParser &parser) { + mlir::Type ty; + if (parser.parseLess() || parser.parseType(ty) || parser.parseGreater()) { + parser.emitError(parser.getCurrentLocation(), "type expected"); + return Type(); + } + return get(context, ty); +} + +mlir::LogicalResult +BoxProcType::verifyConstructionInvariants(mlir::Location loc, + mlir::Type eleTy) { + if (eleTy.isa()) + return mlir::success(); + if (auto refTy = eleTy.dyn_cast()) + if (refTy.isa()) + return mlir::success(); + return mlir::emitError(loc, "invalid type for boxproc") << eleTy << '\n'; +} + +} // namespace fir