# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

foo$0(a int8)
foo$1(a int8[C1:C2])
foo$2(a ptr[out, array[int32]])
foo$3(a union_arg)
foo$4() r0
foo$5(a int8['a':'z'])
foo$6(a int8[-20:-10])
foo$7(a int8[-20:20])
foo$8(a ptr[in, strings])

resource r0[intptr]

union_arg [
	f1	int8
	f2	int64
	f3	ptr[in, int32]
	f4	r0
	f5	const[1, intptr]
	f6	flags[int_flags, int32]
	f7	proc[0, 1, int16]
]

strings {
	f1	string
	f2	string["foo"]
	f3	string["foo", 10]
	f4	string[string_flags1, 10]
	f5	stringnoz
	f6	stringnoz["foo"]
	f7	string[""]
	f8	string["", 10]
	f9	stringnoz[""]
	f11	stringnoz[string_flags1]
	f12	string[string_flags2]
	f13	stringnoz[string_flags2]
} [packed]

string_flags1 = "foo", "barbaz"
string_flags2 = ""
int_flags = 0, 1, 0xabc, 'x', -11
_ = 1, 2
_ = C1, C2

# Proc type.

proc_struct1 {
	f1	proc[C0, 8, int8]
}

foo$proc1(a ptr[in, proc_struct1])

# Len/bytesize types.

type len_templ1[DATA1, DATA2] {
	data	DATA1
	inner	len_temp2[DATA2]
}

type len_temp2[DATA] {
	data	DATA
	len	len[len_templ1, int8]
}

foo$len_templ(a ptr[in, len_templ1[int8, int16]])
foo$len_var0(a ptr[in, array[string]], b len[a])
foo$len_var1(a ptr[in, array[string]], b ptr[in, len[a, int32]])

# Void type.

void0 {
	f	void
}

void1 {
	f1	void
	f2	int8
}

void2 {
	f1	void
	f2	int8
}

void3 [
	f1	void
	f2	int8
]

void4 [
	f1	void
	f2	int8
] [varlen]

void5 {
	f1	void
	f2	void
}

struct_with_void0 {
	f1	int8
	f2	array[array[void]]
	f3	int64
}

struct_with_void1 {
	f1	int8
	f2	array[void5]
	f3	int64
	f4	optional[int8]
}

foo$void0(a ptr[in, void0])
foo$void1(a ptr[in, void1])
foo$void2(a ptr[in, void2])
foo$void3(a ptr[in, void3])
foo$void4(a ptr[in, void4])
foo$void5(a ptr[in, void5])
foo$void6(a ptr[in, struct_with_void0])
foo$void7(a ptr[in, struct_with_void1])
foo$void8(a ptr[in, void])

# Bitfields.

bitfield0 {
	f1	int8:1
	f2	int8:2
}

foo$bitfield0(a ptr[in, bitfield0])

# Type templates.

type type0 int8
type templ0[A, B] const[A, B]
type templ2[STR] string[STR]
type type3 templ2["a"]

type templ_struct0[A, B] {
	len	len[parent, int16]
	typ	const[A, int16]
	data	B
} [align_4]

type templ_struct1[C] {
	f1	const[C, int8]
	f2	int8[0:C]
}

union_with_templ_struct [
	f1	templ_struct0[C1, type0]
	f2	templ_struct0[C2, struct0]
] [varlen]

struct0 {
	f1	int8
	f2	int16
}

type templ_base0[TYPE, CONST] {
	f1	TYPE
	f2	const[CONST, int32]
}

type templ_base1[TYPE, CONST] {
	f2	const[CONST, int8]
	f1	TYPE
}

type templ_templ[BASE, CONST] {
	f1	BASE[int8, CONST]
	f2	BASE[int32, 0]
}

templ_templ_use {
	f1	templ_templ[templ_base0, 0]
	f2	templ_templ[templ_base1, 1]
}

type templ_struct2[A] templ_struct0[A, int8]
type templ_struct3 templ_struct2[C1]
type templ_struct4 templ_struct3
type templ_struct5 templ_struct0[C1, templ_struct0[C2, int8]]
type templ_struct6 templ_struct0[C1, templ_struct2[C2]]
type templ_union union_with_templ_struct

foo$templ0(a templ0[42, int8])
foo$templ1(a ptr[in, templ_struct0[C2, int8]])
foo$templ2(a ptr[in, union_with_templ_struct])
foo$templ3(a ptr[in, templ_struct1[1]], b ptr[in, templ_struct1[2]])
foo$templ4(a ptr[in, templ_struct1[3]])
foo$templ5(a ptr[in, templ_struct1[3]])
foo$templ6(a ptr[in, templ_struct4])
foo$templ7(a ptr[in, templ_struct5], b ptr[in, templ_struct6], c ptr[in, templ_union], d ptr[in, type3])
foo$templ8(a ptr[in, templ_templ_use])

# Structs.

s0 {
	f1	int8
} [size[64]]

s1 {
	f1	int8
} [size[C2]]

foo$s0(a ptr[in, s0], b ptr[in, s1])

# Unions.

u0 [
	f1	int32
]

foo$u0(a ptr[in, u0])

# fmt

foo$fmt0(a ptr[in, fmt[dec, int32[1:10]]])
foo$fmt1(a ptr[in, fmt[hex, flags[int_flags]]])
foo$fmt2(a ptr[in, fmt[oct, len[b]]], b ptr[in, array[int8]])
foo$fmt3(a ptr[in, fmt[dec, proc[10, 20]]])
foo$fmt4(a ptr[in, fmt[dec, r0]])
foo$fmt5(a ptr[in, struct$fmt0])

struct$fmt0 {
	f0	fmt[dec, int8]
}