@@ -797,8 +797,23 @@ struct CppInterfaceGenerator<'a> {
797797
798798impl CppInterfaceGenerator < ' _ > {
799799 fn types ( & mut self , iface : InterfaceId ) {
800- let iface = & self . resolve ( ) . interfaces [ iface] ;
801- for ( name, id) in iface. types . iter ( ) {
800+ let iface_data = & self . resolve ( ) . interfaces [ iface] ;
801+
802+ // First pass: emit forward declarations for all resources
803+ // This ensures resources can reference each other in method signatures
804+ for ( name, id) in iface_data. types . iter ( ) {
805+ let ty = & self . resolve ( ) . types [ * id] ;
806+ if matches ! ( & ty. kind, TypeDefKind :: Resource ) {
807+ let pascal = name. to_upper_camel_case ( ) ;
808+ let guest_import = self . gen . imported_interfaces . contains ( & iface) ;
809+ let namespc = namespace ( self . resolve , & ty. owner , !guest_import, & self . gen . opts ) ;
810+ self . gen . h_src . change_namespace ( & namespc) ;
811+ uwriteln ! ( self . gen . h_src. src, "class {pascal};" ) ;
812+ }
813+ }
814+
815+ // Second pass: emit full type definitions
816+ for ( name, id) in iface_data. types . iter ( ) {
802817 self . define_type ( name, * id) ;
803818 }
804819 }
@@ -1055,7 +1070,7 @@ impl CppInterfaceGenerator<'_> {
10551070 ""
10561071 } ;
10571072 res. arguments . push ( (
1058- name . to_snake_case ( ) ,
1073+ to_c_ident ( name ) ,
10591074 self . type_name ( param, & res. namespace , Flavor :: Argument ( abi_variant) ) + is_pointer,
10601075 ) ) ;
10611076 }
@@ -1662,7 +1677,7 @@ impl CppInterfaceGenerator<'_> {
16621677 uwriteln ! ( self . gen . h_src. src, "struct {pascal} {{" ) ;
16631678 for field in record. fields . iter ( ) {
16641679 let typename = self . type_name ( & field. ty , namespc, flavor) ;
1665- let fname = field. name . to_snake_case ( ) ;
1680+ let fname = to_c_ident ( & field. name ) ;
16661681 uwriteln ! ( self . gen . h_src. src, "{typename} {fname};" ) ;
16671682 }
16681683 uwriteln ! ( self . gen . h_src. src, "}};" ) ;
@@ -1703,7 +1718,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
17031718 for field in record. fields . iter ( ) {
17041719 Self :: docs ( & mut self . gen . h_src . src , & field. docs ) ;
17051720 let typename = self . type_name ( & field. ty , & namespc, Flavor :: InStruct ) ;
1706- let fname = field. name . to_snake_case ( ) ;
1721+ let fname = to_c_ident ( & field. name ) ;
17071722 uwriteln ! ( self . gen . h_src. src, "{typename} {fname};" ) ;
17081723 }
17091724 uwriteln ! ( self . gen . h_src. src, "}};" ) ;
@@ -1884,7 +1899,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
18841899 uwriteln ! ( self . gen . h_src. src, "k_None = 0," ) ;
18851900 for ( n, field) in flags. flags . iter ( ) . enumerate ( ) {
18861901 Self :: docs ( & mut self . gen . h_src . src , & field. docs ) ;
1887- let fname = field. name . to_pascal_case ( ) ;
1902+ let fname = to_c_ident ( & field. name ) . to_pascal_case ( ) ;
18881903 uwriteln ! ( self . gen . h_src. src, "k{fname} = (1ULL<<{n})," ) ;
18891904 }
18901905 uwriteln ! ( self . gen . h_src. src, "}};" ) ;
@@ -1926,7 +1941,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
19261941 let mut all_types = String :: new ( ) ;
19271942 for case in variant. cases . iter ( ) {
19281943 Self :: docs ( & mut self . gen . h_src . src , & case. docs ) ;
1929- let case_pascal = case. name . to_pascal_case ( ) ;
1944+ let case_pascal = to_c_ident ( & case. name ) . to_pascal_case ( ) ;
19301945 if !all_types. is_empty ( ) {
19311946 all_types += ", " ;
19321947 }
@@ -1985,7 +2000,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
19852000 uwriteln ! (
19862001 self . gen . h_src. src,
19872002 " k{} = {i}," ,
1988- case. name. to_pascal_case( ) ,
2003+ to_c_ident ( & case. name) . to_pascal_case( ) ,
19892004 ) ;
19902005 }
19912006 uwriteln ! ( self . gen . h_src. src, "}};\n " ) ;
@@ -2655,7 +2670,8 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
26552670 uwriteln ! ( self . src, "case {}: {{" , i) ;
26562671 if let Some ( ty) = case. ty . as_ref ( ) {
26572672 let ty = self . gen . type_name ( ty, & self . namespace , Flavor :: InStruct ) ;
2658- let case = format ! ( "{elem_ns}::{}" , case. name. to_pascal_case( ) ) ;
2673+ let case =
2674+ format ! ( "{elem_ns}::{}" , to_c_ident( & case. name) . to_pascal_case( ) ) ;
26592675 uwriteln ! (
26602676 self . src,
26612677 "{} &{} = std::get<{case}>({}.variants).value;" ,
@@ -2686,24 +2702,26 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
26862702 let resultno = self . tmp ( ) ;
26872703 let result = format ! ( "variant{resultno}" ) ;
26882704
2689- uwriteln ! ( self . src, "{ty} {result};" ) ;
2690-
26912705 let op0 = & operands[ 0 ] ;
26922706
2707+ // Use std::optional to avoid default constructor issues
2708+ self . gen . gen . dependencies . needs_optional = true ;
2709+ uwriteln ! ( self . src, "std::optional<{ty}> {result}_opt;" ) ;
26932710 uwriteln ! ( self . src, "switch ({op0}) {{" ) ;
26942711 for ( i, ( case, ( block, block_results) ) ) in
26952712 variant. cases . iter ( ) . zip ( blocks) . enumerate ( )
26962713 {
2697- let tp = case. name . clone ( ) . to_pascal_case ( ) ;
2714+ let tp = to_c_ident ( & case. name ) . to_pascal_case ( ) ;
26982715 uwriteln ! ( self . src, "case {i}: {{ {block}" ) ;
26992716 uwriteln ! (
27002717 self . src,
2701- "{result}.variants = {ty}::{tp}{{{}}};" ,
2718+ "{result}_opt = {ty}{{{{{ty} ::{tp}{{{}}}} }}};" ,
27022719 move_if_necessary( & block_results. first( ) . cloned( ) . unwrap_or_default( ) )
27032720 ) ;
27042721 uwriteln ! ( self . src, "}} break;" ) ;
27052722 }
27062723 uwriteln ! ( self . src, "}}" ) ;
2724+ uwriteln ! ( self . src, "{ty} {result} = std::move(*{result}_opt);" ) ;
27072725
27082726 results. push ( result) ;
27092727 }
0 commit comments