aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler
diff options
context:
space:
mode:
authorPaul Chaignon <paul.chaignon@gmail.com>2023-11-10 17:56:02 +0100
committerAleksandr Nogikh <nogikh@google.com>2023-11-28 10:18:54 +0000
commit0f164300b33f421468051a8815711503a34cd49c (patch)
tree38e68ee43424e7aef3318d74102304f83b66d18a /pkg/compiler
parent2e35bb9a19c0711162e650f3723e2dbe061051ee (diff)
compiler: support const as int first argument
This commit adds support for the following syntax: int8[constant] as an equivalent to: const[constant, int8] The goal is to have a unified const/flags definition that we can use in templates. For example: type template[CLASS, ...] { class int8:3[CLASS] // ... } type singleClassType template[SINGLE_CONST] type subClassType template[abc_class_flags] In this example, the CLASS template field can be either a constant or a flag. This is especially useful when defining both a generic instance of the template as well as specialized instances (ex. bpf_alu_ops and bpf_add_op). Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Diffstat (limited to 'pkg/compiler')
-rw-r--r--pkg/compiler/testdata/all.txt3
-rw-r--r--pkg/compiler/testdata/errors.txt3
-rw-r--r--pkg/compiler/testdata/errors2.txt1
-rw-r--r--pkg/compiler/types.go19
4 files changed, 13 insertions, 13 deletions
diff --git a/pkg/compiler/testdata/all.txt b/pkg/compiler/testdata/all.txt
index 1b3873bf5..edf4bd896 100644
--- a/pkg/compiler/testdata/all.txt
+++ b/pkg/compiler/testdata/all.txt
@@ -21,6 +21,8 @@ foo_13() (disabled)
foo_14() r0 (timeout[100])
foo_15() r0 (disabled, timeout[C1], prog_timeout[C2])
foo_16(a int32[int_flags])
+foo_17(a int8[C1])
+foo_18(a int64[100])
resource r0[intptr]
@@ -182,6 +184,7 @@ bitfield0 {
f4 int16:8[0:255]
f5 int64:64[-1:1]
f6 int32:4[int_flags]
+ f7 int8:3[C1]
}
foo_bitfield0(a ptr[in, bitfield0])
diff --git a/pkg/compiler/testdata/errors.txt b/pkg/compiler/testdata/errors.txt
index bc3054a64..84cfad221 100644
--- a/pkg/compiler/testdata/errors.txt
+++ b/pkg/compiler/testdata/errors.txt
@@ -88,7 +88,6 @@ foo$11(a buffer["in"]) ### unexpected string "in" for direction argument of ptr
foo$12(a buffer[10]) ### unexpected int 10 for direction argument of ptr type, expect [in out inout]
foo$13(a int32[2:3])
foo$14(a int32[2:2])
-foo$16(a int32[3]) ### first argument of int32 needs to be a range or flag
foo$17(a ptr[in, int32])
foo$18(a ptr[in, int32[2:3]])
foo$19(a ptr[in, int32[opt]])
@@ -134,7 +133,7 @@ foo$64(a ptr[in, flags[f1[int32], int32]]) ### flags argument has subargs
foo$65(a int32, b len[1]) ### unexpected int 1 for len target argument of len type, expect identifier
foo$66(a int32, b len[a:1]) ### unexpected int 1 after colon, expect identifier
foo$67(x int32[1:2:3, opt]) ### unexpected ':'
-foo$68(a int32[15, 2]) ### first argument of int32 needs to be a range or flag
+foo$68(a int32[15, 2]) ### align argument of int32 is not supported unless first argument is a range
foo$69() (foo) ### unknown syscall foo$69 attribute foo
foo$70() ("foo") ### unexpected string "foo", expect attribute
foo$71() (42) ### unexpected int 42, expect attribute
diff --git a/pkg/compiler/testdata/errors2.txt b/pkg/compiler/testdata/errors2.txt
index e99610c58..e583094fa 100644
--- a/pkg/compiler/testdata/errors2.txt
+++ b/pkg/compiler/testdata/errors2.txt
@@ -369,6 +369,7 @@ foo$531(a ptr[in, const[0xffffffffffffffab, int8]])
foo$532(a ptr[in, const[0x7234567812345678, int64]])
foo$533(a ptr[in, const[0x12, int8:4]]) ### const val 0x12 does not fit into 4 bits
foo$534(a ptr[in, flags[large_flags, int8]]) ### large_flags U16_MAX=0xffff doesn't fit into 8 bits
+foo$535(a int64[no]) ### unknown flags no
large_flags = U8_MAX, U16_MAX
diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go
index 1dd2361f2..d9373e621 100644
--- a/pkg/compiler/types.go
+++ b/pkg/compiler/types.go
@@ -89,13 +89,6 @@ var typeInt = &typeDesc{
},
Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) {
typeArgBase.Type.Check(comp, t)
- if len(args) > 0 {
- _, isIntFlag := comp.intFlags[args[0].Ident]
- if len(args[0].Colon) == 0 && !isIntFlag {
- comp.error(args[0].Pos, "first argument of %v needs to be a range or flag", t.Ident)
- return
- }
- }
if len(args) > 1 && len(args[0].Colon) == 0 {
comp.error(args[1].Pos, "align argument of %v is not supported unless first argument is a range",
t.Ident)
@@ -151,10 +144,14 @@ var typeInt = &typeDesc{
if _, isIntFlag := comp.intFlags[rangeArg.Ident]; isIntFlag {
return generateFlagsType(comp, base, rangeArg.Ident)
}
- kind, rangeBegin, rangeEnd = prog.IntRange, rangeArg.Value, rangeArg.Value
- if len(rangeArg.Colon) != 0 {
- rangeEnd = rangeArg.Colon[0].Value
+ if len(rangeArg.Colon) == 0 {
+ // If we have an argument that is not a range, then it's a const.
+ return &prog.ConstType{
+ IntTypeCommon: base,
+ Val: args[0].Value,
+ }
}
+ kind, rangeBegin, rangeEnd = prog.IntRange, rangeArg.Value, rangeArg.Colon[0].Value
if len(args) > 1 {
align = args[1].Value
}
@@ -1022,7 +1019,7 @@ var typeArgInt = &typeArg{
var typeArgIntValue = &typeArg{
Kind: kindInt | kindIdent,
MaxColon: 1,
- Check: func(comp *compiler, t *ast.Type) {
+ CheckConsts: func(comp *compiler, t *ast.Type) {
// If the first arg is not a range, then it should be a valid flags.
if len(t.Colon) == 0 && t.Ident != "" && comp.intFlags[t.Ident] == nil {
comp.error(t.Pos, "unknown flags %v", t.Ident)