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_variable
= FALSE
;
517 result
.is_temporary
= FALSE
;
518 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
521 result
.is_variable
= FALSE
;
522 result
.is_temporary
= TRUE
;
523 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_CHAR
, 0), NULL
);
526 result
.is_variable
= FALSE
;
527 result
.is_temporary
= TRUE
;
528 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_WCHAR
, 0), NULL
);
531 result
.is_variable
= FALSE
;
532 result
.is_temporary
= TRUE
;
533 result
.type
= type_new_int(TYPE_BASIC_CHAR
, 0);
536 result
.is_variable
= FALSE
;
537 result
.is_temporary
= TRUE
;
538 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
540 case EXPR_IDENTIFIER
:
542 int found_in_cont_type
;
543 result
.is_variable
= TRUE
;
544 result
.is_temporary
= FALSE
;
545 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
548 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
549 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
550 expr_loc
->attr
? expr_loc
->attr
: "");
555 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
556 check_scalar_type(expr_loc
, cont_type
, result
.type
);
557 result
.is_variable
= FALSE
;
558 result
.is_temporary
= FALSE
;
559 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
562 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
563 check_integer_type(expr_loc
, cont_type
, result
.type
);
564 result
.is_variable
= FALSE
;
568 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
569 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
570 result
.is_variable
= FALSE
;
573 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
574 if (!result
.is_variable
)
575 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
576 expr_loc
->attr
? " for attribute " : "",
577 expr_loc
->attr
? expr_loc
->attr
: "");
578 result
.is_variable
= FALSE
;
579 result
.is_temporary
= TRUE
;
580 result
.type
= type_new_pointer(RPC_FC_UP
, result
.type
, NULL
);
583 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
584 if (result
.type
&& is_ptr(result
.type
))
585 result
.type
= type_pointer_get_ref(result
.type
);
586 else if(result
.type
&& is_array(result
.type
)
587 && type_array_is_decl_as_ptr(result
.type
))
588 result
.type
= type_array_get_element(result
.type
);
590 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
591 expr_loc
->attr
? " for attribute " : "",
592 expr_loc
->attr
? expr_loc
->attr
: "");
595 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
596 result
.type
= e
->u
.tref
;
599 result
.is_variable
= FALSE
;
600 result
.is_temporary
= FALSE
;
601 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
614 struct expression_type result_right
;
615 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
616 result
.is_variable
= FALSE
;
617 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
618 /* FIXME: these checks aren't strict enough for some of the operators */
619 check_scalar_type(expr_loc
, cont_type
, result
.type
);
620 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
626 case EXPR_INEQUALITY
:
632 struct expression_type result_left
, result_right
;
633 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
634 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
635 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
636 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
637 result
.is_variable
= FALSE
;
638 result
.is_temporary
= FALSE
;
639 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
643 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
644 if (result
.type
&& is_valid_member_operand(result
.type
))
645 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
647 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",
648 expr_loc
->attr
? " for attribute " : "",
649 expr_loc
->attr
? expr_loc
->attr
: "");
653 struct expression_type result_first
, result_second
, result_third
;
654 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
655 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
656 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
657 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
658 /* FIXME: determine the correct return type */
659 result
= result_second
;
660 result
.is_variable
= FALSE
;
664 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
665 if (result
.type
&& is_array(result
.type
))
667 struct expression_type index_result
;
668 result
.type
= type_array_get_element(result
.type
);
669 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
670 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
671 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
672 expr_loc
->attr
? " for attribute " : "",
673 expr_loc
->attr
? expr_loc
->attr
: "");
676 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
677 expr_loc
->attr
? " for attribute " : "",
678 expr_loc
->attr
? expr_loc
->attr
: "");
684 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
686 struct expression_type expr_type
;
687 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
688 return expr_type
.type
;
691 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
692 int toplevel
, const char *toplevel_prefix
,
693 const type_t
*cont_type
, const char *local_var_prefix
)
700 fprintf(h
, "%u", e
->u
.lval
);
703 fprintf(h
, "0x%x", e
->u
.lval
);
706 fprintf(h
, "%#.15g", e
->u
.dval
);
714 case EXPR_IDENTIFIER
:
715 if (toplevel
&& toplevel_prefix
&& cont_type
)
717 int found_in_cont_type
;
718 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
719 if (found_in_cont_type
)
721 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
725 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
728 fprintf(h
, "\"%s\"", e
->u
.sval
);
731 fprintf(h
, "L\"%s\"", e
->u
.sval
);
734 fprintf(h
, "'%s'", e
->u
.sval
);
738 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
742 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
746 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
750 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
754 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
758 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
762 write_type_decl(h
, e
->u
.tref
, NULL
);
764 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
767 fprintf(h
, "sizeof(");
768 write_type_decl(h
, e
->u
.tref
, NULL
);
784 case EXPR_INEQUALITY
:
789 if (brackets
) fprintf(h
, "(");
790 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
793 case EXPR_SHL
: fprintf(h
, " << "); break;
794 case EXPR_SHR
: fprintf(h
, " >> "); break;
795 case EXPR_MOD
: fprintf(h
, " %% "); break;
796 case EXPR_MUL
: fprintf(h
, " * "); break;
797 case EXPR_DIV
: fprintf(h
, " / "); break;
798 case EXPR_ADD
: fprintf(h
, " + "); break;
799 case EXPR_SUB
: fprintf(h
, " - "); break;
800 case EXPR_AND
: fprintf(h
, " & "); break;
801 case EXPR_OR
: fprintf(h
, " | "); break;
802 case EXPR_LOGOR
: fprintf(h
, " || "); break;
803 case EXPR_LOGAND
: fprintf(h
, " && "); break;
804 case EXPR_XOR
: fprintf(h
, " ^ "); break;
805 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
806 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
807 case EXPR_GTR
: fprintf(h
, " > "); break;
808 case EXPR_LESS
: fprintf(h
, " < "); break;
809 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
810 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
813 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
814 if (brackets
) fprintf(h
, ")");
817 if (brackets
) fprintf(h
, "(");
818 if (e
->ref
->type
== EXPR_PPTR
)
820 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
825 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
828 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
829 if (brackets
) fprintf(h
, ")");
832 if (brackets
) fprintf(h
, "(");
833 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
835 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
837 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
838 if (brackets
) fprintf(h
, ")");
841 if (brackets
) fprintf(h
, "(");
842 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
844 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
846 if (brackets
) fprintf(h
, ")");
851 /* This is actually fairly involved to implement precisely, due to the
852 effects attributes may have and things like that. Right now this is
853 only used for optimization, so just check for a very small set of
854 criteria that guarantee the types are equivalent; assume every thing
855 else is different. */
856 static int compare_type(const type_t
*a
, const type_t
*b
)
861 && strcmp(a
->name
, b
->name
) == 0))
863 /* Ordering doesn't need to be implemented yet. */
867 int compare_expr(const expr_t
*a
, const expr_t
*b
)
871 if (a
->type
!= b
->type
)
872 return a
->type
- b
->type
;
879 return a
->u
.lval
- b
->u
.lval
;
881 return a
->u
.dval
- b
->u
.dval
;
882 case EXPR_IDENTIFIER
:
886 return strcmp(a
->u
.sval
, b
->u
.sval
);
888 ret
= compare_expr(a
->ref
, b
->ref
);
891 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
894 return compare_expr(a
->ext2
, b
->ext2
);
910 case EXPR_INEQUALITY
:
915 ret
= compare_expr(a
->ref
, b
->ref
);
918 return compare_expr(a
->u
.ext
, b
->u
.ext
);
920 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
930 return compare_expr(a
->ref
, b
->ref
);
932 return compare_type(a
->u
.tref
, b
->u
.tref
);