aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler/check.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-01-05 20:05:11 +0100
committerDmitry Vyukov <dvyukov@google.com>2022-01-11 16:30:08 +0100
commit2cfe62f82077ba012aef55db5288985bc0c426d9 (patch)
tree501d83deb358a230d157c9d7efc6fc393e239472 /pkg/compiler/check.go
parent16e21d13ea26a631e9b3a30c94635b1d565fd78f (diff)
pkg/compiler: add out_overlay field attribute
Diffstat (limited to 'pkg/compiler/check.go')
-rw-r--r--pkg/compiler/check.go36
1 files changed, 33 insertions, 3 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index c5fc226d6..676b96c5c 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -182,13 +182,33 @@ func (comp *compiler) checkStructFields(n *ast.Struct, typ, name string) {
if len(n.Fields) < 1 {
comp.error(n.Pos, "%v %v has no fields, need at least 1 field", typ, name)
}
- for _, f := range n.Fields {
+ hasDirections, hasOutOverlay := false, false
+ for fieldIdx, f := range n.Fields {
attrs := comp.parseAttrs(fieldAttrs, f, f.Attrs)
-
- if attrs[attrIn]+attrs[attrOut]+attrs[attrInOut] > 1 {
+ dirCount := attrs[attrIn] + attrs[attrOut] + attrs[attrInOut]
+ if dirCount != 0 {
+ hasDirections = true
+ }
+ if dirCount > 1 {
_, typ, _ := f.Info()
comp.error(f.Pos, "%v has multiple direction attributes", typ)
}
+ if attrs[attrOutOverlay] > 0 {
+ if n.IsUnion {
+ _, typ, name := f.Info()
+ comp.error(f.Pos, "unknown %v %v attribute %v", typ, name, attrOutOverlay.Name)
+ }
+ if fieldIdx == 0 {
+ comp.error(f.Pos, "%v attribute must not be specified on the first field", attrOutOverlay.Name)
+ }
+ if hasOutOverlay || attrs[attrOutOverlay] > 1 {
+ comp.error(f.Pos, "multiple %v attributes", attrOutOverlay.Name)
+ }
+ hasOutOverlay = true
+ }
+ if hasDirections && hasOutOverlay {
+ comp.error(f.Pos, "mix of direction and %v attributes is not supported", attrOutOverlay.Name)
+ }
}
}
@@ -301,12 +321,22 @@ func (comp *compiler) checkAttributeValues() {
}
// Check each field's attributes.
st := decl.(*ast.Struct)
+ hasOutOverlay := false
for _, f := range st.Fields {
+ isOut := hasOutOverlay
for _, attr := range f.Attrs {
desc := fieldAttrs[attr.Ident]
if desc.CheckConsts != nil {
desc.CheckConsts(comp, f, attr)
}
+ switch attr.Ident {
+ case attrOutOverlay.Name:
+ hasOutOverlay = true
+ isOut = true
+ }
+ }
+ if isOut && comp.getTypeDesc(f.Type).CantBeOut {
+ comp.error(f.Pos, "%v type must not be used as output", f.Type.Ident)
}
}
}