ReactOS  0.4.12-dev-685-gf36cbf7
expr.c
Go to the documentation of this file.
1 /*
2  * Expression Abstract Syntax Tree Functions
3  *
4  * Copyright 2002 Ove Kaaven
5  * Copyright 2006-2008 Robert Shearman
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 #include "config.h"
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <assert.h>
28 #include <ctype.h>
29 #include <string.h>
30 
31 #include "widl.h"
32 #include "utils.h"
33 #include "expr.h"
34 #include "header.h"
35 #include "typetree.h"
36 #include "typegen.h"
37 
38 static int is_integer_type(const type_t *type)
39 {
40  switch (type_get_type(type))
41  {
42  case TYPE_ENUM:
43  return TRUE;
44  case TYPE_BASIC:
45  switch (type_basic_get_type(type))
46  {
47  case TYPE_BASIC_INT8:
48  case TYPE_BASIC_INT16:
49  case TYPE_BASIC_INT32:
50  case TYPE_BASIC_INT64:
51  case TYPE_BASIC_INT:
52  case TYPE_BASIC_INT3264:
53  case TYPE_BASIC_LONG:
54  case TYPE_BASIC_CHAR:
55  case TYPE_BASIC_HYPER:
56  case TYPE_BASIC_BYTE:
57  case TYPE_BASIC_WCHAR:
59  return TRUE;
60  case TYPE_BASIC_FLOAT:
61  case TYPE_BASIC_DOUBLE:
62  case TYPE_BASIC_HANDLE:
63  return FALSE;
64  }
65  return FALSE;
66  default:
67  return FALSE;
68  }
69 }
70 
72 {
73  switch (type_get_type(type))
74  {
75  case TYPE_ENUM:
76  return FALSE;
77  case TYPE_BASIC:
78  switch (type_basic_get_type(type))
79  {
80  case TYPE_BASIC_INT8:
81  case TYPE_BASIC_INT16:
82  case TYPE_BASIC_INT32:
83  case TYPE_BASIC_INT64:
84  case TYPE_BASIC_INT:
85  case TYPE_BASIC_INT3264:
86  case TYPE_BASIC_LONG:
87  return type_basic_get_sign(type) < 0;
88  case TYPE_BASIC_CHAR:
89  return TRUE;
90  case TYPE_BASIC_HYPER:
91  case TYPE_BASIC_BYTE:
92  case TYPE_BASIC_WCHAR:
94  case TYPE_BASIC_FLOAT:
95  case TYPE_BASIC_DOUBLE:
96  case TYPE_BASIC_HANDLE:
97  return FALSE;
98  }
99  /* FALLTHROUGH */
100  default:
101  return FALSE;
102  }
103 }
104 
105 static int is_float_type(const type_t *type)
106 {
107  return (type_get_type(type) == TYPE_BASIC &&
110 }
111 
113 {
114  expr_t *e = xmalloc(sizeof(expr_t));
115  e->type = type;
116  e->ref = NULL;
117  e->u.lval = 0;
118  e->is_const = FALSE;
119  e->cval = 0;
120  return e;
121 }
122 
124 {
125  expr_t *e = xmalloc(sizeof(expr_t));
126  e->type = type;
127  e->ref = NULL;
128  e->u.lval = val;
129  e->is_const = FALSE;
130  /* check for numeric constant */
131  if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
132  {
133  /* make sure true/false value is valid */
134  assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
135  e->is_const = TRUE;
136  e->cval = val;
137  }
138  return e;
139 }
140 
142 {
143  expr_t *e = xmalloc(sizeof(expr_t));
144  e->type = type;
145  e->ref = NULL;
146  e->u.dval = val;
147  e->is_const = TRUE;
148  e->cval = val;
149  return e;
150 }
151 
153 {
154  expr_t *e;
155  e = xmalloc(sizeof(expr_t));
156  e->type = type;
157  e->ref = NULL;
158  e->u.sval = val;
159  e->is_const = FALSE;
160  /* check for predefined constants */
161  switch (type)
162  {
163  case EXPR_IDENTIFIER:
164  {
165  var_t *c = find_const(val, 0);
166  if (c)
167  {
168  e->u.sval = c->name;
169  free(val);
170  e->is_const = TRUE;
171  e->cval = c->eval->cval;
172  }
173  break;
174  }
175  case EXPR_CHARCONST:
176  if (!val[0])
177  error_loc("empty character constant\n");
178  else if (val[1])
179  error_loc("multi-character constants are endian dependent\n");
180  else
181  {
182  e->is_const = TRUE;
183  e->cval = *val;
184  }
185  break;
186  default:
187  break;
188  }
189  return e;
190 }
191 
193 {
194  expr_t *e;
195  type_t *tref;
196 
197  if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
198  error_loc("invalid storage class for type expression\n");
199 
200  tref = var->type;
201 
202  e = xmalloc(sizeof(expr_t));
203  e->type = type;
204  e->ref = expr;
205  e->u.tref = tref;
206  e->is_const = FALSE;
207  if (type == EXPR_SIZEOF)
208  {
209  /* only do this for types that should be the same on all platforms */
210  if (is_integer_type(tref) || is_float_type(tref))
211  {
212  e->is_const = TRUE;
213  e->cval = type_memsize(tref);
214  }
215  }
216  /* check for cast of constant expression */
217  if (type == EXPR_CAST && expr->is_const)
218  {
219  if (is_integer_type(tref))
220  {
221  unsigned int cast_type_bits = type_memsize(tref) * 8;
222  unsigned int cast_mask;
223 
224  e->is_const = TRUE;
225  if (is_signed_integer_type(tref))
226  {
227  cast_mask = (1u << (cast_type_bits - 1)) - 1;
228  if (expr->cval & (1u << (cast_type_bits - 1)))
229  e->cval = -((-expr->cval) & cast_mask);
230  else
231  e->cval = expr->cval & cast_mask;
232  }
233  else
234  {
235  /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
236  cast_mask = ((1u << (cast_type_bits - 1)) - 1) |
237  1u << (cast_type_bits - 1);
238  e->cval = expr->cval & cast_mask;
239  }
240  }
241  else
242  {
243  e->is_const = TRUE;
244  e->cval = expr->cval;
245  }
246  }
247  free(var);
248  return e;
249 }
250 
252 {
253  expr_t *e;
254  e = xmalloc(sizeof(expr_t));
255  e->type = type;
256  e->ref = expr;
257  e->u.lval = 0;
258  e->is_const = FALSE;
259  /* check for compile-time optimization */
260  if (expr->is_const)
261  {
262  e->is_const = TRUE;
263  switch (type)
264  {
265  case EXPR_LOGNOT:
266  e->cval = !expr->cval;
267  break;
268  case EXPR_POS:
269  e->cval = +expr->cval;
270  break;
271  case EXPR_NEG:
272  e->cval = -expr->cval;
273  break;
274  case EXPR_NOT:
275  e->cval = ~expr->cval;
276  break;
277  default:
278  e->is_const = FALSE;
279  break;
280  }
281  }
282  return e;
283 }
284 
285 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
286 {
287  expr_t *e;
288  e = xmalloc(sizeof(expr_t));
289  e->type = type;
290  e->ref = expr1;
291  e->u.ext = expr2;
292  e->is_const = FALSE;
293  /* check for compile-time optimization */
294  if (expr1->is_const && expr2->is_const)
295  {
296  e->is_const = TRUE;
297  switch (type)
298  {
299  case EXPR_ADD:
300  e->cval = expr1->cval + expr2->cval;
301  break;
302  case EXPR_SUB:
303  e->cval = expr1->cval - expr2->cval;
304  break;
305  case EXPR_MOD:
306  if (expr2->cval == 0)
307  {
308  error_loc("divide by zero in expression\n");
309  e->cval = 0;
310  }
311  else
312  e->cval = expr1->cval % expr2->cval;
313  break;
314  case EXPR_MUL:
315  e->cval = expr1->cval * expr2->cval;
316  break;
317  case EXPR_DIV:
318  if (expr2->cval == 0)
319  {
320  error_loc("divide by zero in expression\n");
321  e->cval = 0;
322  }
323  else
324  e->cval = expr1->cval / expr2->cval;
325  break;
326  case EXPR_OR:
327  e->cval = expr1->cval | expr2->cval;
328  break;
329  case EXPR_AND:
330  e->cval = expr1->cval & expr2->cval;
331  break;
332  case EXPR_SHL:
333  e->cval = expr1->cval << expr2->cval;
334  break;
335  case EXPR_SHR:
336  e->cval = expr1->cval >> expr2->cval;
337  break;
338  case EXPR_LOGOR:
339  e->cval = expr1->cval || expr2->cval;
340  break;
341  case EXPR_LOGAND:
342  e->cval = expr1->cval && expr2->cval;
343  break;
344  case EXPR_XOR:
345  e->cval = expr1->cval ^ expr2->cval;
346  break;
347  case EXPR_EQUALITY:
348  e->cval = expr1->cval == expr2->cval;
349  break;
350  case EXPR_INEQUALITY:
351  e->cval = expr1->cval != expr2->cval;
352  break;
353  case EXPR_GTR:
354  e->cval = expr1->cval > expr2->cval;
355  break;
356  case EXPR_LESS:
357  e->cval = expr1->cval < expr2->cval;
358  break;
359  case EXPR_GTREQL:
360  e->cval = expr1->cval >= expr2->cval;
361  break;
362  case EXPR_LESSEQL:
363  e->cval = expr1->cval <= expr2->cval;
364  break;
365  default:
366  e->is_const = FALSE;
367  break;
368  }
369  }
370  return e;
371 }
372 
373 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
374 {
375  expr_t *e;
376  e = xmalloc(sizeof(expr_t));
377  e->type = type;
378  e->ref = expr1;
379  e->u.ext = expr2;
380  e->ext2 = expr3;
381  e->is_const = FALSE;
382  /* check for compile-time optimization */
383  if (expr1->is_const && expr2->is_const && expr3->is_const)
384  {
385  e->is_const = TRUE;
386  switch (type)
387  {
388  case EXPR_COND:
389  e->cval = expr1->cval ? expr2->cval : expr3->cval;
390  break;
391  default:
392  e->is_const = FALSE;
393  break;
394  }
395  }
396  return e;
397 }
398 
400 {
401  int is_variable; /* is the expression resolved to a variable? */
402  int is_temporary; /* should the type be freed? */
404 };
405 
406 static void check_scalar_type(const struct expr_loc *expr_loc,
407  const type_t *cont_type, const type_t *type)
408 {
409  if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
410  !is_float_type(type)))
411  error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
412  expr_loc->attr ? " for attribute " : "",
413  expr_loc->attr ? expr_loc->attr : "");
414 }
415 
416 static void check_arithmetic_type(const struct expr_loc *expr_loc,
417  const type_t *cont_type, const type_t *type)
418 {
419  if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
420  error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
421  expr_loc->attr ? " for attribute " : "",
422  expr_loc->attr ? expr_loc->attr : "");
423 }
424 
425 static void check_integer_type(const struct expr_loc *expr_loc,
426  const type_t *cont_type, const type_t *type)
427 {
428  if (!cont_type || !is_integer_type(type))
429  error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
430  expr_loc->attr ? " for attribute " : "",
431  expr_loc->attr ? expr_loc->attr : "");
432 }
433 
434 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
435 {
436  type_t *type = NULL;
437  const var_t *field;
438  const var_list_t *fields = NULL;
439 
440  *found_in_cont_type = 0;
441 
442  if (cont_type)
443  {
444  switch (type_get_type(cont_type))
445  {
446  case TYPE_FUNCTION:
447  fields = type_function_get_args(cont_type);
448  break;
449  case TYPE_STRUCT:
450  fields = type_struct_get_fields(cont_type);
451  break;
452  case TYPE_UNION:
454  fields = type_union_get_cases(cont_type);
455  break;
456  case TYPE_VOID:
457  case TYPE_BASIC:
458  case TYPE_ENUM:
459  case TYPE_MODULE:
460  case TYPE_COCLASS:
461  case TYPE_INTERFACE:
462  case TYPE_POINTER:
463  case TYPE_ARRAY:
464  case TYPE_BITFIELD:
465  /* nothing to do */
466  break;
467  case TYPE_ALIAS:
468  /* shouldn't get here because of using type_get_type above */
469  assert(0);
470  break;
471  }
472  }
473 
474  if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
475  if (field->name && !strcmp(identifier, field->name))
476  {
477  type = field->type;
478  *found_in_cont_type = 1;
479  break;
480  }
481 
482  if (!type)
483  {
484  var_t *const_var = find_const(identifier, 0);
485  if (const_var) type = const_var->type;
486  }
487 
488  return type;
489 }
490 
492 {
493  switch (type_get_type(type))
494  {
495  case TYPE_STRUCT:
496  case TYPE_UNION:
497  case TYPE_ENUM:
498  return TRUE;
499  default:
500  return FALSE;
501  }
502 }
503 
505  const type_t *cont_type,
506  const expr_t *e)
507 {
508  struct expression_type result;
510  result.is_temporary = FALSE;
511  result.type = NULL;
512  switch (e->type)
513  {
514  case EXPR_VOID:
515  break;
516  case EXPR_HEXNUM:
517  case EXPR_NUM:
518  case EXPR_TRUEFALSE:
519  result.is_temporary = FALSE;
521  break;
522  case EXPR_STRLIT:
523  result.is_temporary = TRUE;
525  break;
526  case EXPR_WSTRLIT:
527  result.is_temporary = TRUE;
529  break;
530  case EXPR_CHARCONST:
531  result.is_temporary = TRUE;
533  break;
534  case EXPR_DOUBLE:
535  result.is_temporary = TRUE;
537  break;
538  case EXPR_IDENTIFIER:
539  {
540  int found_in_cont_type;
541  result.is_variable = TRUE;
542  result.is_temporary = FALSE;
543  result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
544  if (!result.type)
545  {
546  error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
547  e->u.sval, expr_loc->attr ? " for attribute " : "",
548  expr_loc->attr ? expr_loc->attr : "");
549  }
550  break;
551  }
552  case EXPR_LOGNOT:
553  result = resolve_expression(expr_loc, cont_type, e->ref);
554  check_scalar_type(expr_loc, cont_type, result.type);
555  result.is_variable = FALSE;
556  result.is_temporary = FALSE;
558  break;
559  case EXPR_NOT:
560  result = resolve_expression(expr_loc, cont_type, e->ref);
561  check_integer_type(expr_loc, cont_type, result.type);
562  result.is_variable = FALSE;
563  break;
564  case EXPR_POS:
565  case EXPR_NEG:
566  result = resolve_expression(expr_loc, cont_type, e->ref);
567  check_arithmetic_type(expr_loc, cont_type, result.type);
568  result.is_variable = FALSE;
569  break;
570  case EXPR_ADDRESSOF:
571  result = resolve_expression(expr_loc, cont_type, e->ref);
572  if (!result.is_variable)
573  error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
574  expr_loc->attr ? " for attribute " : "",
575  expr_loc->attr ? expr_loc->attr : "");
576  result.is_variable = FALSE;
577  result.is_temporary = TRUE;
578  result.type = type_new_pointer(FC_UP, result.type, NULL);
579  break;
580  case EXPR_PPTR:
581  result = resolve_expression(expr_loc, cont_type, e->ref);
582  if (result.type && is_ptr(result.type))
583  result.type = type_pointer_get_ref(result.type);
584  else if(result.type && is_array(result.type)
586  result.type = type_array_get_element(result.type);
587  else
588  error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
589  expr_loc->attr ? " for attribute " : "",
590  expr_loc->attr ? expr_loc->attr : "");
591  break;
592  case EXPR_CAST:
593  result = resolve_expression(expr_loc, cont_type, e->ref);
594  result.type = e->u.tref;
595  break;
596  case EXPR_SIZEOF:
597  result.is_temporary = FALSE;
599  break;
600  case EXPR_SHL:
601  case EXPR_SHR:
602  case EXPR_MOD:
603  case EXPR_MUL:
604  case EXPR_DIV:
605  case EXPR_ADD:
606  case EXPR_SUB:
607  case EXPR_AND:
608  case EXPR_OR:
609  case EXPR_XOR:
610  {
611  struct expression_type result_right;
612  result = resolve_expression(expr_loc, cont_type, e->ref);
613  result.is_variable = FALSE;
614  result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
615  /* FIXME: these checks aren't strict enough for some of the operators */
616  check_scalar_type(expr_loc, cont_type, result.type);
617  check_scalar_type(expr_loc, cont_type, result_right.type);
618  break;
619  }
620  case EXPR_LOGOR:
621  case EXPR_LOGAND:
622  case EXPR_EQUALITY:
623  case EXPR_INEQUALITY:
624  case EXPR_GTR:
625  case EXPR_LESS:
626  case EXPR_GTREQL:
627  case EXPR_LESSEQL:
628  {
629  struct expression_type result_left, result_right;
630  result_left = resolve_expression(expr_loc, cont_type, e->ref);
631  result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
632  check_scalar_type(expr_loc, cont_type, result_left.type);
633  check_scalar_type(expr_loc, cont_type, result_right.type);
634  result.is_temporary = FALSE;
636  break;
637  }
638  case EXPR_MEMBER:
639  result = resolve_expression(expr_loc, cont_type, e->ref);
640  if (result.type && is_valid_member_operand(result.type))
641  result = resolve_expression(expr_loc, result.type, e->u.ext);
642  else
643  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",
644  expr_loc->attr ? " for attribute " : "",
645  expr_loc->attr ? expr_loc->attr : "");
646  break;
647  case EXPR_COND:
648  {
649  struct expression_type result_first, result_second, result_third;
650  result_first = resolve_expression(expr_loc, cont_type, e->ref);
651  check_scalar_type(expr_loc, cont_type, result_first.type);
652  result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
653  result_third = resolve_expression(expr_loc, cont_type, e->ext2);
654  check_scalar_type(expr_loc, cont_type, result_second.type);
655  check_scalar_type(expr_loc, cont_type, result_third.type);
656  if (!is_ptr(result_second.type) ^ !is_ptr(result_third.type))
657  error_loc_info(&expr_loc->v->loc_info, "type mismatch in ?: expression\n" );
658  /* FIXME: determine the correct return type */
659  result = result_second;
661  break;
662  }
663  case EXPR_ARRAY:
664  result = resolve_expression(expr_loc, cont_type, e->ref);
665  if (result.type && is_array(result.type))
666  {
667  struct expression_type index_result;
669  index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
670  if (!index_result.type || !is_integer_type(index_result.type))
671  error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
672  expr_loc->attr ? " for attribute " : "",
673  expr_loc->attr ? expr_loc->attr : "");
674  }
675  else
676  error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
677  expr_loc->attr ? " for attribute " : "",
678  expr_loc->attr ? expr_loc->attr : "");
679  break;
680  }
681  return result;
682 }
683 
684 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
685 {
686  struct expression_type expr_type;
687  expr_type = resolve_expression(expr_loc, cont_type, expr);
688  return expr_type.type;
689 }
690 
691 void write_expr(FILE *h, const expr_t *e, int brackets,
692  int toplevel, const char *toplevel_prefix,
693  const type_t *cont_type, const char *local_var_prefix)
694 {
695  switch (e->type)
696  {
697  case EXPR_VOID:
698  break;
699  case EXPR_NUM:
700  fprintf(h, "%u", e->u.lval);
701  break;
702  case EXPR_HEXNUM:
703  fprintf(h, "0x%x", e->u.lval);
704  break;
705  case EXPR_DOUBLE:
706  fprintf(h, "%#.15g", e->u.dval);
707  break;
708  case EXPR_TRUEFALSE:
709  if (e->u.lval == 0)
710  fprintf(h, "FALSE");
711  else
712  fprintf(h, "TRUE");
713  break;
714  case EXPR_IDENTIFIER:
715  if (toplevel && toplevel_prefix && cont_type)
716  {
717  int found_in_cont_type;
718  find_identifier(e->u.sval, cont_type, &found_in_cont_type);
719  if (found_in_cont_type)
720  {
721  fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
722  break;
723  }
724  }
725  fprintf(h, "%s%s", local_var_prefix, e->u.sval);
726  break;
727  case EXPR_STRLIT:
728  fprintf(h, "\"%s\"", e->u.sval);
729  break;
730  case EXPR_WSTRLIT:
731  fprintf(h, "L\"%s\"", e->u.sval);
732  break;
733  case EXPR_CHARCONST:
734  fprintf(h, "'%s'", e->u.sval);
735  break;
736  case EXPR_LOGNOT:
737  fprintf(h, "!");
738  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
739  break;
740  case EXPR_NOT:
741  fprintf(h, "~");
742  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
743  break;
744  case EXPR_POS:
745  fprintf(h, "+");
746  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
747  break;
748  case EXPR_NEG:
749  fprintf(h, "-");
750  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
751  break;
752  case EXPR_ADDRESSOF:
753  fprintf(h, "&");
754  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
755  break;
756  case EXPR_PPTR:
757  fprintf(h, "*");
758  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
759  break;
760  case EXPR_CAST:
761  fprintf(h, "(");
762  write_type_decl(h, e->u.tref, NULL);
763  fprintf(h, ")");
764  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
765  break;
766  case EXPR_SIZEOF:
767  fprintf(h, "sizeof(");
768  write_type_decl(h, e->u.tref, NULL);
769  fprintf(h, ")");
770  break;
771  case EXPR_SHL:
772  case EXPR_SHR:
773  case EXPR_MOD:
774  case EXPR_MUL:
775  case EXPR_DIV:
776  case EXPR_ADD:
777  case EXPR_SUB:
778  case EXPR_AND:
779  case EXPR_OR:
780  case EXPR_LOGOR:
781  case EXPR_LOGAND:
782  case EXPR_XOR:
783  case EXPR_EQUALITY:
784  case EXPR_INEQUALITY:
785  case EXPR_GTR:
786  case EXPR_LESS:
787  case EXPR_GTREQL:
788  case EXPR_LESSEQL:
789  if (brackets) fprintf(h, "(");
790  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
791  switch (e->type)
792  {
793  case EXPR_SHL: fprintf(h, " << "); break;
794  case EXPR_SHR: fprintf(h, " >> "); break;
795  case EXPR_MOD: fprintf(h, " %% "); break;
796  case EXPR_MUL: fprintf(h, " * "); break;
797  case EXPR_DIV: fprintf(h, " / "); break;
798  case EXPR_ADD: fprintf(h, " + "); break;
799  case EXPR_SUB: fprintf(h, " - "); break;
800  case EXPR_AND: fprintf(h, " & "); break;
801  case EXPR_OR: fprintf(h, " | "); break;
802  case EXPR_LOGOR: fprintf(h, " || "); break;
803  case EXPR_LOGAND: fprintf(h, " && "); break;
804  case EXPR_XOR: fprintf(h, " ^ "); break;
805  case EXPR_EQUALITY: fprintf(h, " == "); break;
806  case EXPR_INEQUALITY: fprintf(h, " != "); break;
807  case EXPR_GTR: fprintf(h, " > "); break;
808  case EXPR_LESS: fprintf(h, " < "); break;
809  case EXPR_GTREQL: fprintf(h, " >= "); break;
810  case EXPR_LESSEQL: fprintf(h, " <= "); break;
811  default: break;
812  }
813  write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
814  if (brackets) fprintf(h, ")");
815  break;
816  case EXPR_MEMBER:
817  if (brackets) fprintf(h, "(");
818  if (e->ref->type == EXPR_PPTR)
819  {
820  write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
821  fprintf(h, "->");
822  }
823  else
824  {
825  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
826  fprintf(h, ".");
827  }
828  write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
829  if (brackets) fprintf(h, ")");
830  break;
831  case EXPR_COND:
832  if (brackets) fprintf(h, "(");
833  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
834  fprintf(h, " ? ");
835  write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
836  fprintf(h, " : ");
837  write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
838  if (brackets) fprintf(h, ")");
839  break;
840  case EXPR_ARRAY:
841  if (brackets) fprintf(h, "(");
842  write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
843  fprintf(h, "[");
844  write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
845  fprintf(h, "]");
846  if (brackets) fprintf(h, ")");
847  break;
848  }
849 }
850 
851 /* This is actually fairly involved to implement precisely, due to the
852  effects attributes may have and things like that. Right now this is
853  only used for optimization, so just check for a very small set of
854  criteria that guarantee the types are equivalent; assume every thing
855  else is different. */
856 static int compare_type(const type_t *a, const type_t *b)
857 {
858  if (a == b
859  || (a->name
860  && b->name
861  && strcmp(a->name, b->name) == 0))
862  return 0;
863  /* Ordering doesn't need to be implemented yet. */
864  return 1;
865 }
866 
867 int compare_expr(const expr_t *a, const expr_t *b)
868 {
869  int ret;
870 
871  if (a->type != b->type)
872  return a->type - b->type;
873 
874  switch (a->type)
875  {
876  case EXPR_NUM:
877  case EXPR_HEXNUM:
878  case EXPR_TRUEFALSE:
879  return a->u.lval - b->u.lval;
880  case EXPR_DOUBLE:
881  return a->u.dval - b->u.dval;
882  case EXPR_IDENTIFIER:
883  case EXPR_STRLIT:
884  case EXPR_WSTRLIT:
885  case EXPR_CHARCONST:
886  return strcmp(a->u.sval, b->u.sval);
887  case EXPR_COND:
888  ret = compare_expr(a->ref, b->ref);
889  if (ret != 0)
890  return ret;
891  ret = compare_expr(a->u.ext, b->u.ext);
892  if (ret != 0)
893  return ret;
894  return compare_expr(a->ext2, b->ext2);
895  case EXPR_OR:
896  case EXPR_AND:
897  case EXPR_ADD:
898  case EXPR_SUB:
899  case EXPR_MOD:
900  case EXPR_MUL:
901  case EXPR_DIV:
902  case EXPR_SHL:
903  case EXPR_SHR:
904  case EXPR_MEMBER:
905  case EXPR_ARRAY:
906  case EXPR_LOGOR:
907  case EXPR_LOGAND:
908  case EXPR_XOR:
909  case EXPR_EQUALITY:
910  case EXPR_INEQUALITY:
911  case EXPR_GTR:
912  case EXPR_LESS:
913  case EXPR_GTREQL:
914  case EXPR_LESSEQL:
915  ret = compare_expr(a->ref, b->ref);
916  if (ret != 0)
917  return ret;
918  return compare_expr(a->u.ext, b->u.ext);
919  case EXPR_CAST:
920  ret = compare_type(a->u.tref, b->u.tref);
921  if (ret != 0)
922  return ret;
923  /* Fall through. */
924  case EXPR_NOT:
925  case EXPR_NEG:
926  case EXPR_PPTR:
927  case EXPR_ADDRESSOF:
928  case EXPR_LOGNOT:
929  case EXPR_POS:
930  return compare_expr(a->ref, b->ref);
931  case EXPR_SIZEOF:
932  return compare_type(a->u.tref, b->u.tref);
933  case EXPR_VOID:
934  return 0;
935  }
936  return -1;
937 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
Definition: parse.h:56
char * name
Definition: wpp.c:36
#define TRUE
Definition: types.h:120
static int compare_type(const type_t *a, const type_t *b)
Definition: expr.c:856
LOCAL int expr(arg_t *ap, int *altp)
Definition: match.c:512
expr_t * make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
Definition: expr.c:285
static var_list_t * type_struct_get_fields(const type_t *type)
Definition: typetree.h:87
static int is_valid_member_operand(const type_t *type)
Definition: expr.c:491
static type_t * type_array_get_element(const type_t *type)
Definition: typetree.h:253
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
const char * attr
Definition: expr.h:25
struct _loc_info_t loc_info
Definition: widltypes.h:459
static int is_signed_integer_type(const type_t *type)
Definition: expr.c:71
static var_list_t * type_union_get_cases(const type_t *type)
Definition: typetree.h:134
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
expr_type
static enum type_basic_type type_basic_get_type(const type_t *type)
Definition: typetree.h:73
enum storage_class stgclass
Definition: widltypes.h:455
expr_t * make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
Definition: expr.c:373
Definition: query.h:86
int compare_expr(const expr_t *a, const expr_t *b)
Definition: expr.c:867
int is_const
Definition: widltypes.h:317
void error_loc_info(const loc_info_t *loc_info, const char *s,...)
Definition: utils.c:85
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
static int is_float_type(const type_t *type)
Definition: expr.c:105
static type_t * type_pointer_get_ref(const type_t *type)
Definition: typetree.h:292
type_t * type_new_int(enum type_basic_type basic_type, int sign)
Definition: typetree.c:251
expr_t * make_exprd(enum expr_type type, double val)
Definition: expr.c:141
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
void * xmalloc(int size)
Definition: uimain.c:747
int cval
Definition: widltypes.h:318
static var_list_t * type_function_get_args(const type_t *type)
Definition: typetree.h:94
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define e
Definition: ke_i.h:82
static int is_ptr(const type_t *t)
Definition: header.h:59
static int is_integer_type(const type_t *type)
Definition: expr.c:38
expr_t * make_exprl(enum expr_type type, int val)
Definition: expr.c:123
void error_loc(const char *s,...)
Definition: utils.c:69
jmp_buf toplevel
Definition: main.c:95
smooth NULL
Definition: ftsmooth.c:416
static int is_array(const type_t *t)
Definition: header.h:64
static type_t * find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
Definition: expr.c:434
void write_type_decl(FILE *f, type_t *t, const char *name)
Definition: header.c:561
expr_t * make_exprs(enum expr_type type, char *val)
Definition: expr.c:152
GLuint GLfloat * val
Definition: glext.h:7180
type_t * type
Definition: expr.c:403
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
static enum type_type type_get_type(const type_t *type)
Definition: typetree.h:68
type_t * type
Definition: widltypes.h:452
Definition: parser.c:43
var_t * find_const(const char *name, int f)
Definition: parser.tab.c:6224
static void check_arithmetic_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:416
Definition: expr.h:22
static struct expression_type resolve_expression(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *e)
Definition: expr.c:504
const GLubyte * c
Definition: glext.h:8905
expr_t * make_exprt(enum expr_type type, var_t *var, expr_t *expr)
Definition: expr.c:192
type_t * type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
Definition: typetree.c:181
int ret
expr_t * make_expr(enum expr_type type)
Definition: expr.c:112
Definition: _list.h:228
static void check_integer_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:425
void write_expr(FILE *h, const expr_t *e, int brackets, int toplevel, const char *toplevel_prefix, const type_t *cont_type, const char *local_var_prefix)
Definition: expr.c:691
expr_t * make_expr1(enum expr_type type, expr_t *expr)
Definition: expr.c:251
Definition: parse.h:44
type_t * type_new_basic(enum type_basic_type basic_type)
Definition: typetree.c:243
const type_t * expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
Definition: expr.c:684
static void check_scalar_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:406
int is_temporary
Definition: expr.c:402
int is_variable
Definition: expr.c:401
static unsigned int type_memsize(ITypeInfo *typeinfo, TYPEDESC *desc)
Definition: ndr_typelib.c:136
static int type_basic_get_sign(const type_t *type)
Definition: typetree.h:80
static int type_array_is_decl_as_ptr(const type_t *type)
Definition: typetree.h:260
#define const
Definition: zconf.h:230
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
Definition: parse.h:48
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
const var_t * v
Definition: expr.h:24
GLuint64EXT * result
Definition: glext.h:11304