@@ -360,6 +360,30 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
360
360
classifyRTTIUniqueness (QualType CanTy, cir::GlobalLinkageKind Linkage) const ;
361
361
friend class CIRGenItaniumRTTIBuilder ;
362
362
};
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
+
363
387
} // namespace
364
388
365
389
CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs (
@@ -404,12 +428,11 @@ CIRGenCXXABI *clang::CIRGen::CreateCIRGenItaniumCXXABI(CIRGenModule &CGM) {
404
428
switch (CGM.getASTContext ().getCXXABIKind ()) {
405
429
case TargetCXXABI::GenericItanium:
406
430
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 ());
411
431
return new CIRGenItaniumCXXABI (CGM);
412
432
433
+ case TargetCXXABI::AppleARM64:
434
+ return new CIRGenAppleARM64CXXABI (CGM);
435
+
413
436
default :
414
437
llvm_unreachable (" bad or NYI ABI kind" );
415
438
}
@@ -2700,4 +2723,56 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &CGF,
2700
2723
auto OffsetOp = CGF.getBuilder ().getSignedInt (Loc, Offset, /* width=*/ 32 );
2701
2724
auto DataPtr = CGF.getBuilder ().createPtrStride (Loc, CastOp, OffsetOp);
2702
2725
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