|  | 
| 8 | 8 | // option. This file may not be copied, modified, or distributed | 
| 9 | 9 | // except according to those terms. | 
| 10 | 10 | 
 | 
| 11 |  | -use llvm::{self, ValueRef}; | 
|  | 11 | +use llvm::{self, ValueRef, Integer, Pointer, Float, Double, Struct, Array, Vector}; | 
| 12 | 12 | use base; | 
| 13 | 13 | use build::AllocaFcx; | 
| 14 | 14 | use common::{type_is_fat_ptr, BlockAndBuilder, C_uint}; | 
| @@ -598,3 +598,73 @@ impl FnType { | 
| 598 | 598 |         } | 
| 599 | 599 |     } | 
| 600 | 600 | } | 
|  | 601 | + | 
|  | 602 | +pub fn align_up_to(off: usize, a: usize) -> usize { | 
|  | 603 | +    return (off + a - 1) / a * a; | 
|  | 604 | +} | 
|  | 605 | + | 
|  | 606 | +fn align(off: usize, ty: Type, pointer: usize) -> usize { | 
|  | 607 | +    let a = ty_align(ty, pointer); | 
|  | 608 | +    return align_up_to(off, a); | 
|  | 609 | +} | 
|  | 610 | + | 
|  | 611 | +pub fn ty_align(ty: Type, pointer: usize) -> usize { | 
|  | 612 | +    match ty.kind() { | 
|  | 613 | +        Integer => ((ty.int_width() as usize) + 7) / 8, | 
|  | 614 | +        Pointer => pointer, | 
|  | 615 | +        Float => 4, | 
|  | 616 | +        Double => 8, | 
|  | 617 | +        Struct => { | 
|  | 618 | +            if ty.is_packed() { | 
|  | 619 | +                1 | 
|  | 620 | +            } else { | 
|  | 621 | +                let str_tys = ty.field_types(); | 
|  | 622 | +                str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t, pointer))) | 
|  | 623 | +            } | 
|  | 624 | +        } | 
|  | 625 | +        Array => { | 
|  | 626 | +            let elt = ty.element_type(); | 
|  | 627 | +            ty_align(elt, pointer) | 
|  | 628 | +        } | 
|  | 629 | +        Vector => { | 
|  | 630 | +            let len = ty.vector_length(); | 
|  | 631 | +            let elt = ty.element_type(); | 
|  | 632 | +            ty_align(elt, pointer) * len | 
|  | 633 | +        } | 
|  | 634 | +        _ => bug!("ty_align: unhandled type") | 
|  | 635 | +    } | 
|  | 636 | +} | 
|  | 637 | + | 
|  | 638 | +pub fn ty_size(ty: Type, pointer: usize) -> usize { | 
|  | 639 | +    match ty.kind() { | 
|  | 640 | +        Integer => ((ty.int_width() as usize) + 7) / 8, | 
|  | 641 | +        Pointer => pointer, | 
|  | 642 | +        Float => 4, | 
|  | 643 | +        Double => 8, | 
|  | 644 | +        Struct => { | 
|  | 645 | +            if ty.is_packed() { | 
|  | 646 | +                let str_tys = ty.field_types(); | 
|  | 647 | +                str_tys.iter().fold(0, |s, t| s + ty_size(*t, pointer)) | 
|  | 648 | +            } else { | 
|  | 649 | +                let str_tys = ty.field_types(); | 
|  | 650 | +                let size = str_tys.iter().fold(0, |s, t| { | 
|  | 651 | +                    align(s, *t, pointer) + ty_size(*t, pointer) | 
|  | 652 | +                }); | 
|  | 653 | +                align(size, ty, pointer) | 
|  | 654 | +            } | 
|  | 655 | +        } | 
|  | 656 | +        Array => { | 
|  | 657 | +            let len = ty.array_length(); | 
|  | 658 | +            let elt = ty.element_type(); | 
|  | 659 | +            let eltsz = ty_size(elt, pointer); | 
|  | 660 | +            len * eltsz | 
|  | 661 | +        } | 
|  | 662 | +        Vector => { | 
|  | 663 | +            let len = ty.vector_length(); | 
|  | 664 | +            let elt = ty.element_type(); | 
|  | 665 | +            let eltsz = ty_size(elt, pointer); | 
|  | 666 | +            len * eltsz | 
|  | 667 | +        }, | 
|  | 668 | +        _ => bug!("ty_size: unhandled type") | 
|  | 669 | +    } | 
|  | 670 | +} | 
0 commit comments