@@ -165,7 +165,8 @@ impl C {
165165 match ty {
166166 Type :: Id ( id) => match & iface. types [ * id] . kind {
167167 TypeDefKind :: Type ( t) => self . is_arg_by_pointer ( iface, t) ,
168- TypeDefKind :: Variant ( v) => !v. is_enum ( ) ,
168+ TypeDefKind :: Variant ( _) => true ,
169+ TypeDefKind :: Enum ( _) => false ,
169170 TypeDefKind :: Flags ( _) => false ,
170171 TypeDefKind :: Tuple ( _) | TypeDefKind :: Record ( _) | TypeDefKind :: List ( _) => true ,
171172 } ,
@@ -244,6 +245,7 @@ impl C {
244245 TypeDefKind :: Type ( t) => self . print_ty ( iface, t) ,
245246 TypeDefKind :: Flags ( _)
246247 | TypeDefKind :: Tuple ( _)
248+ | TypeDefKind :: Enum ( _)
247249 | TypeDefKind :: Record ( _)
248250 | TypeDefKind :: List ( _)
249251 | TypeDefKind :: Variant ( _) => {
@@ -282,7 +284,9 @@ impl C {
282284 }
283285 match & ty. kind {
284286 TypeDefKind :: Type ( t) => self . print_ty_name ( iface, t) ,
285- TypeDefKind :: Record ( _) | TypeDefKind :: Flags ( _) => unimplemented ! ( ) ,
287+ TypeDefKind :: Record ( _) | TypeDefKind :: Flags ( _) | TypeDefKind :: Enum ( _) => {
288+ unimplemented ! ( )
289+ }
286290 TypeDefKind :: Tuple ( t) => {
287291 self . src . h ( "tuple" ) ;
288292 self . src . h ( & t. types . len ( ) . to_string ( ) ) ;
@@ -324,7 +328,10 @@ impl C {
324328 self . src . h ( "typedef " ) ;
325329 let kind = & iface. types [ ty] . kind ;
326330 match kind {
327- TypeDefKind :: Type ( _) | TypeDefKind :: Flags ( _) | TypeDefKind :: Record ( _) => {
331+ TypeDefKind :: Type ( _)
332+ | TypeDefKind :: Flags ( _)
333+ | TypeDefKind :: Record ( _)
334+ | TypeDefKind :: Enum ( _) => {
328335 unreachable ! ( )
329336 }
330337 TypeDefKind :: Tuple ( t) => {
@@ -347,25 +354,21 @@ impl C {
347354 self . src . h ( " val;\n " ) ;
348355 self . src . h ( "}" ) ;
349356 } else if let Some ( ( ok, err) ) = v. as_expected ( ) {
350- if ok. is_none ( ) && err. is_none ( ) {
351- self . src . h ( "uint8_t" ) ;
352- } else {
353- self . src . h ( "struct {
354- // 0 if `val` is `ok`, 1 otherwise
355- uint8_t tag;
356- union {
357- " ) ;
358- if let Some ( ok) = ok {
359- self . print_ty ( iface, ok) ;
360- self . src . h ( " ok;\n " ) ;
361- }
362- if let Some ( err) = err {
363- self . print_ty ( iface, err) ;
364- self . src . h ( " err;\n " ) ;
365- }
366- self . src . h ( "} val;\n " ) ;
367- self . src . h ( "}" ) ;
357+ self . src . h ( "struct {
358+ // 0 if `val` is `ok`, 1 otherwise
359+ uint8_t tag;
360+ union {
361+ " ) ;
362+ if let Some ( ok) = ok {
363+ self . print_ty ( iface, ok) ;
364+ self . src . h ( " ok;\n " ) ;
365+ }
366+ if let Some ( err) = err {
367+ self . print_ty ( iface, err) ;
368+ self . src . h ( " err;\n " ) ;
368369 }
370+ self . src . h ( "} val;\n " ) ;
371+ self . src . h ( "}" ) ;
369372 } else {
370373 unimplemented ! ( ) ;
371374 }
@@ -453,6 +456,7 @@ impl C {
453456 TypeDefKind :: Type ( t) => self . free ( iface, t, "ptr" ) ,
454457
455458 TypeDefKind :: Flags ( _) => { }
459+ TypeDefKind :: Enum ( _) => { }
456460
457461 TypeDefKind :: Record ( r) => {
458462 for field in r. fields . iter ( ) {
@@ -527,6 +531,7 @@ impl C {
527531 TypeDefKind :: Record ( r) => r. fields . iter ( ) . any ( |t| self . owns_anything ( iface, & t. ty ) ) ,
528532 TypeDefKind :: Tuple ( t) => t. types . iter ( ) . any ( |t| self . owns_anything ( iface, t) ) ,
529533 TypeDefKind :: Flags ( _) => false ,
534+ TypeDefKind :: Enum ( _) => false ,
530535 TypeDefKind :: List ( _) => true ,
531536 TypeDefKind :: Variant ( v) => v
532537 . cases
@@ -597,8 +602,8 @@ impl Return {
597602 // other records/lists/buffers always go to return pointers
598603 TypeDefKind :: List ( _) => self . retptrs . push ( * orig_ty) ,
599604
600- // Enums are scalars (this includes bools)
601- TypeDefKind :: Variant ( v ) if v . is_enum ( ) => {
605+ // Enums are scalars
606+ TypeDefKind :: Enum ( _ ) => {
602607 self . scalar = Some ( Scalar :: Type ( * orig_ty) ) ;
603608 }
604609
@@ -617,17 +622,15 @@ impl Return {
617622 // returned through the normal returns.
618623 if let Some ( ( ok, err) ) = r. as_expected ( ) {
619624 if let Some ( Type :: Id ( err) ) = err {
620- if let TypeDefKind :: Variant ( e) = & iface. types [ * err] . kind {
621- if e. is_enum ( ) {
622- self . scalar = Some ( Scalar :: ExpectedEnum {
623- err : * err,
624- max_err : e. cases . len ( ) ,
625- } ) ;
626- if let Some ( ok) = ok {
627- self . splat_tuples ( iface, ok, ok) ;
628- }
629- return ;
625+ if let TypeDefKind :: Enum ( e) = & iface. types [ * err] . kind {
626+ self . scalar = Some ( Scalar :: ExpectedEnum {
627+ err : * err,
628+ max_err : e. cases . len ( ) ,
629+ } ) ;
630+ if let Some ( ok) = ok {
631+ self . splat_tuples ( iface, ok, ok) ;
630632 }
633+ return ;
631634 }
632635 }
633636 }
@@ -760,40 +763,31 @@ impl Generator for C {
760763 let prev = mem:: take ( & mut self . src . header ) ;
761764 self . docs ( docs) ;
762765 self . names . insert ( & name. to_snake_case ( ) ) . unwrap ( ) ;
763- if variant. is_enum ( ) {
764- self . src . h ( "typedef " ) ;
765- self . src . h ( int_repr ( variant. tag ) ) ;
766- self . src . h ( " " ) ;
767- self . print_namespace ( iface) ;
768- self . src . h ( & name. to_snake_case ( ) ) ;
769- self . src . h ( "_t;\n " ) ;
770- } else {
771- self . src . h ( "typedef struct {\n " ) ;
772- self . src . h ( int_repr ( variant. tag ) ) ;
773- self . src . h ( " tag;\n " ) ;
774- match variant. as_option ( ) {
775- Some ( ty) => {
776- self . print_ty ( iface, ty) ;
777- self . src . h ( " val;\n " ) ;
778- }
779- None => {
780- self . src . h ( "union {\n " ) ;
781- for case in variant. cases . iter ( ) {
782- if let Some ( ty) = & case. ty {
783- self . print_ty ( iface, ty) ;
784- self . src . h ( " " ) ;
785- self . src . h ( & case_field_name ( case) ) ;
786- self . src . h ( ";\n " ) ;
787- }
766+ self . src . h ( "typedef struct {\n " ) ;
767+ self . src . h ( int_repr ( variant. tag ) ) ;
768+ self . src . h ( " tag;\n " ) ;
769+ match variant. as_option ( ) {
770+ Some ( ty) => {
771+ self . print_ty ( iface, ty) ;
772+ self . src . h ( " val;\n " ) ;
773+ }
774+ None => {
775+ self . src . h ( "union {\n " ) ;
776+ for case in variant. cases . iter ( ) {
777+ if let Some ( ty) = & case. ty {
778+ self . print_ty ( iface, ty) ;
779+ self . src . h ( " " ) ;
780+ self . src . h ( & case_field_name ( case) ) ;
781+ self . src . h ( ";\n " ) ;
788782 }
789- self . src . h ( "} val;\n " ) ;
790783 }
784+ self . src . h ( "} val;\n " ) ;
791785 }
792- self . src . h ( "} " ) ;
793- self . print_namespace ( iface) ;
794- self . src . h ( & name. to_snake_case ( ) ) ;
795- self . src . h ( "_t;\n " ) ;
796786 }
787+ self . src . h ( "} " ) ;
788+ self . print_namespace ( iface) ;
789+ self . src . h ( & name. to_snake_case ( ) ) ;
790+ self . src . h ( "_t;\n " ) ;
797791 for ( i, case) in variant. cases . iter ( ) . enumerate ( ) {
798792 self . src . h ( & format ! (
799793 "#define {}_{}_{} {}\n " ,
@@ -808,6 +802,30 @@ impl Generator for C {
808802 . insert ( id, mem:: replace ( & mut self . src . header , prev) ) ;
809803 }
810804
805+ fn type_enum ( & mut self , iface : & Interface , id : TypeId , name : & str , enum_ : & Enum , docs : & Docs ) {
806+ let prev = mem:: take ( & mut self . src . header ) ;
807+ self . docs ( docs) ;
808+ self . names . insert ( & name. to_snake_case ( ) ) . unwrap ( ) ;
809+ self . src . h ( "typedef " ) ;
810+ self . src . h ( int_repr ( enum_. tag ( ) ) ) ;
811+ self . src . h ( " " ) ;
812+ self . print_namespace ( iface) ;
813+ self . src . h ( & name. to_snake_case ( ) ) ;
814+ self . src . h ( "_t;\n " ) ;
815+ for ( i, case) in enum_. cases . iter ( ) . enumerate ( ) {
816+ self . src . h ( & format ! (
817+ "#define {}_{}_{} {}\n " ,
818+ iface. name. to_shouty_snake_case( ) ,
819+ name. to_shouty_snake_case( ) ,
820+ case. name. to_shouty_snake_case( ) ,
821+ i,
822+ ) ) ;
823+ }
824+
825+ self . types
826+ . insert ( id, mem:: replace ( & mut self . src . header , prev) ) ;
827+ }
828+
811829 fn type_resource ( & mut self , iface : & Interface , ty : ResourceId ) {
812830 drop ( ( iface, ty) ) ;
813831 }
@@ -1477,6 +1495,7 @@ impl Bindgen for FunctionBindgen<'_> {
14771495 results. push ( format ! ( "*{}" , name) ) ;
14781496 self . payloads . push ( name) ;
14791497 }
1498+
14801499 Instruction :: VariantLower {
14811500 variant,
14821501 results : result_types,
@@ -1491,11 +1510,6 @@ impl Bindgen for FunctionBindgen<'_> {
14911510 . drain ( self . payloads . len ( ) - variant. cases . len ( ) ..)
14921511 . collect :: < Vec < _ > > ( ) ;
14931512
1494- if results. len ( ) == 1 && variant. is_enum ( ) {
1495- results. push ( format ! ( "(int32_t) {}" , operands[ 0 ] ) ) ;
1496- return ;
1497- }
1498-
14991513 let mut variant_results = Vec :: new ( ) ;
15001514 for ty in result_types. iter ( ) {
15011515 let name = self . locals . tmp ( "variant" ) ;
@@ -1507,11 +1521,7 @@ impl Bindgen for FunctionBindgen<'_> {
15071521 variant_results. push ( name) ;
15081522 }
15091523
1510- let expr_to_match = if variant. is_enum ( ) {
1511- operands[ 0 ] . to_string ( )
1512- } else {
1513- format ! ( "({}).tag" , operands[ 0 ] )
1514- } ;
1524+ let expr_to_match = format ! ( "({}).tag" , operands[ 0 ] ) ;
15151525
15161526 self . src
15171527 . push_str ( & format ! ( "switch ((int32_t) {}) {{\n " , expr_to_match) ) ;
@@ -1549,10 +1559,6 @@ impl Bindgen for FunctionBindgen<'_> {
15491559 . drain ( self . blocks . len ( ) - variant. cases . len ( ) ..)
15501560 . collect :: < Vec < _ > > ( ) ;
15511561
1552- if variant. is_enum ( ) {
1553- return results. push ( operands. pop ( ) . unwrap ( ) ) ;
1554- }
1555-
15561562 let ty = self . gen . type_string ( iface, & Type :: Id ( * ty) ) ;
15571563 let result = self . locals . tmp ( "variant" ) ;
15581564 self . src . push_str ( & format ! ( "{} {};\n " , ty, result) ) ;
@@ -1583,6 +1589,9 @@ impl Bindgen for FunctionBindgen<'_> {
15831589 results. push ( result) ;
15841590 }
15851591
1592+ Instruction :: EnumLower { .. } => results. push ( format ! ( "(int32_t) {}" , operands[ 0 ] ) ) ,
1593+ Instruction :: EnumLift { .. } => results. push ( operands. pop ( ) . unwrap ( ) ) ,
1594+
15861595 Instruction :: ListCanonLower { .. } | Instruction :: StringLower { .. } => {
15871596 results. push ( format ! ( "(int32_t) ({}).ptr" , operands[ 0 ] ) ) ;
15881597 results. push ( format ! ( "(int32_t) ({}).len" , operands[ 0 ] ) ) ;
0 commit comments