Filter: index array, sequences, implement bitwise binary operators
[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:
87942d06 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
87942d06 143#if 0
953192ba 144static
5590fc2c
MD
145struct ir_op *make_op_load_field_ref(char *string,
146 enum ir_side side)
953192ba
MD
147{
148 struct ir_op *op;
149
150 op = calloc(sizeof(struct ir_op), 1);
151 if (!op)
152 return NULL;
153 op->op = IR_OP_LOAD;
154 op->data_type = IR_DATA_FIELD_REF;
155 op->signedness = IR_SIGN_DYN;
156 op->side = side;
157 op->u.load.u.ref = strdup(string);
158 if (!op->u.load.u.ref) {
5590fc2c
MD
159 goto error;
160 }
161 return op;
162
163error:
164 free(op);
165 return NULL;
166}
87942d06 167#endif
5590fc2c
MD
168
169static
87942d06 170void free_load_expression(struct ir_load_expression *load_expression)
5590fc2c 171{
87942d06 172 struct ir_load_expression_op *exp_op;
5590fc2c 173
87942d06
MD
174 if (!load_expression)
175 return;
176 exp_op = load_expression->child;
177 for (;;) {
178 struct ir_load_expression_op *prev_exp_op;
179
180 if (!exp_op)
181 break;
182 switch (exp_op->type) {
183 case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT:
184 case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT:
185 case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT:
186 case IR_LOAD_EXPRESSION_GET_INDEX:
187 case IR_LOAD_EXPRESSION_LOAD_FIELD:
188 break;
189 case IR_LOAD_EXPRESSION_GET_SYMBOL:
190 free(exp_op->u.symbol);
191 break;
192 }
193 prev_exp_op = exp_op;
194 exp_op = exp_op->next;
195 free(prev_exp_op);
953192ba 196 }
87942d06
MD
197 free(load_expression);
198}
5590fc2c 199
87942d06
MD
200/*
201 * Returns the first node of the chain, after initializing the next
202 * pointers.
203 */
204static
205struct filter_node *load_expression_get_forward_chain(struct filter_node *node)
206{
207 struct filter_node *prev_node;
208
209 for (;;) {
210 assert(node->type == NODE_EXPRESSION);
211 prev_node = node;
212 node = node->u.expression.prev;
213 if (!node) {
214 break;
215 }
216 node->u.expression.next = prev_node;
217 }
218 return prev_node;
953192ba
MD
219}
220
586dc72f 221static
87942d06 222struct ir_load_expression *create_load_expression(struct filter_node *node)
586dc72f 223{
87942d06
MD
224 struct ir_load_expression *load_exp;
225 struct ir_load_expression_op *load_exp_op, *prev_op;
226 char *str;
586dc72f 227
87942d06
MD
228 /* Get forward chain. */
229 node = load_expression_get_forward_chain(node);
230 if (!node)
586dc72f 231 return NULL;
87942d06
MD
232 load_exp = calloc(sizeof(struct ir_load_expression), 1);
233 if (!load_exp)
234 return NULL;
235
236 /* Root */
237 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
238 if (!load_exp_op)
5590fc2c 239 goto error;
87942d06
MD
240 load_exp->child = load_exp_op;
241 str = node->u.expression.u.string;
242 if (!strcmp(str, "$ctx")) {
243 load_exp_op->type = IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT;
244 node = node->u.expression.next;
245 if (!node) {
246 fprintf(stderr, "[error] Expecting identifier after \'%s\'\n", str);
247 goto error;
248 }
249 str = node->u.expression.u.string;
250 } else if (!strcmp(str, "$app")) {
251 load_exp_op->type = IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT;
252 node = node->u.expression.next;
253 if (!node) {
254 fprintf(stderr, "[error] Expecting identifier after \'%s\'\n", str);
255 goto error;
256 }
257 str = node->u.expression.u.string;
258 } else if (str[0] == '$') {
259 fprintf(stderr, "[error] Unexpected identifier \'%s\'\n", str);
260 goto error;
261 } else {
262 load_exp_op->type = IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT;
5590fc2c 263 }
87942d06
MD
264
265 for (;;) {
266 struct filter_node *bracket_node;
267
268 prev_op = load_exp_op;
269 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
270 if (!load_exp_op)
271 goto error;
272 prev_op->next = load_exp_op;
273 load_exp_op->type = IR_LOAD_EXPRESSION_GET_SYMBOL;
274 load_exp_op->u.symbol = strdup(str);
275 if (!load_exp_op->u.symbol)
276 goto error;
277
278 /* Explore brackets from current node. */
279 for (bracket_node = node->u.expression.next_bracket;
280 bracket_node != NULL;
281 bracket_node = bracket_node->u.expression.next_bracket) {
282 prev_op = load_exp_op;
283 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
284 if (!load_exp_op)
285 goto error;
286 prev_op->next = load_exp_op;
287 load_exp_op->type = IR_LOAD_EXPRESSION_GET_INDEX;
288 load_exp_op->u.index = bracket_node->u.expression.u.constant;
289 }
290 /* Go to next chain element. */
291 node = node->u.expression.next;
292 if (!node)
293 break;
294 str = node->u.expression.u.string;
295 }
296 /* Add final load field */
297 prev_op = load_exp_op;
298 load_exp_op = calloc(sizeof(struct ir_load_expression_op), 1);
299 if (!load_exp_op)
300 goto error;
301 prev_op->next = load_exp_op;
302 load_exp_op->type = IR_LOAD_EXPRESSION_LOAD_FIELD;
303 return load_exp;
5590fc2c
MD
304
305error:
87942d06 306 free_load_expression(load_exp);
5590fc2c
MD
307 return NULL;
308}
309
310static
87942d06 311struct ir_op *make_op_load_expression(struct filter_node *node,
5590fc2c
MD
312 enum ir_side side)
313{
314 struct ir_op *op;
315
316 op = calloc(sizeof(struct ir_op), 1);
317 if (!op)
586dc72f 318 return NULL;
5590fc2c 319 op->op = IR_OP_LOAD;
87942d06 320 op->data_type = IR_DATA_EXPRESSION;
5590fc2c
MD
321 op->signedness = IR_SIGN_DYN;
322 op->side = side;
87942d06
MD
323 op->u.load.u.expression = create_load_expression(node);
324 if (!op->u.load.u.expression) {
5590fc2c
MD
325 goto error;
326 }
586dc72f 327 return op;
5590fc2c
MD
328
329error:
87942d06 330 free_load_expression(op->u.load.u.expression);
5590fc2c
MD
331 free(op);
332 return NULL;
586dc72f
MD
333}
334
953192ba
MD
335static
336struct ir_op *make_op_unary(enum unary_op_type unary_op_type,
337 const char *op_str, enum ir_op_signedness signedness,
338 struct ir_op *child, enum ir_side side)
339{
340 struct ir_op *op = NULL;
341
342 if (child->data_type == IR_DATA_STRING) {
343 fprintf(stderr, "[error] unary operation '%s' not allowed on string literal\n", op_str);
344 goto error;
345 }
346
347 op = calloc(sizeof(struct ir_op), 1);
348 if (!op)
349 return NULL;
350 op->op = IR_OP_UNARY;
351 op->data_type = child->data_type;
352 op->signedness = signedness;
353 op->side = side;
354 op->u.unary.type = unary_op_type;
355 op->u.unary.child = child;
356 return op;
357
358error:
359 free(op);
360 return NULL;
361}
362
363/*
364 * unary + is pretty much useless.
365 */
366static
367struct ir_op *make_op_unary_plus(struct ir_op *child, enum ir_side side)
368{
369 return make_op_unary(AST_UNARY_PLUS, "+", child->signedness,
370 child, side);
371}
372
373static
374struct ir_op *make_op_unary_minus(struct ir_op *child, enum ir_side side)
375{
376 return make_op_unary(AST_UNARY_MINUS, "-", child->signedness,
377 child, side);
378}
379
380static
381struct ir_op *make_op_unary_not(struct ir_op *child, enum ir_side side)
382{
383 return make_op_unary(AST_UNARY_NOT, "!", child->signedness,
384 child, side);
385}
386
953192ba
MD
387static
388struct ir_op *make_op_binary_compare(enum op_type bin_op_type,
389 const char *op_str, struct ir_op *left, struct ir_op *right,
390 enum ir_side side)
391{
392 struct ir_op *op = NULL;
393
394 if (left->data_type == IR_DATA_UNKNOWN
395 || right->data_type == IR_DATA_UNKNOWN) {
396 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
397 goto error;
398
399 }
400 if ((left->data_type == IR_DATA_STRING
e90d8561
MD
401 && (right->data_type == IR_DATA_NUMERIC || right->data_type == IR_DATA_FLOAT))
402 || ((left->data_type == IR_DATA_NUMERIC || left->data_type == IR_DATA_FLOAT) &&
953192ba
MD
403 right->data_type == IR_DATA_STRING)) {
404 fprintf(stderr, "[error] binary operation '%s' operand type mismatch\n", op_str);
405 goto error;
406 }
407
408 op = calloc(sizeof(struct ir_op), 1);
409 if (!op)
410 return NULL;
411 op->op = IR_OP_BINARY;
412 op->u.binary.type = bin_op_type;
413 op->u.binary.left = left;
414 op->u.binary.right = right;
415
416 /* we return a boolean, represented as signed numeric */
417 op->data_type = IR_DATA_NUMERIC;
418 op->signedness = IR_SIGNED;
419 op->side = side;
420
421 return op;
422
423error:
424 free(op);
425 return NULL;
426}
427
428static
429struct ir_op *make_op_binary_eq(struct ir_op *left, struct ir_op *right,
430 enum ir_side side)
431{
432 return make_op_binary_compare(AST_OP_EQ, "==", left, right, side);
433}
434
435static
436struct ir_op *make_op_binary_ne(struct ir_op *left, struct ir_op *right,
437 enum ir_side side)
438{
439 return make_op_binary_compare(AST_OP_NE, "!=", left, right, side);
440}
441
442static
443struct ir_op *make_op_binary_gt(struct ir_op *left, struct ir_op *right,
444 enum ir_side side)
445{
446 return make_op_binary_compare(AST_OP_GT, ">", left, right, side);
447}
448
449static
450struct ir_op *make_op_binary_lt(struct ir_op *left, struct ir_op *right,
451 enum ir_side side)
452{
453 return make_op_binary_compare(AST_OP_LT, "<", left, right, side);
454}
455
456static
457struct ir_op *make_op_binary_ge(struct ir_op *left, struct ir_op *right,
458 enum ir_side side)
459{
460 return make_op_binary_compare(AST_OP_GE, ">=", left, right, side);
461}
462
463static
464struct ir_op *make_op_binary_le(struct ir_op *left, struct ir_op *right,
465 enum ir_side side)
466{
467 return make_op_binary_compare(AST_OP_LE, "<=", left, right, side);
468}
469
470static
471struct ir_op *make_op_binary_logical(enum op_type bin_op_type,
472 const char *op_str, struct ir_op *left, struct ir_op *right,
473 enum ir_side side)
474{
475 struct ir_op *op = NULL;
476
477 if (left->data_type == IR_DATA_UNKNOWN
478 || right->data_type == IR_DATA_UNKNOWN) {
479 fprintf(stderr, "[error] binary operation '%s' has unknown operand type\n", op_str);
480 goto error;
481
482 }
483 if (left->data_type == IR_DATA_STRING
484 || right->data_type == IR_DATA_STRING) {
485 fprintf(stderr, "[error] logical binary operation '%s' cannot have string operand\n", op_str);
486 goto error;
487 }
488
489 op = calloc(sizeof(struct ir_op), 1);
490 if (!op)
491 return NULL;
492 op->op = IR_OP_LOGICAL;
493 op->u.binary.type = bin_op_type;
494 op->u.binary.left = left;
495 op->u.binary.right = right;
496
497 /* we return a boolean, represented as signed numeric */
498 op->data_type = IR_DATA_NUMERIC;
499 op->signedness = IR_SIGNED;
500 op->side = side;
501
502 return op;
503
504error:
505 free(op);
506 return NULL;
507}
508
87942d06
MD
509static
510struct ir_op *make_op_binary_bitwise(enum op_type bin_op_type,
511 const char *op_str, struct ir_op *left, struct ir_op *right,
512 enum ir_side side)
513{
514 struct ir_op *op = NULL;
515
516 if (left->data_type == IR_DATA_UNKNOWN
517 || right->data_type == IR_DATA_UNKNOWN) {
518 fprintf(stderr, "[error] bitwise binary operation '%s' has unknown operand type\n", op_str);
519 goto error;
520
521 }
522 if (left->data_type == IR_DATA_STRING
523 || right->data_type == IR_DATA_STRING) {
524 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have string operand\n", op_str);
525 goto error;
526 }
527 if (left->data_type == IR_DATA_FLOAT
528 || right->data_type == IR_DATA_FLOAT) {
529 fprintf(stderr, "[error] bitwise binary operation '%s' cannot have floating point operand\n", op_str);
530 goto error;
531 }
532
533 op = calloc(sizeof(struct ir_op), 1);
534 if (!op)
535 return NULL;
536 op->op = IR_OP_BINARY;
537 op->u.binary.type = bin_op_type;
538 op->u.binary.left = left;
539 op->u.binary.right = right;
540
541 /* we return a signed numeric */
542 op->data_type = IR_DATA_NUMERIC;
543 op->signedness = IR_SIGNED;
544 op->side = side;
545
546 return op;
547
548error:
549 free(op);
550 return NULL;
551}
552
953192ba
MD
553static
554struct ir_op *make_op_binary_logical_and(struct ir_op *left, struct ir_op *right,
555 enum ir_side side)
556{
557 return make_op_binary_logical(AST_OP_AND, "&&", left, right, side);
558}
559
560static
561struct ir_op *make_op_binary_logical_or(struct ir_op *left, struct ir_op *right,
562 enum ir_side side)
563{
564 return make_op_binary_logical(AST_OP_OR, "||", left, right, side);
565}
566
87942d06
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;
87942d06
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:
87942d06
MD
651 case AST_EXP_GLOBAL_IDENTIFIER:
652 return make_op_load_expression(node, side);
653#if 0
5590fc2c
MD
654 switch (node->u.expression.pre_op) {
655 case AST_LINK_UNKNOWN:
656 return make_op_load_field_ref(node->u.expression.u.identifier,
657 side);
658 case AST_LINK_BRACKET:
659 return make_op_load_field_ref_index(node->u.expression.u.identifier,
660 node->u.expression.next,
661 side);
662 default:
953192ba
MD
663 fprintf(stderr, "[error] %s: dotted and dereferenced identifiers not supported\n", __func__);
664 return NULL;
665 }
87942d06
MD
666#endif
667#if 0
586dc72f 668 {
a1f68b22 669 const char *name;
586dc72f 670
a1f68b22
MD
671 /*
672 * We currently only support $ctx (context) and $app
673 * identifiers.
674 */
586dc72f 675 if (strncmp(node->u.expression.u.identifier,
a1f68b22
MD
676 "$ctx.", strlen("$ctx.")) != 0
677 && strncmp(node->u.expression.u.identifier,
678 "$app.", strlen("$app.")) != 0) {
679 fprintf(stderr, "[error] %s: \"%s\" global identifier is unknown. Only \"$ctx\" and \"$app\" are currently implemented.\n", __func__, node->u.expression.u.identifier);
586dc72f
MD
680 return NULL;
681 }
a1f68b22
MD
682 name = strchr(node->u.expression.u.identifier, '.');
683 if (!name) {
684 fprintf(stderr, "[error] %s: Expecting '.'\n", __func__);
586dc72f
MD
685 return NULL;
686 }
a1f68b22
MD
687 name++; /* Skip . */
688 if (!strlen(name)) {
689 fprintf(stderr, "[error] %s: Expecting a context name, e.g. \'$ctx.name\'.\n", __func__);
586dc72f
MD
690 return NULL;
691 }
5590fc2c
MD
692 switch (node->u.expression.pre_op) {
693 case AST_LINK_UNKNOWN:
694 return make_op_load_get_context_ref(node->u.expression.u.identifier,
586dc72f 695 side);
5590fc2c
MD
696 case AST_LINK_BRACKET:
697 return make_op_load_get_context_ref_index(node->u.expression.u.identifier,
698 node->u.expression.next,
699 side);
700 default:
701 fprintf(stderr, "[error] %s: dotted and dereferenced identifiers not supported\n", __func__);
702 return NULL;
703 }
704
586dc72f 705 }
87942d06 706#endif
953192ba
MD
707 case AST_EXP_NESTED:
708 return generate_ir_recursive(ctx, node->u.expression.u.child,
709 side);
710 }
711}
712
713static
714struct ir_op *make_op(struct filter_parser_ctx *ctx,
715 struct filter_node *node, enum ir_side side)
716{
717 struct ir_op *op = NULL, *lchild, *rchild;
718 const char *op_str = "?";
719
720 switch (node->u.op.type) {
721 case AST_OP_UNKNOWN:
722 default:
723 fprintf(stderr, "[error] %s: unknown binary op type\n", __func__);
724 return NULL;
725
726 /*
87942d06
MD
727 * The following binary operators other than comparators and
728 * logical and/or are not supported yet.
953192ba
MD
729 */
730 case AST_OP_MUL:
731 op_str = "*";
732 goto error_not_supported;
733 case AST_OP_DIV:
734 op_str = "/";
735 goto error_not_supported;
736 case AST_OP_MOD:
737 op_str = "%";
738 goto error_not_supported;
739 case AST_OP_PLUS:
740 op_str = "+";
741 goto error_not_supported;
742 case AST_OP_MINUS:
743 op_str = "-";
744 goto error_not_supported;
745 case AST_OP_RSHIFT:
746 op_str = ">>";
747 goto error_not_supported;
748 case AST_OP_LSHIFT:
749 op_str = "<<";
750 goto error_not_supported;
87942d06
MD
751
752 case AST_OP_BIT_AND:
753 case AST_OP_BIT_OR:
754 case AST_OP_BIT_XOR:
755 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
756 if (!lchild)
757 return NULL;
758 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
759 if (!rchild) {
760 filter_free_ir_recursive(lchild);
761 return NULL;
762 }
763 break;
953192ba
MD
764
765 case AST_OP_EQ:
766 case AST_OP_NE:
767 case AST_OP_GT:
768 case AST_OP_LT:
769 case AST_OP_GE:
770 case AST_OP_LE:
771 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
772 if (!lchild)
773 return NULL;
774 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_RIGHT);
775 if (!rchild) {
776 filter_free_ir_recursive(lchild);
777 return NULL;
778 }
779 break;
780
781 case AST_OP_AND:
782 case AST_OP_OR:
783 /*
784 * Both children considered as left, since we need to
785 * populate R0.
786 */
787 lchild = generate_ir_recursive(ctx, node->u.op.lchild, IR_LEFT);
788 if (!lchild)
789 return NULL;
790 rchild = generate_ir_recursive(ctx, node->u.op.rchild, IR_LEFT);
791 if (!rchild) {
792 filter_free_ir_recursive(lchild);
793 return NULL;
794 }
795 break;
796 }
797
798 switch (node->u.op.type) {
799 case AST_OP_AND:
800 op = make_op_binary_logical_and(lchild, rchild, side);
801 break;
802 case AST_OP_OR:
803 op = make_op_binary_logical_or(lchild, rchild, side);
804 break;
805 case AST_OP_EQ:
806 op = make_op_binary_eq(lchild, rchild, side);
807 break;
808 case AST_OP_NE:
809 op = make_op_binary_ne(lchild, rchild, side);
810 break;
811 case AST_OP_GT:
812 op = make_op_binary_gt(lchild, rchild, side);
813 break;
814 case AST_OP_LT:
815 op = make_op_binary_lt(lchild, rchild, side);
816 break;
817 case AST_OP_GE:
818 op = make_op_binary_ge(lchild, rchild, side);
819 break;
820 case AST_OP_LE:
821 op = make_op_binary_le(lchild, rchild, side);
822 break;
87942d06
MD
823 case AST_OP_BIT_AND:
824 op = make_op_binary_bitwise_and(lchild, rchild, side);
825 break;
826 case AST_OP_BIT_OR:
827 op = make_op_binary_bitwise_or(lchild, rchild, side);
828 break;
829 case AST_OP_BIT_XOR:
830 op = make_op_binary_bitwise_xor(lchild, rchild, side);
831 break;
953192ba
MD
832 default:
833 break;
834 }
835
836 if (!op) {
837 filter_free_ir_recursive(rchild);
838 filter_free_ir_recursive(lchild);
839 }
840 return op;
841
842error_not_supported:
843 fprintf(stderr, "[error] %s: binary operation '%s' not supported\n",
844 __func__, op_str);
845 return NULL;
846}
847
848static
849struct ir_op *make_unary_op(struct filter_parser_ctx *ctx,
850 struct filter_node *node, enum ir_side side)
851{
ab78f161
CB
852 const char *op_str = "?";
853
953192ba
MD
854 switch (node->u.unary_op.type) {
855 case AST_UNARY_UNKNOWN:
856 default:
857 fprintf(stderr, "[error] %s: unknown unary op type\n", __func__);
858 return NULL;
859
860 case AST_UNARY_PLUS:
861 {
862 struct ir_op *op, *child;
863
864 child = generate_ir_recursive(ctx, node->u.unary_op.child,
865 side);
866 if (!child)
867 return NULL;
868 op = make_op_unary_plus(child, side);
869 if (!op) {
870 filter_free_ir_recursive(child);
871 return NULL;
872 }
873 return op;
874 }
875 case AST_UNARY_MINUS:
876 {
877 struct ir_op *op, *child;
878
879 child = generate_ir_recursive(ctx, node->u.unary_op.child,
880 side);
881 if (!child)
882 return NULL;
883 op = make_op_unary_minus(child, side);
884 if (!op) {
885 filter_free_ir_recursive(child);
886 return NULL;
887 }
888 return op;
889 }
890 case AST_UNARY_NOT:
891 {
892 struct ir_op *op, *child;
893
894 child = generate_ir_recursive(ctx, node->u.unary_op.child,
895 side);
896 if (!child)
897 return NULL;
898 op = make_op_unary_not(child, side);
899 if (!op) {
900 filter_free_ir_recursive(child);
901 return NULL;
902 }
903 return op;
904 }
87942d06 905 case AST_UNARY_BIT_NOT:
ab78f161
CB
906 {
907 op_str = "~";
908 goto error_not_supported;
909 }
953192ba 910 }
ab78f161
CB
911
912error_not_supported:
913 fprintf(stderr, "[error] %s: unary operation '%s' not supported\n",
914 __func__, op_str);
915 return NULL;
953192ba
MD
916}
917
918static
919struct ir_op *generate_ir_recursive(struct filter_parser_ctx *ctx,
920 struct filter_node *node, enum ir_side side)
921{
922 switch (node->type) {
923 case NODE_UNKNOWN:
924 default:
925 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
926 return NULL;
927
928 case NODE_ROOT:
929 {
930 struct ir_op *op, *child;
931
932 child = generate_ir_recursive(ctx, node->u.root.child,
933 side);
934 if (!child)
935 return NULL;
936 op = make_op_root(child, side);
937 if (!op) {
938 filter_free_ir_recursive(child);
939 return NULL;
940 }
941 return op;
942 }
943 case NODE_EXPRESSION:
944 return make_expression(ctx, node, side);
945 case NODE_OP:
946 return make_op(ctx, node, side);
947 case NODE_UNARY_OP:
948 return make_unary_op(ctx, node, side);
949 }
950 return 0;
951}
952
a187da1a 953LTTNG_HIDDEN
953192ba
MD
954void filter_ir_free(struct filter_parser_ctx *ctx)
955{
956 filter_free_ir_recursive(ctx->ir_root);
957 ctx->ir_root = NULL;
958}
959
a187da1a 960LTTNG_HIDDEN
953192ba
MD
961int filter_visitor_ir_generate(struct filter_parser_ctx *ctx)
962{
963 struct ir_op *op;
964
965 op = generate_ir_recursive(ctx, &ctx->ast->root, IR_LEFT);
966 if (!op) {
967 return -EINVAL;
968 }
969 ctx->ir_root = op;
970 return 0;
971}
This page took 0.090925 seconds and 5 git commands to generate.