Fix: validate that array expression contains constant
[lttng-tools.git] / src / common / filter / filter-visitor-generate-ir.c
CommitLineData
953192ba
MD
1/*
2 * filter-visitor-generate-ir.c
3 *
4 * LTTng filter generate intermediate representation
5 *
ab5be9fa 6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
953192ba 7 *
ab5be9fa 8 * SPDX-License-Identifier: LGPL-2.1-only
953192ba 9 *
953192ba
MD
10 */
11
12#include <stdio.h>
13#include <unistd.h>
14#include <string.h>
15#include <stdlib.h>
16#include <assert.h>
953192ba 17#include <inttypes.h>
953192ba 18#include "filter-ast.h"
95b9bd90 19#include "filter-parser.h"
953192ba
MD
20#include "filter-ir.h"
21
edf4b93e 22#include <common/compat/errno.h>
a187da1a 23#include <common/macros.h>
9f449915 24#include <common/string-utils/string-utils.h>
a187da1a 25
953192ba
MD
26static
27struct ir_op *generate_ir_recursive(struct filter_parser_ctx *ctx,
28 struct filter_node *node, enum ir_side side);
29
30static
31struct 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");
7d8868f9 42 free(op);
953192ba
MD
43 return NULL;
44 case IR_DATA_STRING:
45 fprintf(stderr, "[error] String cannot be root data type\n");
7d8868f9 46 free(op);
953192ba
MD
47 return NULL;
48 case IR_DATA_NUMERIC:
49 case IR_DATA_FIELD_REF:
586dc72f 50 case IR_DATA_GET_CONTEXT_REF:
bff988fa 51 case IR_DATA_EXPRESSION:
953192ba
MD
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
9f449915
PP
63static
64enum 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
953192ba 79static
b53d4e59 80struct ir_op *make_op_load_string(const char *string, enum ir_side side)
953192ba
MD
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;
9f449915
PP
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) {
953192ba
MD
94 free(op);
95 return NULL;
96 }
97 return op;
98}
99
100static
101struct 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
e90d8561
MD
117static
118struct 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
953192ba 133static
bff988fa 134void free_load_expression(struct ir_load_expression *load_expression)
953192ba 135{
bff988fa 136 struct ir_load_expression_op *exp_op;
953192ba 137
bff988fa
MD
138 if (!load_expression)
139 return;
140 exp_op = load_expression->child;
141 for (;;) {
142 struct ir_load_expression_op *prev_exp_op;
661dfdd1 143
bff988fa
MD
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);
661dfdd1
MD
162}
163
bff988fa
MD
164/*
165 * Returns the first node of the chain, after initializing the next
166 * pointers.
167 */
661dfdd1 168static
bff988fa 169struct filter_node *load_expression_get_forward_chain(struct filter_node *node)
661dfdd1 170{
bff988fa 171 struct filter_node *prev_node;
661dfdd1 172
bff988fa
MD
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;
953192ba 181 }
bff988fa 182 return prev_node;
953192ba
MD
183}
184
586dc72f 185static
bff988fa 186struct ir_load_expression *create_load_expression(struct filter_node *node)
586dc72f 187{
bff988fa
MD
188 struct ir_load_expression *load_exp;
189 struct ir_load_expression_op *load_exp_op, *prev_op;
b53d4e59 190 const char *str;
586dc72f 191
bff988fa
MD
192 /* Get forward chain. */
193 node = load_expression_get_forward_chain(node);
194 if (!node)
586dc72f 195 return NULL;
bff988fa
MD
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);
661dfdd1 224 goto error;
bff988fa
MD
225 } else {
226 load_exp_op->type = IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT;
661dfdd1 227 }
bff988fa
MD
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;
4062406e
MD
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 }
bff988fa
MD
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;
661dfdd1
MD
273
274error:
bff988fa 275 free_load_expression(load_exp);
661dfdd1
MD
276 return NULL;
277}
278
279static
bff988fa 280struct ir_op *make_op_load_expression(struct filter_node *node,
661dfdd1
MD
281 enum ir_side side)
282{
283 struct ir_op *op;
284
285 op = calloc(sizeof(struct ir_op), 1);
286 if (!op)
586dc72f 287 return NULL;
661dfdd1 288 op->op = IR_OP_LOAD;
bff988fa 289 op->data_type = IR_DATA_EXPRESSION;
661dfdd1
MD
290 op->signedness = IR_SIGN_DYN;
291 op->side = side;
bff988fa
MD
292 op->u.load.u.expression = create_load_expression(node);
293 if (!op->u.load.u.expression) {
661dfdd1
MD
294 goto error;
295 }
586dc72f 296 return op;
661dfdd1
MD
297
298error:
bff988fa 299 free_load_expression(op->u.load.u.expression);
661dfdd1
MD
300 free(op);
301 return NULL;
586dc72f
MD
302}
303
953192ba
MD
304static
305struct 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
327error:
328 free(op);
329 return NULL;
330}
331
332/*
333 * unary + is pretty much useless.
334 */
335static
336struct 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
342static
343struct 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
349static
350struct 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
116d3c01
MD
356static
357struct 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
953192ba
MD
363static
364struct 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
e90d8561
MD
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) &&
953192ba
MD
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
399error:
400 free(op);
401 return NULL;
402}
403
404static
405struct 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
411static
412struct 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
418static
419struct 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
425static
426struct 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
432static
433struct 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
439static
440struct 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
446static
447struct 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
480error:
481 free(op);
482 return NULL;
483}
484
bff988fa
MD
485static
486struct 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
524error:
525 free(op);
526 return NULL;
527}
528
953192ba
MD
529static
530struct 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
536static
537struct 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
116d3c01
MD
543static
544struct 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
550static
551struct 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
bff988fa
MD
557static
558struct 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
564static
565struct 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
571static
572struct 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
953192ba
MD
578static
579void 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:
9f449915 595 free(op->u.load.u.string.value);
953192ba 596 break;
586dc72f
MD
597 case IR_DATA_FIELD_REF: /* fall-through */
598 case IR_DATA_GET_CONTEXT_REF:
953192ba
MD
599 free(op->u.load.u.ref);
600 break;
bff988fa
MD
601 case IR_DATA_EXPRESSION:
602 free_load_expression(op->u.load.u.expression);
953192ba
MD
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
622static
623struct 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);
e90d8561
MD
637 case AST_EXP_FLOAT_CONSTANT:
638 return make_op_load_float(node->u.expression.u.float_constant,
639 side);
953192ba 640 case AST_EXP_IDENTIFIER:
586dc72f 641 case AST_EXP_GLOBAL_IDENTIFIER:
bff988fa 642 return make_op_load_expression(node, side);
953192ba
MD
643 case AST_EXP_NESTED:
644 return generate_ir_recursive(ctx, node->u.expression.u.child,
645 side);
646 }
647}
648
649static
650struct 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 /*
bff988fa
MD
663 * The following binary operators other than comparators and
664 * logical and/or are not supported yet.
953192ba
MD
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;
bff988fa 681
116d3c01
MD
682 case AST_OP_BIT_RSHIFT:
683 case AST_OP_BIT_LSHIFT:
bff988fa
MD
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;
953192ba
MD
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;
116d3c01
MD
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;
bff988fa
MD
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;
953192ba
MD
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
780error_not_supported:
781 fprintf(stderr, "[error] %s: binary operation '%s' not supported\n",
782 __func__, op_str);
783 return NULL;
784}
785
786static
787struct 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 }
bff988fa 841 case AST_UNARY_BIT_NOT:
ab78f161 842 {
116d3c01
MD
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;
ab78f161 855 }
953192ba 856 }
ab78f161 857
ab78f161 858 return NULL;
953192ba
MD
859}
860
861static
862struct 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
a187da1a 896LTTNG_HIDDEN
953192ba
MD
897void filter_ir_free(struct filter_parser_ctx *ctx)
898{
899 filter_free_ir_recursive(ctx->ir_root);
900 ctx->ir_root = NULL;
901}
902
a187da1a 903LTTNG_HIDDEN
953192ba
MD
904int 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.083334 seconds and 4 git commands to generate.