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
:
55 case TYPE_BASIC_HYPER
:
57 case TYPE_BASIC_WCHAR
:
58 case TYPE_BASIC_ERROR_STATUS_T
:
60 case TYPE_BASIC_FLOAT
:
61 case TYPE_BASIC_DOUBLE
:
62 case TYPE_BASIC_HANDLE
:
71 static int is_signed_integer_type(const type_t
*type
)
73 switch (type_get_type(type
))
78 switch (type_basic_get_type(type
))
81 case TYPE_BASIC_INT16
:
82 case TYPE_BASIC_INT32
:
83 case TYPE_BASIC_INT64
:
85 case TYPE_BASIC_INT3264
:
87 return type_basic_get_sign(type
) < 0;
90 case TYPE_BASIC_HYPER
:
92 case TYPE_BASIC_WCHAR
:
93 case TYPE_BASIC_ERROR_STATUS_T
:
94 case TYPE_BASIC_FLOAT
:
95 case TYPE_BASIC_DOUBLE
:
96 case TYPE_BASIC_HANDLE
:
105 static int is_float_type(const type_t
*type
)
107 return (type_get_type(type
) == TYPE_BASIC
&&
108 (type_basic_get_type(type
) == TYPE_BASIC_FLOAT
||
109 type_basic_get_type(type
) == TYPE_BASIC_DOUBLE
));
112 expr_t
*make_expr(enum expr_type type
)
114 expr_t
*e
= xmalloc(sizeof(expr_t
));
123 expr_t
*make_exprl(enum expr_type type
, int val
)
125 expr_t
*e
= xmalloc(sizeof(expr_t
));
130 /* check for numeric constant */
131 if (type
== EXPR_NUM
|| type
== EXPR_HEXNUM
|| type
== EXPR_TRUEFALSE
)
133 /* make sure true/false value is valid */
134 assert(type
!= EXPR_TRUEFALSE
|| val
== 0 || val
== 1);
141 expr_t
*make_exprd(enum expr_type type
, double val
)
143 expr_t
*e
= xmalloc(sizeof(expr_t
));
152 expr_t
*make_exprs(enum expr_type type
, char *val
)
155 e
= xmalloc(sizeof(expr_t
));
160 /* check for predefined constants */
163 case EXPR_IDENTIFIER
:
165 var_t
*c
= find_const(val
, 0);
171 e
->cval
= c
->eval
->cval
;
177 error_loc("empty character constant\n");
179 error_loc("multi-character constants are endian dependent\n");
192 expr_t
*make_exprt(enum expr_type type
, var_t
*var
, expr_t
*expr
)
197 if (var
->declspec
.stgclass
!= STG_NONE
&& var
->declspec
.stgclass
!= STG_REGISTER
)
198 error_loc("invalid storage class for type expression\n");
200 tref
= var
->declspec
.type
;
202 e
= xmalloc(sizeof(expr_t
));
205 e
->u
.tref
= var
->declspec
;
207 if (type
== EXPR_SIZEOF
)
209 /* only do this for types that should be the same on all platforms */
210 if (is_integer_type(tref
) || is_float_type(tref
))
213 e
->cval
= type_memsize(tref
);
216 /* check for cast of constant expression */
217 if (type
== EXPR_CAST
&& expr
->is_const
)
219 if (is_integer_type(tref
))
221 unsigned int cast_type_bits
= type_memsize(tref
) * 8;
222 unsigned int cast_mask
;
225 if (is_signed_integer_type(tref
))
227 cast_mask
= (1u << (cast_type_bits
- 1)) - 1;
228 if (expr
->cval
& (1u << (cast_type_bits
- 1)))
229 e
->cval
= -((-expr
->cval
) & cast_mask
);
231 e
->cval
= expr
->cval
& cast_mask
;
235 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
236 cast_mask
= ((1u << (cast_type_bits
- 1)) - 1) |
237 1u << (cast_type_bits
- 1);
238 e
->cval
= expr
->cval
& cast_mask
;
244 e
->cval
= expr
->cval
;
251 expr_t
*make_expr1(enum expr_type type
, expr_t
*expr
)
254 e
= xmalloc(sizeof(expr_t
));
259 /* check for compile-time optimization */
266 e
->cval
= !expr
->cval
;
269 e
->cval
= +expr
->cval
;
272 e
->cval
= -expr
->cval
;
275 e
->cval
= ~expr
->cval
;
285 expr_t
*make_expr2(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
)
288 e
= xmalloc(sizeof(expr_t
));
293 /* check for compile-time optimization */
294 if (expr1
->is_const
&& expr2
->is_const
)
300 e
->cval
= expr1
->cval
+ expr2
->cval
;
303 e
->cval
= expr1
->cval
- expr2
->cval
;
306 if (expr2
->cval
== 0)
308 error_loc("divide by zero in expression\n");
312 e
->cval
= expr1
->cval
% expr2
->cval
;
315 e
->cval
= expr1
->cval
* expr2
->cval
;
318 if (expr2
->cval
== 0)
320 error_loc("divide by zero in expression\n");
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
;
348 e
->cval
= expr1
->cval
== expr2
->cval
;
350 case EXPR_INEQUALITY
:
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
;
363 e
->cval
= expr1
->cval
<= expr2
->cval
;
373 expr_t
*make_expr3(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
, expr_t
*expr3
)
376 e
= xmalloc(sizeof(expr_t
));
382 /* check for compile-time optimization */
383 if (expr1
->is_const
&& expr2
->is_const
&& expr3
->is_const
)
389 e
->cval
= expr1
->cval
? expr2
->cval
: expr3
->cval
;
399 struct expression_type
401 int is_variable
; /* is the expression resolved to a variable? */
402 int is_temporary
; /* should the type be freed? */
406 static void check_scalar_type(const struct expr_loc
*expr_loc
,
407 const type_t
*cont_type
, const type_t
*type
)
409 if (!cont_type
|| (!is_integer_type(type
) && !is_ptr(type
) &&
410 !is_float_type(type
)))
411 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
412 expr_loc
->attr
? " for attribute " : "",
413 expr_loc
->attr
? expr_loc
->attr
: "");
416 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
417 const type_t
*cont_type
, const type_t
*type
)
419 if (!cont_type
|| (!is_integer_type(type
) && !is_float_type(type
)))
420 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
421 expr_loc
->attr
? " for attribute " : "",
422 expr_loc
->attr
? expr_loc
->attr
: "");
425 static void check_integer_type(const struct expr_loc
*expr_loc
,
426 const type_t
*cont_type
, const type_t
*type
)
428 if (!cont_type
|| !is_integer_type(type
))
429 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
430 expr_loc
->attr
? " for attribute " : "",
431 expr_loc
->attr
? expr_loc
->attr
: "");
434 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
438 const var_list_t
*fields
= NULL
;
440 *found_in_cont_type
= 0;
444 switch (type_get_type(cont_type
))
447 fields
= type_function_get_args(cont_type
);
450 fields
= type_struct_get_fields(cont_type
);
453 case TYPE_ENCAPSULATED_UNION
:
454 fields
= type_union_get_cases(cont_type
);
468 /* shouldn't get here because of using type_get_type above */
474 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
475 if (field
->name
&& !strcmp(identifier
, field
->name
))
477 type
= field
->declspec
.type
;
478 *found_in_cont_type
= 1;
484 var_t
*const_var
= find_const(identifier
, 0);
485 if (const_var
) type
= const_var
->declspec
.type
;
491 static int is_valid_member_operand(const type_t
*type
)
493 switch (type_get_type(type
))
504 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
505 const type_t
*cont_type
,
508 struct expression_type result
;
509 result
.is_variable
= FALSE
;
510 result
.is_temporary
= FALSE
;
519 result
.is_temporary
= FALSE
;
520 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
523 result
.is_temporary
= TRUE
;
524 result
.type
= type_new_pointer(type_new_int(TYPE_BASIC_CHAR
, 0));
527 result
.is_temporary
= TRUE
;
528 result
.type
= type_new_pointer(type_new_int(TYPE_BASIC_WCHAR
, 0));
531 result
.is_temporary
= TRUE
;
532 result
.type
= type_new_int(TYPE_BASIC_CHAR
, 0);
535 result
.is_temporary
= TRUE
;
536 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
538 case EXPR_IDENTIFIER
:
540 int found_in_cont_type
;
541 result
.is_variable
= TRUE
;
542 result
.is_temporary
= FALSE
;
543 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
546 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
547 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
548 expr_loc
->attr
? expr_loc
->attr
: "");
553 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
554 check_scalar_type(expr_loc
, cont_type
, result
.type
);
555 result
.is_variable
= FALSE
;
556 result
.is_temporary
= FALSE
;
557 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
560 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
561 check_integer_type(expr_loc
, cont_type
, result
.type
);
562 result
.is_variable
= FALSE
;
566 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
567 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
568 result
.is_variable
= FALSE
;
571 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
572 if (!result
.is_variable
)
573 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
574 expr_loc
->attr
? " for attribute " : "",
575 expr_loc
->attr
? expr_loc
->attr
: "");
576 result
.is_variable
= FALSE
;
577 result
.is_temporary
= TRUE
;
578 result
.type
= type_new_pointer(result
.type
);
581 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
582 if (result
.type
&& is_ptr(result
.type
))
583 result
.type
= type_pointer_get_ref_type(result
.type
);
584 else if(result
.type
&& is_array(result
.type
)
585 && type_array_is_decl_as_ptr(result
.type
))
586 result
.type
= type_array_get_element_type(result
.type
);
588 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
589 expr_loc
->attr
? " for attribute " : "",
590 expr_loc
->attr
? expr_loc
->attr
: "");
593 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
594 result
.type
= e
->u
.tref
.type
;
597 result
.is_temporary
= FALSE
;
598 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
611 struct expression_type result_right
;
612 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
613 result
.is_variable
= FALSE
;
614 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
615 /* FIXME: these checks aren't strict enough for some of the operators */
616 check_scalar_type(expr_loc
, cont_type
, result
.type
);
617 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
623 case EXPR_INEQUALITY
:
629 struct expression_type result_left
, result_right
;
630 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
631 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
632 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
633 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
634 result
.is_temporary
= FALSE
;
635 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
639 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
640 if (result
.type
&& is_valid_member_operand(result
.type
))
641 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
643 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",
644 expr_loc
->attr
? " for attribute " : "",
645 expr_loc
->attr
? expr_loc
->attr
: "");
649 struct expression_type result_first
, result_second
, result_third
;
650 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
651 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
652 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
653 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
654 check_scalar_type(expr_loc
, cont_type
, result_second
.type
);
655 check_scalar_type(expr_loc
, cont_type
, result_third
.type
);
656 if (!is_ptr(result_second
.type
) ^ !is_ptr(result_third
.type
))
657 error_loc_info(&expr_loc
->v
->loc_info
, "type mismatch in ?: expression\n" );
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_type(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
.type
, b
->u
.tref
.type
);
930 return compare_expr(a
->ref
, b
->ref
);
932 return compare_type(a
->u
.tref
.type
, b
->u
.tref
.type
);