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
)
40 switch (type_get_type(type
))
45 switch (type_basic_get_type(type
))
48 case TYPE_BASIC_INT16
:
49 case TYPE_BASIC_INT32
:
50 case TYPE_BASIC_INT64
:
52 case TYPE_BASIC_INT3264
:
54 case TYPE_BASIC_HYPER
:
56 case TYPE_BASIC_WCHAR
:
57 case TYPE_BASIC_ERROR_STATUS_T
:
59 case TYPE_BASIC_FLOAT
:
60 case TYPE_BASIC_DOUBLE
:
61 case TYPE_BASIC_HANDLE
:
70 static int is_signed_integer_type(const type_t
*type
)
72 switch (type_get_type(type
))
77 switch (type_basic_get_type(type
))
80 case TYPE_BASIC_INT16
:
81 case TYPE_BASIC_INT32
:
82 case TYPE_BASIC_INT64
:
84 case TYPE_BASIC_INT3264
:
85 return type_basic_get_sign(type
) < 0;
88 case TYPE_BASIC_HYPER
:
90 case TYPE_BASIC_WCHAR
:
91 case TYPE_BASIC_ERROR_STATUS_T
:
92 case TYPE_BASIC_FLOAT
:
93 case TYPE_BASIC_DOUBLE
:
94 case TYPE_BASIC_HANDLE
:
102 static int is_float_type(const type_t
*type
)
104 return (type_get_type(type
) == TYPE_BASIC
&&
105 (type_basic_get_type(type
) == TYPE_BASIC_FLOAT
||
106 type_basic_get_type(type
) == TYPE_BASIC_DOUBLE
));
109 expr_t
*make_expr(enum expr_type type
)
111 expr_t
*e
= xmalloc(sizeof(expr_t
));
120 expr_t
*make_exprl(enum expr_type type
, int val
)
122 expr_t
*e
= xmalloc(sizeof(expr_t
));
127 /* check for numeric constant */
128 if (type
== EXPR_NUM
|| type
== EXPR_HEXNUM
|| type
== EXPR_TRUEFALSE
)
130 /* make sure true/false value is valid */
131 assert(type
!= EXPR_TRUEFALSE
|| val
== 0 || val
== 1);
138 expr_t
*make_exprd(enum expr_type type
, double val
)
140 expr_t
*e
= xmalloc(sizeof(expr_t
));
149 expr_t
*make_exprs(enum expr_type type
, char *val
)
152 e
= xmalloc(sizeof(expr_t
));
157 /* check for predefined constants */
160 case EXPR_IDENTIFIER
:
162 var_t
*c
= find_const(val
, 0);
168 e
->cval
= c
->eval
->cval
;
174 error_loc("empty character constant\n");
176 error_loc("multi-character constants are endian dependent\n");
189 expr_t
*make_exprt(enum expr_type type
, var_t
*var
, expr_t
*expr
)
194 if (var
->stgclass
!= STG_NONE
&& var
->stgclass
!= STG_REGISTER
)
195 error_loc("invalid storage class for type expression\n");
199 e
= xmalloc(sizeof(expr_t
));
204 if (type
== EXPR_SIZEOF
)
206 /* only do this for types that should be the same on all platforms */
207 if (is_integer_type(tref
) || is_float_type(tref
))
210 e
->cval
= type_memsize(tref
);
213 /* check for cast of constant expression */
214 if (type
== EXPR_CAST
&& expr
->is_const
)
216 if (is_integer_type(tref
))
218 unsigned int cast_type_bits
= type_memsize(tref
) * 8;
219 unsigned int cast_mask
;
222 if (is_signed_integer_type(tref
))
224 cast_mask
= (1 << (cast_type_bits
- 1)) - 1;
225 if (expr
->cval
& (1 << (cast_type_bits
- 1)))
226 e
->cval
= -((-expr
->cval
) & cast_mask
);
228 e
->cval
= expr
->cval
& cast_mask
;
232 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
233 cast_mask
= ((1 << (cast_type_bits
- 1)) - 1) |
234 1 << (cast_type_bits
- 1);
235 e
->cval
= expr
->cval
& cast_mask
;
241 e
->cval
= expr
->cval
;
248 expr_t
*make_expr1(enum expr_type type
, expr_t
*expr
)
251 e
= xmalloc(sizeof(expr_t
));
256 /* check for compile-time optimization */
263 e
->cval
= !expr
->cval
;
266 e
->cval
= +expr
->cval
;
269 e
->cval
= -expr
->cval
;
272 e
->cval
= ~expr
->cval
;
282 expr_t
*make_expr2(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
)
285 e
= xmalloc(sizeof(expr_t
));
290 /* check for compile-time optimization */
291 if (expr1
->is_const
&& expr2
->is_const
)
297 e
->cval
= expr1
->cval
+ expr2
->cval
;
300 e
->cval
= expr1
->cval
- expr2
->cval
;
303 if (expr2
->cval
== 0)
305 error_loc("divide by zero in expression\n");
309 e
->cval
= expr1
->cval
% expr2
->cval
;
312 e
->cval
= expr1
->cval
* expr2
->cval
;
315 if (expr2
->cval
== 0)
317 error_loc("divide by zero in expression\n");
321 e
->cval
= expr1
->cval
/ expr2
->cval
;
324 e
->cval
= expr1
->cval
| expr2
->cval
;
327 e
->cval
= expr1
->cval
& expr2
->cval
;
330 e
->cval
= expr1
->cval
<< expr2
->cval
;
333 e
->cval
= expr1
->cval
>> expr2
->cval
;
336 e
->cval
= expr1
->cval
|| expr2
->cval
;
339 e
->cval
= expr1
->cval
&& expr2
->cval
;
342 e
->cval
= expr1
->cval
^ expr2
->cval
;
345 e
->cval
= expr1
->cval
== expr2
->cval
;
347 case EXPR_INEQUALITY
:
348 e
->cval
= expr1
->cval
!= expr2
->cval
;
351 e
->cval
= expr1
->cval
> expr2
->cval
;
354 e
->cval
= expr1
->cval
< expr2
->cval
;
357 e
->cval
= expr1
->cval
>= expr2
->cval
;
360 e
->cval
= expr1
->cval
<= expr2
->cval
;
370 expr_t
*make_expr3(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
, expr_t
*expr3
)
373 e
= xmalloc(sizeof(expr_t
));
379 /* check for compile-time optimization */
380 if (expr1
->is_const
&& expr2
->is_const
&& expr3
->is_const
)
386 e
->cval
= expr1
->cval
? expr2
->cval
: expr3
->cval
;
396 struct expression_type
398 int is_variable
; /* is the expression resolved to a variable? */
399 int is_temporary
; /* should the type be freed? */
403 static void check_scalar_type(const struct expr_loc
*expr_loc
,
404 const type_t
*cont_type
, const type_t
*type
)
406 if (!cont_type
|| (!is_integer_type(type
) && !is_ptr(type
) &&
407 !is_float_type(type
)))
408 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
409 expr_loc
->attr
? " for attribute " : "",
410 expr_loc
->attr
? expr_loc
->attr
: "");
413 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
414 const type_t
*cont_type
, const type_t
*type
)
416 if (!cont_type
|| (!is_integer_type(type
) && !is_float_type(type
)))
417 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
418 expr_loc
->attr
? " for attribute " : "",
419 expr_loc
->attr
? expr_loc
->attr
: "");
422 static void check_integer_type(const struct expr_loc
*expr_loc
,
423 const type_t
*cont_type
, const type_t
*type
)
425 if (!cont_type
|| !is_integer_type(type
))
426 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
427 expr_loc
->attr
? " for attribute " : "",
428 expr_loc
->attr
? expr_loc
->attr
: "");
431 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
435 const var_list_t
*fields
= NULL
;
437 *found_in_cont_type
= 0;
441 switch (type_get_type(cont_type
))
444 fields
= type_function_get_args(cont_type
);
447 fields
= type_struct_get_fields(cont_type
);
450 case TYPE_ENCAPSULATED_UNION
:
451 fields
= type_union_get_cases(cont_type
);
465 /* shouldn't get here because of using type_get_type above */
471 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
472 if (field
->name
&& !strcmp(identifier
, field
->name
))
475 *found_in_cont_type
= 1;
481 var_t
*const_var
= find_const(identifier
, 0);
482 if (const_var
) type
= const_var
->type
;
488 static int is_valid_member_operand(const type_t
*type
)
490 switch (type_get_type(type
))
501 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
502 const type_t
*cont_type
,
505 struct expression_type result
;
506 result
.is_variable
= FALSE
;
507 result
.is_temporary
= FALSE
;
516 result
.is_temporary
= FALSE
;
517 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
520 result
.is_temporary
= TRUE
;
521 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_CHAR
, 0), NULL
);
524 result
.is_temporary
= TRUE
;
525 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_WCHAR
, 0), NULL
);
528 result
.is_temporary
= TRUE
;
529 result
.type
= type_new_int(TYPE_BASIC_CHAR
, 0);
532 result
.is_temporary
= TRUE
;
533 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
535 case EXPR_IDENTIFIER
:
537 int found_in_cont_type
;
538 result
.is_variable
= TRUE
;
539 result
.is_temporary
= FALSE
;
540 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
543 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
544 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
545 expr_loc
->attr
? expr_loc
->attr
: "");
550 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
551 check_scalar_type(expr_loc
, cont_type
, result
.type
);
552 result
.is_variable
= FALSE
;
553 result
.is_temporary
= FALSE
;
554 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
557 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
558 check_integer_type(expr_loc
, cont_type
, result
.type
);
559 result
.is_variable
= FALSE
;
563 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
564 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
565 result
.is_variable
= FALSE
;
568 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
569 if (!result
.is_variable
)
570 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
571 expr_loc
->attr
? " for attribute " : "",
572 expr_loc
->attr
? expr_loc
->attr
: "");
573 result
.is_variable
= FALSE
;
574 result
.is_temporary
= TRUE
;
575 result
.type
= type_new_pointer(RPC_FC_UP
, result
.type
, NULL
);
578 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
579 if (result
.type
&& is_ptr(result
.type
))
580 result
.type
= type_pointer_get_ref(result
.type
);
581 else if(result
.type
&& is_array(result
.type
)
582 && type_array_is_decl_as_ptr(result
.type
))
583 result
.type
= type_array_get_element(result
.type
);
585 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
586 expr_loc
->attr
? " for attribute " : "",
587 expr_loc
->attr
? expr_loc
->attr
: "");
590 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
591 result
.type
= e
->u
.tref
;
594 result
.is_temporary
= FALSE
;
595 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
608 struct expression_type result_right
;
609 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
610 result
.is_variable
= FALSE
;
611 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
612 /* FIXME: these checks aren't strict enough for some of the operators */
613 check_scalar_type(expr_loc
, cont_type
, result
.type
);
614 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
620 case EXPR_INEQUALITY
:
626 struct expression_type result_left
, result_right
;
627 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
628 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
629 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
630 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
631 result
.is_temporary
= FALSE
;
632 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
636 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
637 if (result
.type
&& is_valid_member_operand(result
.type
))
638 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
640 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",
641 expr_loc
->attr
? " for attribute " : "",
642 expr_loc
->attr
? expr_loc
->attr
: "");
646 struct expression_type result_first
, result_second
, result_third
;
647 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
648 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
649 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
650 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
651 /* FIXME: determine the correct return type */
652 result
= result_second
;
653 result
.is_variable
= FALSE
;
657 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
658 if (result
.type
&& is_array(result
.type
))
660 struct expression_type index_result
;
661 result
.type
= type_array_get_element(result
.type
);
662 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
663 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
664 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
665 expr_loc
->attr
? " for attribute " : "",
666 expr_loc
->attr
? expr_loc
->attr
: "");
669 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
670 expr_loc
->attr
? " for attribute " : "",
671 expr_loc
->attr
? expr_loc
->attr
: "");
677 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
679 struct expression_type expr_type
;
680 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
681 return expr_type
.type
;
684 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
685 int toplevel
, const char *toplevel_prefix
,
686 const type_t
*cont_type
, const char *local_var_prefix
)
693 fprintf(h
, "%u", e
->u
.lval
);
696 fprintf(h
, "0x%x", e
->u
.lval
);
699 fprintf(h
, "%#.15g", e
->u
.dval
);
707 case EXPR_IDENTIFIER
:
708 if (toplevel
&& toplevel_prefix
&& cont_type
)
710 int found_in_cont_type
;
711 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
712 if (found_in_cont_type
)
714 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
718 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
721 fprintf(h
, "\"%s\"", e
->u
.sval
);
724 fprintf(h
, "L\"%s\"", e
->u
.sval
);
727 fprintf(h
, "'%s'", e
->u
.sval
);
731 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
735 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
739 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
743 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
747 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
751 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
755 write_type_decl(h
, e
->u
.tref
, NULL
);
757 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
760 fprintf(h
, "sizeof(");
761 write_type_decl(h
, e
->u
.tref
, NULL
);
777 case EXPR_INEQUALITY
:
782 if (brackets
) fprintf(h
, "(");
783 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
786 case EXPR_SHL
: fprintf(h
, " << "); break;
787 case EXPR_SHR
: fprintf(h
, " >> "); break;
788 case EXPR_MOD
: fprintf(h
, " %% "); break;
789 case EXPR_MUL
: fprintf(h
, " * "); break;
790 case EXPR_DIV
: fprintf(h
, " / "); break;
791 case EXPR_ADD
: fprintf(h
, " + "); break;
792 case EXPR_SUB
: fprintf(h
, " - "); break;
793 case EXPR_AND
: fprintf(h
, " & "); break;
794 case EXPR_OR
: fprintf(h
, " | "); break;
795 case EXPR_LOGOR
: fprintf(h
, " || "); break;
796 case EXPR_LOGAND
: fprintf(h
, " && "); break;
797 case EXPR_XOR
: fprintf(h
, " ^ "); break;
798 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
799 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
800 case EXPR_GTR
: fprintf(h
, " > "); break;
801 case EXPR_LESS
: fprintf(h
, " < "); break;
802 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
803 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
806 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
807 if (brackets
) fprintf(h
, ")");
810 if (brackets
) fprintf(h
, "(");
811 if (e
->ref
->type
== EXPR_PPTR
)
813 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
818 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
821 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
822 if (brackets
) fprintf(h
, ")");
825 if (brackets
) fprintf(h
, "(");
826 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
828 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
830 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
831 if (brackets
) fprintf(h
, ")");
834 if (brackets
) fprintf(h
, "(");
835 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
837 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
839 if (brackets
) fprintf(h
, ")");
844 /* This is actually fairly involved to implement precisely, due to the
845 effects attributes may have and things like that. Right now this is
846 only used for optimization, so just check for a very small set of
847 criteria that guarantee the types are equivalent; assume every thing
848 else is different. */
849 static int compare_type(const type_t
*a
, const type_t
*b
)
854 && strcmp(a
->name
, b
->name
) == 0))
856 /* Ordering doesn't need to be implemented yet. */
860 int compare_expr(const expr_t
*a
, const expr_t
*b
)
864 if (a
->type
!= b
->type
)
865 return a
->type
- b
->type
;
872 return a
->u
.lval
- b
->u
.lval
;
874 return a
->u
.dval
- b
->u
.dval
;
875 case EXPR_IDENTIFIER
:
879 return strcmp(a
->u
.sval
, b
->u
.sval
);
881 ret
= compare_expr(a
->ref
, b
->ref
);
884 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
887 return compare_expr(a
->ext2
, b
->ext2
);
903 case EXPR_INEQUALITY
:
908 ret
= compare_expr(a
->ref
, b
->ref
);
911 return compare_expr(a
->u
.ext
, b
->u
.ext
);
913 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
923 return compare_expr(a
->ref
, b
->ref
);
925 return compare_type(a
->u
.tref
, b
->u
.tref
);