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
37 expr_t
*make_expr(enum expr_type type
)
39 expr_t
*e
= xmalloc(sizeof(expr_t
));
48 expr_t
*make_exprl(enum expr_type type
, long val
)
50 expr_t
*e
= xmalloc(sizeof(expr_t
));
55 /* check for numeric constant */
56 if (type
== EXPR_NUM
|| type
== EXPR_HEXNUM
|| type
== EXPR_TRUEFALSE
)
58 /* make sure true/false value is valid */
59 assert(type
!= EXPR_TRUEFALSE
|| val
== 0 || val
== 1);
66 expr_t
*make_exprd(enum expr_type type
, double val
)
68 expr_t
*e
= xmalloc(sizeof(expr_t
));
77 expr_t
*make_exprs(enum expr_type type
, char *val
)
80 e
= xmalloc(sizeof(expr_t
));
85 /* check for predefined constants */
86 if (type
== EXPR_IDENTIFIER
)
88 var_t
*c
= find_const(val
, 0);
94 e
->cval
= c
->eval
->cval
;
100 expr_t
*make_exprt(enum expr_type type
, type_t
*tref
, expr_t
*expr
)
103 e
= xmalloc(sizeof(expr_t
));
108 /* check for cast of constant expression */
109 if (type
== EXPR_SIZEOF
)
129 case RPC_FC_ERROR_STATUS_T
:
140 if (type
== EXPR_CAST
&& expr
->is_const
)
143 e
->cval
= expr
->cval
;
148 expr_t
*make_expr1(enum expr_type type
, expr_t
*expr
)
151 e
= xmalloc(sizeof(expr_t
));
156 /* check for compile-time optimization */
163 e
->cval
= !expr
->cval
;
166 e
->cval
= +expr
->cval
;
169 e
->cval
= -expr
->cval
;
172 e
->cval
= ~expr
->cval
;
182 expr_t
*make_expr2(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
)
185 e
= xmalloc(sizeof(expr_t
));
190 /* check for compile-time optimization */
191 if (expr1
->is_const
&& expr2
->is_const
)
197 e
->cval
= expr1
->cval
+ expr2
->cval
;
200 e
->cval
= expr1
->cval
- expr2
->cval
;
203 if (expr2
->cval
== 0)
205 error_loc("divide by zero in expression\n");
209 e
->cval
= expr1
->cval
% expr2
->cval
;
212 e
->cval
= expr1
->cval
* expr2
->cval
;
215 if (expr2
->cval
== 0)
217 error_loc("divide by zero in expression\n");
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
;
239 e
->cval
= expr1
->cval
&& expr2
->cval
;
242 e
->cval
= expr1
->cval
^ expr2
->cval
;
245 e
->cval
= expr1
->cval
== expr2
->cval
;
247 case EXPR_INEQUALITY
:
248 e
->cval
= expr1
->cval
!= expr2
->cval
;
251 e
->cval
= expr1
->cval
> expr2
->cval
;
254 e
->cval
= expr1
->cval
< expr2
->cval
;
257 e
->cval
= expr1
->cval
>= expr2
->cval
;
260 e
->cval
= expr1
->cval
<= expr2
->cval
;
270 expr_t
*make_expr3(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
, expr_t
*expr3
)
273 e
= xmalloc(sizeof(expr_t
));
279 /* check for compile-time optimization */
280 if (expr1
->is_const
&& expr2
->is_const
&& expr3
->is_const
)
286 e
->cval
= expr1
->cval
? expr2
->cval
: expr3
->cval
;
296 struct expression_type
298 int is_variable
; /* is the expression resolved to a variable? */
299 int is_temporary
; /* should the type be freed? */
303 static int is_integer_type(const type_t
*type
)
317 case RPC_FC_UINT3264
:
327 static void check_scalar_type(const struct expr_loc
*expr_loc
,
328 const type_t
*cont_type
, const type_t
*type
)
330 if (!cont_type
|| (!is_integer_type(type
) && !is_ptr(type
) &&
331 type
->type
!= RPC_FC_FLOAT
&&
332 type
->type
!= RPC_FC_DOUBLE
))
333 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
334 expr_loc
->attr
? " for attribute " : "",
335 expr_loc
->attr
? expr_loc
->attr
: "");
338 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
339 const type_t
*cont_type
, const type_t
*type
)
341 if (!cont_type
|| (!is_integer_type(type
) &&
342 type
->type
!= RPC_FC_FLOAT
&&
343 type
->type
!= RPC_FC_DOUBLE
))
344 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
345 expr_loc
->attr
? " for attribute " : "",
346 expr_loc
->attr
? expr_loc
->attr
: "");
349 static void check_integer_type(const struct expr_loc
*expr_loc
,
350 const type_t
*cont_type
, const type_t
*type
)
352 if (!cont_type
|| !is_integer_type(type
))
353 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
354 expr_loc
->attr
? " for attribute " : "",
355 expr_loc
->attr
? expr_loc
->attr
: "");
358 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
362 const var_list_t
*fields
= NULL
;
364 *found_in_cont_type
= 0;
368 if (cont_type
->type
== RPC_FC_FUNCTION
)
369 fields
= type_function_get_args(cont_type
);
370 else if (is_struct(cont_type
->type
))
371 fields
= type_struct_get_fields(cont_type
);
372 else if (is_union(cont_type
->type
))
373 fields
= type_union_get_cases(cont_type
);
376 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
377 if (field
->name
&& !strcmp(identifier
, field
->name
))
380 *found_in_cont_type
= 1;
386 var_t
*const_var
= find_const(identifier
, 0);
387 if (const_var
) type
= const_var
->type
;
393 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
394 const type_t
*cont_type
,
397 struct expression_type result
;
398 result
.is_variable
= FALSE
;
399 result
.is_temporary
= FALSE
;
408 result
.is_variable
= FALSE
;
409 result
.is_temporary
= FALSE
;
410 result
.type
= find_type("int", 0);
413 result
.is_variable
= FALSE
;
414 result
.is_temporary
= TRUE
;
415 result
.type
= make_type(RPC_FC_RP
, find_type("char", 0));
418 result
.is_variable
= FALSE
;
419 result
.is_temporary
= TRUE
;
420 result
.type
= make_type(RPC_FC_RP
, find_type("wchar_t", 0));
423 result
.is_variable
= FALSE
;
424 result
.is_temporary
= FALSE
;
425 result
.type
= find_type("double", 0);
427 case EXPR_IDENTIFIER
:
429 int found_in_cont_type
;
430 result
.is_variable
= TRUE
;
431 result
.is_temporary
= FALSE
;
432 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
435 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
436 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
437 expr_loc
->attr
? expr_loc
->attr
: "");
442 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
443 check_scalar_type(expr_loc
, cont_type
, result
.type
);
444 result
.is_variable
= FALSE
;
445 result
.is_temporary
= FALSE
;
446 result
.type
= find_type("int", 0);
449 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
450 check_integer_type(expr_loc
, cont_type
, result
.type
);
451 result
.is_variable
= FALSE
;
455 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
456 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
457 result
.is_variable
= FALSE
;
460 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
461 if (!result
.is_variable
)
462 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
463 expr_loc
->attr
? " for attribute " : "",
464 expr_loc
->attr
? expr_loc
->attr
: "");
465 result
.is_variable
= FALSE
;
466 result
.is_temporary
= TRUE
;
467 result
.type
= make_type(RPC_FC_RP
, result
.type
);
470 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
471 if (result
.type
&& is_ptr(result
.type
))
472 result
.type
= type_pointer_get_ref(result
.type
);
474 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
475 expr_loc
->attr
? " for attribute " : "",
476 expr_loc
->attr
? expr_loc
->attr
: "");
479 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
480 result
.type
= e
->u
.tref
;
483 result
.is_variable
= FALSE
;
484 result
.is_temporary
= FALSE
;
485 result
.type
= find_type("int", 0);
498 struct expression_type result_right
;
499 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
500 result
.is_variable
= FALSE
;
501 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
502 /* FIXME: these checks aren't strict enough for some of the operators */
503 check_scalar_type(expr_loc
, cont_type
, result
.type
);
504 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
510 case EXPR_INEQUALITY
:
516 struct expression_type result_left
, result_right
;
517 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
518 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
519 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
520 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
521 result
.is_variable
= FALSE
;
522 result
.is_temporary
= FALSE
;
523 result
.type
= find_type("int", 0);
527 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
528 if (result
.type
&& (is_struct(result
.type
->type
) || is_union(result
.type
->type
) || result
.type
->type
== RPC_FC_ENUM16
|| result
.type
->type
== RPC_FC_ENUM32
))
529 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
531 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",
532 expr_loc
->attr
? " for attribute " : "",
533 expr_loc
->attr
? expr_loc
->attr
: "");
537 struct expression_type result_first
, result_second
, result_third
;
538 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
539 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
540 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
541 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
542 /* FIXME: determine the correct return type */
543 result
= result_second
;
544 result
.is_variable
= FALSE
;
548 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
549 if (result
.type
&& is_array(result
.type
))
551 struct expression_type index_result
;
552 result
.type
= type_array_get_element(result
.type
);
553 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
554 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
555 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
556 expr_loc
->attr
? " for attribute " : "",
557 expr_loc
->attr
? expr_loc
->attr
: "");
560 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
561 expr_loc
->attr
? " for attribute " : "",
562 expr_loc
->attr
? expr_loc
->attr
: "");
568 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
570 struct expression_type expr_type
;
571 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
572 return expr_type
.type
;
575 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
576 int toplevel
, const char *toplevel_prefix
,
577 const type_t
*cont_type
, const char *local_var_prefix
)
584 fprintf(h
, "%lu", e
->u
.lval
);
587 fprintf(h
, "0x%lx", e
->u
.lval
);
590 fprintf(h
, "%#.15g", e
->u
.dval
);
598 case EXPR_IDENTIFIER
:
599 if (toplevel
&& toplevel_prefix
&& cont_type
)
601 int found_in_cont_type
;
602 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
603 if (found_in_cont_type
)
605 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
609 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
612 fprintf(h
, "\"%s\"", e
->u
.sval
);
615 fprintf(h
, "L\"%s\"", e
->u
.sval
);
619 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
623 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
627 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
631 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
635 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
639 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
643 write_type_decl(h
, e
->u
.tref
, NULL
);
645 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
648 fprintf(h
, "sizeof(");
649 write_type_decl(h
, e
->u
.tref
, NULL
);
665 case EXPR_INEQUALITY
:
670 if (brackets
) fprintf(h
, "(");
671 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
674 case EXPR_SHL
: fprintf(h
, " << "); break;
675 case EXPR_SHR
: fprintf(h
, " >> "); break;
676 case EXPR_MOD
: fprintf(h
, " %% "); break;
677 case EXPR_MUL
: fprintf(h
, " * "); break;
678 case EXPR_DIV
: fprintf(h
, " / "); break;
679 case EXPR_ADD
: fprintf(h
, " + "); break;
680 case EXPR_SUB
: fprintf(h
, " - "); break;
681 case EXPR_AND
: fprintf(h
, " & "); break;
682 case EXPR_OR
: fprintf(h
, " | "); break;
683 case EXPR_LOGOR
: fprintf(h
, " || "); break;
684 case EXPR_LOGAND
: fprintf(h
, " && "); break;
685 case EXPR_XOR
: fprintf(h
, " ^ "); break;
686 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
687 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
688 case EXPR_GTR
: fprintf(h
, " > "); break;
689 case EXPR_LESS
: fprintf(h
, " < "); break;
690 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
691 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
694 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
695 if (brackets
) fprintf(h
, ")");
698 if (brackets
) fprintf(h
, "(");
699 if (e
->ref
->type
== EXPR_PPTR
)
701 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
706 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
709 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
710 if (brackets
) fprintf(h
, ")");
713 if (brackets
) fprintf(h
, "(");
714 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
716 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
718 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
719 if (brackets
) fprintf(h
, ")");
722 if (brackets
) fprintf(h
, "(");
723 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
725 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
727 if (brackets
) fprintf(h
, ")");
732 /* This is actually fairly involved to implement precisely, due to the
733 effects attributes may have and things like that. Right now this is
734 only used for optimization, so just check for a very small set of
735 criteria that guarantee the types are equivalent; assume every thing
736 else is different. */
737 static int compare_type(const type_t
*a
, const type_t
*b
)
742 && strcmp(a
->name
, b
->name
) == 0))
744 /* Ordering doesn't need to be implemented yet. */
748 int compare_expr(const expr_t
*a
, const expr_t
*b
)
752 if (a
->type
!= b
->type
)
753 return a
->type
- b
->type
;
760 return a
->u
.lval
- b
->u
.lval
;
762 return a
->u
.dval
- b
->u
.dval
;
763 case EXPR_IDENTIFIER
:
766 return strcmp(a
->u
.sval
, b
->u
.sval
);
768 ret
= compare_expr(a
->ref
, b
->ref
);
771 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
774 return compare_expr(a
->ext2
, b
->ext2
);
790 case EXPR_INEQUALITY
:
795 ret
= compare_expr(a
->ref
, b
->ref
);
798 return compare_expr(a
->u
.ext
, b
->u
.ext
);
800 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
810 return compare_expr(a
->ref
, b
->ref
);
812 return compare_type(a
->u
.tref
, b
->u
.tref
);