1 /*
2 * Copyright (c) 2015 PLUMgrid, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <vector>
20 #include <bitset>
21 #include <string>
22 #include <memory>
23 #include <algorithm>
24 #include <stdint.h>
25
26 #include "common.h"
27 #include "bcc_exception.h"
28 #include "scope.h"
29
30 #define REVISION_MASK 0xfff
31 #define MAJOR_VER_POS 22
32 #define MAJOR_VER_MASK ~((1 << MAJOR_VER_POS) - 1)
33 #define MINOR_VER_POS 12
34 #define MINOR_VER_MASK (~((1 << MINOR_VER_POS) - 1) & (~(MAJOR_VER_MASK)))
35 #define GET_MAJOR_VER(version) ((version & MAJOR_VER_MASK) >> MAJOR_VER_POS)
36 #define GET_MINOR_VER(version) ((version & MINOR_VER_MASK) >> MINOR_VER_POS)
37 #define GET_REVISION(version) (version & REVISION_MASK)
38 #define MAKE_VERSION(major, minor, rev) \
39 ((major << MAJOR_VER_POS) | \
40 (minor << MINOR_VER_POS) | \
41 (rev & REVISION_MASK))
42
43 #define STATUS_RETURN __attribute((warn_unused_result)) StatusTuple
44
45 namespace ebpf {
46
47 namespace cc {
48
49 using std::unique_ptr;
50 using std::move;
51 using std::string;
52 using std::vector;
53 using std::bitset;
54 using std::find;
55
56 typedef unique_ptr<string> String;
57
58 #define NODE_EXPRESSIONS(EXPAND) \
59 EXPAND(IdentExprNode, ident_expr_node) \
60 EXPAND(AssignExprNode, assign_expr_node) \
61 EXPAND(PacketExprNode, packet_expr_node) \
62 EXPAND(IntegerExprNode, integer_expr_node) \
63 EXPAND(StringExprNode, string_expr_node) \
64 EXPAND(BinopExprNode, binop_expr_node) \
65 EXPAND(UnopExprNode, unop_expr_node) \
66 EXPAND(BitopExprNode, bitop_expr_node) \
67 EXPAND(GotoExprNode, goto_expr_node) \
68 EXPAND(ReturnExprNode, return_expr_node) \
69 EXPAND(MethodCallExprNode, method_call_expr_node) \
70 EXPAND(TableIndexExprNode, table_index_expr_node)
71
72 #define NODE_STATEMENTS(EXPAND) \
73 EXPAND(ExprStmtNode, expr_stmt_node) \
74 EXPAND(BlockStmtNode, block_stmt_node) \
75 EXPAND(IfStmtNode, if_stmt_node) \
76 EXPAND(OnValidStmtNode, onvalid_stmt_node) \
77 EXPAND(SwitchStmtNode, switch_stmt_node) \
78 EXPAND(CaseStmtNode, case_stmt_node) \
79 EXPAND(StructVariableDeclStmtNode, struct_variable_decl_stmt_node) \
80 EXPAND(IntegerVariableDeclStmtNode, integer_variable_decl_stmt_node) \
81 EXPAND(StructDeclStmtNode, struct_decl_stmt_node) \
82 EXPAND(StateDeclStmtNode, state_decl_stmt_node) \
83 EXPAND(ParserStateStmtNode, parser_state_stmt_node) \
84 EXPAND(MatchDeclStmtNode, match_decl_stmt_node) \
85 EXPAND(MissDeclStmtNode, miss_decl_stmt_node) \
86 EXPAND(FailureDeclStmtNode, failure_decl_stmt_node) \
87 EXPAND(TableDeclStmtNode, table_decl_stmt_node) \
88 EXPAND(FuncDeclStmtNode, func_decl_stmt_node)
89
90 #define EXPAND_NODES(EXPAND) \
91 NODE_EXPRESSIONS(EXPAND) \
92 NODE_STATEMENTS(EXPAND)
93
94 class Visitor;
95
96 // forward declare all classes
97 #define FORWARD(type, func) class type;
EXPAND_NODES(FORWARD)98 EXPAND_NODES(FORWARD)
99 #undef FORWARD
100
101 #define DECLARE(type) \
102 typedef unique_ptr<type> Ptr; \
103 virtual StatusTuple accept(Visitor* v);
104
105 class Node {
106 public:
107 typedef unique_ptr<Node> Ptr;
108 Node() : line_(-1), column_(-1) {}
109 virtual ~Node() {}
110 virtual StatusTuple accept(Visitor* v) = 0;
111 int line_;
112 int column_;
113 string text_;
114 };
115
116 template <typename... Args>
mkstatus_(Node * n,const char * fmt,Args...args)117 StatusTuple mkstatus_(Node *n, const char *fmt, Args... args) {
118 StatusTuple status = StatusTuple(n->line_ ? n->line_ : -1, fmt, args...);
119 if (n->line_ > 0)
120 status.append_msg("\n" + n->text_);
121 return status;
122 }
123
mkstatus_(Node * n,const char * msg)124 static inline StatusTuple mkstatus_(Node *n, const char *msg) {
125 StatusTuple status = StatusTuple(n->line_ ? n->line_ : -1, msg);
126 if (n->line_ > 0)
127 status.append_msg("\n" + n->text_);
128 return status;
129 }
130
131 class StmtNode : public Node {
132 public:
133 typedef unique_ptr<StmtNode> Ptr;
134 virtual StatusTuple accept(Visitor* v) = 0;
135
136 };
137 typedef vector<StmtNode::Ptr> StmtNodeList;
138
139 class ExprNode : public Node {
140 public:
141 typedef unique_ptr<ExprNode> Ptr;
142 virtual StatusTuple accept(Visitor* v) = 0;
143 enum expr_type { STRUCT, INTEGER, STRING, VOID, UNKNOWN };
144 enum prop_flag { READ = 0, WRITE, PROTO, IS_LHS, IS_REF, IS_PKT, LAST };
145 expr_type typeof_;
146 StructDeclStmtNode *struct_type_;
147 size_t bit_width_;
148 bitset<LAST> flags_;
149 unique_ptr<BitopExprNode> bitop_;
ExprNode()150 ExprNode() : typeof_(UNKNOWN), struct_type_(NULL), flags_(1 << READ) {}
copy_type(const ExprNode & other)151 void copy_type(const ExprNode& other) {
152 typeof_ = other.typeof_;
153 struct_type_ = other.struct_type_;
154 bit_width_ = other.bit_width_;
155 flags_ = other.flags_;
156 }
is_lhs()157 bool is_lhs() const { return flags_[IS_LHS]; }
is_ref()158 bool is_ref() const { return flags_[IS_REF]; }
is_pkt()159 bool is_pkt() const { return flags_[IS_PKT]; }
160 };
161
162 typedef vector<ExprNode::Ptr> ExprNodeList;
163
164 class IdentExprNode : public ExprNode {
165 public:
166 DECLARE(IdentExprNode)
167
168 string name_;
169 string sub_name_;
170 string scope_name_;
171 VariableDeclStmtNode *decl_;
172 VariableDeclStmtNode *sub_decl_;
IdentExprNode(const IdentExprNode & other)173 IdentExprNode(const IdentExprNode& other) {
174 name_ = other.name_;
175 sub_name_ = other.sub_name_;
176 scope_name_ = other.scope_name_;
177 decl_ = other.decl_;
178 sub_decl_ = other.sub_decl_;
179 }
copy()180 IdentExprNode::Ptr copy() const {
181 return IdentExprNode::Ptr(new IdentExprNode(*this));
182 }
IdentExprNode(const string & id)183 explicit IdentExprNode(const string& id) : name_(id) {}
IdentExprNode(const char * id)184 explicit IdentExprNode(const char* id) : name_(id) {}
prepend_scope(const string & id)185 void prepend_scope(const string& id) {
186 scope_name_ = id;
187 }
append_scope(const string & id)188 void append_scope(const string& id) {
189 scope_name_ = move(name_);
190 name_ = id;
191 }
prepend_dot(const string & id)192 void prepend_dot(const string& id) {
193 sub_name_ = move(name_);
194 name_ = id;
195 }
append_dot(const string & id)196 void append_dot(const string& id) {
197 // we don't support nested struct so keep all subs as single variable
198 if (!sub_name_.empty()) {
199 sub_name_ += "." + id;
200 } else {
201 sub_name_ = id;
202 }
203 }
full_name()204 const string& full_name() {
205 if (full_name_.size()) {
206 return full_name_; // lazy init
207 }
208 if (scope_name_.size()) {
209 full_name_ += scope_name_ + "::";
210 }
211 full_name_ += name_;
212 if (sub_name_.size()) {
213 full_name_ += "." + sub_name_;
214 }
215 return full_name_;
216 }
c_str()217 const char* c_str() const { return name_.c_str(); }
218 private:
219 string full_name_;
220 };
221
222 class BitopExprNode : public ExprNode {
223 public:
224 DECLARE(BitopExprNode)
225
226 ExprNode::Ptr expr_;
227 size_t bit_offset_;
228 size_t bit_width_;
BitopExprNode(const string & bofs,const string & bsz)229 BitopExprNode(const string& bofs, const string& bsz)
230 : bit_offset_(strtoul(bofs.c_str(), NULL, 0)), bit_width_(strtoul(bsz.c_str(), NULL, 0)) {}
231 };
232
233 typedef vector<IdentExprNode::Ptr> IdentExprNodeList;
234
235 class AssignExprNode : public ExprNode {
236 public:
237 DECLARE(AssignExprNode)
238
239 //IdentExprNode *id_;
240 ExprNode::Ptr lhs_;
241 ExprNode::Ptr rhs_;
AssignExprNode(IdentExprNode::Ptr id,ExprNode::Ptr rhs)242 AssignExprNode(IdentExprNode::Ptr id, ExprNode::Ptr rhs)
243 : lhs_(move(id)), rhs_(move(rhs)) {
244 //id_ = (IdentExprNode *)lhs_.get();
245 lhs_->flags_[ExprNode::IS_LHS] = true;
246 }
AssignExprNode(ExprNode::Ptr lhs,ExprNode::Ptr rhs)247 AssignExprNode(ExprNode::Ptr lhs, ExprNode::Ptr rhs)
248 : lhs_(move(lhs)), rhs_(move(rhs)) {
249 //id_ = nullptr;
250 lhs_->flags_[ExprNode::IS_LHS] = true;
251 }
252 };
253
254 class PacketExprNode : public ExprNode {
255 public:
256 DECLARE(PacketExprNode)
257
258 IdentExprNode::Ptr id_;
PacketExprNode(IdentExprNode::Ptr id)259 explicit PacketExprNode(IdentExprNode::Ptr id) : id_(move(id)) {}
260 };
261
262 class StringExprNode : public ExprNode {
263 public:
DECLARE(StringExprNode)264 DECLARE(StringExprNode)
265
266 string val_;
267 explicit StringExprNode(string *val) : val_(move(*val)) {
268 delete val;
269 }
StringExprNode(const string & val)270 explicit StringExprNode(const string &val) : val_(val) {}
271 };
272
273 class IntegerExprNode : public ExprNode {
274 public:
275 DECLARE(IntegerExprNode)
276
277 size_t bits_;
278 string val_;
IntegerExprNode(string * val,string * bits)279 IntegerExprNode(string* val, string* bits)
280 : bits_(strtoul(bits->c_str(), NULL, 0)), val_(move(*val)) {
281 delete val;
282 delete bits;
283 }
IntegerExprNode(string * val)284 explicit IntegerExprNode(string* val)
285 : bits_(0), val_(move(*val)) {
286 delete val;
287 }
IntegerExprNode(const string & val)288 explicit IntegerExprNode(const string& val) : bits_(0), val_(val) {}
IntegerExprNode(const string & val,size_t bits)289 explicit IntegerExprNode(const string& val, size_t bits) : bits_(bits), val_(val) {}
290 };
291
292 class BinopExprNode : public ExprNode {
293 public:
294 DECLARE(BinopExprNode)
295
296 ExprNode::Ptr lhs_;
297 int op_;
298 ExprNode::Ptr rhs_;
BinopExprNode(ExprNode::Ptr lhs,int op,ExprNode::Ptr rhs)299 BinopExprNode(ExprNode::Ptr lhs, int op, ExprNode::Ptr rhs)
300 : lhs_(move(lhs)), op_(op), rhs_(move(rhs))
301 {}
302 };
303
304 class UnopExprNode : public ExprNode {
305 public:
306 DECLARE(UnopExprNode)
307
308 ExprNode::Ptr expr_;
309 int op_;
UnopExprNode(int op,ExprNode::Ptr expr)310 UnopExprNode(int op, ExprNode::Ptr expr) : expr_(move(expr)), op_(op) {}
311 };
312
313 class GotoExprNode : public ExprNode {
314 public:
315 DECLARE(GotoExprNode)
316
317 bool is_continue_;
318 IdentExprNode::Ptr id_;
319 GotoExprNode(IdentExprNode::Ptr id, bool is_continue = false)
is_continue_(is_continue)320 : is_continue_(is_continue), id_(move(id)) {}
321 };
322
323 class ReturnExprNode : public ExprNode {
324 public:
325 DECLARE(ReturnExprNode)
326
327 ExprNode::Ptr expr_;
ReturnExprNode(ExprNode::Ptr expr)328 ReturnExprNode(ExprNode::Ptr expr)
329 : expr_(move(expr)) {}
330 };
331
332 class BlockStmtNode : public StmtNode {
333 public:
DECLARE(BlockStmtNode)334 DECLARE(BlockStmtNode)
335
336 explicit BlockStmtNode(StmtNodeList stmts = StmtNodeList())
337 : stmts_(move(stmts)), scope_(NULL) {}
~BlockStmtNode()338 ~BlockStmtNode() { delete scope_; }
339 StmtNodeList stmts_;
340 Scopes::VarScope* scope_;
341 };
342
343 class MethodCallExprNode : public ExprNode {
344 public:
345 DECLARE(MethodCallExprNode)
346
347 IdentExprNode::Ptr id_;
348 ExprNodeList args_;
349 BlockStmtNode::Ptr block_;
MethodCallExprNode(IdentExprNode::Ptr id,ExprNodeList && args,int lineno)350 MethodCallExprNode(IdentExprNode::Ptr id, ExprNodeList&& args, int lineno)
351 : id_(move(id)), args_(move(args)), block_(make_unique<BlockStmtNode>()) {
352 line_ = lineno;
353 }
354 };
355
356 class TableIndexExprNode : public ExprNode {
357 public:
358 DECLARE(TableIndexExprNode)
359
360 IdentExprNode::Ptr id_;
361 IdentExprNode::Ptr sub_;
362 ExprNode::Ptr index_;
363 TableDeclStmtNode *table_;
364 VariableDeclStmtNode *sub_decl_;
TableIndexExprNode(IdentExprNode::Ptr id,ExprNode::Ptr index)365 TableIndexExprNode(IdentExprNode::Ptr id, ExprNode::Ptr index)
366 : id_(move(id)), index_(move(index)), table_(nullptr), sub_decl_(nullptr)
367 {}
368 };
369
370 class ExprStmtNode : public StmtNode {
371 public:
372 DECLARE(ExprStmtNode)
373
374 ExprNode::Ptr expr_;
ExprStmtNode(ExprNode::Ptr expr)375 explicit ExprStmtNode(ExprNode::Ptr expr) : expr_(move(expr)) {}
376 };
377
378 class IfStmtNode : public StmtNode {
379 public:
380 DECLARE(IfStmtNode)
381
382 ExprNode::Ptr cond_;
383 StmtNode::Ptr true_block_;
384 StmtNode::Ptr false_block_;
385 // create an if () {} expression
IfStmtNode(ExprNode::Ptr cond,StmtNode::Ptr true_block)386 IfStmtNode(ExprNode::Ptr cond, StmtNode::Ptr true_block)
387 : cond_(move(cond)), true_block_(move(true_block)) {}
388 // create an if () {} else {} expression
IfStmtNode(ExprNode::Ptr cond,StmtNode::Ptr true_block,StmtNode::Ptr false_block)389 IfStmtNode(ExprNode::Ptr cond, StmtNode::Ptr true_block, StmtNode::Ptr false_block)
390 : cond_(move(cond)), true_block_(move(true_block)),
391 false_block_(move(false_block)) {}
392 };
393
394 class OnValidStmtNode : public StmtNode {
395 public:
396 DECLARE(OnValidStmtNode)
397
398 IdentExprNode::Ptr cond_;
399 StmtNode::Ptr block_;
400 StmtNode::Ptr else_block_;
401 // create an onvalid () {} expression
OnValidStmtNode(IdentExprNode::Ptr cond,StmtNode::Ptr block)402 OnValidStmtNode(IdentExprNode::Ptr cond, StmtNode::Ptr block)
403 : cond_(move(cond)), block_(move(block)) {}
404 // create an onvalid () {} else {} expression
OnValidStmtNode(IdentExprNode::Ptr cond,StmtNode::Ptr block,StmtNode::Ptr else_block)405 OnValidStmtNode(IdentExprNode::Ptr cond, StmtNode::Ptr block, StmtNode::Ptr else_block)
406 : cond_(move(cond)), block_(move(block)),
407 else_block_(move(else_block)) {}
408 };
409
410 class SwitchStmtNode : public StmtNode {
411 public:
412 DECLARE(SwitchStmtNode)
413 ExprNode::Ptr cond_;
414 BlockStmtNode::Ptr block_;
SwitchStmtNode(ExprNode::Ptr cond,BlockStmtNode::Ptr block)415 SwitchStmtNode(ExprNode::Ptr cond, BlockStmtNode::Ptr block)
416 : cond_(move(cond)), block_(move(block)) {}
417 };
418
419 class CaseStmtNode : public StmtNode {
420 public:
421 DECLARE(CaseStmtNode)
422 IntegerExprNode::Ptr value_;
423 BlockStmtNode::Ptr block_;
CaseStmtNode(IntegerExprNode::Ptr value,BlockStmtNode::Ptr block)424 CaseStmtNode(IntegerExprNode::Ptr value, BlockStmtNode::Ptr block)
425 : value_(move(value)), block_(move(block)) {}
CaseStmtNode(BlockStmtNode::Ptr block)426 explicit CaseStmtNode(BlockStmtNode::Ptr block) : block_(move(block)) {}
427 };
428
429 class VariableDeclStmtNode : public StmtNode {
430 public:
431 typedef unique_ptr<VariableDeclStmtNode> Ptr;
432 virtual StatusTuple accept(Visitor* v) = 0;
433 enum storage_type { INTEGER, STRUCT, STRUCT_REFERENCE };
434
435 IdentExprNode::Ptr id_;
436 ExprNodeList init_;
437 enum storage_type storage_type_;
438 size_t bit_width_;
439 size_t bit_offset_;
440 int slot_;
441 string scope_id_;
442 explicit VariableDeclStmtNode(IdentExprNode::Ptr id, storage_type t, size_t bit_width = 0, size_t bit_offset = 0)
id_(move (id))443 : id_(move(id)), storage_type_(t), bit_width_(bit_width), bit_offset_(bit_offset), slot_(0) {}
scope_id()444 const char* scope_id() const { return scope_id_.c_str(); }
is_struct()445 bool is_struct() { return (storage_type_ == STRUCT || storage_type_ == STRUCT_REFERENCE); }
is_pointer()446 bool is_pointer() { return (storage_type_ == STRUCT_REFERENCE); }
447 };
448
449 typedef vector<VariableDeclStmtNode::Ptr> FormalList;
450
451 class StructVariableDeclStmtNode : public VariableDeclStmtNode {
452 public:
453 DECLARE(StructVariableDeclStmtNode)
454
455 IdentExprNode::Ptr struct_id_;
456 StructVariableDeclStmtNode(IdentExprNode::Ptr struct_id, IdentExprNode::Ptr id,
457 VariableDeclStmtNode::storage_type t = VariableDeclStmtNode::STRUCT)
VariableDeclStmtNode(move (id),t)458 : VariableDeclStmtNode(move(id), t), struct_id_(move(struct_id)) {}
459 };
460
461 class IntegerVariableDeclStmtNode : public VariableDeclStmtNode {
462 public:
DECLARE(IntegerVariableDeclStmtNode)463 DECLARE(IntegerVariableDeclStmtNode)
464
465 IntegerVariableDeclStmtNode(IdentExprNode::Ptr id, const string& bits)
466 : VariableDeclStmtNode(move(id), VariableDeclStmtNode::INTEGER, strtoul(bits.c_str(), NULL, 0)) {}
467 };
468
469 class StructDeclStmtNode : public StmtNode {
470 public:
471 DECLARE(StructDeclStmtNode)
472
473 IdentExprNode::Ptr id_;
474 FormalList stmts_;
475 size_t bit_width_;
476 bool packed_;
477 StructDeclStmtNode(IdentExprNode::Ptr id, FormalList&& stmts = FormalList())
id_(move (id))478 : id_(move(id)), stmts_(move(stmts)), bit_width_(0), packed_(false) {}
479 VariableDeclStmtNode* field(const string& name) const;
480 int indexof(const string& name) const;
is_packed()481 bool is_packed() const { return packed_; }
482 };
483
484 class ParserStateStmtNode : public StmtNode {
485 public:
486 DECLARE(ParserStateStmtNode)
487
488 IdentExprNode::Ptr id_;
489 StmtNode* next_state_;
490 string scope_id_;
ParserStateStmtNode(IdentExprNode::Ptr id)491 explicit ParserStateStmtNode(IdentExprNode::Ptr id)
492 : id_(move(id)) {}
make(const IdentExprNode::Ptr & id)493 static Ptr make(const IdentExprNode::Ptr& id) {
494 return Ptr(new ParserStateStmtNode(id->copy()));
495 }
scoped_name()496 string scoped_name() const { return scope_id_ + id_->name_; }
497 };
498
499 class StateDeclStmtNode : public StmtNode {
500 public:
501 DECLARE(StateDeclStmtNode)
502
503 struct Sub {
504 IdentExprNode::Ptr id_;
505 BlockStmtNode::Ptr block_;
506 ParserStateStmtNode::Ptr parser_;
507 Scopes::StateScope* scope_;
SubSub508 Sub(decltype(id_) id, decltype(block_) block, decltype(parser_) parser, decltype(scope_) scope)
509 : id_(move(id)), block_(move(block)), parser_(move(parser)), scope_(scope) {}
~SubSub510 ~Sub() { delete scope_; }
SubSub511 Sub(Sub&& other) : scope_(NULL) {
512 *this = move(other);
513 }
514 Sub& operator=(Sub&& other) {
515 if (this == &other) {
516 return *this;
517 }
518 id_ = move(other.id_);
519 block_ = move(other.block_);
520 parser_ = move(other.parser_);
521 std::swap(scope_, other.scope_);
522 return *this;
523 }
524 };
525
526 IdentExprNode::Ptr id_;
527 StmtNodeList init_;
528 string scope_id_;
529 ParserStateStmtNode::Ptr parser_;
530 vector<Sub> subs_;
StateDeclStmtNode()531 StateDeclStmtNode() {}
StateDeclStmtNode(IdentExprNode::Ptr id,BlockStmtNode::Ptr block)532 StateDeclStmtNode(IdentExprNode::Ptr id, BlockStmtNode::Ptr block) : id_(move(id)) {
533 subs_.push_back(Sub(make_unique<IdentExprNode>(""), move(block), ParserStateStmtNode::Ptr(), NULL));
534 }
StateDeclStmtNode(IdentExprNode::Ptr id1,IdentExprNode::Ptr id2,BlockStmtNode::Ptr block)535 StateDeclStmtNode(IdentExprNode::Ptr id1, IdentExprNode::Ptr id2, BlockStmtNode::Ptr block)
536 : id_(move(id1)) {
537 subs_.push_back(Sub(move(id2), move(block), ParserStateStmtNode::Ptr(), NULL));
538 }
scoped_name()539 string scoped_name() const { return scope_id_ + id_->name_; }
find_sub(const string & id)540 vector<Sub>::iterator find_sub(const string& id) {
541 return find_if(subs_.begin(), subs_.end(), [&id] (const Sub& sub) {
542 if (sub.id_->name_ == id)
543 return true;
544 return false;
545 });
546
547 }
548 };
549
550 class MatchDeclStmtNode : public StmtNode {
551 public:
552 DECLARE(MatchDeclStmtNode)
553
554 IdentExprNode::Ptr id_;
555 FormalList formals_;
556 BlockStmtNode::Ptr block_;
MatchDeclStmtNode(IdentExprNode::Ptr id,FormalList && formals,BlockStmtNode::Ptr block)557 MatchDeclStmtNode(IdentExprNode::Ptr id, FormalList&& formals, BlockStmtNode::Ptr block)
558 : id_(move(id)), formals_(move(formals)), block_(move(block)) {}
559 };
560
561 class MissDeclStmtNode : public StmtNode {
562 public:
563 DECLARE(MissDeclStmtNode)
564
565 IdentExprNode::Ptr id_;
566 FormalList formals_;
567 BlockStmtNode::Ptr block_;
MissDeclStmtNode(IdentExprNode::Ptr id,FormalList && formals,BlockStmtNode::Ptr block)568 MissDeclStmtNode(IdentExprNode::Ptr id, FormalList&& formals, BlockStmtNode::Ptr block)
569 : id_(move(id)), formals_(move(formals)), block_(move(block)) {}
570 };
571
572 class FailureDeclStmtNode : public StmtNode {
573 public:
574 DECLARE(FailureDeclStmtNode)
575
576 IdentExprNode::Ptr id_;
577 FormalList formals_;
578 BlockStmtNode::Ptr block_;
FailureDeclStmtNode(IdentExprNode::Ptr id,FormalList && formals,BlockStmtNode::Ptr block)579 FailureDeclStmtNode(IdentExprNode::Ptr id, FormalList&& formals, BlockStmtNode::Ptr block)
580 : id_(move(id)), formals_(move(formals)), block_(move(block)) {}
581 };
582
583 class TableDeclStmtNode : public StmtNode {
584 public:
585 DECLARE(TableDeclStmtNode)
586
587 IdentExprNode::Ptr table_type_;
588 IdentExprNodeList templates_;
589 IdentExprNode::Ptr id_;
590 StructDeclStmtNode *key_type_;
591 StructDeclStmtNode *leaf_type_;
key_id()592 IdentExprNode * key_id() { return templates_.at(0).get(); }
leaf_id()593 IdentExprNode * leaf_id() { return templates_.at(1).get(); }
type_id()594 IdentExprNode * type_id() { return templates_.at(2).get(); }
policy_id()595 IdentExprNode * policy_id() { return templates_.at(3).get(); }
596 size_t size_;
TableDeclStmtNode(IdentExprNode::Ptr table_type,IdentExprNodeList && templates,IdentExprNode::Ptr id,string * size)597 TableDeclStmtNode(IdentExprNode::Ptr table_type, IdentExprNodeList&& templates,
598 IdentExprNode::Ptr id, string* size)
599 : table_type_(move(table_type)), templates_(move(templates)), id_(move(id)),
600 key_type_(nullptr), leaf_type_(nullptr), size_(strtoul(size->c_str(), NULL, 0)) {
601 delete size;
602 }
603 };
604
605 class FuncDeclStmtNode : public StmtNode {
606 public:
607 DECLARE(FuncDeclStmtNode)
608
609 IdentExprNode::Ptr id_;
610 FormalList formals_;
611 BlockStmtNode::Ptr block_;
612 Scopes::StateScope* scope_;
FuncDeclStmtNode(IdentExprNode::Ptr id,FormalList && formals,BlockStmtNode::Ptr block)613 FuncDeclStmtNode(IdentExprNode::Ptr id, FormalList&& formals, BlockStmtNode::Ptr block)
614 : id_(move(id)), formals_(move(formals)), block_(move(block)), scope_(NULL) {}
615 };
616
617 class Visitor {
618 public:
619 typedef StatusTuple Ret;
~Visitor()620 virtual ~Visitor() {}
621 #define VISIT(type, func) virtual STATUS_RETURN visit_##func(type* n) = 0;
622 EXPAND_NODES(VISIT)
623 #undef VISIT
624 };
625
626 #undef DECLARE
627
628 } // namespace cc
629 } // namespace ebpf
630