[clang] [CIR] Upstream support for calling through method pointers (PR #176063)
Hendrik Hübner via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 16 06:52:20 PST 2026
================
@@ -197,6 +224,129 @@ mlir::Operation *LowerItaniumCXXABI::lowerGetRuntimeMember(
cir::CastKind::bitcast, memberBytesPtr);
}
+void LowerItaniumCXXABI::lowerGetMethod(
+ cir::GetMethodOp op, mlir::Value (&loweredResults)[2],
+ mlir::Value loweredMethod, mlir::Value loweredObjectPtr,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ // In the Itanium and ARM ABIs, method pointers have the form:
+ // struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
+ //
+ // In the Itanium ABI:
+ // - method pointers are virtual if (memptr.ptr & 1) is nonzero
+ // - the this-adjustment is (memptr.adj)
+ // - the virtual offset is (memptr.ptr - 1)
+ //
+ // In the ARM ABI:
+ // - method pointers are virtual if (memptr.adj & 1) is nonzero
+ // - the this-adjustment is (memptr.adj >> 1)
+ // - the virtual offset is (memptr.ptr)
+ // ARM uses 'adj' for the virtual flag because Thumb functions
+ // may be only single-byte aligned.
+ //
+ // If the member is virtual, the adjusted 'this' pointer points
+ // to a vtable pointer from which the virtual offset is applied.
+ //
+ // If the member is non-virtual, memptr.ptr is the address of
+ // the function to call.
+
+ mlir::Value &callee = loweredResults[0];
----------------
HendrikHuebner wrote:
Perhaps we could just pass the `callee` and `adjustedThis` separately instead of as an array of references, to make it more explicit what is being passed around and in what order?
https://github.com/llvm/llvm-project/pull/176063
More information about the cfe-commits
mailing list