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;
109 mlir::Value lowerVTableGetTypeInfo(cir::VTableGetTypeInfoOp op,
110 mlir::OpBuilder &builder)
const override;
120 case clang::TargetCXXABI::GenericAArch64:
121 case clang::TargetCXXABI::AppleARM64:
125 return std::make_unique<LowerItaniumCXXABI>(lm,
128 case clang::TargetCXXABI::GenericItanium:
129 return std::make_unique<LowerItaniumCXXABI>(lm);
131 case clang::TargetCXXABI::Microsoft:
132 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
134 llvm_unreachable(
"Other Itanium ABI?");
146mlir::Type LowerItaniumCXXABI::lowerDataMemberType(
147 cir::DataMemberType type,
const mlir::TypeConverter &typeConverter)
const {
151 return getPtrDiffCIRTy(lm);
154mlir::Type LowerItaniumCXXABI::lowerMethodType(
155 cir::MethodType type,
const mlir::TypeConverter &typeConverter)
const {
170 return cir::RecordType::get(
type.getContext(), {ptrdiffCIRTy, ptrdiffCIRTy},
172 cir::RecordType::Struct);
175mlir::TypedAttr LowerItaniumCXXABI::lowerDataMemberConstant(
176 cir::DataMemberAttr attr,
const mlir::DataLayout &layout,
177 const mlir::TypeConverter &typeConverter)
const {
179 if (
attr.isNullPtr()) {
187 unsigned memberIndex =
attr.getMemberIndex().value();
189 attr.getType().getClassTy().getElementOffset(layout, memberIndex);
192 mlir::Type abiTy = lowerDataMemberType(
attr.getType(), typeConverter);
193 return cir::IntAttr::get(abiTy, memberOffset);
196mlir::TypedAttr LowerItaniumCXXABI::lowerMethodConstant(
197 cir::MethodAttr attr,
const mlir::DataLayout &layout,
198 const mlir::TypeConverter &typeConverter)
const {
204 auto loweredMethodTy = mlir::cast<cir::RecordType>(
205 lowerMethodType(
attr.getType(), typeConverter));
207 auto zero = cir::IntAttr::get(ptrdiffCIRTy, 0);
228 return cir::ConstRecordAttr::get(
229 loweredMethodTy, mlir::ArrayAttr::get(
attr.getContext(), {zero, zero}));
232 if (
attr.isVirtual()) {
233 if (useARMMethodPtrABI) {
240 llvm_unreachable(
"ARM method ptr abi NYI");
251 cir::IntAttr::get(ptrdiffCIRTy, 1 +
attr.getVtableOffset().value());
252 return cir::ConstRecordAttr::get(
253 loweredMethodTy, mlir::ArrayAttr::get(
attr.getContext(), {ptr, zero}));
261 auto ptr = cir::GlobalViewAttr::get(ptrdiffCIRTy,
attr.getSymbol().value());
262 return cir::ConstRecordAttr::get(
263 loweredMethodTy, mlir::ArrayAttr::get(
attr.getContext(), {ptr, zero}));
266mlir::Operation *LowerItaniumCXXABI::lowerGetRuntimeMember(
267 cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
268 mlir::Value loweredAddr, mlir::Value loweredMember,
269 mlir::OpBuilder &builder)
const {
270 auto byteTy = cir::IntType::get(op.getContext(), 8,
true);
271 auto bytePtrTy = cir::PointerType::get(
273 mlir::cast<cir::PointerType>(op.getAddr().getType()).getAddrSpace());
274 auto objectBytesPtr = cir::CastOp::create(
275 builder, op.getLoc(), bytePtrTy, cir::CastKind::bitcast, op.getAddr());
276 auto memberBytesPtr = cir::PtrStrideOp::create(
277 builder, op.getLoc(), bytePtrTy, objectBytesPtr, loweredMember);
278 return cir::CastOp::create(builder, op.getLoc(), op.getType(),
279 cir::CastKind::bitcast, memberBytesPtr);
282void LowerItaniumCXXABI::lowerGetMethod(
283 cir::GetMethodOp op, mlir::Value &callee, mlir::Value &thisArg,
284 mlir::Value loweredMethod, mlir::Value loweredObjectPtr,
285 mlir::ConversionPatternRewriter &rewriter)
const {
307 mlir::ImplicitLocOpBuilder locBuilder(op.getLoc(), rewriter);
308 mlir::Type calleePtrTy = op.getCallee().getType();
311 mlir::Value ptrdiffOne =
312 cir::ConstantOp::create(locBuilder, cir::IntAttr::get(ptrdiffCIRTy, 1));
315 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredMethod, 1);
316 if (useARMMethodPtrABI) {
317 op.emitError(
"ARM method ptr abi NYI");
322 mlir::Type thisVoidPtrTy =
323 cir::PointerType::get(cir::VoidType::get(locBuilder.getContext()),
324 op.getObject().getType().getAddrSpace());
325 mlir::Value thisVoidPtr = cir::CastOp::create(
326 locBuilder, thisVoidPtrTy, cir::CastKind::bitcast, loweredObjectPtr);
328 cir::PtrStrideOp::create(locBuilder, thisVoidPtrTy, thisVoidPtr, adj);
332 mlir::Value methodPtrField =
333 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredMethod, 0);
334 mlir::Value virtualBit =
335 cir::AndOp::create(rewriter, op.getLoc(), methodPtrField, ptrdiffOne);
336 mlir::Value isVirtual;
337 if (useARMMethodPtrABI)
338 llvm_unreachable(
"ARM method ptr abi NYI");
340 isVirtual = cir::CmpOp::create(locBuilder, cir::CmpOpKind::eq, virtualBit,
347 auto buildVirtualCallee = [&](mlir::OpBuilder &
b, mlir::Location loc) {
351 cir::PointerType::get(cir::IntType::get(
b.getContext(), 8,
true));
352 auto vtablePtrPtrTy = cir::PointerType::get(
353 vtablePtrTy, op.getObject().getType().getAddrSpace());
354 auto vtablePtrPtr = cir::CastOp::create(
b, loc, vtablePtrPtrTy,
355 cir::CastKind::bitcast, thisArg);
357 mlir::Value vtablePtr =
358 cir::LoadOp::create(
b, loc, vtablePtrPtr,
false,
361 cir::SyncScopeKindAttr{},
362 cir::MemOrderAttr());
365 mlir::Value vtableOffset = methodPtrField;
366 assert(!useARMMethodPtrABI &&
"ARM method ptr abi NYI");
367 vtableOffset = cir::SubOp::create(
b, loc, vtableOffset.getType(),
368 vtableOffset, ptrdiffOne);
376 mlir::Value vfpAddr = cir::PtrStrideOp::create(locBuilder, vtablePtrTy,
377 vtablePtr, vtableOffset);
378 auto vfpPtrTy = cir::PointerType::get(calleePtrTy);
379 mlir::Value vfpPtr = cir::CastOp::create(locBuilder, vfpPtrTy,
380 cir::CastKind::bitcast, vfpAddr);
381 auto fnPtr = cir::LoadOp::create(
b, loc, vfpPtr,
384 cir::SyncScopeKindAttr{},
385 cir::MemOrderAttr());
387 cir::YieldOp::create(
b, loc, fnPtr.getResult());
391 callee = cir::TernaryOp::create(
392 locBuilder, isVirtual, buildVirtualCallee,
394 [&](mlir::OpBuilder &
b, mlir::Location loc) {
395 auto fnPtr = cir::CastOp::create(
b, loc, calleePtrTy,
396 cir::CastKind::int_to_ptr,
398 cir::YieldOp::create(
b, loc, fnPtr.getResult());
404 mlir::Value loweredSrc,
406 bool isDerivedToBase,
407 mlir::OpBuilder &builder) {
410 mlir::Location loc = op->getLoc();
411 mlir::Type ty = loweredSrc.getType();
413 auto getConstantInt = [&](int64_t value) -> cir::ConstantOp {
414 return cir::ConstantOp::create(builder, loc, cir::IntAttr::get(ty, value));
417 cir::ConstantOp nullValue = getConstantInt(-1);
418 auto isNull = cir::CmpOp::create(builder, loc, cir::CmpOpKind::eq, loweredSrc,
421 cir::ConstantOp offsetValue = getConstantInt(offset);
422 mlir::Value adjustedPtr;
423 if (isDerivedToBase) {
424 auto subOp = cir::SubOp::create(builder, loc, ty, loweredSrc, offsetValue);
425 subOp.setNoSignedWrap(
true);
428 auto addOp = cir::AddOp::create(builder, loc, ty, loweredSrc, offsetValue);
429 addOp.setNoSignedWrap(
true);
433 return cir::SelectOp::create(builder, loc, ty, isNull, loweredSrc,
438LowerItaniumCXXABI::lowerBaseDataMember(cir::BaseDataMemberOp op,
439 mlir::Value loweredSrc,
440 mlir::OpBuilder &builder)
const {
441 return lowerDataMemberCast(op, loweredSrc, op.getOffset().getSExtValue(),
446LowerItaniumCXXABI::lowerDerivedDataMember(cir::DerivedDataMemberOp op,
447 mlir::Value loweredSrc,
448 mlir::OpBuilder &builder)
const {
454 std::int64_t offset,
bool isDerivedToBase,
456 mlir::OpBuilder &builder) {
461 auto adjField = cir::ExtractMemberOp::create(builder, op->getLoc(),
462 ptrdiffCIRTy, loweredSrc, 1);
464 auto offsetValue = cir::ConstantOp::create(
465 builder, op->getLoc(), cir::IntAttr::get(ptrdiffCIRTy, offset));
466 mlir::Value adjustedAdjField;
467 if (isDerivedToBase) {
468 auto subOp = cir::SubOp::create(builder, op->getLoc(), ptrdiffCIRTy,
469 adjField, offsetValue);
470 subOp.setNoSignedWrap(
true);
471 adjustedAdjField = subOp;
473 auto addOp = cir::AddOp::create(builder, op->getLoc(), ptrdiffCIRTy,
474 adjField, offsetValue);
475 addOp.setNoSignedWrap(
true);
476 adjustedAdjField = addOp;
479 return cir::InsertMemberOp::create(builder, op->getLoc(), loweredSrc, 1,
484LowerItaniumCXXABI::lowerBaseMethod(cir::BaseMethodOp op,
485 mlir::Value loweredSrc,
486 mlir::OpBuilder &builder)
const {
487 return lowerMethodCast(op, loweredSrc, op.getOffset().getSExtValue(),
492LowerItaniumCXXABI::lowerDerivedMethod(cir::DerivedMethodOp op,
493 mlir::Value loweredSrc,
494 mlir::OpBuilder &builder)
const {
500LowerItaniumCXXABI::lowerDataMemberCmp(cir::CmpOp op, mlir::Value loweredLhs,
501 mlir::Value loweredRhs,
502 mlir::OpBuilder &builder)
const {
503 return cir::CmpOp::create(builder, op.getLoc(), op.getKind(), loweredLhs,
507mlir::Value LowerItaniumCXXABI::lowerMethodCmp(cir::CmpOp op,
508 mlir::Value loweredLhs,
509 mlir::Value loweredRhs,
510 mlir::OpBuilder &builder)
const {
511 assert(op.getKind() == cir::CmpOpKind::eq ||
512 op.getKind() == cir::CmpOpKind::ne);
514 mlir::ImplicitLocOpBuilder locBuilder(op.getLoc(), builder);
516 mlir::Value ptrdiffZero =
517 cir::ConstantOp::create(locBuilder, cir::IntAttr::get(ptrdiffCIRTy, 0));
519 mlir::Value lhsPtrField =
520 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredLhs, 0);
521 mlir::Value rhsPtrField =
522 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredRhs, 0);
524 cir::CmpOp::create(locBuilder, op.getKind(), lhsPtrField, rhsPtrField);
525 mlir::Value ptrCmpToNull =
526 cir::CmpOp::create(locBuilder, op.getKind(), lhsPtrField, ptrdiffZero);
528 mlir::Value lhsAdjField =
529 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredLhs, 1);
530 mlir::Value rhsAdjField =
531 cir::ExtractMemberOp::create(locBuilder, ptrdiffCIRTy, loweredRhs, 1);
533 cir::CmpOp::create(locBuilder, op.getKind(), lhsAdjField, rhsAdjField);
535 auto create_and = [&](mlir::Value lhs, mlir::Value rhs) {
536 return cir::AndOp::create(locBuilder, lhs.getType(), lhs, rhs);
538 auto create_or = [&](mlir::Value lhs, mlir::Value rhs) {
539 return cir::OrOp::create(locBuilder, lhs.getType(), lhs, rhs);
543 if (op.getKind() == cir::CmpOpKind::eq) {
545 result = create_and(ptrCmp, create_or(ptrCmpToNull, adjCmp));
548 result = create_or(ptrCmp, create_and(ptrCmpToNull, adjCmp));
554mlir::Value LowerItaniumCXXABI::lowerDataMemberBitcast(
555 cir::CastOp op, mlir::Type loweredDstTy, mlir::Value loweredSrc,
556 mlir::OpBuilder &builder)
const {
557 if (loweredSrc.getType() == loweredDstTy)
560 return cir::CastOp::create(builder, op.getLoc(), loweredDstTy,
561 cir::CastKind::bitcast, loweredSrc);
564mlir::Value LowerItaniumCXXABI::lowerDataMemberToBoolCast(
565 cir::CastOp op, mlir::Value loweredSrc, mlir::OpBuilder &builder)
const {
569 auto nullValue = cir::ConstantOp::create(builder, op.getLoc(), nullAttr);
570 return cir::CmpOp::create(builder, op.getLoc(), cir::CmpOpKind::ne,
571 loweredSrc, nullValue);
575LowerItaniumCXXABI::lowerMethodBitcast(cir::CastOp op, mlir::Type loweredDstTy,
576 mlir::Value loweredSrc,
577 mlir::OpBuilder &builder)
const {
578 if (loweredSrc.getType() == loweredDstTy)
584mlir::Value LowerItaniumCXXABI::lowerMethodToBoolCast(
585 cir::CastOp op, mlir::Value loweredSrc, mlir::OpBuilder &builder)
const {
592 mlir::Value ptrdiffZero = cir::ConstantOp::create(
593 builder, op.getLoc(), cir::IntAttr::get(ptrdiffCIRTy, 0));
594 mlir::Value ptrField = cir::ExtractMemberOp::create(
595 builder, op.getLoc(), ptrdiffCIRTy, loweredSrc, 0);
596 return cir::CmpOp::create(builder, op.getLoc(), cir::CmpOpKind::ne, ptrField,
601 mlir::FlatSymbolRefAttr badCastFuncRef) {
602 cir::CallOp::create(builder, loc, badCastFuncRef, cir::VoidType(),
607 cir::UnreachableOp::create(builder, loc);
608 builder.clearInsertionPoint();
612 mlir::OpBuilder &builder) {
613 mlir::Location loc = op->getLoc();
614 mlir::Value srcValue = op.getSrc();
615 cir::DynamicCastInfoAttr castInfo = op.getInfo().value();
621 cir::PointerType::get(cir::VoidType::get(builder.getContext()));
623 mlir::Value srcPtr = cir::CastOp::create(builder, loc, voidPtrTy,
624 cir::CastKind::bitcast, srcValue);
625 mlir::Value srcRtti =
626 cir::ConstantOp::create(builder, loc, castInfo.getSrcRtti());
627 mlir::Value destRtti =
628 cir::ConstantOp::create(builder, loc, castInfo.getDestRtti());
629 mlir::Value offsetHint =
630 cir::ConstantOp::create(builder, loc, castInfo.getOffsetHint());
632 mlir::FlatSymbolRefAttr dynCastFuncRef = castInfo.getRuntimeFunc();
633 mlir::Value dynCastFuncArgs[4] = {srcPtr, srcRtti, destRtti, offsetHint};
635 mlir::Value castedPtr = cir::CallOp::create(builder, loc, dynCastFuncRef,
636 voidPtrTy, dynCastFuncArgs)
639 assert(mlir::isa<cir::PointerType>(castedPtr.getType()) &&
640 "the return value of __dynamic_cast should be a ptr");
644 if (op.isRefCast()) {
646 mlir::Value null = cir::ConstantOp::create(
648 cir::ConstPtrAttr::get(castedPtr.getType(),
649 builder.getI64IntegerAttr(0)));
650 mlir::Value castedPtrIsNull =
651 cir::CmpOp::create(builder, loc, cir::CmpOpKind::eq, castedPtr, null);
652 cir::IfOp::create(builder, loc, castedPtrIsNull,
false,
653 [&](mlir::OpBuilder &, mlir::Location) {
655 castInfo.getBadCastFunc());
661 return cir::CastOp::create(builder, loc, op.getType(), cir::CastKind::bitcast,
667 mlir::Location loc = op.getLoc();
668 bool vtableUsesRelativeLayout = op.getRelativeLayout();
673 mlir::Type vtableElemTy;
674 uint64_t vtableElemAlign;
675 if (vtableUsesRelativeLayout) {
677 cir::IntType::get(builder.getContext(), 32,
true);
681 vtableElemAlign = llvm::divideCeil(
685 mlir::Type vtableElemPtrTy = cir::PointerType::get(vtableElemTy);
686 mlir::Type i64Ty = cir::IntType::get(builder.getContext(), 64,
692 auto vptrPtr = cir::VTableGetVPtrOp::create(builder, loc, op.getSrc());
693 mlir::Value vptr = cir::LoadOp::create(
694 builder, loc, vptrPtr,
697 builder.getI64IntegerAttr(vtableElemAlign),
698 cir::SyncScopeKindAttr(),
699 cir::MemOrderAttr());
700 mlir::Value elementPtr = cir::CastOp::create(builder, loc, vtableElemPtrTy,
701 cir::CastKind::bitcast, vptr);
702 mlir::Value minusTwo =
703 cir::ConstantOp::create(builder, loc, cir::IntAttr::get(i64Ty, -2));
704 mlir::Value offsetToTopSlotPtr = cir::PtrStrideOp::create(
705 builder, loc, vtableElemPtrTy, elementPtr, minusTwo);
706 mlir::Value offsetToTop = cir::LoadOp::create(
707 builder, loc, offsetToTopSlotPtr,
710 builder.getI64IntegerAttr(vtableElemAlign),
711 cir::SyncScopeKindAttr(),
712 cir::MemOrderAttr());
715 cir::PointerType::get(cir::VoidType::get(builder.getContext()));
720 cir::PointerType::get(cir::IntType::get(builder.getContext(), 8,
722 mlir::Value srcBytePtr = cir::CastOp::create(
723 builder, loc, u8PtrTy, cir::CastKind::bitcast, op.getSrc());
725 cir::PtrStrideOp::create(builder, loc, u8PtrTy, srcBytePtr, offsetToTop);
727 return cir::CastOp::create(builder, loc, voidPtrTy, cir::CastKind::bitcast,
732LowerItaniumCXXABI::lowerDynamicCast(cir::DynamicCastOp op,
733 mlir::OpBuilder &builder)
const {
734 mlir::Location loc = op->getLoc();
735 mlir::Value srcValue = op.getSrc();
740 return buildDynamicCastAfterNullCheck(op, builder);
742 mlir::Value srcValueIsNotNull = cir::CastOp::create(
743 builder, loc, cir::BoolType::get(builder.getContext()),
744 cir::CastKind::ptr_to_bool, srcValue);
745 return cir::TernaryOp::create(
746 builder, loc, srcValueIsNotNull,
747 [&](mlir::OpBuilder &, mlir::Location) {
748 mlir::Value castedValue =
750 ? buildDynamicCastToVoidAfterNullCheck(op, lm, builder)
751 : buildDynamicCastAfterNullCheck(op, builder);
752 cir::YieldOp::create(builder, loc, castedValue);
754 [&](mlir::OpBuilder &, mlir::Location) {
755 mlir::Value null = cir::ConstantOp::create(
757 cir::ConstPtrAttr::get(op.getType(),
758 builder.getI64IntegerAttr(0)));
759 cir::YieldOp::create(builder, loc, null);
764LowerItaniumCXXABI::lowerVTableGetTypeInfo(cir::VTableGetTypeInfoOp op,
765 mlir::OpBuilder &builder)
const {
766 mlir::Location loc = op->getLoc();
767 auto offset = cir::ConstantOp::create(
771 auto vptrCast = cir::CastOp::create(builder, loc, op.getType(),
772 cir::CastKind::bitcast, op.getVptr());
774 return cir::PtrStrideOp::create(builder, loc, vptrCast.getType(), vptrCast,
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 ----------------------------—===//