@@ -239,10 +239,19 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
239239 if (ForVTable && !Thunk.hasLocalLinkage ())
240240 Thunk.setLinkage (cir::GlobalLinkageKind::AvailableExternallyLinkage);
241241 const auto *ND = cast<NamedDecl>(GD.getDecl ());
242- CGM.setGVProperties (Thunk. getOperation () , ND);
242+ CGM.setGVProperties (Thunk, ND);
243243 }
244244
245245 bool exportThunk () override { return true ; }
246+
247+ mlir::Value performThisAdjustment (CIRGenFunction &cgf, Address thisAddr,
248+ const CXXRecordDecl *unadjustedClass,
249+ const ThunkInfo &ti) override ;
250+
251+ mlir::Value performReturnAdjustment (CIRGenFunction &cgf, Address ret,
252+ const CXXRecordDecl *unadjustedClass,
253+ const ReturnAdjustment &ra) override ;
254+
246255 mlir::Attribute getAddrOfRTTIDescriptor (mlir::Location loc,
247256 QualType Ty) override ;
248257 bool useThunkForDtorVariant (const CXXDestructorDecl *Dtor,
@@ -2144,6 +2153,63 @@ mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
21442153 return CIRGenItaniumRTTIBuilder (*this , CGM).BuildTypeInfo (loc, Ty);
21452154}
21462155
2156+ static mlir::Value performTypeAdjustment (CIRGenFunction &cgf,
2157+ Address initialPtr,
2158+ const CXXRecordDecl *unadjustedClass,
2159+ int64_t nonVirtualAdjustment,
2160+ int64_t virtualAdjustment,
2161+ bool isReturnAdjustment) {
2162+ if (!nonVirtualAdjustment && !virtualAdjustment)
2163+ return initialPtr.getPointer ();
2164+
2165+ auto &builder = cgf.getBuilder ();
2166+ auto loc = builder.getUnknownLoc ();
2167+ auto i8PtrTy = builder.getUInt8PtrTy ();
2168+ mlir::Value v = builder.createBitcast (initialPtr.getPointer (), i8PtrTy);
2169+
2170+ // In a base-to-derived cast, the non-virtual adjustment is applied first.
2171+ if (nonVirtualAdjustment && !isReturnAdjustment) {
2172+ auto offsetConst = builder.getSInt64 (nonVirtualAdjustment, loc);
2173+ v = builder.create <cir::PtrStrideOp>(loc, i8PtrTy, v, offsetConst);
2174+ }
2175+
2176+ // Perform the virtual adjustment if we have one.
2177+ mlir::Value resultPtr;
2178+ if (virtualAdjustment) {
2179+ llvm_unreachable (" Virtual adjustment NYI - requires vtable offset lookup" );
2180+ } else {
2181+ resultPtr = v;
2182+ }
2183+
2184+ // In a derived-to-base conversion, the non-virtual adjustment is
2185+ // applied second.
2186+ if (nonVirtualAdjustment && isReturnAdjustment) {
2187+ auto offsetConst = builder.getSInt64 (nonVirtualAdjustment, loc);
2188+ resultPtr =
2189+ builder.create <cir::PtrStrideOp>(loc, i8PtrTy, resultPtr, offsetConst);
2190+ }
2191+
2192+ // Cast back to original pointer type
2193+ return builder.createBitcast (resultPtr, initialPtr.getType ());
2194+ }
2195+
2196+ mlir::Value CIRGenItaniumCXXABI::performThisAdjustment (
2197+ CIRGenFunction &cgf, Address thisAddr, const CXXRecordDecl *unadjustedClass,
2198+ const ThunkInfo &ti) {
2199+ return performTypeAdjustment (cgf, thisAddr, unadjustedClass,
2200+ ti.This .NonVirtual ,
2201+ ti.This .Virtual .Itanium .VCallOffsetOffset ,
2202+ /* IsReturnAdjustment=*/ false );
2203+ }
2204+
2205+ mlir::Value CIRGenItaniumCXXABI::performReturnAdjustment (
2206+ CIRGenFunction &cgf, Address ret, const CXXRecordDecl *unadjustedClass,
2207+ const ReturnAdjustment &ra) {
2208+ return performTypeAdjustment (cgf, ret, unadjustedClass, ra.NonVirtual ,
2209+ ra.Virtual .Itanium .VBaseOffsetOffset ,
2210+ /* IsReturnAdjustment=*/ true );
2211+ }
2212+
21472213void CIRGenItaniumCXXABI::emitVTableDefinitions (CIRGenVTables &CGVT,
21482214 const CXXRecordDecl *RD) {
21492215 auto VTable = getAddrOfVTable (RD, CharUnits ());
0 commit comments