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
);
39 static int is_float_type(const type_t
*type
);
41 expr_t
*make_expr(enum expr_type type
)
43 expr_t
*e
= xmalloc(sizeof(expr_t
));
52 expr_t
*make_exprl(enum expr_type type
, long val
)
54 expr_t
*e
= xmalloc(sizeof(expr_t
));
59 /* check for numeric constant */
60 if (type
== EXPR_NUM
|| type
== EXPR_HEXNUM
|| type
== EXPR_TRUEFALSE
)
62 /* make sure true/false value is valid */
63 assert(type
!= EXPR_TRUEFALSE
|| val
== 0 || val
== 1);
70 expr_t
*make_exprd(enum expr_type type
, double val
)
72 expr_t
*e
= xmalloc(sizeof(expr_t
));
81 expr_t
*make_exprs(enum expr_type type
, char *val
)
84 e
= xmalloc(sizeof(expr_t
));
89 /* check for predefined constants */
90 if (type
== EXPR_IDENTIFIER
)
92 var_t
*c
= find_const(val
, 0);
98 e
->cval
= c
->eval
->cval
;
104 expr_t
*make_exprt(enum expr_type type
, type_t
*tref
, expr_t
*expr
)
107 e
= xmalloc(sizeof(expr_t
));
112 if (type
== EXPR_SIZEOF
)
114 /* only do this for types that should be the same on all platforms */
115 if (is_integer_type(tref
) || is_float_type(tref
))
117 unsigned int align
= 0;
119 e
->cval
= type_memsize(tref
, &align
);
122 /* check for cast of constant expression */
123 if (type
== EXPR_CAST
&& expr
->is_const
)
126 e
->cval
= expr
->cval
;
131 expr_t
*make_expr1(enum expr_type type
, expr_t
*expr
)
134 e
= xmalloc(sizeof(expr_t
));
139 /* check for compile-time optimization */
146 e
->cval
= !expr
->cval
;
149 e
->cval
= +expr
->cval
;
152 e
->cval
= -expr
->cval
;
155 e
->cval
= ~expr
->cval
;
165 expr_t
*make_expr2(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
)
168 e
= xmalloc(sizeof(expr_t
));
173 /* check for compile-time optimization */
174 if (expr1
->is_const
&& expr2
->is_const
)
180 e
->cval
= expr1
->cval
+ expr2
->cval
;
183 e
->cval
= expr1
->cval
- expr2
->cval
;
186 if (expr2
->cval
== 0)
188 error_loc("divide by zero in expression\n");
192 e
->cval
= expr1
->cval
% expr2
->cval
;
195 e
->cval
= expr1
->cval
* expr2
->cval
;
198 if (expr2
->cval
== 0)
200 error_loc("divide by zero in expression\n");
204 e
->cval
= expr1
->cval
/ expr2
->cval
;
207 e
->cval
= expr1
->cval
| expr2
->cval
;
210 e
->cval
= expr1
->cval
& expr2
->cval
;
213 e
->cval
= expr1
->cval
<< expr2
->cval
;
216 e
->cval
= expr1
->cval
>> expr2
->cval
;
219 e
->cval
= expr1
->cval
|| expr2
->cval
;
222 e
->cval
= expr1
->cval
&& expr2
->cval
;
225 e
->cval
= expr1
->cval
^ expr2
->cval
;
228 e
->cval
= expr1
->cval
== expr2
->cval
;
230 case EXPR_INEQUALITY
:
231 e
->cval
= expr1
->cval
!= expr2
->cval
;
234 e
->cval
= expr1
->cval
> expr2
->cval
;
237 e
->cval
= expr1
->cval
< expr2
->cval
;
240 e
->cval
= expr1
->cval
>= expr2
->cval
;
243 e
->cval
= expr1
->cval
<= expr2
->cval
;
253 expr_t
*make_expr3(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
, expr_t
*expr3
)
256 e
= xmalloc(sizeof(expr_t
));
262 /* check for compile-time optimization */
263 if (expr1
->is_const
&& expr2
->is_const
&& expr3
->is_const
)
269 e
->cval
= expr1
->cval
? expr2
->cval
: expr3
->cval
;
279 struct expression_type
281 int is_variable
; /* is the expression resolved to a variable? */
282 int is_temporary
; /* should the type be freed? */
286 static int is_integer_type(const type_t
*type
)
288 switch (type_get_type(type
))
293 switch (type_basic_get_type(type
))
295 case TYPE_BASIC_INT8
:
296 case TYPE_BASIC_INT16
:
297 case TYPE_BASIC_INT32
:
298 case TYPE_BASIC_INT64
:
300 case TYPE_BASIC_INT3264
:
301 case TYPE_BASIC_CHAR
:
302 case TYPE_BASIC_HYPER
:
303 case TYPE_BASIC_BYTE
:
304 case TYPE_BASIC_WCHAR
:
305 case TYPE_BASIC_ERROR_STATUS_T
:
307 case TYPE_BASIC_FLOAT
:
308 case TYPE_BASIC_DOUBLE
:
309 case TYPE_BASIC_HANDLE
:
318 static int is_float_type(const type_t
*type
)
320 return (type_get_type(type
) == TYPE_BASIC
&&
321 (type_basic_get_type(type
) == TYPE_BASIC_FLOAT
||
322 type_basic_get_type(type
) == TYPE_BASIC_DOUBLE
));
325 static void check_scalar_type(const struct expr_loc
*expr_loc
,
326 const type_t
*cont_type
, const type_t
*type
)
328 if (!cont_type
|| (!is_integer_type(type
) && !is_ptr(type
) &&
329 !is_float_type(type
)))
330 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
331 expr_loc
->attr
? " for attribute " : "",
332 expr_loc
->attr
? expr_loc
->attr
: "");
335 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
336 const type_t
*cont_type
, const type_t
*type
)
338 if (!cont_type
|| (!is_integer_type(type
) && !is_float_type(type
)))
339 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
340 expr_loc
->attr
? " for attribute " : "",
341 expr_loc
->attr
? expr_loc
->attr
: "");
344 static void check_integer_type(const struct expr_loc
*expr_loc
,
345 const type_t
*cont_type
, const type_t
*type
)
347 if (!cont_type
|| !is_integer_type(type
))
348 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
349 expr_loc
->attr
? " for attribute " : "",
350 expr_loc
->attr
? expr_loc
->attr
: "");
353 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
357 const var_list_t
*fields
= NULL
;
359 *found_in_cont_type
= 0;
363 switch (type_get_type(cont_type
))
366 fields
= type_function_get_args(cont_type
);
369 fields
= type_struct_get_fields(cont_type
);
372 case TYPE_ENCAPSULATED_UNION
:
373 fields
= type_union_get_cases(cont_type
);
387 /* shouldn't get here because of using type_get_type above */
393 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
394 if (field
->name
&& !strcmp(identifier
, field
->name
))
397 *found_in_cont_type
= 1;
403 var_t
*const_var
= find_const(identifier
, 0);
404 if (const_var
) type
= const_var
->type
;
410 static int is_valid_member_operand(const type_t
*type
)
412 switch (type_get_type(type
))
423 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
424 const type_t
*cont_type
,
427 struct expression_type result
;
428 result
.is_variable
= FALSE
;
429 result
.is_temporary
= FALSE
;
438 result
.is_variable
= FALSE
;
439 result
.is_temporary
= FALSE
;
440 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
443 result
.is_variable
= FALSE
;
444 result
.is_temporary
= TRUE
;
445 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_CHAR
, 0), NULL
);
448 result
.is_variable
= FALSE
;
449 result
.is_temporary
= TRUE
;
450 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_WCHAR
, 0), NULL
);
453 result
.is_variable
= FALSE
;
454 result
.is_temporary
= TRUE
;
455 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
457 case EXPR_IDENTIFIER
:
459 int found_in_cont_type
;
460 result
.is_variable
= TRUE
;
461 result
.is_temporary
= FALSE
;
462 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
465 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
466 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
467 expr_loc
->attr
? expr_loc
->attr
: "");
472 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
473 check_scalar_type(expr_loc
, cont_type
, result
.type
);
474 result
.is_variable
= FALSE
;
475 result
.is_temporary
= FALSE
;
476 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
479 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
480 check_integer_type(expr_loc
, cont_type
, result
.type
);
481 result
.is_variable
= FALSE
;
485 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
486 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
487 result
.is_variable
= FALSE
;
490 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
491 if (!result
.is_variable
)
492 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
493 expr_loc
->attr
? " for attribute " : "",
494 expr_loc
->attr
? expr_loc
->attr
: "");
495 result
.is_variable
= FALSE
;
496 result
.is_temporary
= TRUE
;
497 result
.type
= type_new_pointer(RPC_FC_UP
, result
.type
, NULL
);
500 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
501 if (result
.type
&& is_ptr(result
.type
))
502 result
.type
= type_pointer_get_ref(result
.type
);
503 else if(result
.type
&& is_array(result
.type
)
504 && type_array_is_decl_as_ptr(result
.type
))
505 result
.type
= type_array_get_element(result
.type
);
507 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
508 expr_loc
->attr
? " for attribute " : "",
509 expr_loc
->attr
? expr_loc
->attr
: "");
512 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
513 result
.type
= e
->u
.tref
;
516 result
.is_variable
= FALSE
;
517 result
.is_temporary
= FALSE
;
518 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
531 struct expression_type result_right
;
532 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
533 result
.is_variable
= FALSE
;
534 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
535 /* FIXME: these checks aren't strict enough for some of the operators */
536 check_scalar_type(expr_loc
, cont_type
, result
.type
);
537 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
543 case EXPR_INEQUALITY
:
549 struct expression_type result_left
, result_right
;
550 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
551 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
552 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
553 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
554 result
.is_variable
= FALSE
;
555 result
.is_temporary
= FALSE
;
556 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
560 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
561 if (result
.type
&& is_valid_member_operand(result
.type
))
562 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
564 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",
565 expr_loc
->attr
? " for attribute " : "",
566 expr_loc
->attr
? expr_loc
->attr
: "");
570 struct expression_type result_first
, result_second
, result_third
;
571 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
572 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
573 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
574 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
575 /* FIXME: determine the correct return type */
576 result
= result_second
;
577 result
.is_variable
= FALSE
;
581 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
582 if (result
.type
&& is_array(result
.type
))
584 struct expression_type index_result
;
585 result
.type
= type_array_get_element(result
.type
);
586 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
587 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
588 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
589 expr_loc
->attr
? " for attribute " : "",
590 expr_loc
->attr
? expr_loc
->attr
: "");
593 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
594 expr_loc
->attr
? " for attribute " : "",
595 expr_loc
->attr
? expr_loc
->attr
: "");
601 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
603 struct expression_type expr_type
;
604 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
605 return expr_type
.type
;
608 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
609 int toplevel
, const char *toplevel_prefix
,
610 const type_t
*cont_type
, const char *local_var_prefix
)
617 fprintf(h
, "%lu", e
->u
.lval
);
620 fprintf(h
, "0x%lx", e
->u
.lval
);
623 fprintf(h
, "%#.15g", e
->u
.dval
);
631 case EXPR_IDENTIFIER
:
632 if (toplevel
&& toplevel_prefix
&& cont_type
)
634 int found_in_cont_type
;
635 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
636 if (found_in_cont_type
)
638 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
642 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
645 fprintf(h
, "\"%s\"", e
->u
.sval
);
648 fprintf(h
, "L\"%s\"", e
->u
.sval
);
652 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
656 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
660 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
664 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
668 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
672 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
676 write_type_decl(h
, e
->u
.tref
, NULL
);
678 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
681 fprintf(h
, "sizeof(");
682 write_type_decl(h
, e
->u
.tref
, NULL
);
698 case EXPR_INEQUALITY
:
703 if (brackets
) fprintf(h
, "(");
704 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
707 case EXPR_SHL
: fprintf(h
, " << "); break;
708 case EXPR_SHR
: fprintf(h
, " >> "); break;
709 case EXPR_MOD
: fprintf(h
, " %% "); break;
710 case EXPR_MUL
: fprintf(h
, " * "); break;
711 case EXPR_DIV
: fprintf(h
, " / "); break;
712 case EXPR_ADD
: fprintf(h
, " + "); break;
713 case EXPR_SUB
: fprintf(h
, " - "); break;
714 case EXPR_AND
: fprintf(h
, " & "); break;
715 case EXPR_OR
: fprintf(h
, " | "); break;
716 case EXPR_LOGOR
: fprintf(h
, " || "); break;
717 case EXPR_LOGAND
: fprintf(h
, " && "); break;
718 case EXPR_XOR
: fprintf(h
, " ^ "); break;
719 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
720 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
721 case EXPR_GTR
: fprintf(h
, " > "); break;
722 case EXPR_LESS
: fprintf(h
, " < "); break;
723 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
724 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
727 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
728 if (brackets
) fprintf(h
, ")");
731 if (brackets
) fprintf(h
, "(");
732 if (e
->ref
->type
== EXPR_PPTR
)
734 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
739 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
742 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
743 if (brackets
) fprintf(h
, ")");
746 if (brackets
) fprintf(h
, "(");
747 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
749 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
751 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
752 if (brackets
) fprintf(h
, ")");
755 if (brackets
) fprintf(h
, "(");
756 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
758 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
760 if (brackets
) fprintf(h
, ")");
765 /* This is actually fairly involved to implement precisely, due to the
766 effects attributes may have and things like that. Right now this is
767 only used for optimization, so just check for a very small set of
768 criteria that guarantee the types are equivalent; assume every thing
769 else is different. */
770 static int compare_type(const type_t
*a
, const type_t
*b
)
775 && strcmp(a
->name
, b
->name
) == 0))
777 /* Ordering doesn't need to be implemented yet. */
781 int compare_expr(const expr_t
*a
, const expr_t
*b
)
785 if (a
->type
!= b
->type
)
786 return a
->type
- b
->type
;
793 return a
->u
.lval
- b
->u
.lval
;
795 return a
->u
.dval
- b
->u
.dval
;
796 case EXPR_IDENTIFIER
:
799 return strcmp(a
->u
.sval
, b
->u
.sval
);
801 ret
= compare_expr(a
->ref
, b
->ref
);
804 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
807 return compare_expr(a
->ext2
, b
->ext2
);
823 case EXPR_INEQUALITY
:
828 ret
= compare_expr(a
->ref
, b
->ref
);
831 return compare_expr(a
->u
.ext
, b
->u
.ext
);
833 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
843 return compare_expr(a
->ref
, b
->ref
);
845 return compare_type(a
->u
.tref
, b
->u
.tref
);