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
38 static int is_integer_type(const type_t *type);
39 static int is_float_type(const type_t *type);
41 expr_t *make_expr(enum expr_type type)
43 expr_t *e = xmalloc(sizeof(expr_t));
52 expr_t *make_exprl(enum expr_type type, long val)
54 expr_t *e = xmalloc(sizeof(expr_t));
59 /* check for numeric constant */
60 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
62 /* make sure true/false value is valid */
63 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
70 expr_t *make_exprd(enum expr_type type, double val)
72 expr_t *e = xmalloc(sizeof(expr_t));
81 expr_t *make_exprs(enum expr_type type, char *val)
84 e = xmalloc(sizeof(expr_t));
89 /* check for predefined constants */
94 var_t *c = find_const(val, 0);
100 e->cval = c->eval->cval;
106 error_loc("empty character constant\n");
108 error_loc("multi-character constants are endian dependent\n");
121 expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
126 if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
127 error_loc("invalid storage class for type expression\n");
131 e = xmalloc(sizeof(expr_t));
136 if (type == EXPR_SIZEOF)
138 /* only do this for types that should be the same on all platforms */
139 if (is_integer_type(tref) || is_float_type(tref))
141 unsigned int align = 0;
143 e->cval = type_memsize(tref, &align);
146 /* check for cast of constant expression */
147 if (type == EXPR_CAST && expr->is_const)
150 e->cval = expr->cval;
156 expr_t *make_expr1(enum expr_type type, expr_t *expr)
159 e = xmalloc(sizeof(expr_t));
164 /* check for compile-time optimization */
171 e->cval = !expr->cval;
174 e->cval = +expr->cval;
177 e->cval = -expr->cval;
180 e->cval = ~expr->cval;
190 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
193 e = xmalloc(sizeof(expr_t));
198 /* check for compile-time optimization */
199 if (expr1->is_const && expr2->is_const)
205 e->cval = expr1->cval + expr2->cval;
208 e->cval = expr1->cval - expr2->cval;
211 if (expr2->cval == 0)
213 error_loc("divide by zero in expression\n");
217 e->cval = expr1->cval % expr2->cval;
220 e->cval = expr1->cval * expr2->cval;
223 if (expr2->cval == 0)
225 error_loc("divide by zero in expression\n");
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;
247 e->cval = expr1->cval && expr2->cval;
250 e->cval = expr1->cval ^ expr2->cval;
253 e->cval = expr1->cval == expr2->cval;
255 case EXPR_INEQUALITY:
256 e->cval = expr1->cval != expr2->cval;
259 e->cval = expr1->cval > expr2->cval;
262 e->cval = expr1->cval < expr2->cval;
265 e->cval = expr1->cval >= expr2->cval;
268 e->cval = expr1->cval <= expr2->cval;
278 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
281 e = xmalloc(sizeof(expr_t));
287 /* check for compile-time optimization */
288 if (expr1->is_const && expr2->is_const && expr3->is_const)
294 e->cval = expr1->cval ? expr2->cval : expr3->cval;
304 struct expression_type
306 int is_variable; /* is the expression resolved to a variable? */
307 int is_temporary; /* should the type be freed? */
311 static int is_integer_type(const type_t *type)
313 switch (type_get_type(type))
318 switch (type_basic_get_type(type))
320 case TYPE_BASIC_INT8:
321 case TYPE_BASIC_INT16:
322 case TYPE_BASIC_INT32:
323 case TYPE_BASIC_INT64:
325 case TYPE_BASIC_INT3264:
326 case TYPE_BASIC_CHAR:
327 case TYPE_BASIC_HYPER:
328 case TYPE_BASIC_BYTE:
329 case TYPE_BASIC_WCHAR:
330 case TYPE_BASIC_ERROR_STATUS_T:
332 case TYPE_BASIC_FLOAT:
333 case TYPE_BASIC_DOUBLE:
334 case TYPE_BASIC_HANDLE:
343 static int is_float_type(const type_t *type)
345 return (type_get_type(type) == TYPE_BASIC &&
346 (type_basic_get_type(type) == TYPE_BASIC_FLOAT ||
347 type_basic_get_type(type) == TYPE_BASIC_DOUBLE));
350 static void check_scalar_type(const struct expr_loc *expr_loc,
351 const type_t *cont_type, const type_t *type)
353 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
354 !is_float_type(type)))
355 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
356 expr_loc->attr ? " for attribute " : "",
357 expr_loc->attr ? expr_loc->attr : "");
360 static void check_arithmetic_type(const struct expr_loc *expr_loc,
361 const type_t *cont_type, const type_t *type)
363 if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
364 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
365 expr_loc->attr ? " for attribute " : "",
366 expr_loc->attr ? expr_loc->attr : "");
369 static void check_integer_type(const struct expr_loc *expr_loc,
370 const type_t *cont_type, const type_t *type)
372 if (!cont_type || !is_integer_type(type))
373 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
374 expr_loc->attr ? " for attribute " : "",
375 expr_loc->attr ? expr_loc->attr : "");
378 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
382 const var_list_t *fields = NULL;
384 *found_in_cont_type = 0;
388 switch (type_get_type(cont_type))
391 fields = type_function_get_args(cont_type);
394 fields = type_struct_get_fields(cont_type);
397 case TYPE_ENCAPSULATED_UNION:
398 fields = type_union_get_cases(cont_type);
412 /* shouldn't get here because of using type_get_type above */
418 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
419 if (field->name && !strcmp(identifier, field->name))
422 *found_in_cont_type = 1;
428 var_t *const_var = find_const(identifier, 0);
429 if (const_var) type = const_var->type;
435 static int is_valid_member_operand(const type_t *type)
437 switch (type_get_type(type))
448 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
449 const type_t *cont_type,
452 struct expression_type result;
453 result.is_variable = FALSE;
454 result.is_temporary = FALSE;
463 result.is_variable = FALSE;
464 result.is_temporary = FALSE;
465 result.type = type_new_int(TYPE_BASIC_INT, 0);
468 result.is_variable = FALSE;
469 result.is_temporary = TRUE;
470 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
473 result.is_variable = FALSE;
474 result.is_temporary = TRUE;
475 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
478 result.is_variable = FALSE;
479 result.is_temporary = TRUE;
480 result.type = type_new_int(TYPE_BASIC_CHAR, 0);
483 result.is_variable = FALSE;
484 result.is_temporary = TRUE;
485 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
487 case EXPR_IDENTIFIER:
489 int found_in_cont_type;
490 result.is_variable = TRUE;
491 result.is_temporary = FALSE;
492 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
495 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
496 e->u.sval, expr_loc->attr ? " for attribute " : "",
497 expr_loc->attr ? expr_loc->attr : "");
502 result = resolve_expression(expr_loc, cont_type, e->ref);
503 check_scalar_type(expr_loc, cont_type, result.type);
504 result.is_variable = FALSE;
505 result.is_temporary = FALSE;
506 result.type = type_new_int(TYPE_BASIC_INT, 0);
509 result = resolve_expression(expr_loc, cont_type, e->ref);
510 check_integer_type(expr_loc, cont_type, result.type);
511 result.is_variable = FALSE;
515 result = resolve_expression(expr_loc, cont_type, e->ref);
516 check_arithmetic_type(expr_loc, cont_type, result.type);
517 result.is_variable = FALSE;
520 result = resolve_expression(expr_loc, cont_type, e->ref);
521 if (!result.is_variable)
522 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
523 expr_loc->attr ? " for attribute " : "",
524 expr_loc->attr ? expr_loc->attr : "");
525 result.is_variable = FALSE;
526 result.is_temporary = TRUE;
527 result.type = type_new_pointer(RPC_FC_UP, result.type, NULL);
530 result = resolve_expression(expr_loc, cont_type, e->ref);
531 if (result.type && is_ptr(result.type))
532 result.type = type_pointer_get_ref(result.type);
533 else if(result.type && is_array(result.type)
534 && type_array_is_decl_as_ptr(result.type))
535 result.type = type_array_get_element(result.type);
537 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
538 expr_loc->attr ? " for attribute " : "",
539 expr_loc->attr ? expr_loc->attr : "");
542 result = resolve_expression(expr_loc, cont_type, e->ref);
543 result.type = e->u.tref;
546 result.is_variable = FALSE;
547 result.is_temporary = FALSE;
548 result.type = type_new_int(TYPE_BASIC_INT, 0);
561 struct expression_type result_right;
562 result = resolve_expression(expr_loc, cont_type, e->ref);
563 result.is_variable = FALSE;
564 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
565 /* FIXME: these checks aren't strict enough for some of the operators */
566 check_scalar_type(expr_loc, cont_type, result.type);
567 check_scalar_type(expr_loc, cont_type, result_right.type);
573 case EXPR_INEQUALITY:
579 struct expression_type result_left, result_right;
580 result_left = resolve_expression(expr_loc, cont_type, e->ref);
581 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
582 check_scalar_type(expr_loc, cont_type, result_left.type);
583 check_scalar_type(expr_loc, cont_type, result_right.type);
584 result.is_variable = FALSE;
585 result.is_temporary = FALSE;
586 result.type = type_new_int(TYPE_BASIC_INT, 0);
590 result = resolve_expression(expr_loc, cont_type, e->ref);
591 if (result.type && is_valid_member_operand(result.type))
592 result = resolve_expression(expr_loc, result.type, e->u.ext);
594 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",
595 expr_loc->attr ? " for attribute " : "",
596 expr_loc->attr ? expr_loc->attr : "");
600 struct expression_type result_first, result_second, result_third;
601 result_first = resolve_expression(expr_loc, cont_type, e->ref);
602 check_scalar_type(expr_loc, cont_type, result_first.type);
603 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
604 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
605 /* FIXME: determine the correct return type */
606 result = result_second;
607 result.is_variable = FALSE;
611 result = resolve_expression(expr_loc, cont_type, e->ref);
612 if (result.type && is_array(result.type))
614 struct expression_type index_result;
615 result.type = type_array_get_element(result.type);
616 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
617 if (!index_result.type || !is_integer_type(index_result.type))
618 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
619 expr_loc->attr ? " for attribute " : "",
620 expr_loc->attr ? expr_loc->attr : "");
623 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
624 expr_loc->attr ? " for attribute " : "",
625 expr_loc->attr ? expr_loc->attr : "");
631 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
633 struct expression_type expr_type;
634 expr_type = resolve_expression(expr_loc, cont_type, expr);
635 return expr_type.type;
638 void write_expr(FILE *h, const expr_t *e, int brackets,
639 int toplevel, const char *toplevel_prefix,
640 const type_t *cont_type, const char *local_var_prefix)
647 fprintf(h, "%lu", e->u.lval);
650 fprintf(h, "0x%lx", e->u.lval);
653 fprintf(h, "%#.15g", e->u.dval);
661 case EXPR_IDENTIFIER:
662 if (toplevel && toplevel_prefix && cont_type)
664 int found_in_cont_type;
665 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
666 if (found_in_cont_type)
668 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
672 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
675 fprintf(h, "\"%s\"", e->u.sval);
678 fprintf(h, "L\"%s\"", e->u.sval);
681 fprintf(h, "'%s'", e->u.sval);
685 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
689 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
693 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
697 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
701 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
705 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
709 write_type_decl(h, e->u.tref, NULL);
711 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
714 fprintf(h, "sizeof(");
715 write_type_decl(h, e->u.tref, NULL);
731 case EXPR_INEQUALITY:
736 if (brackets) fprintf(h, "(");
737 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
740 case EXPR_SHL: fprintf(h, " << "); break;
741 case EXPR_SHR: fprintf(h, " >> "); break;
742 case EXPR_MOD: fprintf(h, " %% "); break;
743 case EXPR_MUL: fprintf(h, " * "); break;
744 case EXPR_DIV: fprintf(h, " / "); break;
745 case EXPR_ADD: fprintf(h, " + "); break;
746 case EXPR_SUB: fprintf(h, " - "); break;
747 case EXPR_AND: fprintf(h, " & "); break;
748 case EXPR_OR: fprintf(h, " | "); break;
749 case EXPR_LOGOR: fprintf(h, " || "); break;
750 case EXPR_LOGAND: fprintf(h, " && "); break;
751 case EXPR_XOR: fprintf(h, " ^ "); break;
752 case EXPR_EQUALITY: fprintf(h, " == "); break;
753 case EXPR_INEQUALITY: fprintf(h, " != "); break;
754 case EXPR_GTR: fprintf(h, " > "); break;
755 case EXPR_LESS: fprintf(h, " < "); break;
756 case EXPR_GTREQL: fprintf(h, " >= "); break;
757 case EXPR_LESSEQL: fprintf(h, " <= "); break;
760 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
761 if (brackets) fprintf(h, ")");
764 if (brackets) fprintf(h, "(");
765 if (e->ref->type == EXPR_PPTR)
767 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
772 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
775 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
776 if (brackets) fprintf(h, ")");
779 if (brackets) fprintf(h, "(");
780 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
782 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
784 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
785 if (brackets) fprintf(h, ")");
788 if (brackets) fprintf(h, "(");
789 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
791 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
793 if (brackets) fprintf(h, ")");
798 /* This is actually fairly involved to implement precisely, due to the
799 effects attributes may have and things like that. Right now this is
800 only used for optimization, so just check for a very small set of
801 criteria that guarantee the types are equivalent; assume every thing
802 else is different. */
803 static int compare_type(const type_t *a, const type_t *b)
808 && strcmp(a->name, b->name) == 0))
810 /* Ordering doesn't need to be implemented yet. */
814 int compare_expr(const expr_t *a, const expr_t *b)
818 if (a->type != b->type)
819 return a->type - b->type;
826 return a->u.lval - b->u.lval;
828 return a->u.dval - b->u.dval;
829 case EXPR_IDENTIFIER:
833 return strcmp(a->u.sval, b->u.sval);
835 ret = compare_expr(a->ref, b->ref);
838 ret = compare_expr(a->u.ext, b->u.ext);
841 return compare_expr(a->ext2, b->ext2);
857 case EXPR_INEQUALITY:
862 ret = compare_expr(a->ref, b->ref);
865 return compare_expr(a->u.ext, b->u.ext);
867 ret = compare_type(a->u.tref, b->u.tref);
877 return compare_expr(a->ref, b->ref);
879 return compare_type(a->u.tref, b->u.tref);