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_fc(type
))
305 case RPC_FC_UINT3264
:
316 static int is_float_type(const type_t
*type
)
318 return (type_get_type(type
) == TYPE_BASIC
&&
319 (type_basic_get_fc(type
) == RPC_FC_FLOAT
||
320 type_basic_get_fc(type
) == RPC_FC_DOUBLE
));
323 static void check_scalar_type(const struct expr_loc
*expr_loc
,
324 const type_t
*cont_type
, const type_t
*type
)
326 if (!cont_type
|| (!is_integer_type(type
) && !is_ptr(type
) &&
327 !is_float_type(type
)))
328 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
329 expr_loc
->attr
? " for attribute " : "",
330 expr_loc
->attr
? expr_loc
->attr
: "");
333 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
334 const type_t
*cont_type
, const type_t
*type
)
336 if (!cont_type
|| (!is_integer_type(type
) && !is_float_type(type
)))
337 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
338 expr_loc
->attr
? " for attribute " : "",
339 expr_loc
->attr
? expr_loc
->attr
: "");
342 static void check_integer_type(const struct expr_loc
*expr_loc
,
343 const type_t
*cont_type
, const type_t
*type
)
345 if (!cont_type
|| !is_integer_type(type
))
346 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
347 expr_loc
->attr
? " for attribute " : "",
348 expr_loc
->attr
? expr_loc
->attr
: "");
351 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
355 const var_list_t
*fields
= NULL
;
357 *found_in_cont_type
= 0;
361 switch (type_get_type(cont_type
))
364 fields
= type_function_get_args(cont_type
);
367 fields
= type_struct_get_fields(cont_type
);
370 case TYPE_ENCAPSULATED_UNION
:
371 fields
= type_union_get_cases(cont_type
);
384 /* shouldn't get here because of using type_get_type above */
390 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
391 if (field
->name
&& !strcmp(identifier
, field
->name
))
394 *found_in_cont_type
= 1;
400 var_t
*const_var
= find_const(identifier
, 0);
401 if (const_var
) type
= const_var
->type
;
407 static int is_valid_member_operand(const type_t
*type
)
409 switch (type_get_type(type
))
420 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
421 const type_t
*cont_type
,
424 struct expression_type result
;
425 result
.is_variable
= FALSE
;
426 result
.is_temporary
= FALSE
;
435 result
.is_variable
= FALSE
;
436 result
.is_temporary
= FALSE
;
437 result
.type
= find_type("int", 0);
440 result
.is_variable
= FALSE
;
441 result
.is_temporary
= TRUE
;
442 result
.type
= make_type(RPC_FC_RP
, find_type("char", 0));
445 result
.is_variable
= FALSE
;
446 result
.is_temporary
= TRUE
;
447 result
.type
= make_type(RPC_FC_RP
, find_type("wchar_t", 0));
450 result
.is_variable
= FALSE
;
451 result
.is_temporary
= FALSE
;
452 result
.type
= find_type("double", 0);
454 case EXPR_IDENTIFIER
:
456 int found_in_cont_type
;
457 result
.is_variable
= TRUE
;
458 result
.is_temporary
= FALSE
;
459 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
462 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
463 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
464 expr_loc
->attr
? expr_loc
->attr
: "");
469 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
470 check_scalar_type(expr_loc
, cont_type
, result
.type
);
471 result
.is_variable
= FALSE
;
472 result
.is_temporary
= FALSE
;
473 result
.type
= find_type("int", 0);
476 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
477 check_integer_type(expr_loc
, cont_type
, result
.type
);
478 result
.is_variable
= FALSE
;
482 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
483 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
484 result
.is_variable
= FALSE
;
487 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
488 if (!result
.is_variable
)
489 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
490 expr_loc
->attr
? " for attribute " : "",
491 expr_loc
->attr
? expr_loc
->attr
: "");
492 result
.is_variable
= FALSE
;
493 result
.is_temporary
= TRUE
;
494 result
.type
= make_type(RPC_FC_RP
, result
.type
);
497 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
498 if (result
.type
&& is_ptr(result
.type
))
499 result
.type
= type_pointer_get_ref(result
.type
);
500 else if(result
.type
&& is_array(result
.type
)
501 && !result
.type
->declarray
)
502 result
.type
= type_array_get_element(result
.type
);
504 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
505 expr_loc
->attr
? " for attribute " : "",
506 expr_loc
->attr
? expr_loc
->attr
: "");
509 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
510 result
.type
= e
->u
.tref
;
513 result
.is_variable
= FALSE
;
514 result
.is_temporary
= FALSE
;
515 result
.type
= find_type("int", 0);
528 struct expression_type result_right
;
529 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
530 result
.is_variable
= FALSE
;
531 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
532 /* FIXME: these checks aren't strict enough for some of the operators */
533 check_scalar_type(expr_loc
, cont_type
, result
.type
);
534 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
540 case EXPR_INEQUALITY
:
546 struct expression_type result_left
, result_right
;
547 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
548 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
549 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
550 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
551 result
.is_variable
= FALSE
;
552 result
.is_temporary
= FALSE
;
553 result
.type
= find_type("int", 0);
557 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
558 if (result
.type
&& is_valid_member_operand(result
.type
))
559 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
561 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",
562 expr_loc
->attr
? " for attribute " : "",
563 expr_loc
->attr
? expr_loc
->attr
: "");
567 struct expression_type result_first
, result_second
, result_third
;
568 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
569 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
570 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
571 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
572 /* FIXME: determine the correct return type */
573 result
= result_second
;
574 result
.is_variable
= FALSE
;
578 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
579 if (result
.type
&& is_array(result
.type
))
581 struct expression_type index_result
;
582 result
.type
= type_array_get_element(result
.type
);
583 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
584 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
585 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
586 expr_loc
->attr
? " for attribute " : "",
587 expr_loc
->attr
? expr_loc
->attr
: "");
590 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
591 expr_loc
->attr
? " for attribute " : "",
592 expr_loc
->attr
? expr_loc
->attr
: "");
598 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
600 struct expression_type expr_type
;
601 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
602 return expr_type
.type
;
605 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
606 int toplevel
, const char *toplevel_prefix
,
607 const type_t
*cont_type
, const char *local_var_prefix
)
614 fprintf(h
, "%lu", e
->u
.lval
);
617 fprintf(h
, "0x%lx", e
->u
.lval
);
620 fprintf(h
, "%#.15g", e
->u
.dval
);
628 case EXPR_IDENTIFIER
:
629 if (toplevel
&& toplevel_prefix
&& cont_type
)
631 int found_in_cont_type
;
632 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
633 if (found_in_cont_type
)
635 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
639 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
642 fprintf(h
, "\"%s\"", e
->u
.sval
);
645 fprintf(h
, "L\"%s\"", e
->u
.sval
);
649 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
653 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
657 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
661 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
665 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
669 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
673 write_type_decl(h
, e
->u
.tref
, NULL
);
675 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
678 fprintf(h
, "sizeof(");
679 write_type_decl(h
, e
->u
.tref
, NULL
);
695 case EXPR_INEQUALITY
:
700 if (brackets
) fprintf(h
, "(");
701 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
704 case EXPR_SHL
: fprintf(h
, " << "); break;
705 case EXPR_SHR
: fprintf(h
, " >> "); break;
706 case EXPR_MOD
: fprintf(h
, " %% "); break;
707 case EXPR_MUL
: fprintf(h
, " * "); break;
708 case EXPR_DIV
: fprintf(h
, " / "); break;
709 case EXPR_ADD
: fprintf(h
, " + "); break;
710 case EXPR_SUB
: fprintf(h
, " - "); break;
711 case EXPR_AND
: fprintf(h
, " & "); break;
712 case EXPR_OR
: fprintf(h
, " | "); break;
713 case EXPR_LOGOR
: fprintf(h
, " || "); break;
714 case EXPR_LOGAND
: fprintf(h
, " && "); break;
715 case EXPR_XOR
: fprintf(h
, " ^ "); break;
716 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
717 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
718 case EXPR_GTR
: fprintf(h
, " > "); break;
719 case EXPR_LESS
: fprintf(h
, " < "); break;
720 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
721 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
724 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
725 if (brackets
) fprintf(h
, ")");
728 if (brackets
) fprintf(h
, "(");
729 if (e
->ref
->type
== EXPR_PPTR
)
731 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
736 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
739 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
740 if (brackets
) fprintf(h
, ")");
743 if (brackets
) fprintf(h
, "(");
744 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
746 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
748 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
749 if (brackets
) fprintf(h
, ")");
752 if (brackets
) fprintf(h
, "(");
753 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
755 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
757 if (brackets
) fprintf(h
, ")");
762 /* This is actually fairly involved to implement precisely, due to the
763 effects attributes may have and things like that. Right now this is
764 only used for optimization, so just check for a very small set of
765 criteria that guarantee the types are equivalent; assume every thing
766 else is different. */
767 static int compare_type(const type_t
*a
, const type_t
*b
)
772 && strcmp(a
->name
, b
->name
) == 0))
774 /* Ordering doesn't need to be implemented yet. */
778 int compare_expr(const expr_t
*a
, const expr_t
*b
)
782 if (a
->type
!= b
->type
)
783 return a
->type
- b
->type
;
790 return a
->u
.lval
- b
->u
.lval
;
792 return a
->u
.dval
- b
->u
.dval
;
793 case EXPR_IDENTIFIER
:
796 return strcmp(a
->u
.sval
, b
->u
.sval
);
798 ret
= compare_expr(a
->ref
, b
->ref
);
801 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
804 return compare_expr(a
->ext2
, b
->ext2
);
820 case EXPR_INEQUALITY
:
825 ret
= compare_expr(a
->ref
, b
->ref
);
828 return compare_expr(a
->u
.ext
, b
->u
.ext
);
830 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
840 return compare_expr(a
->ref
, b
->ref
);
842 return compare_type(a
->u
.tref
, b
->u
.tref
);