aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-08-01 16:29:40 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-08-02 16:57:31 +0200
commit3a4641d90c293137bd33e6472e721a4c15b0d7da (patch)
tree3a9cd28c3379610ad58120ee6051f5cc4d03daba /pkg
parent2e17e2c0adcbae89c1634e4fadc398494b6639fb (diff)
pkg/compiler: refactor structGen
Still too complex. Split more. Update #538
Diffstat (limited to 'pkg')
-rw-r--r--pkg/compiler/gen.go137
1 files changed, 75 insertions, 62 deletions
diff --git a/pkg/compiler/gen.go b/pkg/compiler/gen.go
index 938790b58..9de43d453 100644
--- a/pkg/compiler/gen.go
+++ b/pkg/compiler/gen.go
@@ -148,83 +148,96 @@ func (ctx *structGen) check(key prog.StructKey, descp **prog.StructDesc) bool {
}
func (ctx *structGen) walk(t0 prog.Type) {
- comp := ctx.comp
switch t := t0.(type) {
case *prog.PtrType:
ctx.walk(t.Type)
case *prog.ArrayType:
- if ctx.padded[t] {
- return
- }
- ctx.walk(t.Type)
- if !t.Type.Varlen() && t.Type.Size() == sizeUnassigned {
- // An inner struct is not padded yet.
- // Leave this array for next iteration.
- return
- }
- ctx.padded[t] = true
- t.TypeSize = 0
- if t.Kind == prog.ArrayRangeLen && t.RangeBegin == t.RangeEnd && !t.Type.Varlen() {
- t.TypeSize = t.RangeBegin * t.Type.Size()
- }
+ ctx.walkArray(t)
case *prog.StructType:
- if !ctx.check(t.Key, &t.StructDesc) {
- return
+ ctx.walkStruct(t)
+ case *prog.UnionType:
+ ctx.walkUnion(t)
+ }
+}
+
+func (ctx *structGen) walkArray(t *prog.ArrayType) {
+ if ctx.padded[t] {
+ return
+ }
+ ctx.walk(t.Type)
+ if !t.Type.Varlen() && t.Type.Size() == sizeUnassigned {
+ // An inner struct is not padded yet.
+ // Leave this array for next iteration.
+ return
+ }
+ ctx.padded[t] = true
+ t.TypeSize = 0
+ if t.Kind == prog.ArrayRangeLen && t.RangeBegin == t.RangeEnd && !t.Type.Varlen() {
+ t.TypeSize = t.RangeBegin * t.Type.Size()
+ }
+}
+
+func (ctx *structGen) walkStruct(t *prog.StructType) {
+ if !ctx.check(t.Key, &t.StructDesc) {
+ return
+ }
+ comp := ctx.comp
+ structNode := comp.structNodes[t.StructDesc]
+ // Add paddings, calculate size, mark bitfields.
+ varlen := false
+ for _, f := range t.Fields {
+ if f.Varlen() {
+ varlen = true
}
- structNode := comp.structNodes[t.StructDesc]
- // Add paddings, calculate size, mark bitfields.
- varlen := false
+ }
+ comp.markBitfields(t.Fields)
+ packed, sizeAttr, alignAttr := comp.parseStructAttrs(structNode)
+ t.Fields = comp.addAlignment(t.Fields, varlen, packed, alignAttr)
+ t.AlignAttr = alignAttr
+ t.TypeSize = 0
+ if !varlen {
for _, f := range t.Fields {
- if f.Varlen() {
- varlen = true
+ if !f.BitfieldMiddle() {
+ t.TypeSize += f.Size()
}
}
- comp.markBitfields(t.Fields)
- packed, sizeAttr, alignAttr := comp.parseStructAttrs(structNode)
- t.Fields = comp.addAlignment(t.Fields, varlen, packed, alignAttr)
- t.AlignAttr = alignAttr
- t.TypeSize = 0
- if !varlen {
- for _, f := range t.Fields {
- if !f.BitfieldMiddle() {
- t.TypeSize += f.Size()
- }
+ if sizeAttr != sizeUnassigned {
+ if t.TypeSize > sizeAttr {
+ comp.error(structNode.Pos, "struct %v has size attribute %v"+
+ " which is less than struct size %v",
+ structNode.Name.Name, sizeAttr, t.TypeSize)
}
- if sizeAttr != sizeUnassigned {
- if t.TypeSize > sizeAttr {
- comp.error(structNode.Pos, "struct %v has size attribute %v"+
- " which is less than struct size %v",
- structNode.Name.Name, sizeAttr, t.TypeSize)
- }
- if pad := sizeAttr - t.TypeSize; pad != 0 {
- t.Fields = append(t.Fields, genPad(pad))
- }
- t.TypeSize = sizeAttr
+ if pad := sizeAttr - t.TypeSize; pad != 0 {
+ t.Fields = append(t.Fields, genPad(pad))
}
+ t.TypeSize = sizeAttr
}
- case *prog.UnionType:
- if !ctx.check(t.Key, &t.StructDesc) {
- return
- }
- structNode := comp.structNodes[t.StructDesc]
- varlen, sizeAttr := comp.parseUnionAttrs(structNode)
- t.TypeSize = 0
- if !varlen {
- for _, fld := range t.Fields {
- sz := fld.Size()
- if sizeAttr != sizeUnassigned && sz > sizeAttr {
- comp.error(structNode.Pos, "union %v has size attribute %v"+
- " which is less than field %v size %v",
- structNode.Name.Name, sizeAttr, fld.Name(), sz)
- }
- if t.TypeSize < sz {
- t.TypeSize = sz
- }
+ }
+}
+
+func (ctx *structGen) walkUnion(t *prog.UnionType) {
+ if !ctx.check(t.Key, &t.StructDesc) {
+ return
+ }
+ comp := ctx.comp
+ structNode := comp.structNodes[t.StructDesc]
+ varlen, sizeAttr := comp.parseUnionAttrs(structNode)
+ t.TypeSize = 0
+ if !varlen {
+ for _, fld := range t.Fields {
+ sz := fld.Size()
+ if sizeAttr != sizeUnassigned && sz > sizeAttr {
+ comp.error(structNode.Pos, "union %v has size attribute %v"+
+ " which is less than field %v size %v",
+ structNode.Name.Name, sizeAttr, fld.Name(), sz)
}
- if sizeAttr != sizeUnassigned {
- t.TypeSize = sizeAttr
+ if t.TypeSize < sz {
+ t.TypeSize = sz
}
}
+ if sizeAttr != sizeUnassigned {
+ t.TypeSize = sizeAttr
+ }
}
}