@@ -356,7 +356,7 @@ fn register_or_cluster_block(
356
356
357
357
// We need to compute the idents of each register/union block first to make sure no conflicts exists.
358
358
regions. resolve_idents ( ) ?;
359
- // The end of the region from the prior iteration of the loop
359
+ // The end of the region for which we previously emitted a field into `fields`
360
360
let mut last_end = 0 ;
361
361
362
362
for ( i, region) in regions. regions . iter ( ) . enumerate ( ) {
@@ -370,20 +370,10 @@ fn register_or_cluster_block(
370
370
} ) ;
371
371
}
372
372
373
- last_end = region. end ;
374
-
375
373
let mut region_fields = Tokens :: new ( ) ;
376
374
let is_region_a_union = region. is_union ( ) ;
377
375
378
376
for reg_block_field in & region. fields {
379
- if reg_block_field. offset != region. offset {
380
- // TODO: need to emit padding for this case.
381
- // Happens for freescale_mkl43z4
382
- warn ! (
383
- "field {:?} has different offset {} than its union container {}" ,
384
- reg_block_field. field. ident, reg_block_field. offset, region. offset
385
- ) ;
386
- }
387
377
let comment = & format ! (
388
378
"0x{:02x} - {}" ,
389
379
reg_block_field. offset,
@@ -411,7 +401,6 @@ fn register_or_cluster_block(
411
401
}
412
402
}
413
403
} ) ;
414
-
415
404
} else {
416
405
region_fields. append ( quote ! {
417
406
#[ doc = #comment]
@@ -424,7 +413,26 @@ fn register_or_cluster_block(
424
413
425
414
if !is_region_a_union {
426
415
fields. append ( & region_fields) ;
416
+ } else {
417
+ // Emit padding for the items that we're not emitting
418
+ // as fields so that subsequent fields have the correct
419
+ // alignment in the struct. We could omit this and just
420
+ // not updated `last_end`, so that the padding check in
421
+ // the outer loop kicks in, but it is nice to be able to
422
+ // see that the padding is attributed to a union when
423
+ // visually inspecting the alignment in the struct.
424
+ //
425
+ // Include the computed ident for the union in the padding
426
+ // name, along with the region number, falling back to
427
+ // the offset and end in case we couldn't figure out a
428
+ // nice identifier.
429
+ let name = Ident :: new ( format ! ( "_reserved_{}_{}" , i, region. compute_ident( ) . unwrap_or_else( || format!( "{}_{}" , region. offset, region. end) ) ) ) ;
430
+ let pad = ( region. end - region. offset ) as usize ;
431
+ fields. append ( quote ! {
432
+ #name: [ u8 ; #pad] ,
433
+ } )
427
434
}
435
+ last_end = region. end ;
428
436
}
429
437
430
438
let name = Ident :: new ( match name {
0 commit comments