1// Copyright 2017 syzkaller project authors. All rights reserved.
2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4// Package ast parses and formats sys files.
5package ast
6
7// Pos represents source info for AST nodes.
8type Pos struct {
9	File string
10	Off  int // byte offset, starting at 0
11	Line int // line number, starting at 1
12	Col  int // column number, starting at 1 (byte count)
13}
14
15// Description contains top-level nodes of a parsed sys description.
16type Description struct {
17	Nodes []Node
18}
19
20// Node is AST node interface.
21type Node interface {
22	Info() (pos Pos, typ string, name string)
23	// Clone makes a deep copy of the node.
24	Clone() Node
25	// Walk calls callback cb for all child nodes of this node.
26	// Note: it's not recursive. Use Recursive helper for recursive walk.
27	Walk(cb func(Node))
28}
29
30// Top-level AST nodes:
31
32type NewLine struct {
33	Pos Pos
34}
35
36func (n *NewLine) Info() (Pos, string, string) {
37	return n.Pos, tok2str[tokNewLine], ""
38}
39
40type Comment struct {
41	Pos  Pos
42	Text string
43}
44
45func (n *Comment) Info() (Pos, string, string) {
46	return n.Pos, tok2str[tokComment], ""
47}
48
49type Include struct {
50	Pos  Pos
51	File *String
52}
53
54func (n *Include) Info() (Pos, string, string) {
55	return n.Pos, tok2str[tokInclude], ""
56}
57
58type Incdir struct {
59	Pos Pos
60	Dir *String
61}
62
63func (n *Incdir) Info() (Pos, string, string) {
64	return n.Pos, tok2str[tokInclude], ""
65}
66
67type Define struct {
68	Pos   Pos
69	Name  *Ident
70	Value *Int
71}
72
73func (n *Define) Info() (Pos, string, string) {
74	return n.Pos, tok2str[tokDefine], n.Name.Name
75}
76
77type Resource struct {
78	Pos    Pos
79	Name   *Ident
80	Base   *Type
81	Values []*Int
82}
83
84func (n *Resource) Info() (Pos, string, string) {
85	return n.Pos, tok2str[tokResource], n.Name.Name
86}
87
88type Call struct {
89	Pos      Pos
90	Name     *Ident
91	CallName string
92	NR       uint64
93	Args     []*Field
94	Ret      *Type
95}
96
97func (n *Call) Info() (Pos, string, string) {
98	return n.Pos, "syscall", n.Name.Name
99}
100
101type Struct struct {
102	Pos      Pos
103	Name     *Ident
104	Fields   []*Field
105	Attrs    []*Type
106	Comments []*Comment
107	IsUnion  bool
108}
109
110func (n *Struct) Info() (Pos, string, string) {
111	typ := "struct"
112	if n.IsUnion {
113		typ = "union"
114	}
115	return n.Pos, typ, n.Name.Name
116}
117
118type IntFlags struct {
119	Pos    Pos
120	Name   *Ident
121	Values []*Int
122}
123
124func (n *IntFlags) Info() (Pos, string, string) {
125	return n.Pos, "flags", n.Name.Name
126}
127
128type StrFlags struct {
129	Pos    Pos
130	Name   *Ident
131	Values []*String
132}
133
134func (n *StrFlags) Info() (Pos, string, string) {
135	return n.Pos, "string flags", n.Name.Name
136}
137
138type TypeDef struct {
139	Pos  Pos
140	Name *Ident
141	// Non-template type aliases have only Type filled.
142	// Templates have Args and either Type or Struct filled.
143	Args   []*Ident
144	Type   *Type
145	Struct *Struct
146}
147
148func (n *TypeDef) Info() (Pos, string, string) {
149	return n.Pos, "type", n.Name.Name
150}
151
152// Not top-level AST nodes:
153
154type Ident struct {
155	Pos  Pos
156	Name string
157}
158
159func (n *Ident) Info() (Pos, string, string) {
160	return n.Pos, tok2str[tokIdent], n.Name
161}
162
163type String struct {
164	Pos   Pos
165	Value string
166}
167
168func (n *String) Info() (Pos, string, string) {
169	return n.Pos, tok2str[tokString], ""
170}
171
172type IntFmt int
173
174const (
175	IntFmtDec IntFmt = iota
176	IntFmtNeg
177	IntFmtHex
178	IntFmtChar
179)
180
181type Int struct {
182	Pos Pos
183	// Only one of Value, Ident, CExpr is filled.
184	Value    uint64
185	ValueFmt IntFmt
186	Ident    string
187	CExpr    string
188}
189
190func (n *Int) Info() (Pos, string, string) {
191	return n.Pos, tok2str[tokInt], ""
192}
193
194type Type struct {
195	Pos Pos
196	// Only one of Value, Ident, String is filled.
197	Value     uint64
198	ValueFmt  IntFmt
199	Ident     string
200	String    string
201	HasString bool
202	// Part after COLON (for ranges and bitfields).
203	HasColon  bool
204	Pos2      Pos
205	Value2    uint64
206	Value2Fmt IntFmt
207	Ident2    string
208	Args      []*Type
209}
210
211func (n *Type) Info() (Pos, string, string) {
212	return n.Pos, "type", n.Ident
213}
214
215type Field struct {
216	Pos      Pos
217	Name     *Ident
218	Type     *Type
219	NewBlock bool // separated from previous fields by a new line
220	Comments []*Comment
221}
222
223func (n *Field) Info() (Pos, string, string) {
224	return n.Pos, "arg/field", n.Name.Name
225}
226