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
) && !is_float_type( type
)))
410 error_at( &expr_loc
->v
->where
, "scalar type required in expression%s%s\n",
411 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
414 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
415 const type_t
*cont_type
, const type_t
*type
)
417 if (!cont_type
|| (!is_integer_type( type
) && !is_float_type( type
)))
418 error_at( &expr_loc
->v
->where
, "arithmetic type required in expression%s%s\n",
419 expr_loc
->attr
? " for attribute " : "", 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_at( &expr_loc
->v
->where
, "integer type required in expression%s%s\n",
427 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
430 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
434 const var_list_t
*fields
= NULL
;
436 *found_in_cont_type
= 0;
440 switch (type_get_type(cont_type
))
443 fields
= type_function_get_args(cont_type
);
446 fields
= type_struct_get_fields(cont_type
);
449 case TYPE_ENCAPSULATED_UNION
:
450 fields
= type_union_get_cases(cont_type
);
461 case TYPE_APICONTRACT
:
462 case TYPE_RUNTIMECLASS
:
463 case TYPE_PARAMETERIZED_TYPE
:
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
);
546 error_at( &expr_loc
->v
->where
, "identifier %s cannot be resolved in expression%s%s\n", e
->u
.sval
,
547 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
551 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
552 check_scalar_type(expr_loc
, cont_type
, result
.type
);
553 result
.is_variable
= FALSE
;
554 result
.is_temporary
= FALSE
;
555 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
558 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
559 check_integer_type(expr_loc
, cont_type
, result
.type
);
560 result
.is_variable
= FALSE
;
564 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
565 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
566 result
.is_variable
= FALSE
;
569 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
570 if (!result
.is_variable
)
571 error_at( &expr_loc
->v
->where
, "address-of operator applied to non-variable type in expression%s%s\n",
572 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
573 result
.is_variable
= FALSE
;
574 result
.is_temporary
= TRUE
;
575 result
.type
= type_new_pointer(result
.type
);
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_type(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_type(result
.type
);
585 error_at( &expr_loc
->v
->where
, "dereference operator applied to non-pointer type in expression%s%s\n",
586 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
589 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
590 result
.type
= e
->u
.tref
.type
;
593 result
.is_temporary
= FALSE
;
594 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
607 struct expression_type result_right
;
608 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
609 result
.is_variable
= FALSE
;
610 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
611 /* FIXME: these checks aren't strict enough for some of the operators */
612 check_scalar_type(expr_loc
, cont_type
, result
.type
);
613 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
619 case EXPR_INEQUALITY
:
625 struct expression_type result_left
, result_right
;
626 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
627 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
628 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
629 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
630 result
.is_temporary
= FALSE
;
631 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
635 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
636 if (result
.type
&& is_valid_member_operand(result
.type
))
637 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
639 error_at( &expr_loc
->v
->where
, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",
640 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
644 struct expression_type result_first
, result_second
, result_third
;
645 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
646 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
647 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
648 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
649 check_scalar_type(expr_loc
, cont_type
, result_second
.type
);
650 check_scalar_type(expr_loc
, cont_type
, result_third
.type
);
651 if (!is_ptr( result_second
.type
) ^ !is_ptr( result_third
.type
))
652 error_at( &expr_loc
->v
->where
, "type mismatch in ?: expression\n" );
653 /* FIXME: determine the correct return type */
654 result
= result_second
;
655 result
.is_variable
= FALSE
;
659 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
660 if (result
.type
&& is_array(result
.type
))
662 struct expression_type index_result
;
663 result
.type
= type_array_get_element_type(result
.type
);
664 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
665 if (!index_result
.type
|| !is_integer_type( index_result
.type
))
666 error_at( &expr_loc
->v
->where
, "array subscript not of integral type in expression%s%s\n",
667 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
671 error_at( &expr_loc
->v
->where
, "array subscript operator applied to non-array type in expression%s%s\n",
672 expr_loc
->attr
? " for attribute " : "", expr_loc
->attr
? expr_loc
->attr
: "" );
679 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
681 struct expression_type expr_type
;
682 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
683 return expr_type
.type
;
686 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
687 int toplevel
, const char *toplevel_prefix
,
688 const type_t
*cont_type
, const char *local_var_prefix
)
695 fprintf(h
, "%u", e
->u
.lval
);
698 fprintf(h
, "0x%x", e
->u
.lval
);
701 fprintf(h
, "%#.15g", e
->u
.dval
);
709 case EXPR_IDENTIFIER
:
710 if (toplevel
&& toplevel_prefix
&& cont_type
)
712 int found_in_cont_type
;
713 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
714 if (found_in_cont_type
)
716 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
720 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
723 fprintf(h
, "\"%s\"", e
->u
.sval
);
726 fprintf(h
, "L\"%s\"", e
->u
.sval
);
729 fprintf(h
, "'%s'", e
->u
.sval
);
733 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
737 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
741 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
745 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
749 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
753 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
757 write_type_decl(h
, &e
->u
.tref
, NULL
);
759 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
762 fprintf(h
, "sizeof(");
763 write_type_decl(h
, &e
->u
.tref
, NULL
);
779 case EXPR_INEQUALITY
:
784 if (brackets
) fprintf(h
, "(");
785 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
788 case EXPR_SHL
: fprintf(h
, " << "); break;
789 case EXPR_SHR
: fprintf(h
, " >> "); break;
790 case EXPR_MOD
: fprintf(h
, " %% "); break;
791 case EXPR_MUL
: fprintf(h
, " * "); break;
792 case EXPR_DIV
: fprintf(h
, " / "); break;
793 case EXPR_ADD
: fprintf(h
, " + "); break;
794 case EXPR_SUB
: fprintf(h
, " - "); break;
795 case EXPR_AND
: fprintf(h
, " & "); break;
796 case EXPR_OR
: fprintf(h
, " | "); break;
797 case EXPR_LOGOR
: fprintf(h
, " || "); break;
798 case EXPR_LOGAND
: fprintf(h
, " && "); break;
799 case EXPR_XOR
: fprintf(h
, " ^ "); break;
800 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
801 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
802 case EXPR_GTR
: fprintf(h
, " > "); break;
803 case EXPR_LESS
: fprintf(h
, " < "); break;
804 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
805 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
808 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
809 if (brackets
) fprintf(h
, ")");
812 if (brackets
) fprintf(h
, "(");
813 if (e
->ref
->type
== EXPR_PPTR
)
815 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
820 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
823 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
824 if (brackets
) fprintf(h
, ")");
827 if (brackets
) fprintf(h
, "(");
828 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
830 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
832 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
833 if (brackets
) fprintf(h
, ")");
836 if (brackets
) fprintf(h
, "(");
837 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
839 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
841 if (brackets
) fprintf(h
, ")");
846 /* This is actually fairly involved to implement precisely, due to the
847 effects attributes may have and things like that. Right now this is
848 only used for optimization, so just check for a very small set of
849 criteria that guarantee the types are equivalent; assume every thing
850 else is different. */
851 static int compare_type(const type_t
*a
, const type_t
*b
)
856 && strcmp(a
->name
, b
->name
) == 0))
858 /* Ordering doesn't need to be implemented yet. */
862 int compare_expr(const expr_t
*a
, const expr_t
*b
)
866 if (a
->type
!= b
->type
)
867 return a
->type
- b
->type
;
874 return a
->u
.lval
- b
->u
.lval
;
876 return a
->u
.dval
- b
->u
.dval
;
877 case EXPR_IDENTIFIER
:
881 return strcmp(a
->u
.sval
, b
->u
.sval
);
883 ret
= compare_expr(a
->ref
, b
->ref
);
886 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
889 return compare_expr(a
->ext2
, b
->ext2
);
905 case EXPR_INEQUALITY
:
910 ret
= compare_expr(a
->ref
, b
->ref
);
913 return compare_expr(a
->u
.ext
, b
->u
.ext
);
915 ret
= compare_type(a
->u
.tref
.type
, b
->u
.tref
.type
);
925 return compare_expr(a
->ref
, b
->ref
);
927 return compare_type(a
->u
.tref
.type
, b
->u
.tref
.type
);