================ @@ -121,29 +359,159 @@ mlir::Value CIRGenFunction::emitScalarExpr(const Expr *e) { return ScalarExprEmitter(*this, builder).Visit(const_cast<Expr *>(e)); } +[[maybe_unused]] static bool MustVisitNullValue(const Expr *e) { + // If a null pointer expression's type is the C++0x nullptr_t, then + // it's not necessarily a simple constant and it must be evaluated + // for its potential side effects. + return e->getType()->isNullPtrType(); +} + // Emit code for an explicit or implicit cast. Implicit // casts have to handle a more broad range of conversions than explicit // casts, as they handle things like function to ptr-to-function decay // etc. mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) { - Expr *e = ce->getSubExpr(); + Expr *subExpr = ce->getSubExpr(); QualType destTy = ce->getType(); CastKind kind = ce->getCastKind(); + // These cases are generally not written to ignore the result of evaluating + // their sub-expressions, so we clear this now. + ignoreResultAssign = false; + switch (kind) { + case clang::CK_Dependent: + llvm_unreachable("dependent cast kind in CIR gen!"); + case clang::CK_BuiltinFnToFnPtr: + llvm_unreachable("builtin functions are handled elsewhere"); + + case CK_CPointerToObjCPointerCast: + case CK_BlockPointerToObjCPointerCast: + case CK_AnyPointerToBlockPointerCast: + case CK_BitCast: { + mlir::Value src = Visit(const_cast<Expr *>(subExpr)); + mlir::Type dstTy = cgf.convertType(destTy); + + assert(!cir::MissingFeatures::addressSpace()); + + if (cgf.sanOpts.has(SanitizerKind::CFIUnrelatedCast)) + cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(), + "sanitizer support"); + + if (cgf.cgm.getCodeGenOpts().StrictVTablePointers) + cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(), + "strict vtable pointers"); + + // Update heapallocsite metadata when there is an explicit pointer cast. + assert(!cir::MissingFeatures::addHeapAllocSiteMetadata()); + + // If Src is a fixed vector and Dst is a scalable vector, and both have the + // same element type, use the llvm.vector.insert intrinsic to perform the + // bitcast. + assert(!cir::MissingFeatures::scalableVectors()); + + // If Src is a scalable vector and Dst is a fixed vector, and both have the + // same element type, use the llvm.vector.extract intrinsic to perform the + // bitcast. + assert(!cir::MissingFeatures::scalableVectors()); + + // Perform VLAT <-> VLST bitcast through memory. + // TODO: since the llvm.experimental.vector.{insert,extract} intrinsics + // require the element types of the vectors to be the same, we + // need to keep this around for bitcasts between VLAT <-> VLST where + // the element types of the vectors are not the same, until we figure + // out a better way of doing these casts. + assert(!cir::MissingFeatures::scalableVectors()); + + return cgf.getBuilder().createBitcast(cgf.getLoc(subExpr->getSourceRange()), + src, dstTy); + } + + case CK_AtomicToNonAtomic: + cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(), + "CastExpr: ", ce->getCastKindName()); + break; ---------------- erichkeane wrote:
still, atomic-to-non-atomic cast can change types, so probably should return something. https://github.com/llvm/llvm-project/pull/130690 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits