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
:
466 case TYPE_RUNTIMECLASS
:
467 case TYPE_PARAMETERIZED_TYPE
:
473 /* shouldn't get here because of using type_get_type above */
479 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
480 if (field
->name
&& !strcmp(identifier
, field
->name
))
482 type
= field
->declspec
.type
;
483 *found_in_cont_type
= 1;
489 var_t
*const_var
= find_const(identifier
, 0);
490 if (const_var
) type
= const_var
->declspec
.type
;
496 static int is_valid_member_operand(const type_t
*type
)
498 switch (type_get_type(type
))
509 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
510 const type_t
*cont_type
,
513 struct expression_type result
;
514 result
.is_variable
= FALSE
;
515 result
.is_temporary
= FALSE
;
524 result
.is_temporary
= FALSE
;
525 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
528 result
.is_temporary
= TRUE
;
529 result
.type
= type_new_pointer(type_new_int(TYPE_BASIC_CHAR
, 0));
532 result
.is_temporary
= TRUE
;
533 result
.type
= type_new_pointer(type_new_int(TYPE_BASIC_WCHAR
, 0));
536 result
.is_temporary
= TRUE
;
537 result
.type
= type_new_int(TYPE_BASIC_CHAR
, 0);
540 result
.is_temporary
= TRUE
;
541 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
543 case EXPR_IDENTIFIER
:
545 int found_in_cont_type
;
546 result
.is_variable
= TRUE
;
547 result
.is_temporary
= FALSE
;
548 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
551 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
552 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
553 expr_loc
->attr
? expr_loc
->attr
: "");
558 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
559 check_scalar_type(expr_loc
, cont_type
, result
.type
);
560 result
.is_variable
= FALSE
;
561 result
.is_temporary
= FALSE
;
562 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
565 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
566 check_integer_type(expr_loc
, cont_type
, result
.type
);
567 result
.is_variable
= FALSE
;
571 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
572 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
573 result
.is_variable
= FALSE
;
576 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
577 if (!result
.is_variable
)
578 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
579 expr_loc
->attr
? " for attribute " : "",
580 expr_loc
->attr
? expr_loc
->attr
: "");
581 result
.is_variable
= FALSE
;
582 result
.is_temporary
= TRUE
;
583 result
.type
= type_new_pointer(result
.type
);
586 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
587 if (result
.type
&& is_ptr(result
.type
))
588 result
.type
= type_pointer_get_ref_type(result
.type
);
589 else if(result
.type
&& is_array(result
.type
)
590 && type_array_is_decl_as_ptr(result
.type
))
591 result
.type
= type_array_get_element_type(result
.type
);
593 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
594 expr_loc
->attr
? " for attribute " : "",
595 expr_loc
->attr
? expr_loc
->attr
: "");
598 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
599 result
.type
= e
->u
.tref
.type
;
602 result
.is_temporary
= FALSE
;
603 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
616 struct expression_type result_right
;
617 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
618 result
.is_variable
= FALSE
;
619 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
620 /* FIXME: these checks aren't strict enough for some of the operators */
621 check_scalar_type(expr_loc
, cont_type
, result
.type
);
622 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
628 case EXPR_INEQUALITY
:
634 struct expression_type result_left
, result_right
;
635 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
636 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
637 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
638 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
639 result
.is_temporary
= FALSE
;
640 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
644 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
645 if (result
.type
&& is_valid_member_operand(result
.type
))
646 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
648 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",
649 expr_loc
->attr
? " for attribute " : "",
650 expr_loc
->attr
? expr_loc
->attr
: "");
654 struct expression_type result_first
, result_second
, result_third
;
655 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
656 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
657 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
658 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
659 check_scalar_type(expr_loc
, cont_type
, result_second
.type
);
660 check_scalar_type(expr_loc
, cont_type
, result_third
.type
);
661 if (!is_ptr(result_second
.type
) ^ !is_ptr(result_third
.type
))
662 error_loc_info(&expr_loc
->v
->loc_info
, "type mismatch in ?: expression\n" );
663 /* FIXME: determine the correct return type */
664 result
= result_second
;
665 result
.is_variable
= FALSE
;
669 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
670 if (result
.type
&& is_array(result
.type
))
672 struct expression_type index_result
;
673 result
.type
= type_array_get_element_type(result
.type
);
674 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
675 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
676 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
677 expr_loc
->attr
? " for attribute " : "",
678 expr_loc
->attr
? expr_loc
->attr
: "");
681 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
682 expr_loc
->attr
? " for attribute " : "",
683 expr_loc
->attr
? expr_loc
->attr
: "");
689 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
691 struct expression_type expr_type
;
692 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
693 return expr_type
.type
;
696 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
697 int toplevel
, const char *toplevel_prefix
,
698 const type_t
*cont_type
, const char *local_var_prefix
)
705 fprintf(h
, "%u", e
->u
.lval
);
708 fprintf(h
, "0x%x", e
->u
.lval
);
711 fprintf(h
, "%#.15g", e
->u
.dval
);
719 case EXPR_IDENTIFIER
:
720 if (toplevel
&& toplevel_prefix
&& cont_type
)
722 int found_in_cont_type
;
723 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
724 if (found_in_cont_type
)
726 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
730 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
733 fprintf(h
, "\"%s\"", e
->u
.sval
);
736 fprintf(h
, "L\"%s\"", e
->u
.sval
);
739 fprintf(h
, "'%s'", e
->u
.sval
);
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_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
767 write_type_decl(h
, &e
->u
.tref
, NULL
);
769 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
772 fprintf(h
, "sizeof(");
773 write_type_decl(h
, &e
->u
.tref
, NULL
);
789 case EXPR_INEQUALITY
:
794 if (brackets
) fprintf(h
, "(");
795 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
798 case EXPR_SHL
: fprintf(h
, " << "); break;
799 case EXPR_SHR
: fprintf(h
, " >> "); break;
800 case EXPR_MOD
: fprintf(h
, " %% "); break;
801 case EXPR_MUL
: fprintf(h
, " * "); break;
802 case EXPR_DIV
: fprintf(h
, " / "); break;
803 case EXPR_ADD
: fprintf(h
, " + "); break;
804 case EXPR_SUB
: fprintf(h
, " - "); break;
805 case EXPR_AND
: fprintf(h
, " & "); break;
806 case EXPR_OR
: fprintf(h
, " | "); break;
807 case EXPR_LOGOR
: fprintf(h
, " || "); break;
808 case EXPR_LOGAND
: fprintf(h
, " && "); break;
809 case EXPR_XOR
: fprintf(h
, " ^ "); break;
810 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
811 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
812 case EXPR_GTR
: fprintf(h
, " > "); break;
813 case EXPR_LESS
: fprintf(h
, " < "); break;
814 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
815 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
818 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
819 if (brackets
) fprintf(h
, ")");
822 if (brackets
) fprintf(h
, "(");
823 if (e
->ref
->type
== EXPR_PPTR
)
825 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
830 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
833 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
834 if (brackets
) fprintf(h
, ")");
837 if (brackets
) fprintf(h
, "(");
838 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
840 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
842 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
843 if (brackets
) fprintf(h
, ")");
846 if (brackets
) fprintf(h
, "(");
847 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
849 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
851 if (brackets
) fprintf(h
, ")");
856 /* This is actually fairly involved to implement precisely, due to the
857 effects attributes may have and things like that. Right now this is
858 only used for optimization, so just check for a very small set of
859 criteria that guarantee the types are equivalent; assume every thing
860 else is different. */
861 static int compare_type(const type_t
*a
, const type_t
*b
)
866 && strcmp(a
->name
, b
->name
) == 0))
868 /* Ordering doesn't need to be implemented yet. */
872 int compare_expr(const expr_t
*a
, const expr_t
*b
)
876 if (a
->type
!= b
->type
)
877 return a
->type
- b
->type
;
884 return a
->u
.lval
- b
->u
.lval
;
886 return a
->u
.dval
- b
->u
.dval
;
887 case EXPR_IDENTIFIER
:
891 return strcmp(a
->u
.sval
, b
->u
.sval
);
893 ret
= compare_expr(a
->ref
, b
->ref
);
896 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
899 return compare_expr(a
->ext2
, b
->ext2
);
915 case EXPR_INEQUALITY
:
920 ret
= compare_expr(a
->ref
, b
->ref
);
923 return compare_expr(a
->u
.ext
, b
->u
.ext
);
925 ret
= compare_type(a
->u
.tref
.type
, b
->u
.tref
.type
);
935 return compare_expr(a
->ref
, b
->ref
);
937 return compare_type(a
->u
.tref
.type
, b
->u
.tref
.type
);