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