@@ -3375,139 +3375,148 @@ impl Print for GlobalVarDecl {
33753375
33763376 let wk = & spv:: spec:: Spec :: get ( ) . well_known ;
33773377
3378- // HACK(eddyb) get the pointee type from SPIR-V `OpTypePointer`, but
3379- // ideally the `GlobalVarDecl` would hold that type itself.
3380- let type_ascription_suffix = match & printer. cx [ * type_of_ptr_to] . kind {
3381- TypeKind :: QPtr if shape. is_some ( ) => match shape. unwrap ( ) {
3382- qptr:: shapes:: GlobalVarShape :: Handles { handle, fixed_count } => {
3383- let handle = match handle {
3384- qptr:: shapes:: Handle :: Opaque ( ty) => ty. print ( printer) ,
3385- qptr:: shapes:: Handle :: Buffer ( addr_space, buf) => pretty:: Fragment :: new ( [
3386- printer. declarative_keyword_style ( ) . apply ( "buffer" ) . into ( ) ,
3387- pretty:: join_comma_sep (
3388- "(" ,
3389- [
3390- addr_space. print ( printer) ,
3391- pretty:: Fragment :: new ( [
3392- printer. pretty_named_argument_prefix ( "size" ) ,
3393- pretty:: Fragment :: new (
3394- Some ( buf. fixed_base . size )
3395- . filter ( |& base_size| {
3396- base_size > 0 || buf. dyn_unit_stride . is_none ( )
3397- } )
3398- . map ( |base_size| {
3399- printer
3400- . numeric_literal_style ( )
3401- . apply ( base_size. to_string ( ) )
3402- . into ( )
3403- } )
3404- . into_iter ( )
3405- . chain ( buf. dyn_unit_stride . map ( |stride| {
3406- pretty:: Fragment :: new ( [
3407- "N × " . into ( ) ,
3408- printer
3409- . numeric_literal_style ( )
3410- . apply ( stride. to_string ( ) ) ,
3411- ] )
3412- } ) )
3413- . intersperse_with ( || " + " . into ( ) ) ,
3414- ) ,
3415- ] ) ,
3416- pretty:: Fragment :: new ( [
3417- printer. pretty_named_argument_prefix ( "align" ) ,
3418- printer
3419- . numeric_literal_style ( )
3420- . apply ( buf. fixed_base . align . to_string ( ) )
3421- . into ( ) ,
3422- ] ) ,
3423- ] ,
3424- ")" ,
3425- ) ,
3426- ] ) ,
3427- } ;
3378+ // HACK(eddyb) to avoid too many syntax variations, most details (other
3379+ // than the type, if present) use named arguments in `GV123(...)`.
3380+ let mut details = SmallVec :: < [ _ ; 4 ] > :: new ( ) ;
34283381
3429- let handles = if fixed_count. map_or ( 0 , |c| c. get ( ) ) == 1 {
3430- handle
3431- } else {
3432- pretty:: Fragment :: new ( [
3433- "[" . into ( ) ,
3434- fixed_count
3435- . map ( |count| {
3436- pretty:: Fragment :: new ( [
3437- printer. numeric_literal_style ( ) . apply ( count. to_string ( ) ) ,
3438- " × " . into ( ) ,
3439- ] )
3440- } )
3441- . unwrap_or_default ( ) ,
3442- handle,
3443- "]" . into ( ) ,
3444- ] )
3445- } ;
3446- pretty:: join_space ( ":" , [ handles] )
3447- }
3448- qptr:: shapes:: GlobalVarShape :: UntypedData ( mem_layout) => pretty:: Fragment :: new ( [
3449- " " . into ( ) ,
3450- printer. declarative_keyword_style ( ) . apply ( "layout" ) . into ( ) ,
3451- pretty:: join_comma_sep (
3452- "(" ,
3453- [
3454- pretty:: Fragment :: new ( [
3455- printer. pretty_named_argument_prefix ( "size" ) ,
3456- printer
3457- . numeric_literal_style ( )
3458- . apply ( mem_layout. size . to_string ( ) )
3459- . into ( ) ,
3460- ] ) ,
3461- pretty:: Fragment :: new ( [
3462- printer. pretty_named_argument_prefix ( "align" ) ,
3463- printer
3464- . numeric_literal_style ( )
3465- . apply ( mem_layout. align . to_string ( ) )
3466- . into ( ) ,
3467- ] ) ,
3468- ] ,
3469- ")" ,
3470- ) ,
3471- ] ) ,
3472- qptr:: shapes:: GlobalVarShape :: TypedInterface ( ty) => {
3473- printer. pretty_type_ascription_suffix ( ty)
3474- }
3475- } ,
3476- TypeKind :: SpvInst { spv_inst, type_and_const_inputs }
3382+ match addr_space {
3383+ AddrSpace :: Handles => { }
3384+ AddrSpace :: SpvStorageClass ( _) => {
3385+ details. push ( addr_space. print ( printer) ) ;
3386+ }
3387+ }
3388+
3389+ // FIXME(eddyb) should this be a helper on `Printer`?
3390+ let num_lit = |x : u32 | printer. numeric_literal_style ( ) . apply ( format ! ( "{x}" ) ) . into ( ) ;
3391+
3392+ // FIXME(eddyb) should the pointer type be shown as something like
3393+ // `&GV123: OpTypePointer(..., T123)` *after* the variable definition?
3394+ // (but each reference can technically have a different type...)
3395+ let ( qptr_shape, spv_ptr_pointee_type) = match & printer. cx [ * type_of_ptr_to] . kind {
3396+ TypeKind :: QPtr => ( shape. as_ref ( ) , None ) ,
3397+
3398+ // HACK(eddyb) get the pointee type from SPIR-V `OpTypePointer`, but
3399+ // ideally the `GlobalVarDecl` would hold that type itself.
3400+ TypeKind :: SpvInst { spv_inst, type_and_const_inputs, .. }
34773401 if spv_inst. opcode == wk. OpTypePointer =>
34783402 {
34793403 match type_and_const_inputs[ ..] {
3480- [ TypeOrConst :: Type ( ty ) ] => printer . pretty_type_ascription_suffix ( ty ) ,
3481- _ => unreachable ! ( ) ,
3404+ [ TypeOrConst :: Type ( pointee_type ) ] => ( None , Some ( pointee_type ) ) ,
3405+ _ => ( None , None ) ,
34823406 }
34833407 }
3484- _ => pretty:: Fragment :: new ( [
3485- ": " . into ( ) ,
3486- printer. error_style ( ) . apply ( "pointee_type_of" ) . into ( ) ,
3487- "(" . into ( ) ,
3488- type_of_ptr_to. print ( printer) ,
3489- ")" . into ( ) ,
3490- ] ) ,
3408+
3409+ _ => ( None , None ) ,
34913410 } ;
3492- let addr_space_suffix = match addr_space {
3493- AddrSpace :: Handles => pretty:: Fragment :: default ( ) ,
3494- AddrSpace :: SpvStorageClass ( _) => {
3495- pretty:: Fragment :: new ( [ " in " . into ( ) , addr_space. print ( printer) ] )
3411+ let ascribe_type = match qptr_shape {
3412+ Some ( qptr:: shapes:: GlobalVarShape :: Handles { handle, fixed_count } ) => {
3413+ let handle = match handle {
3414+ qptr:: shapes:: Handle :: Opaque ( ty) => ty. print ( printer) ,
3415+ qptr:: shapes:: Handle :: Buffer ( addr_space, buf) => pretty:: Fragment :: new ( [
3416+ printer. declarative_keyword_style ( ) . apply ( "buffer" ) . into ( ) ,
3417+ pretty:: join_comma_sep (
3418+ "(" ,
3419+ [
3420+ addr_space. print ( printer) ,
3421+ pretty:: Fragment :: new ( [
3422+ printer. pretty_named_argument_prefix ( "size" ) ,
3423+ pretty:: Fragment :: new (
3424+ [
3425+ Some ( buf. fixed_base . size )
3426+ . filter ( |& base_size| {
3427+ base_size > 0 || buf. dyn_unit_stride . is_none ( )
3428+ } )
3429+ . map ( num_lit) ,
3430+ buf. dyn_unit_stride . map ( |stride| {
3431+ pretty:: Fragment :: new ( [
3432+ "N × " . into ( ) ,
3433+ num_lit ( stride. get ( ) ) ,
3434+ ] )
3435+ } ) ,
3436+ ]
3437+ . into_iter ( )
3438+ . flatten ( )
3439+ . intersperse_with ( || " + " . into ( ) ) ,
3440+ ) ,
3441+ ] ) ,
3442+ pretty:: Fragment :: new ( [
3443+ printer. pretty_named_argument_prefix ( "align" ) ,
3444+ num_lit ( buf. fixed_base . align ) ,
3445+ ] ) ,
3446+ ] ,
3447+ ")" ,
3448+ ) ,
3449+ ] ) ,
3450+ } ;
3451+
3452+ let handles = if fixed_count. map_or ( 0 , |c| c. get ( ) ) == 1 {
3453+ handle
3454+ } else {
3455+ pretty:: Fragment :: new ( [
3456+ "[" . into ( ) ,
3457+ fixed_count
3458+ . map ( |count| {
3459+ pretty:: Fragment :: new ( [ num_lit ( count. get ( ) ) , " × " . into ( ) ] )
3460+ } )
3461+ . unwrap_or_default ( ) ,
3462+ handle,
3463+ "]" . into ( ) ,
3464+ ] )
3465+ } ;
3466+ Some ( handles)
3467+ }
3468+ Some ( qptr:: shapes:: GlobalVarShape :: UntypedData ( mem_layout) ) => {
3469+ details. extend ( [
3470+ pretty:: Fragment :: new ( [
3471+ printer. pretty_named_argument_prefix ( "size" ) ,
3472+ num_lit ( mem_layout. size ) ,
3473+ ] ) ,
3474+ pretty:: Fragment :: new ( [
3475+ printer. pretty_named_argument_prefix ( "align" ) ,
3476+ num_lit ( mem_layout. align ) ,
3477+ ] ) ,
3478+ ] ) ;
3479+ None
34963480 }
3481+ Some ( qptr:: shapes:: GlobalVarShape :: TypedInterface ( ty) ) => Some ( ty. print ( printer) ) ,
3482+
3483+ None => Some ( match spv_ptr_pointee_type {
3484+ Some ( ty) => ty. print ( printer) ,
3485+ None => pretty:: Fragment :: new ( [
3486+ printer. error_style ( ) . apply ( "pointee_type_of" ) . into ( ) ,
3487+ "(" . into ( ) ,
3488+ type_of_ptr_to. print ( printer) ,
3489+ ")" . into ( ) ,
3490+ ] ) ,
3491+ } ) ,
34973492 } ;
3498- let header = pretty:: Fragment :: new ( [ addr_space_suffix, type_ascription_suffix] ) ;
34993493
3500- let maybe_rhs = match def {
3494+ let import = match def {
3495+ // FIXME(eddyb) deduplicate with `FuncDecl`, and maybe consider
3496+ // putting the import *before* the declaration, to end up with:
3497+ // import "..."
3498+ // as global_var GV...
35013499 DeclDef :: Imported ( import) => Some ( import. print ( printer) ) ,
35023500 DeclDef :: Present ( GlobalVarDefBody { initializer } ) => {
3503- // FIXME(eddyb) `global_varX in AS: T = Y` feels a bit wonky for
3504- // the initializer, but it's cleaner than obvious alternatives.
3505- initializer. map ( |initializer| initializer. print ( printer) )
3501+ if let Some ( initializer) = initializer {
3502+ details. push ( pretty:: Fragment :: new ( [
3503+ printer. pretty_named_argument_prefix ( "init" ) ,
3504+ initializer. print ( printer) ,
3505+ ] ) ) ;
3506+ }
3507+ None
35063508 }
35073509 } ;
3508- let body = maybe_rhs. map ( |rhs| pretty:: Fragment :: new ( [ "= " . into ( ) , rhs] ) ) ;
35093510
3510- let def_without_name = pretty:: Fragment :: new ( [ header, pretty:: join_space ( "" , body) ] ) ;
3511+ let def_without_name = pretty:: Fragment :: new (
3512+ [
3513+ ( !details. is_empty ( ) ) . then ( || pretty:: join_comma_sep ( "(" , details, ")" ) ) ,
3514+ ascribe_type. map ( |ty| pretty:: join_space ( ":" , [ ty] ) ) ,
3515+ import. map ( |import| pretty:: Fragment :: new ( [ " = " . into ( ) , import] ) ) ,
3516+ ]
3517+ . into_iter ( )
3518+ . flatten ( ) ,
3519+ ) ;
35113520
35123521 AttrsAndDef { attrs : attrs. print ( printer) , def_without_name }
35133522 }
@@ -3552,9 +3561,17 @@ impl Print for FuncDecl {
35523561 ] ) ;
35533562
35543563 let def_without_name = match def {
3555- DeclDef :: Imported ( import) => {
3556- pretty:: Fragment :: new ( [ sig, " = " . into ( ) , import. print ( printer) ] )
3557- }
3564+ // FIXME(eddyb) deduplicate with `GlobalVarDecl`, and maybe consider
3565+ // putting the import *before* the declaration, to end up with:
3566+ // import "..."
3567+ // as func F...
3568+ DeclDef :: Imported ( import) => pretty:: Fragment :: new ( [
3569+ sig,
3570+ pretty:: join_space (
3571+ "" ,
3572+ [ pretty:: Fragment :: new ( [ "= " . into ( ) , import. print ( printer) ] ) ] ,
3573+ ) ,
3574+ ] ) ,
35583575
35593576 // FIXME(eddyb) this can probably go into `impl Print for FuncDefBody`.
35603577 DeclDef :: Present ( def) => pretty:: Fragment :: new ( [
0 commit comments