Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow calling pure virtual functions #305

Closed
adetaylor opened this issue Mar 23, 2021 · 1 comment · Fixed by #315
Closed

Allow calling pure virtual functions #305

adetaylor opened this issue Mar 23, 2021 · 1 comment · Fixed by #315
Labels
cpp-feature C++ feature not yet supported

Comments

@adetaylor
Copy link
Collaborator

At the moment, trying to generate code for a pure virtual class says:

gen/content/browser/gen0.cc:134:5: error: field type 'content::RenderFrameHost' is an abstract class
  T value;
    ^
gen/content/browser/gen0.cc:344:91: note: in instantiation of template class 'rust::MaybeUninit<content::RenderFrameHost>' requested here
  ::content::RenderFrameHost *uninit = reinterpret_cast<::content::RenderFrameHost *>(new ::rust::MaybeUninit<::content::RenderFrameHost>);
                                                                                          ^
../../ipc/ipc_listener.h:25:16: note: unimplemented pure virtual method 'OnMessageReceived' in 'RenderFrameHost'
  virtual bool OnMessageReceived(const Message& message) = 0;
               ^

Relevant bits of code from the generated C++:

template <typename T>
union MaybeUninit {
  T value;
  void *operator new(::std::size_t sz) { return detail::operator_new<T>{}(sz); }
  MaybeUninit() {}
  ~MaybeUninit() {}
};

...

::content::RenderFrameHost *cxxbridge1$unique_ptr$content$RenderFrameHost$uninit(::std::unique_ptr<::content::RenderFrameHost> *ptr) noexcept {
  ::content::RenderFrameHost *uninit = reinterpret_cast<::content::RenderFrameHost *>(new ::rust::MaybeUninit<::content::RenderFrameHost>);
  ::new (ptr) ::std::unique_ptr<::content::RenderFrameHost>(uninit);
  return uninit;
}

This is, I think, because we are doing impl UniquePtr<content::RenderFrameHost> in our generated cxx::bridge.

@adetaylor
Copy link
Collaborator Author

Sitrep:

#include <cstdint>
class A {
public:
    virtual uint32_t get_val() const = 0;
};
class B : public A {
public:
    virtual uint32_t get_val() const { return 3; }
};
const B b;
inline const A* get_a() { return &b; };

Bindgen generates:

pub mod root {
        #[allow(unused_imports)]
        use self::super::root;
        #[repr(C)]
        pub struct A__bindgen_vtable(::std::os::raw::c_void);
        #[repr(C)]
        pub struct A {
            pub vtable_: *const A__bindgen_vtable,
        }
        extern "C" {
            #[link_name = "\u{1}__Z5get_av"]
            pub fn get_a() -> *const root::A;
        }
    }
     }

and thus we don't find out about virtual functions at all. rust-lang/rust-bindgen#1143

Options:

  • Fix upstream bindgen issue (but this isn't quite ideal for us; we don't want to call functions using the vtable from Rust; we simply want to know of their existence so we can generate C++ wrapper functions)
  • Modify our autocxx-bindgen 'temporary' fork to output some metadata about these
  • Eventually switch away from bindgen and use libclang directly

@adetaylor adetaylor changed the title Allow raw pointers to pure virtual classes Allow calling pure virtual functions Mar 24, 2021
@adetaylor adetaylor added the cpp-feature C++ feature not yet supported label Mar 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cpp-feature C++ feature not yet supported
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant