From 3a4641d90c293137bd33e6472e721a4c15b0d7da Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 1 Aug 2018 16:29:40 +0200 Subject: pkg/compiler: refactor structGen Still too complex. Split more. Update #538 --- pkg/compiler/gen.go | 137 ++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 62 deletions(-) (limited to 'pkg') 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 + } } } -- cgit mrf-deployment