diff options
| author | Paul Chaignon <paul.chaignon@gmail.com> | 2024-09-08 11:37:59 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-09-09 11:43:00 +0000 |
| commit | e5005d1750564a41e2ae7fc840131133ded452d6 (patch) | |
| tree | 87d4c0e0ab03d68d3c505f8ff477aea56097dfc3 /pkg/compiler | |
| parent | 11cbc3b9349d6a8b0e2f98e4a877cfbf4f2774c4 (diff) | |
compiler: support constants in conditional fields
This commit adds support for using the value of constants in conditional
fields in addition to integers and flags. Intuitively, this probably
looks like it shouldn't be needed: constants are known so the condition
can be resolved ahead of time. It is however useful in the case of
templates (example in the next commit) where the type of a field may be
interchangeably an integer or a constant:
type example_t[TYPE] {
f1 TYPE
f2 int32 (if[value[f1] == 3])
}
type example1 example_t[int64]
type example2 example_t[const[0, int64]]
Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Diffstat (limited to 'pkg/compiler')
| -rw-r--r-- | pkg/compiler/check.go | 4 | ||||
| -rw-r--r-- | pkg/compiler/testdata/all.txt | 2 | ||||
| -rw-r--r-- | pkg/compiler/testdata/errors2.txt | 4 |
3 files changed, 6 insertions, 4 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go index 5345e2e3f..3bda9cfe6 100644 --- a/pkg/compiler/check.go +++ b/pkg/compiler/check.go @@ -650,8 +650,8 @@ func (comp *compiler) checkPathField(target, t *ast.Type, field *ast.Field) bool func (comp *compiler) checkExprLastField(target *ast.Type, field *ast.Field) { _, desc := comp.derefPointers(field.Type) - if desc != typeInt && desc != typeFlags { - comp.error(target.Pos, "%v does not refer to an integer or a flag", field.Name.Name) + if desc != typeInt && desc != typeFlags && desc != typeConst { + comp.error(target.Pos, "%v does not refer to a constant, an integer, or a flag", field.Name.Name) } } diff --git a/pkg/compiler/testdata/all.txt b/pkg/compiler/testdata/all.txt index 68e85492d..098da4604 100644 --- a/pkg/compiler/testdata/all.txt +++ b/pkg/compiler/testdata/all.txt @@ -357,6 +357,8 @@ struct$conditional { f1 int64 (if[value[f0] == 1]) f2 struct$conditional2 f3 union$conditional3 + f4 const[0, int64] + f5 int64 (if[value[f4] == 0]) } [packed] struct$conditional2 { diff --git a/pkg/compiler/testdata/errors2.txt b/pkg/compiler/testdata/errors2.txt index ffb2e5bc5..71e2aa5ad 100644 --- a/pkg/compiler/testdata/errors2.txt +++ b/pkg/compiler/testdata/errors2.txt @@ -470,11 +470,11 @@ conditional_fields { f3 some_nested_flags f4 int32 (if[value[f3:f1] != 0]) f5 int32 (if[value[f3:f2:f4] != 0]) ### value path f2 does not refer to a struct - f6 int32 (if[value[f3:f4] != 0]) ### f4 does not refer to an integer or a flag + f6 int32 (if[value[f3:f4] != 0]) ### f4 does not refer to a constant, an integer, or a flag f7 int32 (if[value[f3:some_field] != 0]) ### value target some_field does not exist in some_nested_flags f8 int32 (if[value[f3:f5] != 0]) ### f5 has conditions, so value path cannot reference it f9 int32 (if[value[parent:a] != 0]) ### value target a does not exist in conditional_fields - f10 int32 (if[value[f3:f6] != 0]) ### f6 does not refer to an integer or a flag + f10 int32 (if[value[f3:f6] != 0]) ### f6 does not refer to a constant, an integer, or a flag f11 len[f2, int32] ### f2 has conditions, so len path cannot reference it f12 union_cond_fields f13 int32:8 (if[1]) ### bitfields may not have conditions |
