@@ -1049,15 +1049,65 @@ impl<'a> CodeGenerator for Vtable<'a> {
1049
1049
) {
1050
1050
assert_eq ! ( item. id( ) , self . item_id) ;
1051
1051
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.
1055
1052
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
+ }
1061
1111
}
1062
1112
}
1063
1113
0 commit comments