cast = builder.create<fir::EmboxProcOp>(loc, boxProcTy, fst);
}
} else {
+ if (fir::isa_derived(snd)) {
+ // FIXME: This seems like a serious bug elsewhere in lowering. Paper
+ // over the problem for now.
+ TODO(loc, "derived type argument passed by value");
+ }
+ assert(!fir::isa_derived(snd));
cast = builder.convertWithSemantics(loc, snd, fst,
callingImplicitInterface);
}
auto seqTy = type.dyn_cast<fir::SequenceType>();
assert(seqTy && "must be an array");
mlir::Location loc = getLoc();
- // TODO: Need to thread the length parameters here. For character, they may
+ // TODO: Need to thread the LEN parameters here. For character, they may
// differ from the operands length (e.g concatenation). So the array loads
// type parameters are not enough.
if (auto charTy = seqTy.getEleTy().dyn_cast<fir::CharacterType>())
mlir::Value multiplier = builder.createIntegerConstant(loc, idxTy, 1);
if (fir::hasDynamicSize(eleTy)) {
if (auto charTy = eleTy.dyn_cast<fir::CharacterType>()) {
- // Array of char with dynamic length parameter. Downcast to an array
+ // Array of char with dynamic LEN parameter. Downcast to an array
// of singleton char, and scale by the len type parameter from
// `exv`.
exv.match(
assert(eleTy && "result must be a reference-like type");
if (fir::characterWithDynamicLen(eleTy)) {
assert(coor.lenParams().size() == 1);
- auto bitsInChar = lowerTy().getKindMap().getCharacterBitsize(
- eleTy.cast<fir::CharacterType>().getFKind());
- auto scaling = genConstantIndex(loc, idxTy, rewriter, bitsInChar / 8);
- auto scaledBySize =
- rewriter.create<mlir::LLVM::MulOp>(loc, idxTy, offset, scaling);
- auto length =
- integerCast(loc, rewriter, idxTy,
- adaptor.getOperands()[coor.lenParamsOffset()]);
- offset = rewriter.create<mlir::LLVM::MulOp>(loc, idxTy, scaledBySize,
- length);
+ auto length = integerCast(loc, rewriter, idxTy,
+ operands[coor.lenParamsOffset()]);
+ offset =
+ rewriter.create<mlir::LLVM::MulOp>(loc, idxTy, offset, length);
+
} else {
TODO(loc, "compute size of derived type with type parameters");
}
// ArrayCoorOp
//===----------------------------------------------------------------------===//
+// CHARACTERs and derived types with LEN PARAMETERs are dependent types that
+// require runtime values to fully define the type of an object.
+static bool validTypeParams(mlir::Type dynTy, mlir::ValueRange typeParams) {
+ dynTy = fir::unwrapAllRefAndSeqType(dynTy);
+ // A box value will contain type parameter values itself.
+ if (dynTy.isa<fir::BoxType>())
+ return typeParams.size() == 0;
+ // Derived type must have all type parameters satisfied.
+ if (auto recTy = dynTy.dyn_cast<fir::RecordType>())
+ return typeParams.size() == recTy.getNumLenParams();
+ // Characters with non-constant LEN must have a type parameter value.
+ if (auto charTy = dynTy.dyn_cast<fir::CharacterType>())
+ if (charTy.hasDynamicLen())
+ return typeParams.size() == 1;
+ // Otherwise, any type parameters are invalid.
+ return typeParams.size() == 0;
+}
+
mlir::LogicalResult fir::ArrayCoorOp::verify() {
auto eleTy = fir::dyn_cast_ptrOrBoxEleTy(getMemref().getType());
auto arrTy = eleTy.dyn_cast<fir::SequenceType>();
if (sliceTy.getRank() != arrDim)
return emitOpError("rank of dimension in slice mismatched");
}
+ if (!validTypeParams(getMemref().getType(), getTypeparams()))
+ return emitOpError("invalid type parameters");
return mlir::success();
}
return emitOpError("rank of dimension in slice mismatched");
}
+ if (!validTypeParams(getMemref().getType(), getTypeparams()))
+ return emitOpError("invalid type parameters");
+
return mlir::success();
}
return emitOpError("type of origin does not match memref element type");
if (getSequence().getType() != eleTy)
return emitOpError("type of sequence does not match memref element type");
+ if (!validTypeParams(getMemref().getType(), getTypeparams()))
+ return emitOpError("invalid type parameters");
return mlir::success();
}
return emitOpError("return type and/or indices do not type check");
if (!mlir::isa<fir::ArrayLoadOp>(getSequence().getDefiningOp()))
return emitOpError("argument #0 must be result of fir.array_load");
+ if (!validTypeParams(arrTy, getTypeparams()))
+ return emitOpError("invalid type parameters");
return mlir::success();
}
mlir::Type ty = validArraySubobject(*this);
if (!ty || fir::ReferenceType::get(ty) != getType())
return emitOpError("return type and/or indices do not type check");
+ if (!validTypeParams(arrTy, getTypeparams()))
+ return emitOpError("invalid type parameters");
return mlir::success();
}
auto ty = validArraySubobject(*this);
if (!ty || ty != ::adjustedElementType(getMerge().getType()))
return emitOpError("merged value and/or indices do not type check");
+ if (!validTypeParams(arrTy, getTypeparams()))
+ return emitOpError("invalid type parameters");
return mlir::success();
}
result.addTypes(results);
}
+//===----------------------------------------------------------------------===//
+// CharConvertOp
+//===----------------------------------------------------------------------===//
+
+mlir::LogicalResult fir::CharConvertOp::verify() {
+ auto unwrap = [&](mlir::Type t) {
+ t = fir::unwrapSequenceType(fir::dyn_cast_ptrEleTy(t));
+ return t.dyn_cast<fir::CharacterType>();
+ };
+ auto inTy = unwrap(getFrom().getType());
+ auto outTy = unwrap(getTo().getType());
+ if (!(inTy && outTy))
+ return emitOpError("not a reference to a character");
+ if (inTy.getFKind() == outTy.getFKind())
+ return emitOpError("buffers must have different KIND values");
+ return mlir::success();
+}
+
//===----------------------------------------------------------------------===//
// CmpOp
//===----------------------------------------------------------------------===//
return mlir::success();
}
-//===----------------------------------------------------------------------===//
-// CharConvertOp
-//===----------------------------------------------------------------------===//
-
-mlir::LogicalResult fir::CharConvertOp::verify() {
- auto unwrap = [&](mlir::Type t) {
- t = fir::unwrapSequenceType(fir::dyn_cast_ptrEleTy(t));
- return t.dyn_cast<fir::CharacterType>();
- };
- auto inTy = unwrap(getFrom().getType());
- auto outTy = unwrap(getTo().getType());
- if (!(inTy && outTy))
- return emitOpError("not a reference to a character");
- if (inTy.getFKind() == outTy.getFKind())
- return emitOpError("buffers must have different KIND values");
- return mlir::success();
-}
-
//===----------------------------------------------------------------------===//
// CmpcOp
//===----------------------------------------------------------------------===//