port: FreeBSD has no ENODATA, alias it to ENOATTR
[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;
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;
661dfdd1
MD
268
269error:
bff988fa 270 free_load_expression(load_exp);
661dfdd1
MD
271 return NULL;
272}
273
274static
bff988fa 275struct ir_op *make_op_load_expression(struct filter_node *node,
661dfdd1
MD
276 enum ir_side side)
277{
278 struct ir_op *op;
279
280 op = calloc(sizeof(struct ir_op), 1);
281 if (!op)
586dc72f 282 return NULL;
661dfdd1 283 op->op = IR_OP_LOAD;
bff988fa 284 op->data_type = IR_DATA_EXPRESSION;
661dfdd1
MD
285 op->signedness = IR_SIGN_DYN;
286 op->side = side;
bff988fa
MD
287 op->u.load.u.expression = create_load_expression(node);
288 if (!op->u.load.u.expression) {
661dfdd1
MD
289 goto error;
290 }
586dc72f 291 return op;
661dfdd1
MD
292
293error:
bff988fa 294 free_load_expression(op->u.load.u.expression);
661dfdd1
MD
295 free(op);
296 return NULL;
586dc72f
MD
297}
298
953192ba
MD
299static
300struct 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
322error:
323 free(op);
324 return NULL;
325}
326
327/*
328 * unary + is pretty much useless.
329 */
330static
331struct 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
337static
338struct 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
344static
345struct 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
116d3c01
MD
351static
352struct 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
953192ba
MD
358static
359struct 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
e90d8561
MD
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) &&
953192ba
MD
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
394error:
395 free(op);
396 return NULL;
397}
398
399static
400struct 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
406static
407struct 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
413static
414struct 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
420static
421struct 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
427static
428struct 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
434static
435struct 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
441static
442struct 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
475error:
476 free(op);
477 return NULL;
478}
479
bff988fa
MD
480static
481struct 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
519error:
520 free(op);
521 return NULL;
522}
523
953192ba
MD
524static
525struct 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
531static
532struct 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
116d3c01
MD
538static
539struct 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
545static
546struct 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
bff988fa
MD
552static
553struct 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
559static
560struct 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
566static
567struct 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
953192ba
MD
573static
574void 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:
9f449915 590 free(op->u.load.u.string.value);
953192ba 591 break;
586dc72f
MD
592 case IR_DATA_FIELD_REF: /* fall-through */
593 case IR_DATA_GET_CONTEXT_REF:
953192ba
MD
594 free(op->u.load.u.ref);
595 break;
bff988fa
MD
596 case IR_DATA_EXPRESSION:
597 free_load_expression(op->u.load.u.expression);
953192ba
MD
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
617static
618struct 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);
e90d8561
MD
632 case AST_EXP_FLOAT_CONSTANT:
633 return make_op_load_float(node->u.expression.u.float_constant,
634 side);
953192ba 635 case AST_EXP_IDENTIFIER:
586dc72f 636 case AST_EXP_GLOBAL_IDENTIFIER:
bff988fa 637 return make_op_load_expression(node, side);
953192ba
MD
638 case AST_EXP_NESTED:
639 return generate_ir_recursive(ctx, node->u.expression.u.child,
640 side);
641 }
642}
643
644static
645struct 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 /*
bff988fa
MD
658 * The following binary operators other than comparators and
659 * logical and/or are not supported yet.
953192ba
MD
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;
bff988fa 676
116d3c01
MD
677 case AST_OP_BIT_RSHIFT:
678 case AST_OP_BIT_LSHIFT:
bff988fa
MD
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;
953192ba
MD
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;
116d3c01
MD
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;
bff988fa
MD
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;
953192ba
MD
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
775error_not_supported:
776 fprintf(stderr, "[error] %s: binary operation '%s' not supported\n",
777 __func__, op_str);
778 return NULL;
779}
780
781static
782struct 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 }
bff988fa 836 case AST_UNARY_BIT_NOT:
ab78f161 837 {
116d3c01
MD
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;
ab78f161 850 }
953192ba 851 }
ab78f161 852
ab78f161 853 return NULL;
953192ba
MD
854}
855
856static
857struct 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
a187da1a 891LTTNG_HIDDEN
953192ba
MD
892void filter_ir_free(struct filter_parser_ctx *ctx)
893{
894 filter_free_ir_recursive(ctx->ir_root);
895 ctx->ir_root = NULL;
896}
897
a187da1a 898LTTNG_HIDDEN
953192ba
MD
899int 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.080927 seconds and 4 git commands to generate.