[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