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