25#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
26#include "mlir/IR/ImplicitLocOpBuilder.h"
27#include "llvm/Support/ErrorHandling.h"
33class LowerItaniumCXXABI :
public CIRCXXABI {
35 bool useARMMethodPtrABI;
38 LowerItaniumCXXABI(LowerModule &lm,
bool useARMMethodPtrABI =
false)
39 : CIRCXXABI(lm), useARMMethodPtrABI(useARMMethodPtrABI) {}
44 lowerDataMemberType(cir::DataMemberType type,
45 const mlir::TypeConverter &typeConverter)
const override;
48 lowerMethodType(cir::MethodType type,
49 const mlir::TypeConverter &typeConverter)
const override;
51 mlir::TypedAttr lowerDataMemberConstant(
52 cir::DataMemberAttr attr,
const mlir::DataLayout &layout,
53 const mlir::TypeConverter &typeConverter)
const override;
56 lowerMethodConstant(cir::MethodAttr attr,
const mlir::DataLayout &layout,
57 const mlir::TypeConverter &typeConverter)
const override;
60 lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
61 mlir::Value loweredAddr, mlir::Value loweredMember,
62 mlir::OpBuilder &builder)
const override;
64 void lowerGetMethod(cir::GetMethodOp op, mlir::Value &callee,
65 mlir::Value &thisArg, mlir::Value loweredMethod,
66 mlir::Value loweredObjectPtr,
67 mlir::ConversionPatternRewriter &rewriter)
const override;
69 mlir::Value lowerBaseDataMember(cir::BaseDataMemberOp op,
70 mlir::Value loweredSrc,
71 mlir::OpBuilder &builder)
const override;
73 mlir::Value lowerDerivedDataMember(cir::DerivedDataMemberOp op,
74 mlir::Value loweredSrc,
75 mlir::OpBuilder &builder)
const override;
77 mlir::Value lowerBaseMethod(cir::BaseMethodOp op, mlir::Value loweredSrc,
78 mlir::OpBuilder &builder)
const override;
80 mlir::Value lowerDerivedMethod(cir::DerivedMethodOp op,
81 mlir::Value loweredSrc,
82 mlir::OpBuilder &builder)
const override;
84 mlir::Value lowerDataMemberCmp(cir::CmpOp op, mlir::Value loweredLhs,
85 mlir::Value loweredRhs,
86 mlir::OpBuilder &builder)
const override;
88 mlir::Value lowerMethodCmp(cir::CmpOp op, mlir::Value loweredLhs,
89 mlir::Value loweredRhs,
90 mlir::OpBuilder &builder)
const override;
92 mlir::Value lowerDataMemberBitcast(cir::CastOp op, mlir::Type loweredDstTy,
93 mlir::Value loweredSrc,
94 mlir::OpBuilder &builder)
const override;
97 lowerDataMemberToBoolCast(cir::CastOp op, mlir::Value loweredSrc,
98 mlir::OpBuilder &builder)
const override;
100 mlir::Value lowerMethodBitcast(cir::CastOp op, mlir::Type loweredDstTy,
101 mlir::Value loweredSrc,
102 mlir::OpBuilder &builder)
const override;
104 mlir::Value lowerMethodToBoolCast(cir::CastOp op, mlir::Value loweredSrc,
105 mlir::OpBuilder &builder)
const override;
107 mlir::Value lowerDynamicCast(cir::DynamicCastOp op,
108 mlir::OpBuilder &builder)
const override;
118 case clang::TargetCXXABI::GenericAArch64:
119 case clang::TargetCXXABI::AppleARM64:
123 return std::make_unique<LowerItaniumCXXABI>(lm,
126 case clang::TargetCXXABI::GenericItanium:
127 return std::make_unique<LowerItaniumCXXABI>(lm);
129 case clang::TargetCXXABI::Microsoft:
130 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
132 llvm_unreachable(
"Other Itanium ABI?");
144mlir::Type LowerItaniumCXXABI::lowerDataMemberType(
145 cir::DataMemberType type,
const mlir::TypeConverter &typeConverter)
const {
149 return getPtrDiffCIRTy(lm);
152mlir::Type LowerItaniumCXXABI::lowerMethodType(
153 cir::MethodType type,
const mlir::TypeConverter &typeConverter)
const {
168 return cir::RecordType::get(
type.getContext(), {ptrdiffCIRTy, ptrdiffCIRTy},
170 cir::RecordType::Struct);
173mlir::TypedAttr LowerItaniumCXXABI::lowerDataMemberConstant(
174 cir::DataMemberAttr attr,
const mlir::DataLayout &layout,
175 const mlir::TypeConverter &typeConverter)
const {
177 if (
attr.isNullPtr()) {
180 memberOffset = -1ull;
185 unsigned memberIndex =
attr.getMemberIndex().value();
187 attr.getType().getClassTy().getElementOffset(layout, memberIndex);
190 mlir::Type abiTy = lowerDataMemberType(
attr.getType(), typeConverter);
191 return cir::IntAttr::get(abiTy, memberOffset);
194mlir::TypedAttr LowerItaniumCXXABI::lowerMethodConstant(
195 cir::MethodAttr attr,
const mlir::DataLayout &layout,
196 const mlir::TypeConverter &typeConverter)
const {
202 auto loweredMethodTy = mlir::cast<cir::RecordType>(
203 lowerMethodType(
attr.getType(), typeConverter));
205 auto zero = cir::IntAttr::get(ptrdiffCIRTy, 0);
226 return cir::ConstRecordAttr::get(
227 loweredMethodTy, mlir::ArrayAttr::get(
attr.getContext(), {zero, zero}));
230 if (
attr.isVirtual()) {
231 if (useARMMethodPtrABI) {
238 llvm_unreachable(
"ARM method ptr abi NYI");
249 cir::IntAttr::get(ptrdiffCIRTy, 1 +
attr.getVtableOffset().value());
250 return cir::ConstRecordAttr::get(
251 loweredMethodTy, mlir::ArrayAttr::get(
attr.getContext(), {ptr, zero}));
259 auto ptr = cir::GlobalViewAttr::get(ptrdiffCIRTy,
attr.getSymbol().value());
260 return cir::ConstRecordAttr::get(
261 loweredMethodTy, mlir::ArrayAttr::get(
attr.getContext(), {ptr, zero}));
264mlir::Operation *LowerItaniumCXXABI::lowerGetRuntimeMember(
265 cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
266 mlir::Value loweredAddr, mlir::Value loweredMember,
267 mlir::OpBuilder &builder)
const {
268 auto byteTy = cir::IntType::get(op.getContext(), 8,
true);
269 auto bytePtrTy = cir::PointerType::get(
271 mlir::cast<cir::PointerType>(op.getAddr().getType()).getAddrSpace());
272 auto objectBytesPtr = cir::CastOp::create(
273 builder, op.getLoc(), bytePtrTy, cir::CastKind::bitcast, op.getAddr());
274 auto memberBytesPtr = cir::PtrStrideOp::create(
275 builder, op.getLoc(), bytePtrTy, objectBytesPtr, loweredMember);
276 return cir::CastOp::create(builder, op.getLoc(), op.getType(),
277 cir::CastKind::bitcast, memberBytesPtr);
280void LowerItaniumCXXABI::lowerGetMethod(
281 cir::GetMethodOp op, mlir::Value &callee, mlir::Value &thisArg,
282 mlir::Value loweredMethod, mlir::Value loweredObjectPtr,
283 mlir::ConversionPatternRewriter &rewriter)
const {
305 mlir::ImplicitLocOpBuilder locBuilder(op.getLoc(), rewriter);
306 mlir::Type calleePtrTy = op.getCallee().getType();
309 mlir::Value ptrdiffOne =
310 cir::ConstantOp::create(locBuilder, cir::IntAttr::get(ptrdiffCIRTy, 1));
313 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredMethod, 1);
314 if (useARMMethodPtrABI) {
315 op.emitError(
"ARM method ptr abi NYI");
320 mlir::Type thisVoidPtrTy =
321 cir::PointerType::get(cir::VoidType::get(locBuilder.getContext()),
322 op.getObject().getType().getAddrSpace());
323 mlir::Value thisVoidPtr = cir::CastOp::create(
324 locBuilder, thisVoidPtrTy, cir::CastKind::bitcast, loweredObjectPtr);
326 cir::PtrStrideOp::create(locBuilder, thisVoidPtrTy, thisVoidPtr, adj);
330 mlir::Value methodPtrField =
331 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredMethod, 0);
332 mlir::Value virtualBit = cir::BinOp::create(
333 rewriter, op.getLoc(), cir::BinOpKind::And, methodPtrField, ptrdiffOne);
334 mlir::Value isVirtual;
335 if (useARMMethodPtrABI)
336 llvm_unreachable(
"ARM method ptr abi NYI");
338 isVirtual = cir::CmpOp::create(locBuilder, cir::CmpOpKind::eq, virtualBit,
345 auto buildVirtualCallee = [&](mlir::OpBuilder &
b, mlir::Location loc) {
349 cir::PointerType::get(cir::IntType::get(
b.getContext(), 8,
true));
350 auto vtablePtrPtrTy = cir::PointerType::get(
351 vtablePtrTy, op.getObject().getType().getAddrSpace());
352 auto vtablePtrPtr = cir::CastOp::create(
b, loc, vtablePtrPtrTy,
353 cir::CastKind::bitcast, thisArg);
355 mlir::Value vtablePtr =
356 cir::LoadOp::create(
b, loc, vtablePtrPtr,
false,
359 cir::SyncScopeKindAttr{},
360 cir::MemOrderAttr());
363 mlir::Value vtableOffset = methodPtrField;
364 assert(!useARMMethodPtrABI &&
"ARM method ptr abi NYI");
365 vtableOffset = cir::BinOp::create(
b, loc, cir::BinOpKind::Sub, vtableOffset,
374 mlir::Value vfpAddr = cir::PtrStrideOp::create(locBuilder, vtablePtrTy,
375 vtablePtr, vtableOffset);
376 auto vfpPtrTy = cir::PointerType::get(calleePtrTy);
377 mlir::Value vfpPtr = cir::CastOp::create(locBuilder, vfpPtrTy,
378 cir::CastKind::bitcast, vfpAddr);
379 auto fnPtr = cir::LoadOp::create(
b, loc, vfpPtr,
382 cir::SyncScopeKindAttr{},
383 cir::MemOrderAttr());
385 cir::YieldOp::create(
b, loc, fnPtr.getResult());
389 callee = cir::TernaryOp::create(
390 locBuilder, isVirtual, buildVirtualCallee,
392 [&](mlir::OpBuilder &
b, mlir::Location loc) {
393 auto fnPtr = cir::CastOp::create(
b, loc, calleePtrTy,
394 cir::CastKind::int_to_ptr,
396 cir::YieldOp::create(
b, loc, fnPtr.getResult());
402 mlir::Value loweredSrc,
404 bool isDerivedToBase,
405 mlir::OpBuilder &builder) {
408 mlir::Location loc = op->getLoc();
409 mlir::Type ty = loweredSrc.getType();
411 auto getConstantInt = [&](int64_t value) -> cir::ConstantOp {
412 return cir::ConstantOp::create(builder, loc, cir::IntAttr::get(ty, value));
415 cir::ConstantOp nullValue = getConstantInt(-1);
416 auto isNull = cir::CmpOp::create(builder, loc, cir::CmpOpKind::eq, loweredSrc,
419 cir::ConstantOp offsetValue = getConstantInt(offset);
420 auto binOpKind = isDerivedToBase ? cir::BinOpKind::Sub : cir::BinOpKind::Add;
421 cir::BinOp adjustedPtr =
422 cir::BinOp::create(builder, loc, ty, binOpKind, loweredSrc, offsetValue);
423 adjustedPtr.setNoSignedWrap(
true);
425 return cir::SelectOp::create(builder, loc, ty, isNull, loweredSrc,
430LowerItaniumCXXABI::lowerBaseDataMember(cir::BaseDataMemberOp op,
431 mlir::Value loweredSrc,
432 mlir::OpBuilder &builder)
const {
433 return lowerDataMemberCast(op, loweredSrc, op.getOffset().getSExtValue(),
438LowerItaniumCXXABI::lowerDerivedDataMember(cir::DerivedDataMemberOp op,
439 mlir::Value loweredSrc,
440 mlir::OpBuilder &builder)
const {
446 std::int64_t offset,
bool isDerivedToBase,
448 mlir::OpBuilder &builder) {
453 auto adjField = cir::ExtractMemberOp::create(builder, op->getLoc(),
454 ptrdiffCIRTy, loweredSrc, 1);
456 auto offsetValue = cir::ConstantOp::create(
457 builder, op->getLoc(), cir::IntAttr::get(ptrdiffCIRTy, offset));
458 auto binOpKind = isDerivedToBase ? cir::BinOpKind::Sub : cir::BinOpKind::Add;
459 auto adjustedAdjField = cir::BinOp::create(
460 builder, op->getLoc(), ptrdiffCIRTy, binOpKind, adjField, offsetValue);
461 adjustedAdjField.setNoSignedWrap(
true);
463 return cir::InsertMemberOp::create(builder, op->getLoc(), loweredSrc, 1,
468LowerItaniumCXXABI::lowerBaseMethod(cir::BaseMethodOp op,
469 mlir::Value loweredSrc,
470 mlir::OpBuilder &builder)
const {
471 return lowerMethodCast(op, loweredSrc, op.getOffset().getSExtValue(),
476LowerItaniumCXXABI::lowerDerivedMethod(cir::DerivedMethodOp op,
477 mlir::Value loweredSrc,
478 mlir::OpBuilder &builder)
const {
484LowerItaniumCXXABI::lowerDataMemberCmp(cir::CmpOp op, mlir::Value loweredLhs,
485 mlir::Value loweredRhs,
486 mlir::OpBuilder &builder)
const {
487 return cir::CmpOp::create(builder, op.getLoc(), op.getKind(), loweredLhs,
491mlir::Value LowerItaniumCXXABI::lowerMethodCmp(cir::CmpOp op,
492 mlir::Value loweredLhs,
493 mlir::Value loweredRhs,
494 mlir::OpBuilder &builder)
const {
495 assert(op.getKind() == cir::CmpOpKind::eq ||
496 op.getKind() == cir::CmpOpKind::ne);
498 mlir::ImplicitLocOpBuilder locBuilder(op.getLoc(), builder);
500 mlir::Value ptrdiffZero =
501 cir::ConstantOp::create(locBuilder, cir::IntAttr::get(ptrdiffCIRTy, 0));
503 mlir::Value lhsPtrField =
504 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredLhs, 0);
505 mlir::Value rhsPtrField =
506 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredRhs, 0);
508 cir::CmpOp::create(locBuilder, op.getKind(), lhsPtrField, rhsPtrField);
509 mlir::Value ptrCmpToNull =
510 cir::CmpOp::create(locBuilder, op.getKind(), lhsPtrField, ptrdiffZero);
512 mlir::Value lhsAdjField =
513 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredLhs, 1);
514 mlir::Value rhsAdjField =
515 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredRhs, 1);
517 cir::CmpOp::create(locBuilder, op.getKind(), lhsAdjField, rhsAdjField);
519 auto create_and = [&](mlir::Value lhs, mlir::Value rhs) {
520 return cir::BinOp::create(locBuilder, cir::BinOpKind::And, lhs, rhs);
522 auto create_or = [&](mlir::Value lhs, mlir::Value rhs) {
523 return cir::BinOp::create(locBuilder, cir::BinOpKind::Or, lhs, rhs);
527 if (op.getKind() == cir::CmpOpKind::eq) {
529 result = create_and(ptrCmp, create_or(ptrCmpToNull, adjCmp));
532 result = create_or(ptrCmp, create_and(ptrCmpToNull, adjCmp));
538mlir::Value LowerItaniumCXXABI::lowerDataMemberBitcast(
539 cir::CastOp op, mlir::Type loweredDstTy, mlir::Value loweredSrc,
540 mlir::OpBuilder &builder)
const {
541 if (loweredSrc.getType() == loweredDstTy)
544 return cir::CastOp::create(builder, op.getLoc(), loweredDstTy,
545 cir::CastKind::bitcast, loweredSrc);
548mlir::Value LowerItaniumCXXABI::lowerDataMemberToBoolCast(
549 cir::CastOp op, mlir::Value loweredSrc, mlir::OpBuilder &builder)
const {
553 auto nullValue = cir::ConstantOp::create(builder, op.getLoc(), nullAttr);
554 return cir::CmpOp::create(builder, op.getLoc(), cir::CmpOpKind::ne,
555 loweredSrc, nullValue);
559LowerItaniumCXXABI::lowerMethodBitcast(cir::CastOp op, mlir::Type loweredDstTy,
560 mlir::Value loweredSrc,
561 mlir::OpBuilder &builder)
const {
562 if (loweredSrc.getType() == loweredDstTy)
568mlir::Value LowerItaniumCXXABI::lowerMethodToBoolCast(
569 cir::CastOp op, mlir::Value loweredSrc, mlir::OpBuilder &builder)
const {
576 mlir::Value ptrdiffZero = cir::ConstantOp::create(
577 builder, op.getLoc(), cir::IntAttr::get(ptrdiffCIRTy, 0));
578 mlir::Value ptrField = cir::ExtractMemberOp::create(
579 builder, op.getLoc(), ptrdiffCIRTy, loweredSrc, 0);
580 return cir::CmpOp::create(builder, op.getLoc(), cir::CmpOpKind::ne, ptrField,
585 mlir::FlatSymbolRefAttr badCastFuncRef) {
586 cir::CallOp::create(builder, loc, badCastFuncRef, cir::VoidType(),
591 cir::UnreachableOp::create(builder, loc);
592 builder.clearInsertionPoint();
596 mlir::OpBuilder &builder) {
597 mlir::Location loc = op->getLoc();
598 mlir::Value srcValue = op.getSrc();
599 cir::DynamicCastInfoAttr castInfo = op.getInfo().value();
605 cir::PointerType::get(cir::VoidType::get(builder.getContext()));
607 mlir::Value srcPtr = cir::CastOp::create(builder, loc, voidPtrTy,
608 cir::CastKind::bitcast, srcValue);
609 mlir::Value srcRtti =
610 cir::ConstantOp::create(builder, loc, castInfo.getSrcRtti());
611 mlir::Value destRtti =
612 cir::ConstantOp::create(builder, loc, castInfo.getDestRtti());
613 mlir::Value offsetHint =
614 cir::ConstantOp::create(builder, loc, castInfo.getOffsetHint());
616 mlir::FlatSymbolRefAttr dynCastFuncRef = castInfo.getRuntimeFunc();
617 mlir::Value dynCastFuncArgs[4] = {srcPtr, srcRtti, destRtti, offsetHint};
619 mlir::Value castedPtr = cir::CallOp::create(builder, loc, dynCastFuncRef,
620 voidPtrTy, dynCastFuncArgs)
623 assert(mlir::isa<cir::PointerType>(castedPtr.getType()) &&
624 "the return value of __dynamic_cast should be a ptr");
628 if (op.isRefCast()) {
630 mlir::Value null = cir::ConstantOp::create(
632 cir::ConstPtrAttr::get(castedPtr.getType(),
633 builder.getI64IntegerAttr(0)));
634 mlir::Value castedPtrIsNull =
635 cir::CmpOp::create(builder, loc, cir::CmpOpKind::eq, castedPtr, null);
636 cir::IfOp::create(builder, loc, castedPtrIsNull,
false,
637 [&](mlir::OpBuilder &, mlir::Location) {
639 castInfo.getBadCastFunc());
645 return cir::CastOp::create(builder, loc, op.getType(), cir::CastKind::bitcast,
651 mlir::Location loc = op.getLoc();
652 bool vtableUsesRelativeLayout = op.getRelativeLayout();
657 mlir::Type vtableElemTy;
658 uint64_t vtableElemAlign;
659 if (vtableUsesRelativeLayout) {
661 cir::IntType::get(builder.getContext(), 32,
true);
665 vtableElemAlign = llvm::divideCeil(
669 mlir::Type vtableElemPtrTy = cir::PointerType::get(vtableElemTy);
670 mlir::Type i64Ty = cir::IntType::get(builder.getContext(), 64,
676 auto vptrPtr = cir::VTableGetVPtrOp::create(builder, loc, op.getSrc());
677 mlir::Value vptr = cir::LoadOp::create(
678 builder, loc, vptrPtr,
681 builder.getI64IntegerAttr(vtableElemAlign),
682 cir::SyncScopeKindAttr(),
683 cir::MemOrderAttr());
684 mlir::Value elementPtr = cir::CastOp::create(builder, loc, vtableElemPtrTy,
685 cir::CastKind::bitcast, vptr);
686 mlir::Value minusTwo =
687 cir::ConstantOp::create(builder, loc, cir::IntAttr::get(i64Ty, -2));
688 mlir::Value offsetToTopSlotPtr = cir::PtrStrideOp::create(
689 builder, loc, vtableElemPtrTy, elementPtr, minusTwo);
690 mlir::Value offsetToTop = cir::LoadOp::create(
691 builder, loc, offsetToTopSlotPtr,
694 builder.getI64IntegerAttr(vtableElemAlign),
695 cir::SyncScopeKindAttr(),
696 cir::MemOrderAttr());
699 cir::PointerType::get(cir::VoidType::get(builder.getContext()));
704 cir::PointerType::get(cir::IntType::get(builder.getContext(), 8,
706 mlir::Value srcBytePtr = cir::CastOp::create(
707 builder, loc, u8PtrTy, cir::CastKind::bitcast, op.getSrc());
709 cir::PtrStrideOp::create(builder, loc, u8PtrTy, srcBytePtr, offsetToTop);
711 return cir::CastOp::create(builder, loc, voidPtrTy, cir::CastKind::bitcast,
716LowerItaniumCXXABI::lowerDynamicCast(cir::DynamicCastOp op,
717 mlir::OpBuilder &builder)
const {
718 mlir::Location loc = op->getLoc();
719 mlir::Value srcValue = op.getSrc();
724 return buildDynamicCastAfterNullCheck(op, builder);
726 mlir::Value srcValueIsNotNull = cir::CastOp::create(
727 builder, loc, cir::BoolType::get(builder.getContext()),
728 cir::CastKind::ptr_to_bool, srcValue);
729 return cir::TernaryOp::create(
730 builder, loc, srcValueIsNotNull,
731 [&](mlir::OpBuilder &, mlir::Location) {
732 mlir::Value castedValue =
734 ? buildDynamicCastToVoidAfterNullCheck(op, lm, builder)
735 : buildDynamicCastAfterNullCheck(op, builder);
736 cir::YieldOp::create(builder, loc, castedValue);
738 [&](mlir::OpBuilder &, mlir::Location) {
739 mlir::Value null = cir::ConstantOp::create(
741 cir::ConstPtrAttr::get(op.getType(),
742 builder.getI64IntegerAttr(0)));
743 cir::YieldOp::create(builder, loc, null);
mlir::MLIRContext * getMLIRContext()
clang::TargetCXXABI::Kind getCXXABIKind() const
const clang::TargetInfo & getTarget() const
Exposes information about the current target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
static bool isTypeSigned(IntType T)
Returns true if the type is signed; false otherwise.
IntType getPtrDiffType(LangAS AddrSpace) const
uint64_t getPointerAlign(LangAS AddrSpace) const
static mlir::Value lowerDataMemberCast(mlir::Operation *op, mlir::Value loweredSrc, std::int64_t offset, bool isDerivedToBase, mlir::OpBuilder &builder)
std::unique_ptr< CIRCXXABI > createItaniumCXXABI(LowerModule &lm)
Creates an Itanium-family ABI.
static mlir::Value buildDynamicCastAfterNullCheck(cir::DynamicCastOp op, mlir::OpBuilder &builder)
static cir::IntType getPtrDiffCIRTy(LowerModule &lm)
static mlir::Value buildDynamicCastToVoidAfterNullCheck(cir::DynamicCastOp op, cir::LowerModule &lm, mlir::OpBuilder &builder)
static void buildBadCastCall(mlir::OpBuilder &builder, mlir::Location loc, mlir::FlatSymbolRefAttr badCastFuncRef)
static mlir::Value lowerMethodCast(mlir::Operation *op, mlir::Value loweredSrc, std::int64_t offset, bool isDerivedToBase, LowerModule &lowerMod, mlir::OpBuilder &builder)
const internal::VariadicAllOfMatcher< Attr > attr
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
static bool addressSpace()
static bool appleArm64CXXABI()
static bool emitCFICheck()
static bool emitVFEInfo()
static bool opFuncNoReturn()
static bool emitWPDInfo()
static bool emitTypeCheck()
IntType
===-— Target Data Type Query Methods ----------------------------—===//