Skip to content

Commit ae34d3b

Browse files
committed
Extremely basic Vtable generation
1 parent bcbd72d commit ae34d3b

File tree

3 files changed

+75
-8
lines changed

3 files changed

+75
-8
lines changed

src/codegen/mod.rs

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,15 +1049,65 @@ impl<'a> CodeGenerator for Vtable<'a> {
10491049
) {
10501050
assert_eq!(item.id(), self.item_id);
10511051
debug_assert!(item.is_enabled_for_codegen(ctx));
1052-
1053-
// For now, generate an empty struct, later we should generate function
1054-
// pointers and whatnot.
10551052
let name = ctx.rust_ident(&self.canonical_name(ctx));
1056-
let void = helpers::ast_ty::c_void(ctx);
1057-
result.push(quote! {
1058-
#[repr(C)]
1059-
pub struct #name ( #void );
1060-
});
1053+
1054+
// For now, we will only generate vtables for classes that do not inherit from others.
1055+
if self.base_classes.is_empty() {
1056+
let methods = self
1057+
.methods
1058+
.iter()
1059+
.filter_map(|m| {
1060+
if !m.is_virtual() {
1061+
return None;
1062+
}
1063+
1064+
let function_item = ctx.resolve_item(m.signature());
1065+
if !function_item.process_before_codegen(ctx, result) {
1066+
return None;
1067+
}
1068+
1069+
let function = function_item.expect_function();
1070+
let signature_item = ctx.resolve_item(function.signature());
1071+
let signature = match signature_item.expect_type().kind() {
1072+
TypeKind::Function(ref sig) => sig,
1073+
_ => panic!("Function signature type mismatch"),
1074+
};
1075+
1076+
// FIXME: Is there a canonical name without the class prepended?
1077+
let function_name = function_item.canonical_name(ctx);
1078+
1079+
// FIXME: Need to account for overloading with times_seen (separately from regular function path).
1080+
let function_name = ctx.rust_ident(function_name);
1081+
let mut args = utils::fnsig_arguments(ctx, signature);
1082+
let ret = utils::fnsig_return_ty(ctx, signature);
1083+
1084+
args[0] = if m.is_const() {
1085+
quote! { &self }
1086+
} else {
1087+
quote! { &mut self }
1088+
};
1089+
1090+
Some(quote! {
1091+
#function_name : fn( #( #args ),* ) #ret
1092+
})
1093+
})
1094+
.collect::<Vec<_>>();
1095+
1096+
result.push(quote! {
1097+
#[repr(C)]
1098+
pub struct #name {
1099+
#( #methods ),*
1100+
}
1101+
})
1102+
} else {
1103+
// For the cases we don't support, simply generate an empty struct.
1104+
let void = helpers::ast_ty::c_void(ctx);
1105+
1106+
result.push(quote! {
1107+
#[repr(C)]
1108+
pub struct #name ( #void );
1109+
});
1110+
}
10611111
}
10621112
}
10631113

tests/headers/virtual_interface.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class PureVirtualIFace {
2+
public:
3+
virtual void Foo() = 0;
4+
virtual void Bar(unsigned int) = 0;
5+
};
6+
7+
class Implementation : public PureVirtualIFace {
8+
public:
9+
void Foo() override {}
10+
void Bar(unsigned int) override {}
11+
};

tests/headers/virtual_pure.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class PureVirtualClass {
2+
public:
3+
virtual void Foo() = 0;
4+
virtual void Bar(unsigned int a, bool b) = 0;
5+
virtual void Baz(unsigned int a) const = 0;
6+
};

0 commit comments

Comments
 (0)