@@ -360,6 +360,30 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
360360 classifyRTTIUniqueness (QualType CanTy, cir::GlobalLinkageKind Linkage) const ;
361361 friend class CIRGenItaniumRTTIBuilder ;
362362};
363+
364+ class CIRGenARMCXXABI : public CIRGenItaniumCXXABI {
365+ public:
366+ CIRGenARMCXXABI (CIRGenModule &CGM) : CIRGenItaniumCXXABI(CGM) {
367+ // TODO(cir): When implemented, /*UseARMMethodPtrABI=*/true,
368+ // /*UseARMGuardVarABI=*/true) {}
369+ assert (!cir::MissingFeatures::appleArm64CXXABI ());
370+ }
371+ CharUnits getArrayCookieSizeImpl (QualType elementType) override ;
372+ Address initializeArrayCookie (CIRGenFunction &CGF, Address NewPtr,
373+ mlir::Value NumElements, const CXXNewExpr *E,
374+ QualType ElementType) override ;
375+ };
376+
377+ class CIRGenAppleARM64CXXABI : public CIRGenARMCXXABI {
378+ public:
379+ CIRGenAppleARM64CXXABI (CIRGenModule &CGM) : CIRGenARMCXXABI(CGM) {
380+ Use32BitVTableOffsetABI = true ;
381+ }
382+
383+ // ARM64 libraries are prepared for non-unique RTTI.
384+ bool shouldRTTIBeUnique () const override { return false ; }
385+ };
386+
363387} // namespace
364388
365389CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs (
@@ -404,12 +428,11 @@ CIRGenCXXABI *clang::CIRGen::CreateCIRGenItaniumCXXABI(CIRGenModule &CGM) {
404428 switch (CGM.getASTContext ().getCXXABIKind ()) {
405429 case TargetCXXABI::GenericItanium:
406430 case TargetCXXABI::GenericAArch64:
407- case TargetCXXABI::AppleARM64:
408- // TODO: this isn't quite right, clang uses AppleARM64CXXABI which inherits
409- // from ARMCXXABI. We'll have to follow suit.
410- assert (!cir::MissingFeatures::appleArm64CXXABI ());
411431 return new CIRGenItaniumCXXABI (CGM);
412432
433+ case TargetCXXABI::AppleARM64:
434+ return new CIRGenAppleARM64CXXABI (CGM);
435+
413436 default :
414437 llvm_unreachable (" bad or NYI ABI kind" );
415438 }
@@ -2700,4 +2723,56 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &CGF,
27002723 auto OffsetOp = CGF.getBuilder ().getSignedInt (Loc, Offset, /* width=*/ 32 );
27012724 auto DataPtr = CGF.getBuilder ().createPtrStride (Loc, CastOp, OffsetOp);
27022725 return Address (DataPtr, NewPtr.getType (), NewPtr.getAlignment ());
2703- }
2726+ }
2727+
2728+ CharUnits CIRGenARMCXXABI::getArrayCookieSizeImpl (QualType elementType) {
2729+ // ARM says that the cookie is always:
2730+ // struct array_cookie {
2731+ // std::size_t element_size; // element_size != 0
2732+ // std::size_t element_count;
2733+ // };
2734+ // But the base ABI doesn't give anything an alignment greater than
2735+ // 8, so we can dismiss this as typical ABI-author blindness to
2736+ // actual language complexity and round up to the element alignment.
2737+ return std::max (CharUnits::fromQuantity (2 * CGM.SizeSizeInBytes ),
2738+ getContext ().getTypeAlignInChars (elementType));
2739+ }
2740+
2741+ Address CIRGenARMCXXABI::initializeArrayCookie (CIRGenFunction &cgf,
2742+ Address newPtr,
2743+ mlir::Value numElements,
2744+ const CXXNewExpr *expr,
2745+ QualType elementType) {
2746+ assert (requiresArrayCookie (expr));
2747+
2748+ // The cookie is always at the start of the buffer.
2749+ auto cookiePtr =
2750+ cgf.getBuilder ().createPtrBitcast (newPtr.getPointer (), cgf.SizeTy );
2751+ Address cookie = Address (cookiePtr, cgf.SizeTy , newPtr.getAlignment ());
2752+
2753+ ASTContext &ctx = getContext ();
2754+ CharUnits sizeSize = cgf.getSizeSize ();
2755+ mlir::Location loc = cgf.getLoc (expr->getSourceRange ());
2756+
2757+ // The first element is the element size.
2758+ mlir::Value elementSize = cgf.getBuilder ().getConstInt (
2759+ loc, cgf.SizeTy , ctx.getTypeSizeInChars (elementType).getQuantity ());
2760+ cgf.getBuilder ().createStore (loc, elementSize, cookie);
2761+
2762+ // The second element is the element count.
2763+ auto offsetOp = cgf.getBuilder ().getSignedInt (loc, 1 , /* width=*/ 32 );
2764+ auto dataPtr =
2765+ cgf.getBuilder ().createPtrStride (loc, cookie.getPointer (), offsetOp);
2766+ cookie = Address (dataPtr, cgf.SizeTy , newPtr.getAlignment ());
2767+ cgf.getBuilder ().createStore (loc, numElements, cookie);
2768+
2769+ // Finally, compute a pointer to the actual data buffer by skipping
2770+ // over the cookie completely.
2771+ CharUnits cookieSize = CIRGenARMCXXABI::getArrayCookieSizeImpl (elementType);
2772+ offsetOp = cgf.getBuilder ().getSignedInt (loc, cookieSize.getQuantity (),
2773+ /* width=*/ 32 );
2774+ auto castOp = cgf.getBuilder ().createPtrBitcast (
2775+ newPtr.getPointer (), cgf.getBuilder ().getUIntNTy (8 ));
2776+ dataPtr = cgf.getBuilder ().createPtrStride (loc, castOp, offsetOp);
2777+ return Address (dataPtr, newPtr.getType (), newPtr.getAlignment ());
2778+ }
0 commit comments