diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2015-12-29 15:00:57 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2015-12-29 15:00:57 +0100 |
| commit | e6529b30ec934f285d57dc16dd8acbbab074f102 (patch) | |
| tree | 9bf9673e44997f24e702833904294f3116d4f209 /sys/decl.go | |
| parent | d40104b8a35f01d31cad1f11e312e76e034ffc4a (diff) | |
sys: add union type
Diffstat (limited to 'sys/decl.go')
| -rw-r--r-- | sys/decl.go | 38 |
1 files changed, 38 insertions, 0 deletions
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 } |
