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
36 expr_t
*make_expr(enum expr_type type
)
38 expr_t
*e
= xmalloc(sizeof(expr_t
));
47 expr_t
*make_exprl(enum expr_type type
, long val
)
49 expr_t
*e
= xmalloc(sizeof(expr_t
));
54 /* check for numeric constant */
55 if (type
== EXPR_NUM
|| type
== EXPR_HEXNUM
|| type
== EXPR_TRUEFALSE
)
57 /* make sure true/false value is valid */
58 assert(type
!= EXPR_TRUEFALSE
|| val
== 0 || val
== 1);
65 expr_t
*make_exprd(enum expr_type type
, double val
)
67 expr_t
*e
= xmalloc(sizeof(expr_t
));
76 expr_t
*make_exprs(enum expr_type type
, char *val
)
79 e
= xmalloc(sizeof(expr_t
));
84 /* check for predefined constants */
85 if (type
== EXPR_IDENTIFIER
)
87 var_t
*c
= find_const(val
, 0);
93 e
->cval
= c
->eval
->cval
;
99 expr_t
*make_exprt(enum expr_type type
, type_t
*tref
, expr_t
*expr
)
102 e
= xmalloc(sizeof(expr_t
));
107 /* check for cast of constant expression */
108 if (type
== EXPR_SIZEOF
)
128 case RPC_FC_ERROR_STATUS_T
:
139 if (type
== EXPR_CAST
&& expr
->is_const
)
142 e
->cval
= expr
->cval
;
147 expr_t
*make_expr1(enum expr_type type
, expr_t
*expr
)
150 e
= xmalloc(sizeof(expr_t
));
155 /* check for compile-time optimization */
162 e
->cval
= !expr
->cval
;
165 e
->cval
= +expr
->cval
;
168 e
->cval
= -expr
->cval
;
171 e
->cval
= ~expr
->cval
;
181 expr_t
*make_expr2(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
)
184 e
= xmalloc(sizeof(expr_t
));
189 /* check for compile-time optimization */
190 if (expr1
->is_const
&& expr2
->is_const
)
196 e
->cval
= expr1
->cval
+ expr2
->cval
;
199 e
->cval
= expr1
->cval
- expr2
->cval
;
202 if (expr2
->cval
== 0)
204 error_loc("divide by zero in expression\n");
208 e
->cval
= expr1
->cval
% expr2
->cval
;
211 e
->cval
= expr1
->cval
* expr2
->cval
;
214 if (expr2
->cval
== 0)
216 error_loc("divide by zero in expression\n");
220 e
->cval
= expr1
->cval
/ expr2
->cval
;
223 e
->cval
= expr1
->cval
| expr2
->cval
;
226 e
->cval
= expr1
->cval
& expr2
->cval
;
229 e
->cval
= expr1
->cval
<< expr2
->cval
;
232 e
->cval
= expr1
->cval
>> expr2
->cval
;
235 e
->cval
= expr1
->cval
|| expr2
->cval
;
238 e
->cval
= expr1
->cval
&& expr2
->cval
;
241 e
->cval
= expr1
->cval
^ expr2
->cval
;
244 e
->cval
= expr1
->cval
== expr2
->cval
;
246 case EXPR_INEQUALITY
:
247 e
->cval
= expr1
->cval
!= expr2
->cval
;
250 e
->cval
= expr1
->cval
> expr2
->cval
;
253 e
->cval
= expr1
->cval
< expr2
->cval
;
256 e
->cval
= expr1
->cval
>= expr2
->cval
;
259 e
->cval
= expr1
->cval
<= expr2
->cval
;
269 expr_t
*make_expr3(enum expr_type type
, expr_t
*expr1
, expr_t
*expr2
, expr_t
*expr3
)
272 e
= xmalloc(sizeof(expr_t
));
278 /* check for compile-time optimization */
279 if (expr1
->is_const
&& expr2
->is_const
&& expr3
->is_const
)
285 e
->cval
= expr1
->cval
? expr2
->cval
: expr3
->cval
;
295 struct expression_type
297 int is_variable
; /* is the expression resolved to a variable? */
298 int is_temporary
; /* should the type be freed? */
302 static int is_integer_type(const type_t
*type
)
316 case RPC_FC_UINT3264
:
326 static void check_scalar_type(const struct expr_loc
*expr_loc
,
327 const type_t
*cont_type
, const type_t
*type
)
329 if (!cont_type
|| (!is_integer_type(type
) && !is_ptr(type
) &&
330 type
->type
!= RPC_FC_FLOAT
&&
331 type
->type
!= RPC_FC_DOUBLE
))
332 error_loc_info(&expr_loc
->v
->loc_info
, "scalar type required in expression%s%s\n",
333 expr_loc
->attr
? " for attribute " : "",
334 expr_loc
->attr
? expr_loc
->attr
: "");
337 static void check_arithmetic_type(const struct expr_loc
*expr_loc
,
338 const type_t
*cont_type
, const type_t
*type
)
340 if (!cont_type
|| (!is_integer_type(type
) &&
341 type
->type
!= RPC_FC_FLOAT
&&
342 type
->type
!= RPC_FC_DOUBLE
))
343 error_loc_info(&expr_loc
->v
->loc_info
, "arithmetic type required in expression%s%s\n",
344 expr_loc
->attr
? " for attribute " : "",
345 expr_loc
->attr
? expr_loc
->attr
: "");
348 static void check_integer_type(const struct expr_loc
*expr_loc
,
349 const type_t
*cont_type
, const type_t
*type
)
351 if (!cont_type
|| !is_integer_type(type
))
352 error_loc_info(&expr_loc
->v
->loc_info
, "integer type required in expression%s%s\n",
353 expr_loc
->attr
? " for attribute " : "",
354 expr_loc
->attr
? expr_loc
->attr
: "");
357 static type_t
*find_identifier(const char *identifier
, const type_t
*cont_type
, int *found_in_cont_type
)
361 const var_list_t
*fields
= NULL
;
363 *found_in_cont_type
= 0;
365 if (cont_type
&& (cont_type
->type
== RPC_FC_FUNCTION
|| is_struct(cont_type
->type
)))
366 fields
= cont_type
->fields_or_args
;
367 else if (cont_type
&& is_union(cont_type
->type
))
369 if (cont_type
->type
== RPC_FC_ENCAPSULATED_UNION
)
371 const var_t
*uv
= LIST_ENTRY(list_tail(cont_type
->fields_or_args
), const var_t
, entry
);
372 fields
= uv
->type
->fields_or_args
;
375 fields
= cont_type
->fields_or_args
;
378 if (fields
) LIST_FOR_EACH_ENTRY( field
, fields
, const var_t
, entry
)
379 if (field
->name
&& !strcmp(identifier
, field
->name
))
382 *found_in_cont_type
= 1;
388 var_t
*const_var
= find_const(identifier
, 0);
389 if (const_var
) type
= const_var
->type
;
395 static struct expression_type
resolve_expression(const struct expr_loc
*expr_loc
,
396 const type_t
*cont_type
,
399 struct expression_type result
;
400 result
.is_variable
= FALSE
;
401 result
.is_temporary
= FALSE
;
410 result
.is_variable
= FALSE
;
411 result
.is_temporary
= FALSE
;
412 result
.type
= find_type("int", 0);
415 result
.is_variable
= FALSE
;
416 result
.is_temporary
= TRUE
;
417 result
.type
= make_type(RPC_FC_RP
, find_type("char", 0));
420 result
.is_variable
= FALSE
;
421 result
.is_temporary
= TRUE
;
422 result
.type
= make_type(RPC_FC_RP
, find_type("wchar_t", 0));
425 result
.is_variable
= FALSE
;
426 result
.is_temporary
= FALSE
;
427 result
.type
= find_type("double", 0);
429 case EXPR_IDENTIFIER
:
431 int found_in_cont_type
;
432 result
.is_variable
= TRUE
;
433 result
.is_temporary
= FALSE
;
434 result
.type
= find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
437 error_loc_info(&expr_loc
->v
->loc_info
, "identifier %s cannot be resolved in expression%s%s\n",
438 e
->u
.sval
, expr_loc
->attr
? " for attribute " : "",
439 expr_loc
->attr
? expr_loc
->attr
: "");
444 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
445 check_scalar_type(expr_loc
, cont_type
, result
.type
);
446 result
.is_variable
= FALSE
;
447 result
.is_temporary
= FALSE
;
448 result
.type
= find_type("int", 0);
451 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
452 check_integer_type(expr_loc
, cont_type
, result
.type
);
453 result
.is_variable
= FALSE
;
457 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
458 check_arithmetic_type(expr_loc
, cont_type
, result
.type
);
459 result
.is_variable
= FALSE
;
462 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
463 if (!result
.is_variable
)
464 error_loc_info(&expr_loc
->v
->loc_info
, "address-of operator applied to non-variable type in expression%s%s\n",
465 expr_loc
->attr
? " for attribute " : "",
466 expr_loc
->attr
? expr_loc
->attr
: "");
467 result
.is_variable
= FALSE
;
468 result
.is_temporary
= TRUE
;
469 result
.type
= make_type(RPC_FC_RP
, result
.type
);
472 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
473 if (result
.type
&& is_ptr(result
.type
))
474 result
.type
= result
.type
->ref
;
476 error_loc_info(&expr_loc
->v
->loc_info
, "dereference operator applied to non-pointer type in expression%s%s\n",
477 expr_loc
->attr
? " for attribute " : "",
478 expr_loc
->attr
? expr_loc
->attr
: "");
481 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
482 result
.type
= e
->u
.tref
;
485 result
.is_variable
= FALSE
;
486 result
.is_temporary
= FALSE
;
487 result
.type
= find_type("int", 0);
500 struct expression_type result_right
;
501 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
502 result
.is_variable
= FALSE
;
503 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
504 /* FIXME: these checks aren't strict enough for some of the operators */
505 check_scalar_type(expr_loc
, cont_type
, result
.type
);
506 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
512 case EXPR_INEQUALITY
:
518 struct expression_type result_left
, result_right
;
519 result_left
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
520 result_right
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
521 check_scalar_type(expr_loc
, cont_type
, result_left
.type
);
522 check_scalar_type(expr_loc
, cont_type
, result_right
.type
);
523 result
.is_variable
= FALSE
;
524 result
.is_temporary
= FALSE
;
525 result
.type
= find_type("int", 0);
529 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
530 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
))
531 result
= resolve_expression(expr_loc
, result
.type
, e
->u
.ext
);
533 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",
534 expr_loc
->attr
? " for attribute " : "",
535 expr_loc
->attr
? expr_loc
->attr
: "");
539 struct expression_type result_first
, result_second
, result_third
;
540 result_first
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
541 check_scalar_type(expr_loc
, cont_type
, result_first
.type
);
542 result_second
= resolve_expression(expr_loc
, cont_type
, e
->u
.ext
);
543 result_third
= resolve_expression(expr_loc
, cont_type
, e
->ext2
);
544 /* FIXME: determine the correct return type */
545 result
= result_second
;
546 result
.is_variable
= FALSE
;
550 result
= resolve_expression(expr_loc
, cont_type
, e
->ref
);
551 if (result
.type
&& is_array(result
.type
))
553 struct expression_type index_result
;
554 result
.type
= result
.type
->ref
;
555 index_result
= resolve_expression(expr_loc
, cont_type
/* FIXME */, e
->u
.ext
);
556 if (!index_result
.type
|| !is_integer_type(index_result
.type
))
557 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript not of integral type in expression%s%s\n",
558 expr_loc
->attr
? " for attribute " : "",
559 expr_loc
->attr
? expr_loc
->attr
: "");
562 error_loc_info(&expr_loc
->v
->loc_info
, "array subscript operator applied to non-array type in expression%s%s\n",
563 expr_loc
->attr
? " for attribute " : "",
564 expr_loc
->attr
? expr_loc
->attr
: "");
570 const type_t
*expr_resolve_type(const struct expr_loc
*expr_loc
, const type_t
*cont_type
, const expr_t
*expr
)
572 struct expression_type expr_type
;
573 expr_type
= resolve_expression(expr_loc
, cont_type
, expr
);
574 return expr_type
.type
;
577 void write_expr(FILE *h
, const expr_t
*e
, int brackets
,
578 int toplevel
, const char *toplevel_prefix
,
579 const type_t
*cont_type
, const char *local_var_prefix
)
586 fprintf(h
, "%lu", e
->u
.lval
);
589 fprintf(h
, "0x%lx", e
->u
.lval
);
592 fprintf(h
, "%#.15g", e
->u
.dval
);
600 case EXPR_IDENTIFIER
:
601 if (toplevel
&& toplevel_prefix
&& cont_type
)
603 int found_in_cont_type
;
604 find_identifier(e
->u
.sval
, cont_type
, &found_in_cont_type
);
605 if (found_in_cont_type
)
607 fprintf(h
, "%s%s", toplevel_prefix
, e
->u
.sval
);
611 fprintf(h
, "%s%s", local_var_prefix
, e
->u
.sval
);
614 fprintf(h
, "\"%s\"", e
->u
.sval
);
617 fprintf(h
, "L\"%s\"", e
->u
.sval
);
621 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
625 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
629 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
633 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
637 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
641 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
645 write_type_decl(h
, e
->u
.tref
, NULL
);
647 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
650 fprintf(h
, "sizeof(");
651 write_type_decl(h
, e
->u
.tref
, NULL
);
667 case EXPR_INEQUALITY
:
672 if (brackets
) fprintf(h
, "(");
673 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
676 case EXPR_SHL
: fprintf(h
, " << "); break;
677 case EXPR_SHR
: fprintf(h
, " >> "); break;
678 case EXPR_MOD
: fprintf(h
, " %% "); break;
679 case EXPR_MUL
: fprintf(h
, " * "); break;
680 case EXPR_DIV
: fprintf(h
, " / "); break;
681 case EXPR_ADD
: fprintf(h
, " + "); break;
682 case EXPR_SUB
: fprintf(h
, " - "); break;
683 case EXPR_AND
: fprintf(h
, " & "); break;
684 case EXPR_OR
: fprintf(h
, " | "); break;
685 case EXPR_LOGOR
: fprintf(h
, " || "); break;
686 case EXPR_LOGAND
: fprintf(h
, " && "); break;
687 case EXPR_XOR
: fprintf(h
, " ^ "); break;
688 case EXPR_EQUALITY
: fprintf(h
, " == "); break;
689 case EXPR_INEQUALITY
: fprintf(h
, " != "); break;
690 case EXPR_GTR
: fprintf(h
, " > "); break;
691 case EXPR_LESS
: fprintf(h
, " < "); break;
692 case EXPR_GTREQL
: fprintf(h
, " >= "); break;
693 case EXPR_LESSEQL
: fprintf(h
, " <= "); break;
696 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
697 if (brackets
) fprintf(h
, ")");
700 if (brackets
) fprintf(h
, "(");
701 if (e
->ref
->type
== EXPR_PPTR
)
703 write_expr(h
, e
->ref
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
708 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
711 write_expr(h
, e
->u
.ext
, 1, 0, toplevel_prefix
, cont_type
, "");
712 if (brackets
) fprintf(h
, ")");
715 if (brackets
) fprintf(h
, "(");
716 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
718 write_expr(h
, e
->u
.ext
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
720 write_expr(h
, e
->ext2
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
721 if (brackets
) fprintf(h
, ")");
724 if (brackets
) fprintf(h
, "(");
725 write_expr(h
, e
->ref
, 1, toplevel
, toplevel_prefix
, cont_type
, local_var_prefix
);
727 write_expr(h
, e
->u
.ext
, 1, 1, toplevel_prefix
, cont_type
, local_var_prefix
);
729 if (brackets
) fprintf(h
, ")");
734 /* This is actually fairly involved to implement precisely, due to the
735 effects attributes may have and things like that. Right now this is
736 only used for optimization, so just check for a very small set of
737 criteria that guarantee the types are equivalent; assume every thing
738 else is different. */
739 static int compare_type(const type_t
*a
, const type_t
*b
)
744 && strcmp(a
->name
, b
->name
) == 0))
746 /* Ordering doesn't need to be implemented yet. */
750 int compare_expr(const expr_t
*a
, const expr_t
*b
)
754 if (a
->type
!= b
->type
)
755 return a
->type
- b
->type
;
762 return a
->u
.lval
- b
->u
.lval
;
764 return a
->u
.dval
- b
->u
.dval
;
765 case EXPR_IDENTIFIER
:
768 return strcmp(a
->u
.sval
, b
->u
.sval
);
770 ret
= compare_expr(a
->ref
, b
->ref
);
773 ret
= compare_expr(a
->u
.ext
, b
->u
.ext
);
776 return compare_expr(a
->ext2
, b
->ext2
);
792 case EXPR_INEQUALITY
:
797 ret
= compare_expr(a
->ref
, b
->ref
);
800 return compare_expr(a
->u
.ext
, b
->u
.ext
);
802 ret
= compare_type(a
->u
.tref
, b
->u
.tref
);
812 return compare_expr(a
->ref
, b
->ref
);
814 return compare_type(a
->u
.tref
, b
->u
.tref
);