aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler/sizes.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2019-11-07 15:34:07 +0100
committerRon Evans <[email protected]>2019-11-07 21:39:29 +0100
commit6108ee6859ff6fa2154ee588709e1e0b68f6b2b5 (patch)
tree11e574189d9b9344adfe9dd49d449e21d8469bf2 /compiler/sizes.go
parent76c9f13e133e09e5633917aecabfe44137f5a4ba (diff)
downloadtinygo-6108ee6859ff6fa2154ee588709e1e0b68f6b2b5.tar.gz
tinygo-6108ee6859ff6fa2154ee588709e1e0b68f6b2b5.zip
cgo: refactor union support
Instead of putting the magic in the AST, generate regular accessor methods. This avoids a number of special cases in the compiler, and avoids missing any of them. The resulting union accesses are somewhat clunkier to use, but the compiler implementation has far less coupling between the CGo implementation and the IR generator.
Diffstat (limited to 'compiler/sizes.go')
-rw-r--r--compiler/sizes.go35
1 files changed, 6 insertions, 29 deletions
diff --git a/compiler/sizes.go b/compiler/sizes.go
index 6d212da0a..7f2b87d3b 100644
--- a/compiler/sizes.go
+++ b/compiler/sizes.go
@@ -63,12 +63,6 @@ func (s *StdSizes) Alignof(T types.Type) int64 {
func (s *StdSizes) Offsetsof(fields []*types.Var) []int64 {
offsets := make([]int64, len(fields))
- if len(fields) > 1 && fields[0].Name() == "C union" {
- // This struct contains the magic "C union" field which indicates that
- // this is actually a union from CGo.
- // All fields in the union start at 0 so return that.
- return offsets // all fields are still set to 0
- }
var o int64
for i, f := range fields {
a := s.Alignof(f.Type())
@@ -143,29 +137,12 @@ func (s *StdSizes) Sizeof(T types.Type) int64 {
maxAlign = al
}
}
- if fields[0].Name() == "C union" {
- // Magic field that indicates this is a CGo union and not a struct.
- // The size is the biggest element, aligned to the element with the
- // biggest alignment. This is not necessarily the same, for example
- // in the following union:
- // union { int32_t l; int16_t s[3] }
- maxSize := int64(0)
- for _, field := range fields[1:] {
- si := s.Sizeof(field.Type())
- if si > maxSize {
- maxSize = si
- }
- }
- return align(maxSize, maxAlign)
- } else {
- // This is a regular struct.
- // Pick the size that fits this struct and add some alignment. Some
- // structs have some extra padding at the end which should also be
- // taken care of:
- // struct { int32 n; byte b }
- offsets := s.Offsetsof(fields)
- return align(offsets[n-1]+s.Sizeof(fields[n-1].Type()), maxAlign)
- }
+ // Pick the size that fits this struct and add some alignment. Some
+ // structs have some extra padding at the end which should also be taken
+ // care of:
+ // struct { int32 n; byte b }
+ offsets := s.Offsetsof(fields)
+ return align(offsets[n-1]+s.Sizeof(fields[n-1].Type()), maxAlign)
case *types.Interface:
return s.PtrSize * 2
case *types.Pointer: