Fix all -Wdiscarded-qualifiers warning instances
[lttng-tools.git] / src / lib / lttng-ctl / 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 <errno.h>
18 #include <inttypes.h>
19 #include "filter-ast.h"
20 #include "filter-parser.h"
21 #include "filter-ir.h"
22
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 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
248 if (!load_exp_op)
249 goto error;
250 prev_op->next = load_exp_op;
251 load_exp_op->type = IR_LOAD_EXPRESSION_GET_INDEX;
252 load_exp_op->u.index = bracket_node->u.expression.u.constant;
253 }
254 /* Go to next chain element. */
255 node = node->u.expression.next;
256 if (!node)
257 break;
258 str = node->u.expression.u.string;
259 }
260 /* Add final load field */
261 prev_op = load_exp_op;
262 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
263 if (!load_exp_op)
264 goto error;
265 prev_op->next = load_exp_op;
266 load_exp_op->type = IR_LOAD_EXPRESSION_LOAD_FIELD;
267 return load_exp;
268
269 error:
270 free_load_expression(load_exp);
271 return NULL;
272 }
273
274 static
275 struct ir_op *make_op_load_expression(struct filter_node *node,
276 enum ir_side side)
277 {
278 struct ir_op *op;
279
280 op = calloc(sizeof(struct ir_op), 1);
281 if (!op)
282 return NULL;
283 op->op = IR_OP_LOAD;
284 op->data_type = IR_DATA_EXPRESSION;
285 op->signedness = IR_SIGN_DYN;
286 op->side = side;
287 op->u.load.u.expression = create_load_expression(node);
288 if (!op->u.load.u.expression) {
289 goto error;
290 }
291 return op;
292
293 error:
294 free_load_expression(op->u.load.u.expression);
295 free(op);
296 return NULL;
297 }
298
299 static
300 struct ir_op *make_op_unary(enum unary_op_type unary_op_type,
301 const char *op_str, enum ir_op_signedness signedness,
302 struct ir_op *child, enum ir_side side)
303 {
304 struct ir_op *op = NULL;
305
306 if (child->data_type == IR_DATA_STRING) {
307 fprintf(stderr, "[error] unary operation '%s' not allowed on string literal\n", op_str);
308 goto error;
309 }
310
311 op = calloc(sizeof(struct ir_op), 1);
312 if (!op)
313 return NULL;
314 op->op = IR_OP_UNARY;
315 op->data_type = child->data_type;
316 op->signedness = signedness;
317 op->side = side;
318 op->u.unary.type = unary_op_type;
319 op->u.unary.child = child;
320 return op;
321
322 error:
323 free(op);
324 return NULL;
325 }
326
327 /*
328 * unary + is pretty much useless.
329 */
330 static
331 struct ir_op *make_op_unary_plus(struct ir_op *child, enum ir_side side)
332 {
333 return make_op_unary(AST_UNARY_PLUS, "+", child->signedness,
334 child, side);
335 }
336
337 static
338 struct ir_op *make_op_unary_minus(struct ir_op *child, enum ir_side side)
339 {
340 return make_op_unary(AST_UNARY_MINUS, "-", child->signedness,
341 child, side);
342 }
343
344 static
345 struct ir_op *make_op_unary_not(struct ir_op *child, enum ir_side side)
346 {
347 return make_op_unary(AST_UNARY_NOT, "!", child->signedness,
348 child, side);
349 }
350
351 static
352 struct ir_op *make_op_unary_bit_not(struct ir_op *child, enum ir_side side)
353 {
354 return make_op_unary(AST_UNARY_BIT_NOT, "~", child->signedness,
355 child, side);
356 }
357
358 static
359 struct ir_op *make_op_binary_compare(enum op_type bin_op_type,
360 const char *op_str, struct ir_op *left, struct ir_op *right,
361 enum ir_side side)
362 {
363 struct ir_op *op = NULL;
364
365 if (left->data_type == IR_DATA_UNKNOWN
366 || right->data_type == IR_DATA_UNKNOWN) {
367 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
368 goto error;
369
370 }
371 if ((left->data_type == IR_DATA_STRING
372 && (right->data_type == IR_DATA_NUMERIC || right->data_type == IR_DATA_FLOAT))
373 || ((left->data_type == IR_DATA_NUMERIC || left->data_type == IR_DATA_FLOAT) &&
374 right->data_type == IR_DATA_STRING)) {
375 fprintf(stderr, "[error] binary operation '%s' operand type mismatch\n", op_str);
376 goto error;
377 }
378
379 op = calloc(sizeof(struct ir_op), 1);
380 if (!op)
381 return NULL;
382 op->op = IR_OP_BINARY;
383 op->u.binary.type = bin_op_type;
384 op->u.binary.left = left;
385 op->u.binary.right = right;
386
387 /* we return a boolean, represented as signed numeric */
388 op->data_type = IR_DATA_NUMERIC;
389 op->signedness = IR_SIGNED;
390 op->side = side;
391
392 return op;
393
394 error:
395 free(op);
396 return NULL;
397 }
398
399 static
400 struct ir_op *make_op_binary_eq(struct ir_op *left, struct ir_op *right,
401 enum ir_side side)
402 {
403 return make_op_binary_compare(AST_OP_EQ, "==", left, right, side);
404 }
405
406 static
407 struct ir_op *make_op_binary_ne(struct ir_op *left, struct ir_op *right,
408 enum ir_side side)
409 {
410 return make_op_binary_compare(AST_OP_NE, "!=", left, right, side);
411 }
412
413 static
414 struct ir_op *make_op_binary_gt(struct ir_op *left, struct ir_op *right,
415 enum ir_side side)
416 {
417 return make_op_binary_compare(AST_OP_GT, ">", left, right, side);
418 }
419
420 static
421 struct ir_op *make_op_binary_lt(struct ir_op *left, struct ir_op *right,
422 enum ir_side side)
423 {
424 return make_op_binary_compare(AST_OP_LT, "<", left, right, side);
425 }
426
427 static
428 struct ir_op *make_op_binary_ge(struct ir_op *left, struct ir_op *right,
429 enum ir_side side)
430 {
431 return make_op_binary_compare(AST_OP_GE, ">=", left, right, side);
432 }
433
434 static
435 struct ir_op *make_op_binary_le(struct ir_op *left, struct ir_op *right,
436 enum ir_side side)
437 {
438 return make_op_binary_compare(AST_OP_LE, "<=", left, right, side);
439 }
440
441 static
442 struct ir_op *make_op_binary_logical(enum op_type bin_op_type,
443 const char *op_str, struct ir_op *left, struct ir_op *right,
444 enum ir_side side)
445 {
446 struct ir_op *op = NULL;
447
448 if (left->data_type == IR_DATA_UNKNOWN
449 || right->data_type == IR_DATA_UNKNOWN) {
450 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
451 goto error;
452
453 }
454 if (left->data_type == IR_DATA_STRING
455 || right->data_type == IR_DATA_STRING) {
456 fprintf(stderr, "[error] logical binary operation '%s' cannot have string operand\n", op_str);
457 goto error;
458 }
459
460 op = calloc(sizeof(struct ir_op), 1);
461 if (!op)
462 return NULL;
463 op->op = IR_OP_LOGICAL;
464 op->u.binary.type = bin_op_type;
465 op->u.binary.left = left;
466 op->u.binary.right = right;
467
468 /* we return a boolean, represented as signed numeric */
469 op->data_type = IR_DATA_NUMERIC;
470 op->signedness = IR_SIGNED;
471 op->side = side;
472
473 return op;
474
475 error:
476 free(op);
477 return NULL;
478 }
479
480 static
481 struct ir_op *make_op_binary_bitwise(enum op_type bin_op_type,
482 const char *op_str, struct ir_op *left, struct ir_op *right,
483 enum ir_side side)
484 {
485 struct ir_op *op = NULL;
486
487 if (left->data_type == IR_DATA_UNKNOWN
488 || right->data_type == IR_DATA_UNKNOWN) {
489 fprintf(stderr, "[error] bitwise binary operation '%s' has unknown operand type\n", op_str);
490 goto error;
491
492 }
493 if (left->data_type == IR_DATA_STRING
494 || right->data_type == IR_DATA_STRING) {
495 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have string operand\n", op_str);
496 goto error;
497 }
498 if (left->data_type == IR_DATA_FLOAT
499 || right->data_type == IR_DATA_FLOAT) {
500 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have floating point operand\n", op_str);
501 goto error;
502 }
503
504 op = calloc(sizeof(struct ir_op), 1);
505 if (!op)
506 return NULL;
507 op->op = IR_OP_BINARY;
508 op->u.binary.type = bin_op_type;
509 op->u.binary.left = left;
510 op->u.binary.right = right;
511
512 /* we return a signed numeric */
513 op->data_type = IR_DATA_NUMERIC;
514 op->signedness = IR_SIGNED;
515 op->side = side;
516
517 return op;
518
519 error:
520 free(op);
521 return NULL;
522 }
523
524 static
525 struct ir_op *make_op_binary_logical_and(struct ir_op *left, struct ir_op *right,
526 enum ir_side side)
527 {
528 return make_op_binary_logical(AST_OP_AND, "&&", left, right, side);
529 }
530
531 static
532 struct ir_op *make_op_binary_logical_or(struct ir_op *left, struct ir_op *right,
533 enum ir_side side)
534 {
535 return make_op_binary_logical(AST_OP_OR, "||", left, right, side);
536 }
537
538 static
539 struct ir_op *make_op_binary_bitwise_rshift(struct ir_op *left, struct ir_op *right,
540 enum ir_side side)
541 {
542 return make_op_binary_bitwise(AST_OP_BIT_RSHIFT, ">>", left, right, side);
543 }
544
545 static
546 struct ir_op *make_op_binary_bitwise_lshift(struct ir_op *left, struct ir_op *right,
547 enum ir_side side)
548 {
549 return make_op_binary_bitwise(AST_OP_BIT_LSHIFT, "<<", left, right, side);
550 }
551
552 static
553 struct ir_op *make_op_binary_bitwise_and(struct ir_op *left, struct ir_op *right,
554 enum ir_side side)
555 {
556 return make_op_binary_bitwise(AST_OP_BIT_AND, "&", left, right, side);
557 }
558
559 static
560 struct ir_op *make_op_binary_bitwise_or(struct ir_op *left, struct ir_op *right,
561 enum ir_side side)
562 {
563 return make_op_binary_bitwise(AST_OP_BIT_OR, "|", left, right, side);
564 }
565
566 static
567 struct ir_op *make_op_binary_bitwise_xor(struct ir_op *left, struct ir_op *right,
568 enum ir_side side)
569 {
570 return make_op_binary_bitwise(AST_OP_BIT_XOR, "^", left, right, side);
571 }
572
573 static
574 void filter_free_ir_recursive(struct ir_op *op)
575 {
576 if (!op)
577 return;
578 switch (op->op) {
579 case IR_OP_UNKNOWN:
580 default:
581 fprintf(stderr, "[error] Unknown op type in %s\n",
582 __func__);
583 break;
584 case IR_OP_ROOT:
585 filter_free_ir_recursive(op->u.root.child);
586 break;
587 case IR_OP_LOAD:
588 switch (op->data_type) {
589 case IR_DATA_STRING:
590 free(op->u.load.u.string.value);
591 break;
592 case IR_DATA_FIELD_REF: /* fall-through */
593 case IR_DATA_GET_CONTEXT_REF:
594 free(op->u.load.u.ref);
595 break;
596 case IR_DATA_EXPRESSION:
597 free_load_expression(op->u.load.u.expression);
598 default:
599 break;
600 }
601 break;
602 case IR_OP_UNARY:
603 filter_free_ir_recursive(op->u.unary.child);
604 break;
605 case IR_OP_BINARY:
606 filter_free_ir_recursive(op->u.binary.left);
607 filter_free_ir_recursive(op->u.binary.right);
608 break;
609 case IR_OP_LOGICAL:
610 filter_free_ir_recursive(op->u.logical.left);
611 filter_free_ir_recursive(op->u.logical.right);
612 break;
613 }
614 free(op);
615 }
616
617 static
618 struct ir_op *make_expression(struct filter_parser_ctx *ctx,
619 struct filter_node *node, enum ir_side side)
620 {
621 switch (node->u.expression.type) {
622 case AST_EXP_UNKNOWN:
623 default:
624 fprintf(stderr, "[error] %s: unknown expression type\n", __func__);
625 return NULL;
626
627 case AST_EXP_STRING:
628 return make_op_load_string(node->u.expression.u.string, side);
629 case AST_EXP_CONSTANT:
630 return make_op_load_numeric(node->u.expression.u.constant,
631 side);
632 case AST_EXP_FLOAT_CONSTANT:
633 return make_op_load_float(node->u.expression.u.float_constant,
634 side);
635 case AST_EXP_IDENTIFIER:
636 case AST_EXP_GLOBAL_IDENTIFIER:
637 return make_op_load_expression(node, side);
638 case AST_EXP_NESTED:
639 return generate_ir_recursive(ctx, node->u.expression.u.child,
640 side);
641 }
642 }
643
644 static
645 struct ir_op *make_op(struct filter_parser_ctx *ctx,
646 struct filter_node *node, enum ir_side side)
647 {
648 struct ir_op *op = NULL, *lchild, *rchild;
649 const char *op_str = "?";
650
651 switch (node->u.op.type) {
652 case AST_OP_UNKNOWN:
653 default:
654 fprintf(stderr, "[error] %s: unknown binary op type\n", __func__);
655 return NULL;
656
657 /*
658 * The following binary operators other than comparators and
659 * logical and/or are not supported yet.
660 */
661 case AST_OP_MUL:
662 op_str = "*";
663 goto error_not_supported;
664 case AST_OP_DIV:
665 op_str = "/";
666 goto error_not_supported;
667 case AST_OP_MOD:
668 op_str = "%";
669 goto error_not_supported;
670 case AST_OP_PLUS:
671 op_str = "+";
672 goto error_not_supported;
673 case AST_OP_MINUS:
674 op_str = "-";
675 goto error_not_supported;
676
677 case AST_OP_BIT_RSHIFT:
678 case AST_OP_BIT_LSHIFT:
679 case AST_OP_BIT_AND:
680 case AST_OP_BIT_OR:
681 case AST_OP_BIT_XOR:
682 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
683 if (!lchild)
684 return NULL;
685 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
686 if (!rchild) {
687 filter_free_ir_recursive(lchild);
688 return NULL;
689 }
690 break;
691
692 case AST_OP_EQ:
693 case AST_OP_NE:
694 case AST_OP_GT:
695 case AST_OP_LT:
696 case AST_OP_GE:
697 case AST_OP_LE:
698 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
699 if (!lchild)
700 return NULL;
701 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
702 if (!rchild) {
703 filter_free_ir_recursive(lchild);
704 return NULL;
705 }
706 break;
707
708 case AST_OP_AND:
709 case AST_OP_OR:
710 /*
711 * Both children considered as left, since we need to
712 * populate R0.
713 */
714 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
715 if (!lchild)
716 return NULL;
717 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_LEFT);
718 if (!rchild) {
719 filter_free_ir_recursive(lchild);
720 return NULL;
721 }
722 break;
723 }
724
725 switch (node->u.op.type) {
726 case AST_OP_AND:
727 op = make_op_binary_logical_and(lchild, rchild, side);
728 break;
729 case AST_OP_OR:
730 op = make_op_binary_logical_or(lchild, rchild, side);
731 break;
732 case AST_OP_EQ:
733 op = make_op_binary_eq(lchild, rchild, side);
734 break;
735 case AST_OP_NE:
736 op = make_op_binary_ne(lchild, rchild, side);
737 break;
738 case AST_OP_GT:
739 op = make_op_binary_gt(lchild, rchild, side);
740 break;
741 case AST_OP_LT:
742 op = make_op_binary_lt(lchild, rchild, side);
743 break;
744 case AST_OP_GE:
745 op = make_op_binary_ge(lchild, rchild, side);
746 break;
747 case AST_OP_LE:
748 op = make_op_binary_le(lchild, rchild, side);
749 break;
750 case AST_OP_BIT_RSHIFT:
751 op = make_op_binary_bitwise_rshift(lchild, rchild, side);
752 break;
753 case AST_OP_BIT_LSHIFT:
754 op = make_op_binary_bitwise_lshift(lchild, rchild, side);
755 break;
756 case AST_OP_BIT_AND:
757 op = make_op_binary_bitwise_and(lchild, rchild, side);
758 break;
759 case AST_OP_BIT_OR:
760 op = make_op_binary_bitwise_or(lchild, rchild, side);
761 break;
762 case AST_OP_BIT_XOR:
763 op = make_op_binary_bitwise_xor(lchild, rchild, side);
764 break;
765 default:
766 break;
767 }
768
769 if (!op) {
770 filter_free_ir_recursive(rchild);
771 filter_free_ir_recursive(lchild);
772 }
773 return op;
774
775 error_not_supported:
776 fprintf(stderr, "[error] %s: binary operation '%s' not supported\n",
777 __func__, op_str);
778 return NULL;
779 }
780
781 static
782 struct ir_op *make_unary_op(struct filter_parser_ctx *ctx,
783 struct filter_node *node, enum ir_side side)
784 {
785 switch (node->u.unary_op.type) {
786 case AST_UNARY_UNKNOWN:
787 default:
788 fprintf(stderr, "[error] %s: unknown unary op type\n", __func__);
789 return NULL;
790
791 case AST_UNARY_PLUS:
792 {
793 struct ir_op *op, *child;
794
795 child = generate_ir_recursive(ctx, node->u.unary_op.child,
796 side);
797 if (!child)
798 return NULL;
799 op = make_op_unary_plus(child, side);
800 if (!op) {
801 filter_free_ir_recursive(child);
802 return NULL;
803 }
804 return op;
805 }
806 case AST_UNARY_MINUS:
807 {
808 struct ir_op *op, *child;
809
810 child = generate_ir_recursive(ctx, node->u.unary_op.child,
811 side);
812 if (!child)
813 return NULL;
814 op = make_op_unary_minus(child, side);
815 if (!op) {
816 filter_free_ir_recursive(child);
817 return NULL;
818 }
819 return op;
820 }
821 case AST_UNARY_NOT:
822 {
823 struct ir_op *op, *child;
824
825 child = generate_ir_recursive(ctx, node->u.unary_op.child,
826 side);
827 if (!child)
828 return NULL;
829 op = make_op_unary_not(child, side);
830 if (!op) {
831 filter_free_ir_recursive(child);
832 return NULL;
833 }
834 return op;
835 }
836 case AST_UNARY_BIT_NOT:
837 {
838 struct ir_op *op, *child;
839
840 child = generate_ir_recursive(ctx, node->u.unary_op.child,
841 side);
842 if (!child)
843 return NULL;
844 op = make_op_unary_bit_not(child, side);
845 if (!op) {
846 filter_free_ir_recursive(child);
847 return NULL;
848 }
849 return op;
850 }
851 }
852
853 return NULL;
854 }
855
856 static
857 struct ir_op *generate_ir_recursive(struct filter_parser_ctx *ctx,
858 struct filter_node *node, enum ir_side side)
859 {
860 switch (node->type) {
861 case NODE_UNKNOWN:
862 default:
863 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
864 return NULL;
865
866 case NODE_ROOT:
867 {
868 struct ir_op *op, *child;
869
870 child = generate_ir_recursive(ctx, node->u.root.child,
871 side);
872 if (!child)
873 return NULL;
874 op = make_op_root(child, side);
875 if (!op) {
876 filter_free_ir_recursive(child);
877 return NULL;
878 }
879 return op;
880 }
881 case NODE_EXPRESSION:
882 return make_expression(ctx, node, side);
883 case NODE_OP:
884 return make_op(ctx, node, side);
885 case NODE_UNARY_OP:
886 return make_unary_op(ctx, node, side);
887 }
888 return 0;
889 }
890
891 LTTNG_HIDDEN
892 void filter_ir_free(struct filter_parser_ctx *ctx)
893 {
894 filter_free_ir_recursive(ctx->ir_root);
895 ctx->ir_root = NULL;
896 }
897
898 LTTNG_HIDDEN
899 int filter_visitor_ir_generate(struct filter_parser_ctx *ctx)
900 {
901 struct ir_op *op;
902
903 op = generate_ir_recursive(ctx, &ctx->ast->root, IR_LEFT);
904 if (!op) {
905 return -EINVAL;
906 }
907 ctx->ir_root = op;
908 return 0;
909 }
This page took 0.048456 seconds and 4 git commands to generate.