# \[C++ Interop\] Virtual function calls

**URL:** <https://forums.swift.org/t/c-interop-virtual-function-calls/27567>\
**Category:** Compiler\
**Tags:** cxx\
**Created:** [August 2, 2019, 10:49pm UTC](https://forums.swift.org/t/c-interop-virtual-function-calls/27567 "2019-08-02T22:49:12Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![pschuh](https://avatars.discourse-cdn.com/v4/letter/p/96bed5/32.png) [@pschuh](https://forums.swift.org/u/pschuh)\
**Post date:** [August 2, 2019, 10:49pm UTC](https://forums.swift.org/t/c-interop-virtual-function-calls/27567/1 "2019-08-02T22:49:12Z")

</div>

If I have a pure virtual function call, that will currently show up in the sil as:

```swift
  %0 = ...
  %1 = function_ref @_ZN5Class2fnEv : $@convention(c) (@inout Class) -> ()
  %2 = apply %1(%0) : $@convention(c) (@inout Class) -> ()

```

Which is a direct reference to Class::fn() which does not exist resulting in a linker error.

Three possible ideas for resolving this:

- Something like `class_method` that ideally adjusts the this ptr and returns the computed vtable pointer.
- Detect in IRGen that the original function\_ref is virtual and go through a different path.
- Somehow generate an inline thunk (manually construct an inline clang AST and send that through codegen) that takes `Class*` in ClangImporter.

@John_McCall ?

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [August 3, 2019, 1:42am UTC](https://forums.swift.org/t/c-interop-virtual-function-calls/27567/2 "2019-08-03T01:42:46Z")

</div>

Virtual function calls should not in general be compiled to `function_ref`. They need to use an instruction that represents resolving the virtual function, probably a new `cxx_virtual_method` instruction.

This is complicated somewhat by multiple inheritance and the need for base-object adjustments.

---

<div class="post-metadata">

**Author:** ![pschuh](https://avatars.discourse-cdn.com/v4/letter/p/96bed5/32.png) [@pschuh](https://forums.swift.org/u/pschuh)\
**Post date:** [August 3, 2019, 2:22am UTC](https://forums.swift.org/t/c-interop-virtual-function-calls/27567/3 "2019-08-03T02:22:57Z")

</div>

Sounds reasonable. The this pointer adjustment is tricky.  
I see the following ways that could work:

- `cxx_virtual_method` just holds the decl. Special logic in the apply detects that and does virtual dispatch instead.
- `cxx_virtual_method` takes a this pointer and returns an adjusted this pointer and the llvm function pointer. Apply then handles it accordingly either as a curried function or as two sil values for each the function pointer and the adjusted this.
- `cxx_virtual_method` somehow does the apply all in one go.
- Somehow we robustly disallow this pointer adjustment? Maybe just disallow importing funcs defined by multiple-inheritance? `cxx_virtual_method` just looks up the method in this case.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [August 3, 2019, 3:21am UTC](https://forums.swift.org/t/c-interop-virtual-function-calls/27567/4 "2019-08-03T03:21:52Z")

</div>

Doing the apply all in one go is annoying if we ever want `cxx_virtual_method` to be usable with different kinds of apply. Currently we don't, but if we want to support C++ exceptions or something similar someday, or allow C++ code to implement a coroutine or something, then we'd want this separation. It's also just nice to separate the concerns as much as we can.

Having `cxx_virtual_method` simultaneously adjust `this` is probably reasonable and would let us both (1) lower the instruction operationally and independently of the application and (2) robustly devirtualize in SIL if we wanted to.
