fb5d815d9958f3bdbf816db74cb52cacffb5f59d
[lttng-tools.git] / src / common / filter / filter-visitor-generate-ir.c
1 /*
2 * filter-visitor-generate-ir.c
3 *
4 * LTTng filter generate intermediate representation
5 *
6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * SPDX-License-Identifier: LGPL-2.1-only
9 *
10 */
11
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <assert.h>
17 #include <inttypes.h>
18 #include "filter-ast.h"
19 #include "filter-parser.h"
20 #include "filter-ir.h"
21
22 #include <common/compat/errno.h>
23 #include <common/macros.h>
24 #include <common/string-utils/string-utils.h>
25
26 static
27 struct ir_op *generate_ir_recursive(struct filter_parser_ctx *ctx,
28 struct filter_node *node, enum ir_side side);
29
30 static
31 struct ir_op *make_op_root(struct ir_op *child, enum ir_side side)
32 {
33 struct ir_op *op;
34
35 op = calloc(sizeof(struct ir_op), 1);
36 if (!op)
37 return NULL;
38 switch (child->data_type) {
39 case IR_DATA_UNKNOWN:
40 default:
41 fprintf(stderr, "[error] Unknown root child data type\n");
42 free(op);
43 return NULL;
44 case IR_DATA_STRING:
45 fprintf(stderr, "[error] String cannot be root data type\n");
46 free(op);
47 return NULL;
48 case IR_DATA_NUMERIC:
49 case IR_DATA_FIELD_REF:
50 case IR_DATA_GET_CONTEXT_REF:
51 case IR_DATA_EXPRESSION:
52 /* ok */
53 break;
54 }
55 op->op = IR_OP_ROOT;
56 op->side = side;
57 op->data_type = child->data_type;
58 op->signedness = child->signedness;
59 op->u.root.child = child;
60 return op;
61 }
62
63 static
64 enum ir_load_string_type get_literal_string_type(const char *string)
65 {
66 assert(string);
67
68 if (strutils_is_star_glob_pattern(string)) {
69 if (strutils_is_star_at_the_end_only_glob_pattern(string)) {
70 return IR_LOAD_STRING_TYPE_GLOB_STAR_END;
71 }
72
73 return IR_LOAD_STRING_TYPE_GLOB_STAR;
74 }
75
76 return IR_LOAD_STRING_TYPE_PLAIN;
77 }
78
79 static
80 struct ir_op *make_op_load_string(const char *string, enum ir_side side)
81 {
82 struct ir_op *op;
83
84 op = calloc(sizeof(struct ir_op), 1);
85 if (!op)
86 return NULL;
87 op->op = IR_OP_LOAD;
88 op->data_type = IR_DATA_STRING;
89 op->signedness = IR_SIGN_UNKNOWN;
90 op->side = side;
91 op->u.load.u.string.type = get_literal_string_type(string);
92 op->u.load.u.string.value = strdup(string);
93 if (!op->u.load.u.string.value) {
94 free(op);
95 return NULL;
96 }
97 return op;
98 }
99
100 static
101 struct ir_op *make_op_load_numeric(int64_t v, enum ir_side side)
102 {
103 struct ir_op *op;
104
105 op = calloc(sizeof(struct ir_op), 1);
106 if (!op)
107 return NULL;
108 op->op = IR_OP_LOAD;
109 op->data_type = IR_DATA_NUMERIC;
110 /* TODO: for now, all numeric values are signed */
111 op->signedness = IR_SIGNED;
112 op->side = side;
113 op->u.load.u.num = v;
114 return op;
115 }
116
117 static
118 struct ir_op *make_op_load_float(double v, enum ir_side side)
119 {
120 struct ir_op *op;
121
122 op = calloc(sizeof(struct ir_op), 1);
123 if (!op)
124 return NULL;
125 op->op = IR_OP_LOAD;
126 op->data_type = IR_DATA_FLOAT;
127 op->signedness = IR_SIGN_UNKNOWN;
128 op->side = side;
129 op->u.load.u.flt = v;
130 return op;
131 }
132
133 static
134 void free_load_expression(struct ir_load_expression *load_expression)
135 {
136 struct ir_load_expression_op *exp_op;
137
138 if (!load_expression)
139 return;
140 exp_op = load_expression->child;
141 for (;;) {
142 struct ir_load_expression_op *prev_exp_op;
143
144 if (!exp_op)
145 break;
146 switch (exp_op->type) {
147 case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT:
148 case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT:
149 case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT:
150 case IR_LOAD_EXPRESSION_GET_INDEX:
151 case IR_LOAD_EXPRESSION_LOAD_FIELD:
152 break;
153 case IR_LOAD_EXPRESSION_GET_SYMBOL:
154 free(exp_op->u.symbol);
155 break;
156 }
157 prev_exp_op = exp_op;
158 exp_op = exp_op->next;
159 free(prev_exp_op);
160 }
161 free(load_expression);
162 }
163
164 /*
165 * Returns the first node of the chain, after initializing the next
166 * pointers.
167 */
168 static
169 struct filter_node *load_expression_get_forward_chain(struct filter_node *node)
170 {
171 struct filter_node *prev_node;
172
173 for (;;) {
174 assert(node->type == NODE_EXPRESSION);
175 prev_node = node;
176 node = node->u.expression.prev;
177 if (!node) {
178 break;
179 }
180 node->u.expression.next = prev_node;
181 }
182 return prev_node;
183 }
184
185 static
186 struct ir_load_expression *create_load_expression(struct filter_node *node)
187 {
188 struct ir_load_expression *load_exp;
189 struct ir_load_expression_op *load_exp_op, *prev_op;
190 const char *str;
191
192 /* Get forward chain. */
193 node = load_expression_get_forward_chain(node);
194 if (!node)
195 return NULL;
196 load_exp = calloc(sizeof(struct ir_load_expression), 1);
197 if (!load_exp)
198 return NULL;
199
200 /* Root */
201 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
202 if (!load_exp_op)
203 goto error;
204 load_exp->child = load_exp_op;
205 str = node->u.expression.u.string;
206 if (!strcmp(str, "$ctx")) {
207 load_exp_op->type = IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT;
208 node = node->u.expression.next;
209 if (!node) {
210 fprintf(stderr, "[error] Expecting identifier after \'%s\'\n", str);
211 goto error;
212 }
213 str = node->u.expression.u.string;
214 } else if (!strcmp(str, "$app")) {
215 load_exp_op->type = IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT;
216 node = node->u.expression.next;
217 if (!node) {
218 fprintf(stderr, "[error] Expecting identifier after \'%s\'\n", str);
219 goto error;
220 }
221 str = node->u.expression.u.string;
222 } else if (str[0] == '$') {
223 fprintf(stderr, "[error] Unexpected identifier \'%s\'\n", str);
224 goto error;
225 } else {
226 load_exp_op->type = IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT;
227 }
228
229 for (;;) {
230 struct filter_node *bracket_node;
231
232 prev_op = load_exp_op;
233 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
234 if (!load_exp_op)
235 goto error;
236 prev_op->next = load_exp_op;
237 load_exp_op->type = IR_LOAD_EXPRESSION_GET_SYMBOL;
238 load_exp_op->u.symbol = strdup(str);
239 if (!load_exp_op->u.symbol)
240 goto error;
241
242 /* Explore brackets from current node. */
243 for (bracket_node = node->u.expression.next_bracket;
244 bracket_node != NULL;
245 bracket_node = bracket_node->u.expression.next_bracket) {
246 prev_op = load_exp_op;
247 if (bracket_node->type != NODE_EXPRESSION ||
248 bracket_node->u.expression.type != AST_EXP_CONSTANT) {
249 fprintf(stderr, "[error] Expecting constant index in array expression\n");
250 goto error;
251 }
252 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
253 if (!load_exp_op)
254 goto error;
255 prev_op->next = load_exp_op;
256 load_exp_op->type = IR_LOAD_EXPRESSION_GET_INDEX;
257 load_exp_op->u.index = bracket_node->u.expression.u.constant;
258 }
259 /* Go to next chain element. */
260 node = node->u.expression.next;
261 if (!node)
262 break;
263 str = node->u.expression.u.string;
264 }
265 /* Add final load field */
266 prev_op = load_exp_op;
267 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
268 if (!load_exp_op)
269 goto error;
270 prev_op->next = load_exp_op;
271 load_exp_op->type = IR_LOAD_EXPRESSION_LOAD_FIELD;
272 return load_exp;
273
274 error:
275 free_load_expression(load_exp);
276 return NULL;
277 }
278
279 static
280 struct ir_op *make_op_load_expression(struct filter_node *node,
281 enum ir_side side)
282 {
283 struct ir_op *op;
284
285 op = calloc(sizeof(struct ir_op), 1);
286 if (!op)
287 return NULL;
288 op->op = IR_OP_LOAD;
289 op->data_type = IR_DATA_EXPRESSION;
290 op->signedness = IR_SIGN_DYN;
291 op->side = side;
292 op->u.load.u.expression = create_load_expression(node);
293 if (!op->u.load.u.expression) {
294 goto error;
295 }
296 return op;
297
298 error:
299 free_load_expression(op->u.load.u.expression);
300 free(op);
301 return NULL;
302 }
303
304 static
305 struct ir_op *make_op_unary(enum unary_op_type unary_op_type,
306 const char *op_str, enum ir_op_signedness signedness,
307 struct ir_op *child, enum ir_side side)
308 {
309 struct ir_op *op = NULL;
310
311 if (child->data_type == IR_DATA_STRING) {
312 fprintf(stderr, "[error] unary operation '%s' not allowed on string literal\n", op_str);
313 goto error;
314 }
315
316 op = calloc(sizeof(struct ir_op), 1);
317 if (!op)
318 return NULL;
319 op->op = IR_OP_UNARY;
320 op->data_type = child->data_type;
321 op->signedness = signedness;
322 op->side = side;
323 op->u.unary.type = unary_op_type;
324 op->u.unary.child = child;
325 return op;
326
327 error:
328 free(op);
329 return NULL;
330 }
331
332 /*
333 * unary + is pretty much useless.
334 */
335 static
336 struct ir_op *make_op_unary_plus(struct ir_op *child, enum ir_side side)
337 {
338 return make_op_unary(AST_UNARY_PLUS, "+", child->signedness,
339 child, side);
340 }
341
342 static
343 struct ir_op *make_op_unary_minus(struct ir_op *child, enum ir_side side)
344 {
345 return make_op_unary(AST_UNARY_MINUS, "-", child->signedness,
346 child, side);
347 }
348
349 static
350 struct ir_op *make_op_unary_not(struct ir_op *child, enum ir_side side)
351 {
352 return make_op_unary(AST_UNARY_NOT, "!", child->signedness,
353 child, side);
354 }
355
356 static
357 struct ir_op *make_op_unary_bit_not(struct ir_op *child, enum ir_side side)
358 {
359 return make_op_unary(AST_UNARY_BIT_NOT, "~", child->signedness,
360 child, side);
361 }
362
363 static
364 struct ir_op *make_op_binary_compare(enum op_type bin_op_type,
365 const char *op_str, struct ir_op *left, struct ir_op *right,
366 enum ir_side side)
367 {
368 struct ir_op *op = NULL;
369
370 if (left->data_type == IR_DATA_UNKNOWN
371 || right->data_type == IR_DATA_UNKNOWN) {
372 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
373 goto error;
374
375 }
376 if ((left->data_type == IR_DATA_STRING
377 && (right->data_type == IR_DATA_NUMERIC || right->data_type == IR_DATA_FLOAT))
378 || ((left->data_type == IR_DATA_NUMERIC || left->data_type == IR_DATA_FLOAT) &&
379 right->data_type == IR_DATA_STRING)) {
380 fprintf(stderr, "[error] binary operation '%s' operand type mismatch\n", op_str);
381 goto error;
382 }
383
384 op = calloc(sizeof(struct ir_op), 1);
385 if (!op)
386 return NULL;
387 op->op = IR_OP_BINARY;
388 op->u.binary.type = bin_op_type;
389 op->u.binary.left = left;
390 op->u.binary.right = right;
391
392 /* we return a boolean, represented as signed numeric */
393 op->data_type = IR_DATA_NUMERIC;
394 op->signedness = IR_SIGNED;
395 op->side = side;
396
397 return op;
398
399 error:
400 free(op);
401 return NULL;
402 }
403
404 static
405 struct ir_op *make_op_binary_eq(struct ir_op *left, struct ir_op *right,
406 enum ir_side side)
407 {
408 return make_op_binary_compare(AST_OP_EQ, "==", left, right, side);
409 }
410
411 static
412 struct ir_op *make_op_binary_ne(struct ir_op *left, struct ir_op *right,
413 enum ir_side side)
414 {
415 return make_op_binary_compare(AST_OP_NE, "!=", left, right, side);
416 }
417
418 static
419 struct ir_op *make_op_binary_gt(struct ir_op *left, struct ir_op *right,
420 enum ir_side side)
421 {
422 return make_op_binary_compare(AST_OP_GT, ">", left, right, side);
423 }
424
425 static
426 struct ir_op *make_op_binary_lt(struct ir_op *left, struct ir_op *right,
427 enum ir_side side)
428 {
429 return make_op_binary_compare(AST_OP_LT, "<", left, right, side);
430 }
431
432 static
433 struct ir_op *make_op_binary_ge(struct ir_op *left, struct ir_op *right,
434 enum ir_side side)
435 {
436 return make_op_binary_compare(AST_OP_GE, ">=", left, right, side);
437 }
438
439 static
440 struct ir_op *make_op_binary_le(struct ir_op *left, struct ir_op *right,
441 enum ir_side side)
442 {
443 return make_op_binary_compare(AST_OP_LE, "<=", left, right, side);
444 }
445
446 static
447 struct ir_op *make_op_binary_logical(enum op_type bin_op_type,
448 const char *op_str, struct ir_op *left, struct ir_op *right,
449 enum ir_side side)
450 {
451 struct ir_op *op = NULL;
452
453 if (left->data_type == IR_DATA_UNKNOWN
454 || right->data_type == IR_DATA_UNKNOWN) {
455 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
456 goto error;
457
458 }
459 if (left->data_type == IR_DATA_STRING
460 || right->data_type == IR_DATA_STRING) {
461 fprintf(stderr, "[error] logical binary operation '%s' cannot have string operand\n", op_str);
462 goto error;
463 }
464
465 op = calloc(sizeof(struct ir_op), 1);
466 if (!op)
467 return NULL;
468 op->op = IR_OP_LOGICAL;
469 op->u.binary.type = bin_op_type;
470 op->u.binary.left = left;
471 op->u.binary.right = right;
472
473 /* we return a boolean, represented as signed numeric */
474 op->data_type = IR_DATA_NUMERIC;
475 op->signedness = IR_SIGNED;
476 op->side = side;
477
478 return op;
479
480 error:
481 free(op);
482 return NULL;
483 }
484
485 static
486 struct ir_op *make_op_binary_bitwise(enum op_type bin_op_type,
487 const char *op_str, struct ir_op *left, struct ir_op *right,
488 enum ir_side side)
489 {
490 struct ir_op *op = NULL;
491
492 if (left->data_type == IR_DATA_UNKNOWN
493 || right->data_type == IR_DATA_UNKNOWN) {
494 fprintf(stderr, "[error] bitwise binary operation '%s' has unknown operand type\n", op_str);
495 goto error;
496
497 }
498 if (left->data_type == IR_DATA_STRING
499 || right->data_type == IR_DATA_STRING) {
500 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have string operand\n", op_str);
501 goto error;
502 }
503 if (left->data_type == IR_DATA_FLOAT
504 || right->data_type == IR_DATA_FLOAT) {
505 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have floating point operand\n", op_str);
506 goto error;
507 }
508
509 op = calloc(sizeof(struct ir_op), 1);
510 if (!op)
511 return NULL;
512 op->op = IR_OP_BINARY;
513 op->u.binary.type = bin_op_type;
514 op->u.binary.left = left;
515 op->u.binary.right = right;
516
517 /* we return a signed numeric */
518 op->data_type = IR_DATA_NUMERIC;
519 op->signedness = IR_SIGNED;
520 op->side = side;
521
522 return op;
523
524 error:
525 free(op);
526 return NULL;
527 }
528
529 static
530 struct ir_op *make_op_binary_logical_and(struct ir_op *left, struct ir_op *right,
531 enum ir_side side)
532 {
533 return make_op_binary_logical(AST_OP_AND, "&&", left, right, side);
534 }
535
536 static
537 struct ir_op *make_op_binary_logical_or(struct ir_op *left, struct ir_op *right,
538 enum ir_side side)
539 {
540 return make_op_binary_logical(AST_OP_OR, "||", left, right, side);
541 }
542
543 static
544 struct ir_op *make_op_binary_bitwise_rshift(struct ir_op *left, struct ir_op *right,
545 enum ir_side side)
546 {
547 return make_op_binary_bitwise(AST_OP_BIT_RSHIFT, ">>", left, right, side);
548 }
549
550 static
551 struct ir_op *make_op_binary_bitwise_lshift(struct ir_op *left, struct ir_op *right,
552 enum ir_side side)
553 {
554 return make_op_binary_bitwise(AST_OP_BIT_LSHIFT, "<<", left, right, side);
555 }
556
557 static
558 struct ir_op *make_op_binary_bitwise_and(struct ir_op *left, struct ir_op *right,
559 enum ir_side side)
560 {
561 return make_op_binary_bitwise(AST_OP_BIT_AND, "&", left, right, side);
562 }
563
564 static
565 struct ir_op *make_op_binary_bitwise_or(struct ir_op *left, struct ir_op *right,
566 enum ir_side side)
567 {
568 return make_op_binary_bitwise(AST_OP_BIT_OR, "|", left, right, side);
569 }
570
571 static
572 struct ir_op *make_op_binary_bitwise_xor(struct ir_op *left, struct ir_op *right,
573 enum ir_side side)
574 {
575 return make_op_binary_bitwise(AST_OP_BIT_XOR, "^", left, right, side);
576 }
577
578 static
579 void filter_free_ir_recursive(struct ir_op *op)
580 {
581 if (!op)
582 return;
583 switch (op->op) {
584 case IR_OP_UNKNOWN:
585 default:
586 fprintf(stderr, "[error] Unknown op type in %s\n",
587 __func__);
588 break;
589 case IR_OP_ROOT:
590 filter_free_ir_recursive(op->u.root.child);
591 break;
592 case IR_OP_LOAD:
593 switch (op->data_type) {
594 case IR_DATA_STRING:
595 free(op->u.load.u.string.value);
596 break;
597 case IR_DATA_FIELD_REF: /* fall-through */
598 case IR_DATA_GET_CONTEXT_REF:
599 free(op->u.load.u.ref);
600 break;
601 case IR_DATA_EXPRESSION:
602 free_load_expression(op->u.load.u.expression);
603 default:
604 break;
605 }
606 break;
607 case IR_OP_UNARY:
608 filter_free_ir_recursive(op->u.unary.child);
609 break;
610 case IR_OP_BINARY:
611 filter_free_ir_recursive(op->u.binary.left);
612 filter_free_ir_recursive(op->u.binary.right);
613 break;
614 case IR_OP_LOGICAL:
615 filter_free_ir_recursive(op->u.logical.left);
616 filter_free_ir_recursive(op->u.logical.right);
617 break;
618 }
619 free(op);
620 }
621
622 static
623 struct ir_op *make_expression(struct filter_parser_ctx *ctx,
624 struct filter_node *node, enum ir_side side)
625 {
626 switch (node->u.expression.type) {
627 case AST_EXP_UNKNOWN:
628 default:
629 fprintf(stderr, "[error] %s: unknown expression type\n", __func__);
630 return NULL;
631
632 case AST_EXP_STRING:
633 return make_op_load_string(node->u.expression.u.string, side);
634 case AST_EXP_CONSTANT:
635 return make_op_load_numeric(node->u.expression.u.constant,
636 side);
637 case AST_EXP_FLOAT_CONSTANT:
638 return make_op_load_float(node->u.expression.u.float_constant,
639 side);
640 case AST_EXP_IDENTIFIER:
641 case AST_EXP_GLOBAL_IDENTIFIER:
642 return make_op_load_expression(node, side);
643 case AST_EXP_NESTED:
644 return generate_ir_recursive(ctx, node->u.expression.u.child,
645 side);
646 }
647 }
648
649 static
650 struct ir_op *make_op(struct filter_parser_ctx *ctx,
651 struct filter_node *node, enum ir_side side)
652 {
653 struct ir_op *op = NULL, *lchild, *rchild;
654 const char *op_str = "?";
655
656 switch (node->u.op.type) {
657 case AST_OP_UNKNOWN:
658 default:
659 fprintf(stderr, "[error] %s: unknown binary op type\n", __func__);
660 return NULL;
661
662 /*
663 * The following binary operators other than comparators and
664 * logical and/or are not supported yet.
665 */
666 case AST_OP_MUL:
667 op_str = "*";
668 goto error_not_supported;
669 case AST_OP_DIV:
670 op_str = "/";
671 goto error_not_supported;
672 case AST_OP_MOD:
673 op_str = "%";
674 goto error_not_supported;
675 case AST_OP_PLUS:
676 op_str = "+";
677 goto error_not_supported;
678 case AST_OP_MINUS:
679 op_str = "-";
680 goto error_not_supported;
681
682 case AST_OP_BIT_RSHIFT:
683 case AST_OP_BIT_LSHIFT:
684 case AST_OP_BIT_AND:
685 case AST_OP_BIT_OR:
686 case AST_OP_BIT_XOR:
687 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
688 if (!lchild)
689 return NULL;
690 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
691 if (!rchild) {
692 filter_free_ir_recursive(lchild);
693 return NULL;
694 }
695 break;
696
697 case AST_OP_EQ:
698 case AST_OP_NE:
699 case AST_OP_GT:
700 case AST_OP_LT:
701 case AST_OP_GE:
702 case AST_OP_LE:
703 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
704 if (!lchild)
705 return NULL;
706 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
707 if (!rchild) {
708 filter_free_ir_recursive(lchild);
709 return NULL;
710 }
711 break;
712
713 case AST_OP_AND:
714 case AST_OP_OR:
715 /*
716 * Both children considered as left, since we need to
717 * populate R0.
718 */
719 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
720 if (!lchild)
721 return NULL;
722 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_LEFT);
723 if (!rchild) {
724 filter_free_ir_recursive(lchild);
725 return NULL;
726 }
727 break;
728 }
729
730 switch (node->u.op.type) {
731 case AST_OP_AND:
732 op = make_op_binary_logical_and(lchild, rchild, side);
733 break;
734 case AST_OP_OR:
735 op = make_op_binary_logical_or(lchild, rchild, side);
736 break;
737 case AST_OP_EQ:
738 op = make_op_binary_eq(lchild, rchild, side);
739 break;
740 case AST_OP_NE:
741 op = make_op_binary_ne(lchild, rchild, side);
742 break;
743 case AST_OP_GT:
744 op = make_op_binary_gt(lchild, rchild, side);
745 break;
746 case AST_OP_LT:
747 op = make_op_binary_lt(lchild, rchild, side);
748 break;
749 case AST_OP_GE:
750 op = make_op_binary_ge(lchild, rchild, side);
751 break;
752 case AST_OP_LE:
753 op = make_op_binary_le(lchild, rchild, side);
754 break;
755 case AST_OP_BIT_RSHIFT:
756 op = make_op_binary_bitwise_rshift(lchild, rchild, side);
757 break;
758 case AST_OP_BIT_LSHIFT:
759 op = make_op_binary_bitwise_lshift(lchild, rchild, side);
760 break;
761 case AST_OP_BIT_AND:
762 op = make_op_binary_bitwise_and(lchild, rchild, side);
763 break;
764 case AST_OP_BIT_OR:
765 op = make_op_binary_bitwise_or(lchild, rchild, side);
766 break;
767 case AST_OP_BIT_XOR:
768 op = make_op_binary_bitwise_xor(lchild, rchild, side);
769 break;
770 default:
771 break;
772 }
773
774 if (!op) {
775 filter_free_ir_recursive(rchild);
776 filter_free_ir_recursive(lchild);
777 }
778 return op;
779
780 error_not_supported:
781 fprintf(stderr, "[error] %s: binary operation '%s' not supported\n",
782 __func__, op_str);
783 return NULL;
784 }
785
786 static
787 struct ir_op *make_unary_op(struct filter_parser_ctx *ctx,
788 struct filter_node *node, enum ir_side side)
789 {
790 switch (node->u.unary_op.type) {
791 case AST_UNARY_UNKNOWN:
792 default:
793 fprintf(stderr, "[error] %s: unknown unary op type\n", __func__);
794 return NULL;
795
796 case AST_UNARY_PLUS:
797 {
798 struct ir_op *op, *child;
799
800 child = generate_ir_recursive(ctx, node->u.unary_op.child,
801 side);
802 if (!child)
803 return NULL;
804 op = make_op_unary_plus(child, side);
805 if (!op) {
806 filter_free_ir_recursive(child);
807 return NULL;
808 }
809 return op;
810 }
811 case AST_UNARY_MINUS:
812 {
813 struct ir_op *op, *child;
814
815 child = generate_ir_recursive(ctx, node->u.unary_op.child,
816 side);
817 if (!child)
818 return NULL;
819 op = make_op_unary_minus(child, side);
820 if (!op) {
821 filter_free_ir_recursive(child);
822 return NULL;
823 }
824 return op;
825 }
826 case AST_UNARY_NOT:
827 {
828 struct ir_op *op, *child;
829
830 child = generate_ir_recursive(ctx, node->u.unary_op.child,
831 side);
832 if (!child)
833 return NULL;
834 op = make_op_unary_not(child, side);
835 if (!op) {
836 filter_free_ir_recursive(child);
837 return NULL;
838 }
839 return op;
840 }
841 case AST_UNARY_BIT_NOT:
842 {
843 struct ir_op *op, *child;
844
845 child = generate_ir_recursive(ctx, node->u.unary_op.child,
846 side);
847 if (!child)
848 return NULL;
849 op = make_op_unary_bit_not(child, side);
850 if (!op) {
851 filter_free_ir_recursive(child);
852 return NULL;
853 }
854 return op;
855 }
856 }
857
858 return NULL;
859 }
860
861 static
862 struct ir_op *generate_ir_recursive(struct filter_parser_ctx *ctx,
863 struct filter_node *node, enum ir_side side)
864 {
865 switch (node->type) {
866 case NODE_UNKNOWN:
867 default:
868 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
869 return NULL;
870
871 case NODE_ROOT:
872 {
873 struct ir_op *op, *child;
874
875 child = generate_ir_recursive(ctx, node->u.root.child,
876 side);
877 if (!child)
878 return NULL;
879 op = make_op_root(child, side);
880 if (!op) {
881 filter_free_ir_recursive(child);
882 return NULL;
883 }
884 return op;
885 }
886 case NODE_EXPRESSION:
887 return make_expression(ctx, node, side);
888 case NODE_OP:
889 return make_op(ctx, node, side);
890 case NODE_UNARY_OP:
891 return make_unary_op(ctx, node, side);
892 }
893 return 0;
894 }
895
896 LTTNG_HIDDEN
897 void filter_ir_free(struct filter_parser_ctx *ctx)
898 {
899 filter_free_ir_recursive(ctx->ir_root);
900 ctx->ir_root = NULL;
901 }
902
903 LTTNG_HIDDEN
904 int filter_visitor_ir_generate(struct filter_parser_ctx *ctx)
905 {
906 struct ir_op *op;
907
908 op = generate_ir_recursive(ctx, &ctx->ast->root, IR_LEFT);
909 if (!op) {
910 return -EINVAL;
911 }
912 ctx->ir_root = op;
913 return 0;
914 }
This page took 0.047577 seconds and 4 git commands to generate.