From e6529b30ec934f285d57dc16dd8acbbab074f102 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 29 Dec 2015 15:00:57 +0100 Subject: sys: add union type --- sys/decl.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'sys/decl.go') diff --git a/sys/decl.go b/sys/decl.go index bc4896b40..65bd2e7f4 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -438,6 +438,25 @@ func (t StructType) Align() uintptr { return align } +type UnionType struct { + TypeCommon + Options []Type +} + +func (t UnionType) Size() uintptr { + panic("union size is not statically known") +} + +func (t UnionType) Align() uintptr { + var align uintptr + for _, opt := range t.Options { + if a1 := opt.Align(); align < a1 { + align = a1 + } + } + return align +} + type Dir int const ( @@ -483,6 +502,12 @@ func ResourceCtors(kind ResourceKind, sk ResourceSubkind, precise bool) []*Call return true } } + case UnionType: + for _, opt := range typ1.Options { + if checkArg(opt, dir) { + return true + } + } case PtrType: if checkArg(typ1.Type, typ1.Dir) { return true @@ -525,6 +550,10 @@ func (c *Call) InputResources() []ResourceType { for _, fld := range typ1.Fields { checkArg(fld, dir) } + case UnionType: + for _, opt := range typ1.Options { + checkArg(opt, dir) + } } } for _, arg := range c.Args { @@ -597,6 +626,15 @@ func init() { t1.Fields[i] = rec(f) } t = addAlignment(t1) + case UnionType: + opts := make(map[string]bool) + for i, opt := range t1.Options { + if opts[opt.Name()] { + panic("duplicate option in union") + } + opts[opt.Name()] = true + t1.Options[i] = rec(opt) + } } return t } -- cgit mrf-deployment