@@ -84,15 +84,20 @@ impl quote::ToTokens for CType {
8484}
8585
8686fn parse_ctype ( i : & str ) -> IResult < & str , CType > {
87- ( alt ( ( value ( CType :: U64 , tag ( "ULL" ) ) , value ( CType :: U32 , tag ( "U" ) ) ) ) ) . parse ( i)
87+ ( alt ( (
88+ value ( CType :: U64 , tag ( "ULL" ) ) ,
89+ value ( CType :: U32 , tag ( "U" ) ) ,
90+ // success(CType::U32), // Only for `0x1234` hexadecimals without type-suffix
91+ ) ) )
92+ . parse ( i)
8893}
8994
9095fn parse_cexpr ( i : & str ) -> IResult < & str , ( CType , String ) > {
9196 ( alt ( (
9297 map ( parse_cfloat, |f| ( CType :: Float , format ! ( "{f:.2}" ) ) ) ,
98+ parse_hexadecimal_number,
9399 parse_inverse_number,
94100 parse_decimal_number,
95- parse_hexadecimal_number,
96101 ) ) )
97102 . parse ( i)
98103}
@@ -156,10 +161,7 @@ fn parse_hexadecimal_number(i: &str) -> IResult<&str, (CType, String)> {
156161 ( preceded (
157162 alt ( ( tag ( "0x" ) , tag ( "0X" ) ) ) ,
158163 map ( pair ( hex_digit1, parse_ctype) , |( num, typ) | {
159- (
160- typ,
161- format ! ( "0x{}{}" , num. to_ascii_lowercase( ) , typ. to_string( ) ) ,
162- )
164+ ( typ, format ! ( "0x{}" , num. to_ascii_lowercase( ) ) )
163165 } ) ,
164166 ) )
165167 . parse ( i)
@@ -398,7 +400,10 @@ pub enum Constant {
398400 Number ( i32 ) ,
399401 Hex ( String ) ,
400402 BitPos ( u32 ) ,
401- CExpr ( vkxml:: CExpression ) ,
403+ /// A C expression, also used for floating point (`1000.0F`) and some integer representations (`(~0ULL)`).
404+ ///
405+ /// Hexadecimals could use this path, but are currently handled separately.
406+ CExpr ( String ) ,
402407 Text ( String ) ,
403408 Alias ( Ident ) ,
404409}
@@ -417,7 +422,7 @@ impl quote::ToTokens for Constant {
417422 Self :: Text ( ref text) => text. to_tokens ( tokens) ,
418423 Self :: CExpr ( ref expr) => {
419424 let ( rem, ( _, rexpr) ) = parse_cexpr ( expr) . expect ( "Unable to parse cexpr" ) ;
420- assert ! ( rem. is_empty( ) ) ;
425+ assert ! ( rem. is_empty( ) , "{rem}" ) ;
421426 tokens. extend ( rexpr. parse :: < TokenStream > ( ) ) ;
422427 }
423428 Self :: BitPos ( pos) => {
@@ -426,7 +431,7 @@ impl quote::ToTokens for Constant {
426431 let bit_string = interleave_number ( '_' , 4 , & bit_string) ;
427432 syn:: LitInt :: new ( & format ! ( "0b{bit_string}" ) , Span :: call_site ( ) ) . to_tokens ( tokens) ;
428433 }
429- Self :: Alias ( ref value) => tokens. extend ( quote ! ( Self :: #value) ) ,
434+ Self :: Alias ( ref value) => tokens. extend ( quote ! ( #value) ) ,
430435 }
431436 }
432437}
@@ -471,10 +476,10 @@ impl Constant {
471476 Self :: Number ( _) | Self :: Hex ( _) => CType :: USize ,
472477 Self :: CExpr ( expr) => {
473478 let ( rem, ( ty, _) ) = parse_cexpr ( expr) . expect ( "Unable to parse cexpr" ) ;
474- assert ! ( rem. is_empty( ) ) ;
479+ assert ! ( rem. is_empty( ) , "{rem}" ) ;
475480 ty
476481 }
477- _ => unimplemented ! ( ) ,
482+ x => unimplemented ! ( "{x:?}" ) ,
478483 }
479484 }
480485
@@ -528,19 +533,26 @@ impl Constant {
528533 Some ( ( Self :: Number ( value as i32 ) , Some ( extends. clone ( ) ) , false ) )
529534 }
530535 EnumSpec :: Value { value, extends } => {
531- let value = value
532- . strip_prefix ( "0x" )
533- . map ( |hex| Self :: Hex ( hex. to_owned ( ) ) )
534- . or_else ( || value. parse :: < i32 > ( ) . ok ( ) . map ( Self :: Number ) ) ?;
536+ let value = if let Ok ( value) = value. parse :: < i32 > ( ) {
537+ Self :: Number ( value)
538+ } else if let Some ( hex) = value. strip_prefix ( "0x" ) {
539+ Self :: Hex ( hex. to_owned ( ) )
540+ } else {
541+ Self :: CExpr ( value. to_owned ( ) )
542+ } ;
543+
535544 Some ( ( value, extends. clone ( ) , false ) )
536545 }
537546 EnumSpec :: Alias { alias, extends } => {
538- let base_type = extends. as_deref ( ) . or ( enum_name) ?;
539- let key = variant_ident ( base_type, alias) ;
547+ let base_type = extends. as_deref ( ) . or ( enum_name) ;
548+ let key = base_type
549+ . map_or ( format_ident ! ( "{}" , constant_name( alias) ) , |base_type| {
550+ variant_ident ( base_type, alias)
551+ } ) ;
540552 if key == "DISPATCH_BASE" {
541553 None
542554 } else {
543- Some ( ( Self :: Alias ( key) , Some ( base_type. to_owned ( ) ) , true ) )
555+ Some ( ( Self :: Alias ( key) , base_type. map ( str :: to_owned ) , true ) )
544556 }
545557 }
546558 _ => None ,
@@ -1685,7 +1697,7 @@ pub fn bitflags_impl_block(
16851697 let notation = constant. doc_attribute ( ) ;
16861698 let constant = constant. constant ( enum_name) ;
16871699 let value = if let Constant :: Alias ( _) = & constant {
1688- quote ! ( #constant)
1700+ quote ! ( Self :: #constant)
16891701 } else {
16901702 quote ! ( Self ( #constant) )
16911703 } ;
@@ -2805,20 +2817,25 @@ pub fn constant_name(name: &str) -> &str {
28052817}
28062818
28072819pub fn generate_constant < ' a > (
2808- constant : & ' a vkxml :: Constant ,
2809- cache : & mut HashSet < & ' a str > ,
2820+ constant : & ' a vk_parse :: Enum ,
2821+ global_const_cache : & mut HashMap < & ' a str , CType > ,
28102822) -> TokenStream {
2811- cache. insert ( constant. name . as_str ( ) ) ;
2812- let c = Constant :: from_constant ( constant) ;
2823+ let ( c, _, is_alias) = Constant :: from_vk_parse_enum ( constant, None , None ) . unwrap ( ) ;
2824+ // This requires knowing the type of the alias, that is unavailable here. Besides
2825+ // backwards-compatibility, stabilization aliases serve no purpose.
28132826 let name = constant_name ( & constant. name ) ;
28142827 let ident = format_ident ! ( "{}" , name) ;
28152828 let notation = constant. doc_attribute ( ) ;
2816-
2817- let ty = if name == "TRUE" || name == "FALSE" {
2829+ let ty = if let Constant :: Alias ( a) = & c {
2830+ // TODO: Drop is_alias over Constant::Alias match
2831+ assert ! ( is_alias) ;
2832+ global_const_cache[ a. to_string ( ) . as_str ( ) ]
2833+ } else if name == "TRUE" || name == "FALSE" {
28182834 CType :: Bool32
28192835 } else {
28202836 c. ty ( )
28212837 } ;
2838+ global_const_cache. insert ( name, ty) ;
28222839 quote ! {
28232840 #notation
28242841 pub const #ident: #ty = #c;
@@ -3064,11 +3081,13 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
30643081 . flat_map ( |definitions| & definitions. elements )
30653082 . collect ( ) ;
30663083
3067- let constants: Vec < & vkxml :: Constant > = spec
3068- . elements
3084+ let constants: Vec < _ > = spec2
3085+ . 0
30693086 . iter ( )
3070- . filter_map ( get_variant ! ( vkxml:: RegistryElement :: Constants ) )
3071- . flat_map ( |constants| & constants. elements )
3087+ . filter_map ( get_variant ! ( vk_parse:: RegistryChild :: Enums ) )
3088+ . filter ( |enums| enums. kind . as_deref ( ) == Some ( "constants" ) )
3089+ . flat_map ( |enums| & enums. children )
3090+ . filter_map ( get_variant ! ( vk_parse:: EnumsChild :: Enum ) )
30723091 . collect ( ) ;
30733092
30743093 let features_children = spec2
@@ -3144,13 +3163,12 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
31443163 acc
31453164 } ) ;
31463165
3147- let mut constants_code: Vec < _ > = constants
3166+ let mut global_const_cache = HashMap :: new ( ) ;
3167+ let constants_code: Vec < _ > = constants
31483168 . iter ( )
3149- . map ( |constant| generate_constant ( constant, & mut const_cache ) )
3169+ . map ( |constant| generate_constant ( constant, & mut global_const_cache ) )
31503170 . collect ( ) ;
31513171
3152- constants_code. push ( quote ! { pub const SHADER_UNUSED_NV : u32 = SHADER_UNUSED_KHR ; } ) ;
3153-
31543172 let union_types = definitions
31553173 . iter ( )
31563174 . filter_map ( get_variant ! ( vkxml:: DefinitionsElement :: Union ) )
0 commit comments