aboutsummaryrefslogtreecommitdiffstats
path: root/sys/decl.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-12-29 15:00:57 +0100
committerDmitry Vyukov <dvyukov@google.com>2015-12-29 15:00:57 +0100
commite6529b30ec934f285d57dc16dd8acbbab074f102 (patch)
tree9bf9673e44997f24e702833904294f3116d4f209 /sys/decl.go
parentd40104b8a35f01d31cad1f11e312e76e034ffc4a (diff)
sys: add union type
Diffstat (limited to 'sys/decl.go')
-rw-r--r--sys/decl.go38
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
}