Filters: generate backward compatible "get field" and "get context" instructions
[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
953192ba
MD
361static
362struct ir_op *make_op_binary_compare(enum op_type bin_op_type,
363 const char *op_str, struct ir_op *left, struct ir_op *right,
364 enum ir_side side)
365{
366 struct ir_op *op = NULL;
367
368 if (left->data_type == IR_DATA_UNKNOWN
369 || right->data_type == IR_DATA_UNKNOWN) {
370 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
371 goto error;
372
373 }
374 if ((left->data_type == IR_DATA_STRING
e90d8561
MD
375 && (right->data_type == IR_DATA_NUMERIC || right->data_type == IR_DATA_FLOAT))
376 || ((left->data_type == IR_DATA_NUMERIC || left->data_type == IR_DATA_FLOAT) &&
953192ba
MD
377 right->data_type == IR_DATA_STRING)) {
378 fprintf(stderr, "[error] binary operation '%s' operand type mismatch\n", op_str);
379 goto error;
380 }
381
382 op = calloc(sizeof(struct ir_op), 1);
383 if (!op)
384 return NULL;
385 op->op = IR_OP_BINARY;
386 op->u.binary.type = bin_op_type;
387 op->u.binary.left = left;
388 op->u.binary.right = right;
389
390 /* we return a boolean, represented as signed numeric */
391 op->data_type = IR_DATA_NUMERIC;
392 op->signedness = IR_SIGNED;
393 op->side = side;
394
395 return op;
396
397error:
398 free(op);
399 return NULL;
400}
401
402static
403struct ir_op *make_op_binary_eq(struct ir_op *left, struct ir_op *right,
404 enum ir_side side)
405{
406 return make_op_binary_compare(AST_OP_EQ, "==", left, right, side);
407}
408
409static
410struct ir_op *make_op_binary_ne(struct ir_op *left, struct ir_op *right,
411 enum ir_side side)
412{
413 return make_op_binary_compare(AST_OP_NE, "!=", left, right, side);
414}
415
416static
417struct ir_op *make_op_binary_gt(struct ir_op *left, struct ir_op *right,
418 enum ir_side side)
419{
420 return make_op_binary_compare(AST_OP_GT, ">", left, right, side);
421}
422
423static
424struct ir_op *make_op_binary_lt(struct ir_op *left, struct ir_op *right,
425 enum ir_side side)
426{
427 return make_op_binary_compare(AST_OP_LT, "<", left, right, side);
428}
429
430static
431struct ir_op *make_op_binary_ge(struct ir_op *left, struct ir_op *right,
432 enum ir_side side)
433{
434 return make_op_binary_compare(AST_OP_GE, ">=", left, right, side);
435}
436
437static
438struct ir_op *make_op_binary_le(struct ir_op *left, struct ir_op *right,
439 enum ir_side side)
440{
441 return make_op_binary_compare(AST_OP_LE, "<=", left, right, side);
442}
443
444static
445struct ir_op *make_op_binary_logical(enum op_type bin_op_type,
446 const char *op_str, struct ir_op *left, struct ir_op *right,
447 enum ir_side side)
448{
449 struct ir_op *op = NULL;
450
451 if (left->data_type == IR_DATA_UNKNOWN
452 || right->data_type == IR_DATA_UNKNOWN) {
453 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
454 goto error;
455
456 }
457 if (left->data_type == IR_DATA_STRING
458 || right->data_type == IR_DATA_STRING) {
459 fprintf(stderr, "[error] logical binary operation '%s' cannot have string operand\n", op_str);
460 goto error;
461 }
462
463 op = calloc(sizeof(struct ir_op), 1);
464 if (!op)
465 return NULL;
466 op->op = IR_OP_LOGICAL;
467 op->u.binary.type = bin_op_type;
468 op->u.binary.left = left;
469 op->u.binary.right = right;
470
471 /* we return a boolean, represented as signed numeric */
472 op->data_type = IR_DATA_NUMERIC;
473 op->signedness = IR_SIGNED;
474 op->side = side;
475
476 return op;
477
478error:
479 free(op);
480 return NULL;
481}
482
bff988fa
MD
483static
484struct ir_op *make_op_binary_bitwise(enum op_type bin_op_type,
485 const char *op_str, struct ir_op *left, struct ir_op *right,
486 enum ir_side side)
487{
488 struct ir_op *op = NULL;
489
490 if (left->data_type == IR_DATA_UNKNOWN
491 || right->data_type == IR_DATA_UNKNOWN) {
492 fprintf(stderr, "[error] bitwise binary operation '%s' has unknown operand type\n", op_str);
493 goto error;
494
495 }
496 if (left->data_type == IR_DATA_STRING
497 || right->data_type == IR_DATA_STRING) {
498 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have string operand\n", op_str);
499 goto error;
500 }
501 if (left->data_type == IR_DATA_FLOAT
502 || right->data_type == IR_DATA_FLOAT) {
503 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have floating point operand\n", op_str);
504 goto error;
505 }
506
507 op = calloc(sizeof(struct ir_op), 1);
508 if (!op)
509 return NULL;
510 op->op = IR_OP_BINARY;
511 op->u.binary.type = bin_op_type;
512 op->u.binary.left = left;
513 op->u.binary.right = right;
514
515 /* we return a signed numeric */
516 op->data_type = IR_DATA_NUMERIC;
517 op->signedness = IR_SIGNED;
518 op->side = side;
519
520 return op;
521
522error:
523 free(op);
524 return NULL;
525}
526
953192ba
MD
527static
528struct ir_op *make_op_binary_logical_and(struct ir_op *left, struct ir_op *right,
529 enum ir_side side)
530{
531 return make_op_binary_logical(AST_OP_AND, "&&", left, right, side);
532}
533
534static
535struct ir_op *make_op_binary_logical_or(struct ir_op *left, struct ir_op *right,
536 enum ir_side side)
537{
538 return make_op_binary_logical(AST_OP_OR, "||", left, right, side);
539}
540
bff988fa
MD
541static
542struct ir_op *make_op_binary_bitwise_and(struct ir_op *left, struct ir_op *right,
543 enum ir_side side)
544{
545 return make_op_binary_bitwise(AST_OP_BIT_AND, "&", left, right, side);
546}
547
548static
549struct ir_op *make_op_binary_bitwise_or(struct ir_op *left, struct ir_op *right,
550 enum ir_side side)
551{
552 return make_op_binary_bitwise(AST_OP_BIT_OR, "|", left, right, side);
553}
554
555static
556struct ir_op *make_op_binary_bitwise_xor(struct ir_op *left, struct ir_op *right,
557 enum ir_side side)
558{
559 return make_op_binary_bitwise(AST_OP_BIT_XOR, "^", left, right, side);
560}
561
953192ba
MD
562static
563void filter_free_ir_recursive(struct ir_op *op)
564{
565 if (!op)
566 return;
567 switch (op->op) {
568 case IR_OP_UNKNOWN:
569 default:
570 fprintf(stderr, "[error] Unknown op type in %s\n",
571 __func__);
572 break;
573 case IR_OP_ROOT:
574 filter_free_ir_recursive(op->u.root.child);
575 break;
576 case IR_OP_LOAD:
577 switch (op->data_type) {
578 case IR_DATA_STRING:
9f449915 579 free(op->u.load.u.string.value);
953192ba 580 break;
586dc72f
MD
581 case IR_DATA_FIELD_REF: /* fall-through */
582 case IR_DATA_GET_CONTEXT_REF:
953192ba
MD
583 free(op->u.load.u.ref);
584 break;
bff988fa
MD
585 case IR_DATA_EXPRESSION:
586 free_load_expression(op->u.load.u.expression);
953192ba
MD
587 default:
588 break;
589 }
590 break;
591 case IR_OP_UNARY:
592 filter_free_ir_recursive(op->u.unary.child);
593 break;
594 case IR_OP_BINARY:
595 filter_free_ir_recursive(op->u.binary.left);
596 filter_free_ir_recursive(op->u.binary.right);
597 break;
598 case IR_OP_LOGICAL:
599 filter_free_ir_recursive(op->u.logical.left);
600 filter_free_ir_recursive(op->u.logical.right);
601 break;
602 }
603 free(op);
604}
605
606static
607struct ir_op *make_expression(struct filter_parser_ctx *ctx,
608 struct filter_node *node, enum ir_side side)
609{
610 switch (node->u.expression.type) {
611 case AST_EXP_UNKNOWN:
612 default:
613 fprintf(stderr, "[error] %s: unknown expression type\n", __func__);
614 return NULL;
615
616 case AST_EXP_STRING:
617 return make_op_load_string(node->u.expression.u.string, side);
618 case AST_EXP_CONSTANT:
619 return make_op_load_numeric(node->u.expression.u.constant,
620 side);
e90d8561
MD
621 case AST_EXP_FLOAT_CONSTANT:
622 return make_op_load_float(node->u.expression.u.float_constant,
623 side);
953192ba 624 case AST_EXP_IDENTIFIER:
586dc72f 625 case AST_EXP_GLOBAL_IDENTIFIER:
bff988fa 626 return make_op_load_expression(node, side);
953192ba
MD
627 case AST_EXP_NESTED:
628 return generate_ir_recursive(ctx, node->u.expression.u.child,
629 side);
630 }
631}
632
633static
634struct ir_op *make_op(struct filter_parser_ctx *ctx,
635 struct filter_node *node, enum ir_side side)
636{
637 struct ir_op *op = NULL, *lchild, *rchild;
638 const char *op_str = "?";
639
640 switch (node->u.op.type) {
641 case AST_OP_UNKNOWN:
642 default:
643 fprintf(stderr, "[error] %s: unknown binary op type\n", __func__);
644 return NULL;
645
646 /*
bff988fa
MD
647 * The following binary operators other than comparators and
648 * logical and/or are not supported yet.
953192ba
MD
649 */
650 case AST_OP_MUL:
651 op_str = "*";
652 goto error_not_supported;
653 case AST_OP_DIV:
654 op_str = "/";
655 goto error_not_supported;
656 case AST_OP_MOD:
657 op_str = "%";
658 goto error_not_supported;
659 case AST_OP_PLUS:
660 op_str = "+";
661 goto error_not_supported;
662 case AST_OP_MINUS:
663 op_str = "-";
664 goto error_not_supported;
665 case AST_OP_RSHIFT:
666 op_str = ">>";
667 goto error_not_supported;
668 case AST_OP_LSHIFT:
669 op_str = "<<";
670 goto error_not_supported;
bff988fa
MD
671
672 case AST_OP_BIT_AND:
673 case AST_OP_BIT_OR:
674 case AST_OP_BIT_XOR:
675 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
676 if (!lchild)
677 return NULL;
678 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
679 if (!rchild) {
680 filter_free_ir_recursive(lchild);
681 return NULL;
682 }
683 break;
953192ba
MD
684
685 case AST_OP_EQ:
686 case AST_OP_NE:
687 case AST_OP_GT:
688 case AST_OP_LT:
689 case AST_OP_GE:
690 case AST_OP_LE:
691 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
692 if (!lchild)
693 return NULL;
694 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
695 if (!rchild) {
696 filter_free_ir_recursive(lchild);
697 return NULL;
698 }
699 break;
700
701 case AST_OP_AND:
702 case AST_OP_OR:
703 /*
704 * Both children considered as left, since we need to
705 * populate R0.
706 */
707 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
708 if (!lchild)
709 return NULL;
710 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_LEFT);
711 if (!rchild) {
712 filter_free_ir_recursive(lchild);
713 return NULL;
714 }
715 break;
716 }
717
718 switch (node->u.op.type) {
719 case AST_OP_AND:
720 op = make_op_binary_logical_and(lchild, rchild, side);
721 break;
722 case AST_OP_OR:
723 op = make_op_binary_logical_or(lchild, rchild, side);
724 break;
725 case AST_OP_EQ:
726 op = make_op_binary_eq(lchild, rchild, side);
727 break;
728 case AST_OP_NE:
729 op = make_op_binary_ne(lchild, rchild, side);
730 break;
731 case AST_OP_GT:
732 op = make_op_binary_gt(lchild, rchild, side);
733 break;
734 case AST_OP_LT:
735 op = make_op_binary_lt(lchild, rchild, side);
736 break;
737 case AST_OP_GE:
738 op = make_op_binary_ge(lchild, rchild, side);
739 break;
740 case AST_OP_LE:
741 op = make_op_binary_le(lchild, rchild, side);
742 break;
bff988fa
MD
743 case AST_OP_BIT_AND:
744 op = make_op_binary_bitwise_and(lchild, rchild, side);
745 break;
746 case AST_OP_BIT_OR:
747 op = make_op_binary_bitwise_or(lchild, rchild, side);
748 break;
749 case AST_OP_BIT_XOR:
750 op = make_op_binary_bitwise_xor(lchild, rchild, side);
751 break;
953192ba
MD
752 default:
753 break;
754 }
755
756 if (!op) {
757 filter_free_ir_recursive(rchild);
758 filter_free_ir_recursive(lchild);
759 }
760 return op;
761
762error_not_supported:
763 fprintf(stderr, "[error] %s: binary operation '%s' not supported\n",
764 __func__, op_str);
765 return NULL;
766}
767
768static
769struct ir_op *make_unary_op(struct filter_parser_ctx *ctx,
770 struct filter_node *node, enum ir_side side)
771{
ab78f161
CB
772 const char *op_str = "?";
773
953192ba
MD
774 switch (node->u.unary_op.type) {
775 case AST_UNARY_UNKNOWN:
776 default:
777 fprintf(stderr, "[error] %s: unknown unary op type\n", __func__);
778 return NULL;
779
780 case AST_UNARY_PLUS:
781 {
782 struct ir_op *op, *child;
783
784 child = generate_ir_recursive(ctx, node->u.unary_op.child,
785 side);
786 if (!child)
787 return NULL;
788 op = make_op_unary_plus(child, side);
789 if (!op) {
790 filter_free_ir_recursive(child);
791 return NULL;
792 }
793 return op;
794 }
795 case AST_UNARY_MINUS:
796 {
797 struct ir_op *op, *child;
798
799 child = generate_ir_recursive(ctx, node->u.unary_op.child,
800 side);
801 if (!child)
802 return NULL;
803 op = make_op_unary_minus(child, side);
804 if (!op) {
805 filter_free_ir_recursive(child);
806 return NULL;
807 }
808 return op;
809 }
810 case AST_UNARY_NOT:
811 {
812 struct ir_op *op, *child;
813
814 child = generate_ir_recursive(ctx, node->u.unary_op.child,
815 side);
816 if (!child)
817 return NULL;
818 op = make_op_unary_not(child, side);
819 if (!op) {
820 filter_free_ir_recursive(child);
821 return NULL;
822 }
823 return op;
824 }
bff988fa 825 case AST_UNARY_BIT_NOT:
ab78f161
CB
826 {
827 op_str = "~";
828 goto error_not_supported;
829 }
953192ba 830 }
ab78f161
CB
831
832error_not_supported:
833 fprintf(stderr, "[error] %s: unary operation '%s' not supported\n",
834 __func__, op_str);
835 return NULL;
953192ba
MD
836}
837
838static
839struct ir_op *generate_ir_recursive(struct filter_parser_ctx *ctx,
840 struct filter_node *node, enum ir_side side)
841{
842 switch (node->type) {
843 case NODE_UNKNOWN:
844 default:
845 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
846 return NULL;
847
848 case NODE_ROOT:
849 {
850 struct ir_op *op, *child;
851
852 child = generate_ir_recursive(ctx, node->u.root.child,
853 side);
854 if (!child)
855 return NULL;
856 op = make_op_root(child, side);
857 if (!op) {
858 filter_free_ir_recursive(child);
859 return NULL;
860 }
861 return op;
862 }
863 case NODE_EXPRESSION:
864 return make_expression(ctx, node, side);
865 case NODE_OP:
866 return make_op(ctx, node, side);
867 case NODE_UNARY_OP:
868 return make_unary_op(ctx, node, side);
869 }
870 return 0;
871}
872
a187da1a 873LTTNG_HIDDEN
953192ba
MD
874void filter_ir_free(struct filter_parser_ctx *ctx)
875{
876 filter_free_ir_recursive(ctx->ir_root);
877 ctx->ir_root = NULL;
878}
879
a187da1a 880LTTNG_HIDDEN
953192ba
MD
881int filter_visitor_ir_generate(struct filter_parser_ctx *ctx)
882{
883 struct ir_op *op;
884
885 op = generate_ir_recursive(ctx, &ctx->ast->root, IR_LEFT);
886 if (!op) {
887 return -EINVAL;
888 }
889 ctx->ir_root = op;
890 return 0;
891}
This page took 0.140187 seconds and 5 git commands to generate.