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 */
90 if (type
== EXPR_IDENTIFIER
)
92 var_t
*c
= find_const(val
, 0);
98 e
->cval
= c
->eval
->cval
;
104 expr_t
*make_exprt(enum expr_type type
, type_t
*tref
, expr_t
*expr
)
107 e
= xmalloc(sizeof(expr_t
));
112 if (type
== EXPR_SIZEOF
)
114 /* only do this for types that should be the same on all platforms */
115 if (is_integer_type(tref
) || is_float_type(tref
))
117 unsigned int align
= 0;
119 e
->cval
= type_memsize(tref
, &align
);
122 /* check for cast of constant expression */
123 if (type
== EXPR_CAST
&& expr
->is_const
)
126 e
->cval
= expr
->cval
;
131 expr_t
*make_expr1(enum expr_type type
, expr_t
*expr
)
134 e
= xmalloc(sizeof(expr_t
));
139 /* check for compile-time optimization */
146 e
->cval
= !expr
->cval
;
149 e
->cval
= +expr
->cval
;
152 e
->cval
= -expr
->cval
;
155 e
->cval
= ~expr
->cval
;
165 expr_t
*make_expr2(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
)
168 e
= xmalloc(sizeof(expr_t
));
173 /* check for compile-time optimization */
174 if (expr1
->is_const
&& expr2
->is_const
)
180 e
->cval
= expr1
->cval
+ expr2
->cval
;
183 e
->cval
= expr1
->cval
- expr2
->cval
;
186 if (expr2
->cval
== 0)
188 error_loc("divide by zero in expression\n");
192 e
->cval
= expr1
->cval
% expr2
->cval
;
195 e
->cval
= expr1
->cval
* expr2
->cval
;
198 if (expr2
->cval
== 0)
200 error_loc("divide by zero in expression\n");
204 e
->cval
= expr1
->cval
/ expr2
->cval
;
207 e
->cval
= expr1
->cval
| expr2
->cval
;
210 e
->cval
= expr1
->cval
& expr2
->cval
;
213 e
->cval
= expr1
->cval
<< expr2
->cval
;
216 e
->cval
= expr1
->cval
>> expr2
->cval
;
219 e
->cval
= expr1
->cval
|| expr2
->cval
;
222 e
->cval
= expr1
->cval
&& expr2
->cval
;
225 e
->cval
= expr1
->cval
^ expr2
->cval
;
228 e
->cval
= expr1
->cval
== expr2
->cval
;
230 case EXPR_INEQUALITY
:
231 e
->cval
= expr1
->cval
!= expr2
->cval
;
234 e
->cval
= expr1
->cval
> expr2
->cval
;
237 e
->cval
= expr1
->cval
< expr2
->cval
;
240 e
->cval
= expr1
->cval
>= expr2
->cval
;
243 e
->cval
= expr1
->cval
<= expr2
->cval
;
253 expr_t
*make_expr3(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
, expr_t
*expr3
)
256 e
= xmalloc(sizeof(expr_t
));
262 /* check for compile-time optimization */
263 if (expr1
->is_const
&& expr2
->is_const
&& expr3
->is_const
)
269 e
->cval
= expr1
->cval
? expr2
->cval
: expr3
->cval
;
279 struct expression_type
281 int is_variable
; /* is the expression resolved to a variable? */
282 int is_temporary
; /* should the type be freed? */
286 static int is_integer_type(const type_t
*type
)
288 switch (type_get_type(type
))
293 switch (type_basic_get_type(type
))
295 case TYPE_BASIC_INT8
:
296 case TYPE_BASIC_INT16
:
297 case TYPE_BASIC_INT32
:
298 case TYPE_BASIC_INT64
:
300 case TYPE_BASIC_CHAR
:
301 case TYPE_BASIC_HYPER
:
302 case TYPE_BASIC_BYTE
:
303 case TYPE_BASIC_WCHAR
:
304 case TYPE_BASIC_ERROR_STATUS_T
:
314 static int is_float_type(const type_t
*type
)
316 return (type_get_type(type
) == TYPE_BASIC
&&
317 (type_basic_get_type(type
) == TYPE_BASIC_FLOAT
||
318 type_basic_get_type(type
) == TYPE_BASIC_DOUBLE
));
321 static void check_scalar_type(const struct expr_loc
*expr_loc
,
322 const type_t
*cont_type
, const type_t
*type
)
324 if (!cont_type
|| (!is_integer_type(type
) && !is_ptr(type
) &&
325 !is_float_type(type
)))
326 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
327 expr_loc
->attr
? " for attribute " : "",
328 expr_loc
->attr
? expr_loc
->attr
: "");
331 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
332 const type_t
*cont_type
, const type_t
*type
)
334 if (!cont_type
|| (!is_integer_type(type
) && !is_float_type(type
)))
335 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
336 expr_loc
->attr
? " for attribute " : "",
337 expr_loc
->attr
? expr_loc
->attr
: "");
340 static void check_integer_type(const struct expr_loc
*expr_loc
,
341 const type_t
*cont_type
, const type_t
*type
)
343 if (!cont_type
|| !is_integer_type(type
))
344 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
345 expr_loc
->attr
? " for attribute " : "",
346 expr_loc
->attr
? expr_loc
->attr
: "");
349 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
353 const var_list_t
*fields
= NULL
;
355 *found_in_cont_type
= 0;
359 switch (type_get_type(cont_type
))
362 fields
= type_function_get_args(cont_type
);
365 fields
= type_struct_get_fields(cont_type
);
368 case TYPE_ENCAPSULATED_UNION
:
369 fields
= type_union_get_cases(cont_type
);
382 /* shouldn't get here because of using type_get_type above */
388 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
389 if (field
->name
&& !strcmp(identifier
, field
->name
))
392 *found_in_cont_type
= 1;
398 var_t
*const_var
= find_const(identifier
, 0);
399 if (const_var
) type
= const_var
->type
;
405 static int is_valid_member_operand(const type_t
*type
)
407 switch (type_get_type(type
))
418 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
419 const type_t
*cont_type
,
422 struct expression_type result
;
423 result
.is_variable
= FALSE
;
424 result
.is_temporary
= FALSE
;
433 result
.is_variable
= FALSE
;
434 result
.is_temporary
= FALSE
;
435 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
438 result
.is_variable
= FALSE
;
439 result
.is_temporary
= TRUE
;
440 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_CHAR
, 0), NULL
);
443 result
.is_variable
= FALSE
;
444 result
.is_temporary
= TRUE
;
445 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_WCHAR
, 0), NULL
);
448 result
.is_variable
= FALSE
;
449 result
.is_temporary
= TRUE
;
450 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
452 case EXPR_IDENTIFIER
:
454 int found_in_cont_type
;
455 result
.is_variable
= TRUE
;
456 result
.is_temporary
= FALSE
;
457 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
460 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
461 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
462 expr_loc
->attr
? expr_loc
->attr
: "");
467 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
468 check_scalar_type(expr_loc
, cont_type
, result
.type
);
469 result
.is_variable
= FALSE
;
470 result
.is_temporary
= FALSE
;
471 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
474 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
475 check_integer_type(expr_loc
, cont_type
, result
.type
);
476 result
.is_variable
= FALSE
;
480 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
481 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
482 result
.is_variable
= FALSE
;
485 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
486 if (!result
.is_variable
)
487 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
488 expr_loc
->attr
? " for attribute " : "",
489 expr_loc
->attr
? expr_loc
->attr
: "");
490 result
.is_variable
= FALSE
;
491 result
.is_temporary
= TRUE
;
492 result
.type
= type_new_pointer(RPC_FC_UP
, result
.type
, NULL
);
495 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
496 if (result
.type
&& is_ptr(result
.type
))
497 result
.type
= type_pointer_get_ref(result
.type
);
498 else if(result
.type
&& is_array(result
.type
)
499 && type_array_is_decl_as_ptr(result
.type
))
500 result
.type
= type_array_get_element(result
.type
);
502 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
503 expr_loc
->attr
? " for attribute " : "",
504 expr_loc
->attr
? expr_loc
->attr
: "");
507 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
508 result
.type
= e
->u
.tref
;
511 result
.is_variable
= FALSE
;
512 result
.is_temporary
= FALSE
;
513 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
526 struct expression_type result_right
;
527 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
528 result
.is_variable
= FALSE
;
529 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
530 /* FIXME: these checks aren't strict enough for some of the operators */
531 check_scalar_type(expr_loc
, cont_type
, result
.type
);
532 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
538 case EXPR_INEQUALITY
:
544 struct expression_type result_left
, result_right
;
545 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
546 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
547 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
548 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
549 result
.is_variable
= FALSE
;
550 result
.is_temporary
= FALSE
;
551 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
555 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
556 if (result
.type
&& is_valid_member_operand(result
.type
))
557 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
559 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",
560 expr_loc
->attr
? " for attribute " : "",
561 expr_loc
->attr
? expr_loc
->attr
: "");
565 struct expression_type result_first
, result_second
, result_third
;
566 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
567 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
568 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
569 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
570 /* FIXME: determine the correct return type */
571 result
= result_second
;
572 result
.is_variable
= FALSE
;
576 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
577 if (result
.type
&& is_array(result
.type
))
579 struct expression_type index_result
;
580 result
.type
= type_array_get_element(result
.type
);
581 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
582 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
583 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
584 expr_loc
->attr
? " for attribute " : "",
585 expr_loc
->attr
? expr_loc
->attr
: "");
588 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
589 expr_loc
->attr
? " for attribute " : "",
590 expr_loc
->attr
? expr_loc
->attr
: "");
596 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
598 struct expression_type expr_type
;
599 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
600 return expr_type
.type
;
603 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
604 int toplevel
, const char *toplevel_prefix
,
605 const type_t
*cont_type
, const char *local_var_prefix
)
612 fprintf(h
, "%lu", e
->u
.lval
);
615 fprintf(h
, "0x%lx", e
->u
.lval
);
618 fprintf(h
, "%#.15g", e
->u
.dval
);
626 case EXPR_IDENTIFIER
:
627 if (toplevel
&& toplevel_prefix
&& cont_type
)
629 int found_in_cont_type
;
630 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
631 if (found_in_cont_type
)
633 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
637 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
640 fprintf(h
, "\"%s\"", e
->u
.sval
);
643 fprintf(h
, "L\"%s\"", e
->u
.sval
);
647 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
651 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
655 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
659 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
663 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
667 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
671 write_type_decl(h
, e
->u
.tref
, NULL
);
673 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
676 fprintf(h
, "sizeof(");
677 write_type_decl(h
, e
->u
.tref
, NULL
);
693 case EXPR_INEQUALITY
:
698 if (brackets
) fprintf(h
, "(");
699 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
702 case EXPR_SHL
: fprintf(h
, " << "); break;
703 case EXPR_SHR
: fprintf(h
, " >> "); break;
704 case EXPR_MOD
: fprintf(h
, " %% "); break;
705 case EXPR_MUL
: fprintf(h
, " * "); break;
706 case EXPR_DIV
: fprintf(h
, " / "); break;
707 case EXPR_ADD
: fprintf(h
, " + "); break;
708 case EXPR_SUB
: fprintf(h
, " - "); break;
709 case EXPR_AND
: fprintf(h
, " & "); break;
710 case EXPR_OR
: fprintf(h
, " | "); break;
711 case EXPR_LOGOR
: fprintf(h
, " || "); break;
712 case EXPR_LOGAND
: fprintf(h
, " && "); break;
713 case EXPR_XOR
: fprintf(h
, " ^ "); break;
714 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
715 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
716 case EXPR_GTR
: fprintf(h
, " > "); break;
717 case EXPR_LESS
: fprintf(h
, " < "); break;
718 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
719 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
722 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
723 if (brackets
) fprintf(h
, ")");
726 if (brackets
) fprintf(h
, "(");
727 if (e
->ref
->type
== EXPR_PPTR
)
729 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
734 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
737 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
738 if (brackets
) fprintf(h
, ")");
741 if (brackets
) fprintf(h
, "(");
742 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
744 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
746 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
747 if (brackets
) fprintf(h
, ")");
750 if (brackets
) fprintf(h
, "(");
751 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
753 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
755 if (brackets
) fprintf(h
, ")");
760 /* This is actually fairly involved to implement precisely, due to the
761 effects attributes may have and things like that. Right now this is
762 only used for optimization, so just check for a very small set of
763 criteria that guarantee the types are equivalent; assume every thing
764 else is different. */
765 static int compare_type(const type_t
*a
, const type_t
*b
)
770 && strcmp(a
->name
, b
->name
) == 0))
772 /* Ordering doesn't need to be implemented yet. */
776 int compare_expr(const expr_t
*a
, const expr_t
*b
)
780 if (a
->type
!= b
->type
)
781 return a
->type
- b
->type
;
788 return a
->u
.lval
- b
->u
.lval
;
790 return a
->u
.dval
- b
->u
.dval
;
791 case EXPR_IDENTIFIER
:
794 return strcmp(a
->u
.sval
, b
->u
.sval
);
796 ret
= compare_expr(a
->ref
, b
->ref
);
799 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
802 return compare_expr(a
->ext2
, b
->ext2
);
818 case EXPR_INEQUALITY
:
823 ret
= compare_expr(a
->ref
, b
->ref
);
826 return compare_expr(a
->u
.ext
, b
->u
.ext
);
828 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
838 return compare_expr(a
->ref
, b
->ref
);
840 return compare_type(a
->u
.tref
, b
->u
.tref
);