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