return parseKindSingleton<fir::ComplexType>(parser);
}
+// `shape` `<` rank `>`
+ShapeType parseShape(mlir::DialectAsmParser &parser) {
+ return parseRankSingleton<ShapeType>(parser);
+}
+
+// `shapeshift` `<` rank `>`
+ShapeShiftType parseShapeShift(mlir::DialectAsmParser &parser) {
+ return parseRankSingleton<ShapeShiftType>(parser);
+}
+
+// `slice` `<` rank `>`
+SliceType parseSlice(mlir::DialectAsmParser &parser) {
+ return parseRankSingleton<SliceType>(parser);
+}
+
// `field`
FieldType parseField(mlir::DialectAsmParser &parser) {
return FieldType::get(parser.getBuilder().getContext());
bool verifyRecordMemberType(mlir::Type ty) {
return !(ty.isa<BoxType>() || ty.isa<BoxCharType>() ||
- ty.isa<BoxProcType>() || ty.isa<FieldType>() || ty.isa<LenType>() ||
+ ty.isa<BoxProcType>() || ty.isa<ShapeType>() ||
+ ty.isa<ShapeShiftType>() || ty.isa<SliceType>() ||
+ ty.isa<FieldType>() || ty.isa<LenType>() ||
ty.isa<ReferenceType>() || ty.isa<TypeDescType>());
}
return parseReal(parser);
if (typeNameLit == "ref")
return parseReference(parser, loc);
+ if (typeNameLit == "shape")
+ return parseShape(parser);
+ if (typeNameLit == "shapeshift")
+ return parseShapeShift(parser);
+ if (typeNameLit == "slice")
+ return parseSlice(parser);
if (typeNameLit == "tdesc")
return parseTypeDesc(parser, loc);
if (typeNameLit == "type")
: kind{kind}, len{len} {}
};
+struct ShapeTypeStorage : public mlir::TypeStorage {
+ using KeyTy = unsigned;
+
+ static unsigned hashKey(const KeyTy &key) { return llvm::hash_combine(key); }
+
+ bool operator==(const KeyTy &key) const { return key == getRank(); }
+
+ static ShapeTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
+ unsigned rank) {
+ auto *storage = allocator.allocate<ShapeTypeStorage>();
+ return new (storage) ShapeTypeStorage{rank};
+ }
+
+ unsigned getRank() const { return rank; }
+
+protected:
+ unsigned rank;
+
+private:
+ ShapeTypeStorage() = delete;
+ explicit ShapeTypeStorage(unsigned rank) : rank{rank} {}
+};
+
+struct ShapeShiftTypeStorage : public mlir::TypeStorage {
+ using KeyTy = unsigned;
+
+ static unsigned hashKey(const KeyTy &key) { return llvm::hash_combine(key); }
+
+ bool operator==(const KeyTy &key) const { return key == getRank(); }
+
+ static ShapeShiftTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
+ unsigned rank) {
+ auto *storage = allocator.allocate<ShapeShiftTypeStorage>();
+ return new (storage) ShapeShiftTypeStorage{rank};
+ }
+
+ unsigned getRank() const { return rank; }
+
+protected:
+ unsigned rank;
+
+private:
+ ShapeShiftTypeStorage() = delete;
+ explicit ShapeShiftTypeStorage(unsigned rank) : rank{rank} {}
+};
+
+struct SliceTypeStorage : public mlir::TypeStorage {
+ using KeyTy = unsigned;
+
+ static unsigned hashKey(const KeyTy &key) { return llvm::hash_combine(key); }
+
+ bool operator==(const KeyTy &key) const { return key == getRank(); }
+
+ static SliceTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
+ unsigned rank) {
+ auto *storage = allocator.allocate<SliceTypeStorage>();
+ return new (storage) SliceTypeStorage{rank};
+ }
+
+ unsigned getRank() const { return rank; }
+
+protected:
+ unsigned rank;
+
+private:
+ SliceTypeStorage() = delete;
+ explicit SliceTypeStorage(unsigned rank) : rank{rank} {}
+};
+
/// The type of a derived type part reference
struct FieldTypeStorage : public mlir::TypeStorage {
using KeyTy = KindTy;
}
bool isa_passbyref_type(mlir::Type t) {
- return t.isa<ReferenceType>() || isa_box_type(t);
+ return t.isa<ReferenceType>() || isa_box_type(t) ||
+ t.isa<mlir::FunctionType>();
}
bool isa_aggregate(mlir::Type t) {
- return t.isa<SequenceType>() || t.isa<RecordType>();
+ return t.isa<SequenceType>() || t.isa<RecordType>() ||
+ t.isa<mlir::TupleType>();
}
mlir::Type dyn_cast_ptrEleTy(mlir::Type t) {
mlir::LogicalResult
fir::ReferenceType::verifyConstructionInvariants(mlir::Location loc,
mlir::Type eleTy) {
- if (eleTy.isa<FieldType>() || eleTy.isa<LenType>() ||
- eleTy.isa<ReferenceType>() || eleTy.isa<TypeDescType>())
+ if (eleTy.isa<ShapeType>() || eleTy.isa<ShapeShiftType>() ||
+ eleTy.isa<SliceType>() || eleTy.isa<FieldType>() ||
+ eleTy.isa<LenType>() || eleTy.isa<ReferenceType>() ||
+ eleTy.isa<TypeDescType>())
return mlir::emitError(loc, "cannot build a reference to type: ")
<< eleTy << '\n';
return mlir::success();
static bool canBePointerOrHeapElementType(mlir::Type eleTy) {
return eleTy.isa<BoxType>() || eleTy.isa<BoxCharType>() ||
- eleTy.isa<BoxProcType>() || eleTy.isa<FieldType>() ||
- eleTy.isa<LenType>() || eleTy.isa<HeapType>() ||
- eleTy.isa<PointerType>() || eleTy.isa<ReferenceType>() ||
- eleTy.isa<TypeDescType>();
+ eleTy.isa<BoxProcType>() || eleTy.isa<ShapeType>() ||
+ eleTy.isa<ShapeShiftType>() || eleTy.isa<SliceType>() ||
+ eleTy.isa<FieldType>() || eleTy.isa<LenType>() ||
+ eleTy.isa<HeapType>() || eleTy.isa<PointerType>() ||
+ eleTy.isa<ReferenceType>() || eleTy.isa<TypeDescType>();
}
mlir::LogicalResult
mlir::AffineMapAttr map) {
// DIMENSION attribute can only be applied to an intrinsic or record type
if (eleTy.isa<BoxType>() || eleTy.isa<BoxCharType>() ||
- eleTy.isa<BoxProcType>() || eleTy.isa<FieldType>() ||
- eleTy.isa<LenType>() || eleTy.isa<HeapType>() ||
+ eleTy.isa<BoxProcType>() || eleTy.isa<ShapeType>() ||
+ eleTy.isa<ShapeShiftType>() || eleTy.isa<SliceType>() ||
+ eleTy.isa<FieldType>() || eleTy.isa<LenType>() || eleTy.isa<HeapType>() ||
eleTy.isa<PointerType>() || eleTy.isa<ReferenceType>() ||
eleTy.isa<TypeDescType>() || eleTy.isa<fir::VectorType>() ||
eleTy.isa<SequenceType>())
return mlir::success();
}
-//===----------------------------------------------------------------------===//
-// Vector type
-//===----------------------------------------------------------------------===//
-
-fir::VectorType fir::VectorType::get(uint64_t len, mlir::Type eleTy) {
- return Base::get(eleTy.getContext(), len, eleTy);
-}
-
-mlir::Type fir::VectorType::getEleTy() const { return getImpl()->getEleTy(); }
-
-uint64_t fir::VectorType::getLen() const { return getImpl()->getLen(); }
-
-mlir::LogicalResult
-fir::VectorType::verifyConstructionInvariants(mlir::Location loc, uint64_t len,
- mlir::Type eleTy) {
- if (!(fir::isa_real(eleTy) || fir::isa_integer(eleTy)))
- return mlir::emitError(loc, "cannot build a vector of type ")
- << eleTy << '\n';
- return mlir::success();
-}
-
// compare if two shapes are equivalent
bool fir::operator==(const SequenceType::Shape &sh_1,
const SequenceType::Shape &sh_2) {
return llvm::hash_combine(0);
}
+// Shape
+
+ShapeType fir::ShapeType::get(mlir::MLIRContext *ctxt, unsigned rank) {
+ return Base::get(ctxt, rank);
+}
+
+unsigned fir::ShapeType::getRank() const { return getImpl()->getRank(); }
+
+// Shapeshift
+
+ShapeShiftType fir::ShapeShiftType::get(mlir::MLIRContext *ctxt,
+ unsigned rank) {
+ return Base::get(ctxt, rank);
+}
+
+unsigned fir::ShapeShiftType::getRank() const { return getImpl()->getRank(); }
+
+// Slice
+
+SliceType fir::SliceType::get(mlir::MLIRContext *ctxt, unsigned rank) {
+ return Base::get(ctxt, rank);
+}
+
+unsigned fir::SliceType::getRank() const { return getImpl()->getRank(); }
+
/// RecordType
///
/// This type captures a Fortran "derived type"
return {};
}
-/// Type descriptor type
-///
-/// This is the type of a type descriptor object (similar to a class instance)
+//===----------------------------------------------------------------------===//
+// Type descriptor type
+//===----------------------------------------------------------------------===//
TypeDescType fir::TypeDescType::get(mlir::Type ofType) {
assert(!ofType.isa<ReferenceType>());
fir::TypeDescType::verifyConstructionInvariants(mlir::Location loc,
mlir::Type eleTy) {
if (eleTy.isa<BoxType>() || eleTy.isa<BoxCharType>() ||
- eleTy.isa<BoxProcType>() || eleTy.isa<FieldType>() ||
- eleTy.isa<LenType>() || eleTy.isa<ReferenceType>() ||
- eleTy.isa<TypeDescType>())
+ eleTy.isa<BoxProcType>() || eleTy.isa<ShapeType>() ||
+ eleTy.isa<ShapeShiftType>() || eleTy.isa<SliceType>() ||
+ eleTy.isa<FieldType>() || eleTy.isa<LenType>() ||
+ eleTy.isa<ReferenceType>() || eleTy.isa<TypeDescType>())
return mlir::emitError(loc, "cannot build a type descriptor of type: ")
<< eleTy << '\n';
return mlir::success();
}
+//===----------------------------------------------------------------------===//
+// Vector type
+//===----------------------------------------------------------------------===//
+
+fir::VectorType fir::VectorType::get(uint64_t len, mlir::Type eleTy) {
+ return Base::get(eleTy.getContext(), len, eleTy);
+}
+
+mlir::Type fir::VectorType::getEleTy() const { return getImpl()->getEleTy(); }
+
+uint64_t fir::VectorType::getLen() const { return getImpl()->getLen(); }
+
+mlir::LogicalResult
+fir::VectorType::verifyConstructionInvariants(mlir::Location loc, uint64_t len,
+ mlir::Type eleTy) {
+ if (!(fir::isa_real(eleTy) || fir::isa_integer(eleTy)))
+ return mlir::emitError(loc, "cannot build a vector of type ")
+ << eleTy << '\n';
+ return mlir::success();
+}
+
namespace {
void printBounds(llvm::raw_ostream &os, const SequenceType::Shape &bounds) {
return;
}
if (auto type = ty.dyn_cast<fir::ComplexType>()) {
+ // Fortran intrinsic type COMPLEX
os << "complex<" << type.getFKind() << '>';
return;
}
if (auto type = ty.dyn_cast<RecordType>()) {
+ // Fortran derived type
os << "type<" << type.getName();
if (!recordTypeVisited.count(type.uniqueKey())) {
recordTypeVisited.insert(type.uniqueKey());
os << '>';
return;
}
+ if (auto type = ty.dyn_cast<ShapeType>()) {
+ os << "shape<" << type.getRank() << '>';
+ return;
+ }
+ if (auto type = ty.dyn_cast<ShapeShiftType>()) {
+ os << "shapeshift<" << type.getRank() << '>';
+ return;
+ }
+ if (auto type = ty.dyn_cast<SliceType>()) {
+ os << "slice<" << type.getRank() << '>';
+ return;
+ }
if (ty.isa<FieldType>()) {
os << "field";
return;
return;
}
if (auto type = ty.dyn_cast<fir::IntegerType>()) {
+ // Fortran intrinsic type INTEGER
os << "int<" << type.getFKind() << '>';
return;
}
return;
}
if (auto type = ty.dyn_cast<LogicalType>()) {
+ // Fortran intrinsic type LOGICAL
os << "logical<" << type.getFKind() << '>';
return;
}
return;
}
if (auto type = ty.dyn_cast<fir::RealType>()) {
+ // Fortran intrinsic types REAL and DOUBLE PRECISION
os << "real<" << type.getFKind() << '>';
return;
}