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
);
465 case TYPE_APICONTRACT
:
469 /* shouldn't get here because of using type_get_type above */
475 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
476 if (field
->name
&& !strcmp(identifier
, field
->name
))
478 type
= field
->declspec
.type
;
479 *found_in_cont_type
= 1;
485 var_t
*const_var
= find_const(identifier
, 0);
486 if (const_var
) type
= const_var
->declspec
.type
;
492 static int is_valid_member_operand(const type_t
*type
)
494 switch (type_get_type(type
))
505 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
506 const type_t
*cont_type
,
509 struct expression_type result
;
510 result
.is_variable
= FALSE
;
511 result
.is_temporary
= FALSE
;
520 result
.is_temporary
= FALSE
;
521 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
524 result
.is_temporary
= TRUE
;
525 result
.type
= type_new_pointer(type_new_int(TYPE_BASIC_CHAR
, 0));
528 result
.is_temporary
= TRUE
;
529 result
.type
= type_new_pointer(type_new_int(TYPE_BASIC_WCHAR
, 0));
532 result
.is_temporary
= TRUE
;
533 result
.type
= type_new_int(TYPE_BASIC_CHAR
, 0);
536 result
.is_temporary
= TRUE
;
537 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
539 case EXPR_IDENTIFIER
:
541 int found_in_cont_type
;
542 result
.is_variable
= TRUE
;
543 result
.is_temporary
= FALSE
;
544 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
547 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
548 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
549 expr_loc
->attr
? expr_loc
->attr
: "");
554 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
555 check_scalar_type(expr_loc
, cont_type
, result
.type
);
556 result
.is_variable
= FALSE
;
557 result
.is_temporary
= FALSE
;
558 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
561 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
562 check_integer_type(expr_loc
, cont_type
, result
.type
);
563 result
.is_variable
= FALSE
;
567 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
568 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
569 result
.is_variable
= FALSE
;
572 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
573 if (!result
.is_variable
)
574 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
575 expr_loc
->attr
? " for attribute " : "",
576 expr_loc
->attr
? expr_loc
->attr
: "");
577 result
.is_variable
= FALSE
;
578 result
.is_temporary
= TRUE
;
579 result
.type
= type_new_pointer(result
.type
);
582 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
583 if (result
.type
&& is_ptr(result
.type
))
584 result
.type
= type_pointer_get_ref_type(result
.type
);
585 else if(result
.type
&& is_array(result
.type
)
586 && type_array_is_decl_as_ptr(result
.type
))
587 result
.type
= type_array_get_element_type(result
.type
);
589 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
590 expr_loc
->attr
? " for attribute " : "",
591 expr_loc
->attr
? expr_loc
->attr
: "");
594 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
595 result
.type
= e
->u
.tref
.type
;
598 result
.is_temporary
= FALSE
;
599 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
612 struct expression_type result_right
;
613 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
614 result
.is_variable
= FALSE
;
615 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
616 /* FIXME: these checks aren't strict enough for some of the operators */
617 check_scalar_type(expr_loc
, cont_type
, result
.type
);
618 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
624 case EXPR_INEQUALITY
:
630 struct expression_type result_left
, result_right
;
631 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
632 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
633 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
634 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
635 result
.is_temporary
= FALSE
;
636 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
640 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
641 if (result
.type
&& is_valid_member_operand(result
.type
))
642 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
644 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",
645 expr_loc
->attr
? " for attribute " : "",
646 expr_loc
->attr
? expr_loc
->attr
: "");
650 struct expression_type result_first
, result_second
, result_third
;
651 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
652 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
653 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
654 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
655 check_scalar_type(expr_loc
, cont_type
, result_second
.type
);
656 check_scalar_type(expr_loc
, cont_type
, result_third
.type
);
657 if (!is_ptr(result_second
.type
) ^ !is_ptr(result_third
.type
))
658 error_loc_info(&expr_loc
->v
->loc_info
, "type mismatch in ?: expression\n" );
659 /* FIXME: determine the correct return type */
660 result
= result_second
;
661 result
.is_variable
= FALSE
;
665 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
666 if (result
.type
&& is_array(result
.type
))
668 struct expression_type index_result
;
669 result
.type
= type_array_get_element_type(result
.type
);
670 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
671 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
672 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
673 expr_loc
->attr
? " for attribute " : "",
674 expr_loc
->attr
? expr_loc
->attr
: "");
677 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
678 expr_loc
->attr
? " for attribute " : "",
679 expr_loc
->attr
? expr_loc
->attr
: "");
685 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
687 struct expression_type expr_type
;
688 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
689 return expr_type
.type
;
692 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
693 int toplevel
, const char *toplevel_prefix
,
694 const type_t
*cont_type
, const char *local_var_prefix
)
701 fprintf(h
, "%u", e
->u
.lval
);
704 fprintf(h
, "0x%x", e
->u
.lval
);
707 fprintf(h
, "%#.15g", e
->u
.dval
);
715 case EXPR_IDENTIFIER
:
716 if (toplevel
&& toplevel_prefix
&& cont_type
)
718 int found_in_cont_type
;
719 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
720 if (found_in_cont_type
)
722 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
726 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
729 fprintf(h
, "\"%s\"", e
->u
.sval
);
732 fprintf(h
, "L\"%s\"", e
->u
.sval
);
735 fprintf(h
, "'%s'", e
->u
.sval
);
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_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
759 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
763 write_type_decl(h
, &e
->u
.tref
, NULL
);
765 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
768 fprintf(h
, "sizeof(");
769 write_type_decl(h
, &e
->u
.tref
, NULL
);
785 case EXPR_INEQUALITY
:
790 if (brackets
) fprintf(h
, "(");
791 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
794 case EXPR_SHL
: fprintf(h
, " << "); break;
795 case EXPR_SHR
: fprintf(h
, " >> "); break;
796 case EXPR_MOD
: fprintf(h
, " %% "); break;
797 case EXPR_MUL
: fprintf(h
, " * "); break;
798 case EXPR_DIV
: fprintf(h
, " / "); break;
799 case EXPR_ADD
: fprintf(h
, " + "); break;
800 case EXPR_SUB
: fprintf(h
, " - "); break;
801 case EXPR_AND
: fprintf(h
, " & "); break;
802 case EXPR_OR
: fprintf(h
, " | "); break;
803 case EXPR_LOGOR
: fprintf(h
, " || "); break;
804 case EXPR_LOGAND
: fprintf(h
, " && "); break;
805 case EXPR_XOR
: fprintf(h
, " ^ "); break;
806 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
807 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
808 case EXPR_GTR
: fprintf(h
, " > "); break;
809 case EXPR_LESS
: fprintf(h
, " < "); break;
810 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
811 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
814 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
815 if (brackets
) fprintf(h
, ")");
818 if (brackets
) fprintf(h
, "(");
819 if (e
->ref
->type
== EXPR_PPTR
)
821 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
826 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
829 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
830 if (brackets
) fprintf(h
, ")");
833 if (brackets
) fprintf(h
, "(");
834 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
836 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
838 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
839 if (brackets
) fprintf(h
, ")");
842 if (brackets
) fprintf(h
, "(");
843 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
845 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
847 if (brackets
) fprintf(h
, ")");
852 /* This is actually fairly involved to implement precisely, due to the
853 effects attributes may have and things like that. Right now this is
854 only used for optimization, so just check for a very small set of
855 criteria that guarantee the types are equivalent; assume every thing
856 else is different. */
857 static int compare_type(const type_t
*a
, const type_t
*b
)
862 && strcmp(a
->name
, b
->name
) == 0))
864 /* Ordering doesn't need to be implemented yet. */
868 int compare_expr(const expr_t
*a
, const expr_t
*b
)
872 if (a
->type
!= b
->type
)
873 return a
->type
- b
->type
;
880 return a
->u
.lval
- b
->u
.lval
;
882 return a
->u
.dval
- b
->u
.dval
;
883 case EXPR_IDENTIFIER
:
887 return strcmp(a
->u
.sval
, b
->u
.sval
);
889 ret
= compare_expr(a
->ref
, b
->ref
);
892 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
895 return compare_expr(a
->ext2
, b
->ext2
);
911 case EXPR_INEQUALITY
:
916 ret
= compare_expr(a
->ref
, b
->ref
);
919 return compare_expr(a
->u
.ext
, b
->u
.ext
);
921 ret
= compare_type(a
->u
.tref
.type
, b
->u
.tref
.type
);
931 return compare_expr(a
->ref
, b
->ref
);
933 return compare_type(a
->u
.tref
.type
, b
->u
.tref
.type
);