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
, var_t
*var
, expr_t
*expr
)
109 if (var
->stgclass
!= STG_NONE
&& var
->stgclass
!= STG_REGISTER
)
110 error_loc("invalid storage class for type expression\n");
114 e
= xmalloc(sizeof(expr_t
));
119 if (type
== EXPR_SIZEOF
)
121 /* only do this for types that should be the same on all platforms */
122 if (is_integer_type(tref
) || is_float_type(tref
))
124 unsigned int align
= 0;
126 e
->cval
= type_memsize(tref
, &align
);
129 /* check for cast of constant expression */
130 if (type
== EXPR_CAST
&& expr
->is_const
)
133 e
->cval
= expr
->cval
;
139 expr_t
*make_expr1(enum expr_type type
, expr_t
*expr
)
142 e
= xmalloc(sizeof(expr_t
));
147 /* check for compile-time optimization */
154 e
->cval
= !expr
->cval
;
157 e
->cval
= +expr
->cval
;
160 e
->cval
= -expr
->cval
;
163 e
->cval
= ~expr
->cval
;
173 expr_t
*make_expr2(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
)
176 e
= xmalloc(sizeof(expr_t
));
181 /* check for compile-time optimization */
182 if (expr1
->is_const
&& expr2
->is_const
)
188 e
->cval
= expr1
->cval
+ expr2
->cval
;
191 e
->cval
= expr1
->cval
- expr2
->cval
;
194 if (expr2
->cval
== 0)
196 error_loc("divide by zero in expression\n");
200 e
->cval
= expr1
->cval
% expr2
->cval
;
203 e
->cval
= expr1
->cval
* expr2
->cval
;
206 if (expr2
->cval
== 0)
208 error_loc("divide by zero in expression\n");
212 e
->cval
= expr1
->cval
/ expr2
->cval
;
215 e
->cval
= expr1
->cval
| expr2
->cval
;
218 e
->cval
= expr1
->cval
& expr2
->cval
;
221 e
->cval
= expr1
->cval
<< expr2
->cval
;
224 e
->cval
= expr1
->cval
>> expr2
->cval
;
227 e
->cval
= expr1
->cval
|| expr2
->cval
;
230 e
->cval
= expr1
->cval
&& expr2
->cval
;
233 e
->cval
= expr1
->cval
^ expr2
->cval
;
236 e
->cval
= expr1
->cval
== expr2
->cval
;
238 case EXPR_INEQUALITY
:
239 e
->cval
= expr1
->cval
!= expr2
->cval
;
242 e
->cval
= expr1
->cval
> expr2
->cval
;
245 e
->cval
= expr1
->cval
< expr2
->cval
;
248 e
->cval
= expr1
->cval
>= expr2
->cval
;
251 e
->cval
= expr1
->cval
<= expr2
->cval
;
261 expr_t
*make_expr3(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
, expr_t
*expr3
)
264 e
= xmalloc(sizeof(expr_t
));
270 /* check for compile-time optimization */
271 if (expr1
->is_const
&& expr2
->is_const
&& expr3
->is_const
)
277 e
->cval
= expr1
->cval
? expr2
->cval
: expr3
->cval
;
287 struct expression_type
289 int is_variable
; /* is the expression resolved to a variable? */
290 int is_temporary
; /* should the type be freed? */
294 static int is_integer_type(const type_t
*type
)
296 switch (type_get_type(type
))
301 switch (type_basic_get_type(type
))
303 case TYPE_BASIC_INT8
:
304 case TYPE_BASIC_INT16
:
305 case TYPE_BASIC_INT32
:
306 case TYPE_BASIC_INT64
:
308 case TYPE_BASIC_INT3264
:
309 case TYPE_BASIC_CHAR
:
310 case TYPE_BASIC_HYPER
:
311 case TYPE_BASIC_BYTE
:
312 case TYPE_BASIC_WCHAR
:
313 case TYPE_BASIC_ERROR_STATUS_T
:
315 case TYPE_BASIC_FLOAT
:
316 case TYPE_BASIC_DOUBLE
:
317 case TYPE_BASIC_HANDLE
:
326 static int is_float_type(const type_t
*type
)
328 return (type_get_type(type
) == TYPE_BASIC
&&
329 (type_basic_get_type(type
) == TYPE_BASIC_FLOAT
||
330 type_basic_get_type(type
) == TYPE_BASIC_DOUBLE
));
333 static void check_scalar_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_ptr(type
) &&
337 !is_float_type(type
)))
338 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
339 expr_loc
->attr
? " for attribute " : "",
340 expr_loc
->attr
? expr_loc
->attr
: "");
343 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
344 const type_t
*cont_type
, const type_t
*type
)
346 if (!cont_type
|| (!is_integer_type(type
) && !is_float_type(type
)))
347 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
348 expr_loc
->attr
? " for attribute " : "",
349 expr_loc
->attr
? expr_loc
->attr
: "");
352 static void check_integer_type(const struct expr_loc
*expr_loc
,
353 const type_t
*cont_type
, const type_t
*type
)
355 if (!cont_type
|| !is_integer_type(type
))
356 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
357 expr_loc
->attr
? " for attribute " : "",
358 expr_loc
->attr
? expr_loc
->attr
: "");
361 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
365 const var_list_t
*fields
= NULL
;
367 *found_in_cont_type
= 0;
371 switch (type_get_type(cont_type
))
374 fields
= type_function_get_args(cont_type
);
377 fields
= type_struct_get_fields(cont_type
);
380 case TYPE_ENCAPSULATED_UNION
:
381 fields
= type_union_get_cases(cont_type
);
395 /* shouldn't get here because of using type_get_type above */
401 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
402 if (field
->name
&& !strcmp(identifier
, field
->name
))
405 *found_in_cont_type
= 1;
411 var_t
*const_var
= find_const(identifier
, 0);
412 if (const_var
) type
= const_var
->type
;
418 static int is_valid_member_operand(const type_t
*type
)
420 switch (type_get_type(type
))
431 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
432 const type_t
*cont_type
,
435 struct expression_type result
;
436 result
.is_variable
= FALSE
;
437 result
.is_temporary
= FALSE
;
446 result
.is_variable
= FALSE
;
447 result
.is_temporary
= FALSE
;
448 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
451 result
.is_variable
= FALSE
;
452 result
.is_temporary
= TRUE
;
453 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_CHAR
, 0), NULL
);
456 result
.is_variable
= FALSE
;
457 result
.is_temporary
= TRUE
;
458 result
.type
= type_new_pointer(RPC_FC_UP
, type_new_int(TYPE_BASIC_WCHAR
, 0), NULL
);
461 result
.is_variable
= FALSE
;
462 result
.is_temporary
= TRUE
;
463 result
.type
= type_new_basic(TYPE_BASIC_DOUBLE
);
465 case EXPR_IDENTIFIER
:
467 int found_in_cont_type
;
468 result
.is_variable
= TRUE
;
469 result
.is_temporary
= FALSE
;
470 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
473 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
474 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
475 expr_loc
->attr
? expr_loc
->attr
: "");
480 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
481 check_scalar_type(expr_loc
, cont_type
, result
.type
);
482 result
.is_variable
= FALSE
;
483 result
.is_temporary
= FALSE
;
484 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
487 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
488 check_integer_type(expr_loc
, cont_type
, result
.type
);
489 result
.is_variable
= FALSE
;
493 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
494 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
495 result
.is_variable
= FALSE
;
498 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
499 if (!result
.is_variable
)
500 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
501 expr_loc
->attr
? " for attribute " : "",
502 expr_loc
->attr
? expr_loc
->attr
: "");
503 result
.is_variable
= FALSE
;
504 result
.is_temporary
= TRUE
;
505 result
.type
= type_new_pointer(RPC_FC_UP
, result
.type
, NULL
);
508 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
509 if (result
.type
&& is_ptr(result
.type
))
510 result
.type
= type_pointer_get_ref(result
.type
);
511 else if(result
.type
&& is_array(result
.type
)
512 && type_array_is_decl_as_ptr(result
.type
))
513 result
.type
= type_array_get_element(result
.type
);
515 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
516 expr_loc
->attr
? " for attribute " : "",
517 expr_loc
->attr
? expr_loc
->attr
: "");
520 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
521 result
.type
= e
->u
.tref
;
524 result
.is_variable
= FALSE
;
525 result
.is_temporary
= FALSE
;
526 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
539 struct expression_type result_right
;
540 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
541 result
.is_variable
= FALSE
;
542 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
543 /* FIXME: these checks aren't strict enough for some of the operators */
544 check_scalar_type(expr_loc
, cont_type
, result
.type
);
545 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
551 case EXPR_INEQUALITY
:
557 struct expression_type result_left
, result_right
;
558 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
559 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
560 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
561 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
562 result
.is_variable
= FALSE
;
563 result
.is_temporary
= FALSE
;
564 result
.type
= type_new_int(TYPE_BASIC_INT
, 0);
568 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
569 if (result
.type
&& is_valid_member_operand(result
.type
))
570 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
572 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",
573 expr_loc
->attr
? " for attribute " : "",
574 expr_loc
->attr
? expr_loc
->attr
: "");
578 struct expression_type result_first
, result_second
, result_third
;
579 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
580 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
581 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
582 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
583 /* FIXME: determine the correct return type */
584 result
= result_second
;
585 result
.is_variable
= FALSE
;
589 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
590 if (result
.type
&& is_array(result
.type
))
592 struct expression_type index_result
;
593 result
.type
= type_array_get_element(result
.type
);
594 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
595 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
596 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
597 expr_loc
->attr
? " for attribute " : "",
598 expr_loc
->attr
? expr_loc
->attr
: "");
601 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
602 expr_loc
->attr
? " for attribute " : "",
603 expr_loc
->attr
? expr_loc
->attr
: "");
609 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
611 struct expression_type expr_type
;
612 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
613 return expr_type
.type
;
616 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
617 int toplevel
, const char *toplevel_prefix
,
618 const type_t
*cont_type
, const char *local_var_prefix
)
625 fprintf(h
, "%lu", e
->u
.lval
);
628 fprintf(h
, "0x%lx", e
->u
.lval
);
631 fprintf(h
, "%#.15g", e
->u
.dval
);
639 case EXPR_IDENTIFIER
:
640 if (toplevel
&& toplevel_prefix
&& cont_type
)
642 int found_in_cont_type
;
643 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
644 if (found_in_cont_type
)
646 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
650 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
653 fprintf(h
, "\"%s\"", e
->u
.sval
);
656 fprintf(h
, "L\"%s\"", e
->u
.sval
);
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_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
680 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
684 write_type_decl(h
, e
->u
.tref
, NULL
);
686 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
689 fprintf(h
, "sizeof(");
690 write_type_decl(h
, e
->u
.tref
, NULL
);
706 case EXPR_INEQUALITY
:
711 if (brackets
) fprintf(h
, "(");
712 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
715 case EXPR_SHL
: fprintf(h
, " << "); break;
716 case EXPR_SHR
: fprintf(h
, " >> "); break;
717 case EXPR_MOD
: fprintf(h
, " %% "); break;
718 case EXPR_MUL
: fprintf(h
, " * "); break;
719 case EXPR_DIV
: fprintf(h
, " / "); break;
720 case EXPR_ADD
: fprintf(h
, " + "); break;
721 case EXPR_SUB
: fprintf(h
, " - "); break;
722 case EXPR_AND
: fprintf(h
, " & "); break;
723 case EXPR_OR
: fprintf(h
, " | "); break;
724 case EXPR_LOGOR
: fprintf(h
, " || "); break;
725 case EXPR_LOGAND
: fprintf(h
, " && "); break;
726 case EXPR_XOR
: fprintf(h
, " ^ "); break;
727 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
728 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
729 case EXPR_GTR
: fprintf(h
, " > "); break;
730 case EXPR_LESS
: fprintf(h
, " < "); break;
731 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
732 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
735 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
736 if (brackets
) fprintf(h
, ")");
739 if (brackets
) fprintf(h
, "(");
740 if (e
->ref
->type
== EXPR_PPTR
)
742 write_expr(h
, e
->ref
->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
);
750 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
751 if (brackets
) fprintf(h
, ")");
754 if (brackets
) fprintf(h
, "(");
755 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
757 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
759 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
760 if (brackets
) fprintf(h
, ")");
763 if (brackets
) fprintf(h
, "(");
764 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
766 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
768 if (brackets
) fprintf(h
, ")");
773 /* This is actually fairly involved to implement precisely, due to the
774 effects attributes may have and things like that. Right now this is
775 only used for optimization, so just check for a very small set of
776 criteria that guarantee the types are equivalent; assume every thing
777 else is different. */
778 static int compare_type(const type_t
*a
, const type_t
*b
)
783 && strcmp(a
->name
, b
->name
) == 0))
785 /* Ordering doesn't need to be implemented yet. */
789 int compare_expr(const expr_t
*a
, const expr_t
*b
)
793 if (a
->type
!= b
->type
)
794 return a
->type
- b
->type
;
801 return a
->u
.lval
- b
->u
.lval
;
803 return a
->u
.dval
- b
->u
.dval
;
804 case EXPR_IDENTIFIER
:
807 return strcmp(a
->u
.sval
, b
->u
.sval
);
809 ret
= compare_expr(a
->ref
, b
->ref
);
812 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
815 return compare_expr(a
->ext2
, b
->ext2
);
831 case EXPR_INEQUALITY
:
836 ret
= compare_expr(a
->ref
, b
->ref
);
839 return compare_expr(a
->u
.ext
, b
->u
.ext
);
841 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
851 return compare_expr(a
->ref
, b
->ref
);
853 return compare_type(a
->u
.tref
, b
->u
.tref
);