2 * Expression Abstract Syntax Tree Functions
4 * Copyright 2002 Ove Kaaven
5 * Copyright 2006-2008 Robert Shearman
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
36 expr_t *make_expr(enum expr_type type)
38 expr_t *e = xmalloc(sizeof(expr_t));
47 expr_t *make_exprl(enum expr_type type, long val)
49 expr_t *e = xmalloc(sizeof(expr_t));
54 /* check for numeric constant */
55 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
57 /* make sure true/false value is valid */
58 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
65 expr_t *make_exprd(enum expr_type type, double val)
67 expr_t *e = xmalloc(sizeof(expr_t));
76 expr_t *make_exprs(enum expr_type type, char *val)
79 e = xmalloc(sizeof(expr_t));
84 /* check for predefined constants */
85 if (type == EXPR_IDENTIFIER)
87 var_t *c = find_const(val, 0);
93 e->cval = c->eval->cval;
99 expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr)
102 e = xmalloc(sizeof(expr_t));
107 /* check for cast of constant expression */
108 if (type == EXPR_SIZEOF)
128 case RPC_FC_ERROR_STATUS_T:
139 if (type == EXPR_CAST && expr->is_const)
142 e->cval = expr->cval;
147 expr_t *make_expr1(enum expr_type type, expr_t *expr)
150 e = xmalloc(sizeof(expr_t));
155 /* check for compile-time optimization */
162 e->cval = !expr->cval;
165 e->cval = +expr->cval;
168 e->cval = -expr->cval;
171 e->cval = ~expr->cval;
181 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
184 e = xmalloc(sizeof(expr_t));
189 /* check for compile-time optimization */
190 if (expr1->is_const && expr2->is_const)
196 e->cval = expr1->cval + expr2->cval;
199 e->cval = expr1->cval - expr2->cval;
202 if (expr2->cval == 0)
204 error_loc("divide by zero in expression\n");
208 e->cval = expr1->cval % expr2->cval;
211 e->cval = expr1->cval * expr2->cval;
214 if (expr2->cval == 0)
216 error_loc("divide by zero in expression\n");
220 e->cval = expr1->cval / expr2->cval;
223 e->cval = expr1->cval | expr2->cval;
226 e->cval = expr1->cval & expr2->cval;
229 e->cval = expr1->cval << expr2->cval;
232 e->cval = expr1->cval >> expr2->cval;
235 e->cval = expr1->cval || expr2->cval;
238 e->cval = expr1->cval && expr2->cval;
241 e->cval = expr1->cval ^ expr2->cval;
244 e->cval = expr1->cval == expr2->cval;
246 case EXPR_INEQUALITY:
247 e->cval = expr1->cval != expr2->cval;
250 e->cval = expr1->cval > expr2->cval;
253 e->cval = expr1->cval < expr2->cval;
256 e->cval = expr1->cval >= expr2->cval;
259 e->cval = expr1->cval <= expr2->cval;
269 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
272 e = xmalloc(sizeof(expr_t));
278 /* check for compile-time optimization */
279 if (expr1->is_const && expr2->is_const && expr3->is_const)
285 e->cval = expr1->cval ? expr2->cval : expr3->cval;
295 struct expression_type
297 int is_variable; /* is the expression resolved to a variable? */
298 int is_temporary; /* should the type be freed? */
302 static int is_integer_type(const type_t *type)
316 case RPC_FC_UINT3264:
326 static void check_scalar_type(const struct expr_loc *expr_loc,
327 const type_t *cont_type, const type_t *type)
329 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
330 type->type != RPC_FC_FLOAT &&
331 type->type != RPC_FC_DOUBLE))
332 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
333 expr_loc->attr ? " for attribute " : "",
334 expr_loc->attr ? expr_loc->attr : "");
337 static void check_arithmetic_type(const struct expr_loc *expr_loc,
338 const type_t *cont_type, const type_t *type)
340 if (!cont_type || (!is_integer_type(type) &&
341 type->type != RPC_FC_FLOAT &&
342 type->type != RPC_FC_DOUBLE))
343 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
344 expr_loc->attr ? " for attribute " : "",
345 expr_loc->attr ? expr_loc->attr : "");
348 static void check_integer_type(const struct expr_loc *expr_loc,
349 const type_t *cont_type, const type_t *type)
351 if (!cont_type || !is_integer_type(type))
352 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
353 expr_loc->attr ? " for attribute " : "",
354 expr_loc->attr ? expr_loc->attr : "");
357 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
361 const var_list_t *fields = NULL;
363 *found_in_cont_type = 0;
365 if (cont_type && (cont_type->type == RPC_FC_FUNCTION || is_struct(cont_type->type)))
366 fields = cont_type->fields_or_args;
367 else if (cont_type && is_union(cont_type->type))
369 if (cont_type->type == RPC_FC_ENCAPSULATED_UNION)
371 const var_t *uv = LIST_ENTRY(list_tail(cont_type->fields_or_args), const var_t, entry);
372 fields = uv->type->fields_or_args;
375 fields = cont_type->fields_or_args;
378 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
379 if (field->name && !strcmp(identifier, field->name))
382 *found_in_cont_type = 1;
388 var_t *const_var = find_const(identifier, 0);
389 if (const_var) type = const_var->type;
395 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
396 const type_t *cont_type,
399 struct expression_type result;
400 result.is_variable = FALSE;
401 result.is_temporary = FALSE;
410 result.is_variable = FALSE;
411 result.is_temporary = FALSE;
412 result.type = find_type("int", 0);
415 result.is_variable = FALSE;
416 result.is_temporary = TRUE;
417 result.type = make_type(RPC_FC_RP, find_type("char", 0));
420 result.is_variable = FALSE;
421 result.is_temporary = TRUE;
422 result.type = make_type(RPC_FC_RP, find_type("wchar_t", 0));
425 result.is_variable = FALSE;
426 result.is_temporary = FALSE;
427 result.type = find_type("double", 0);
429 case EXPR_IDENTIFIER:
431 int found_in_cont_type;
432 result.is_variable = TRUE;
433 result.is_temporary = FALSE;
434 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
437 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
438 e->u.sval, expr_loc->attr ? " for attribute " : "",
439 expr_loc->attr ? expr_loc->attr : "");
444 result = resolve_expression(expr_loc, cont_type, e->ref);
445 check_scalar_type(expr_loc, cont_type, result.type);
446 result.is_variable = FALSE;
447 result.is_temporary = FALSE;
448 result.type = find_type("int", 0);
451 result = resolve_expression(expr_loc, cont_type, e->ref);
452 check_integer_type(expr_loc, cont_type, result.type);
453 result.is_variable = FALSE;
457 result = resolve_expression(expr_loc, cont_type, e->ref);
458 check_arithmetic_type(expr_loc, cont_type, result.type);
459 result.is_variable = FALSE;
462 result = resolve_expression(expr_loc, cont_type, e->ref);
463 if (!result.is_variable)
464 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
465 expr_loc->attr ? " for attribute " : "",
466 expr_loc->attr ? expr_loc->attr : "");
467 result.is_variable = FALSE;
468 result.is_temporary = TRUE;
469 result.type = make_type(RPC_FC_RP, result.type);
472 result = resolve_expression(expr_loc, cont_type, e->ref);
473 if (result.type && is_ptr(result.type))
474 result.type = result.type->ref;
476 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
477 expr_loc->attr ? " for attribute " : "",
478 expr_loc->attr ? expr_loc->attr : "");
481 result = resolve_expression(expr_loc, cont_type, e->ref);
482 result.type = e->u.tref;
485 result.is_variable = FALSE;
486 result.is_temporary = FALSE;
487 result.type = find_type("int", 0);
500 struct expression_type result_right;
501 result = resolve_expression(expr_loc, cont_type, e->ref);
502 result.is_variable = FALSE;
503 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
504 /* FIXME: these checks aren't strict enough for some of the operators */
505 check_scalar_type(expr_loc, cont_type, result.type);
506 check_scalar_type(expr_loc, cont_type, result_right.type);
512 case EXPR_INEQUALITY:
518 struct expression_type result_left, result_right;
519 result_left = resolve_expression(expr_loc, cont_type, e->ref);
520 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
521 check_scalar_type(expr_loc, cont_type, result_left.type);
522 check_scalar_type(expr_loc, cont_type, result_right.type);
523 result.is_variable = FALSE;
524 result.is_temporary = FALSE;
525 result.type = find_type("int", 0);
529 result = resolve_expression(expr_loc, cont_type, e->ref);
530 if (result.type && (is_struct(result.type->type) || is_union(result.type->type) || result.type->type == RPC_FC_ENUM16 || result.type->type == RPC_FC_ENUM32))
531 result = resolve_expression(expr_loc, result.type, e->u.ext);
533 error_loc_info(&expr_loc->v->loc_info, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",
534 expr_loc->attr ? " for attribute " : "",
535 expr_loc->attr ? expr_loc->attr : "");
539 struct expression_type result_first, result_second, result_third;
540 result_first = resolve_expression(expr_loc, cont_type, e->ref);
541 check_scalar_type(expr_loc, cont_type, result_first.type);
542 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
543 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
544 /* FIXME: determine the correct return type */
545 result = result_second;
546 result.is_variable = FALSE;
550 result = resolve_expression(expr_loc, cont_type, e->ref);
551 if (result.type && is_array(result.type))
553 struct expression_type index_result;
554 result.type = result.type->ref;
555 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
556 if (!index_result.type || !is_integer_type(index_result.type))
557 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
558 expr_loc->attr ? " for attribute " : "",
559 expr_loc->attr ? expr_loc->attr : "");
562 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
563 expr_loc->attr ? " for attribute " : "",
564 expr_loc->attr ? expr_loc->attr : "");
570 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
572 struct expression_type expr_type;
573 expr_type = resolve_expression(expr_loc, cont_type, expr);
574 return expr_type.type;
577 void write_expr(FILE *h, const expr_t *e, int brackets,
578 int toplevel, const char *toplevel_prefix,
579 const type_t *cont_type)
586 fprintf(h, "%lu", e->u.lval);
589 fprintf(h, "0x%lx", e->u.lval);
592 fprintf(h, "%#.15g", e->u.dval);
600 case EXPR_IDENTIFIER:
601 if (toplevel && toplevel_prefix && cont_type)
603 int found_in_cont_type;
604 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
605 if (found_in_cont_type) fprintf(h, "%s", toplevel_prefix);
607 fprintf(h, "%s", e->u.sval);
610 fprintf(h, "\"%s\"", e->u.sval);
613 fprintf(h, "L\"%s\"", e->u.sval);
617 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
621 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
625 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
629 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
633 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
637 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
641 write_type_decl(h, e->u.tref, NULL);
643 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
646 fprintf(h, "sizeof(");
647 write_type_decl(h, e->u.tref, NULL);
663 case EXPR_INEQUALITY:
668 if (brackets) fprintf(h, "(");
669 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
672 case EXPR_SHL: fprintf(h, " << "); break;
673 case EXPR_SHR: fprintf(h, " >> "); break;
674 case EXPR_MOD: fprintf(h, " %% "); break;
675 case EXPR_MUL: fprintf(h, " * "); break;
676 case EXPR_DIV: fprintf(h, " / "); break;
677 case EXPR_ADD: fprintf(h, " + "); break;
678 case EXPR_SUB: fprintf(h, " - "); break;
679 case EXPR_AND: fprintf(h, " & "); break;
680 case EXPR_OR: fprintf(h, " | "); break;
681 case EXPR_LOGOR: fprintf(h, " || "); break;
682 case EXPR_LOGAND: fprintf(h, " && "); break;
683 case EXPR_XOR: fprintf(h, " ^ "); break;
684 case EXPR_EQUALITY: fprintf(h, " == "); break;
685 case EXPR_INEQUALITY: fprintf(h, " != "); break;
686 case EXPR_GTR: fprintf(h, " > "); break;
687 case EXPR_LESS: fprintf(h, " < "); break;
688 case EXPR_GTREQL: fprintf(h, " >= "); break;
689 case EXPR_LESSEQL: fprintf(h, " <= "); break;
692 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type);
693 if (brackets) fprintf(h, ")");
696 if (brackets) fprintf(h, "(");
697 if (e->ref->type == EXPR_PPTR)
699 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type);
704 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
707 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type);
708 if (brackets) fprintf(h, ")");
711 if (brackets) fprintf(h, "(");
712 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
714 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type);
716 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type);
717 if (brackets) fprintf(h, ")");
720 if (brackets) fprintf(h, "(");
721 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type);
723 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type);
725 if (brackets) fprintf(h, ")");
730 /* This is actually fairly involved to implement precisely, due to the
731 effects attributes may have and things like that. Right now this is
732 only used for optimization, so just check for a very small set of
733 criteria that guarantee the types are equivalent; assume every thing
734 else is different. */
735 static int compare_type(const type_t *a, const type_t *b)
740 && strcmp(a->name, b->name) == 0))
742 /* Ordering doesn't need to be implemented yet. */
746 int compare_expr(const expr_t *a, const expr_t *b)
750 if (a->type != b->type)
751 return a->type - b->type;
758 return a->u.lval - b->u.lval;
760 return a->u.dval - b->u.dval;
761 case EXPR_IDENTIFIER:
764 return strcmp(a->u.sval, b->u.sval);
766 ret = compare_expr(a->ref, b->ref);
769 ret = compare_expr(a->u.ext, b->u.ext);
772 return compare_expr(a->ext2, b->ext2);
788 case EXPR_INEQUALITY:
793 ret = compare_expr(a->ref, b->ref);
796 return compare_expr(a->u.ext, b->u.ext);
798 ret = compare_type(a->u.tref, b->u.tref);
808 return compare_expr(a->ref, b->ref);
810 return compare_type(a->u.tref, b->u.tref);