dxdiag: Add code for plain-text information output.
[wine] / programs / winedbg / expr.c
1 /*
2  * File expr.c - expression handling for Wine internal debugger.
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdarg.h>
26
27 #include "debugger.h"
28 #include "expr.h"
29 #include "wine/debug.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
32
33 struct expr
34 {
35     unsigned int        type;
36     union
37     {
38         struct
39         {
40             long int            value;
41         } s_const;
42
43         struct
44         {
45             long unsigned int   value;
46         } u_const;
47
48         struct
49         {
50             const char*         str;
51         } string;
52
53         struct
54         {
55             const char*         name;
56         } symbol;
57
58         struct
59         {
60             const char*         name;
61         } intvar;
62
63         struct
64         {
65             int                 unop_type;
66             struct expr*        exp1;
67             long int            result;
68         } unop;
69
70         struct
71         {
72             int                 binop_type;
73             struct expr*        exp1;
74             struct expr*        exp2;
75             long int            result;
76         } binop;
77
78         struct
79         {
80             struct type_expr_t  cast_to;
81             struct expr*        expr;
82         } cast;
83
84         struct
85         {
86             struct expr*        exp1;
87             const char*         element_name;
88             long int            result;
89         } structure;
90
91         struct
92         {
93             const char*         funcname;
94             int                 nargs;
95             struct expr*        arg[5];
96             long int            result;
97         } call;
98
99     } un;
100 };
101
102 #define EXPR_TYPE_S_CONST       0
103 #define EXPR_TYPE_U_CONST       1
104 #define EXPR_TYPE_SYMBOL        2
105 #define EXPR_TYPE_INTVAR        3
106 #define EXPR_TYPE_BINOP         4
107 #define EXPR_TYPE_UNOP          5
108 #define EXPR_TYPE_STRUCT        6
109 #define EXPR_TYPE_PSTRUCT       7
110 #define EXPR_TYPE_CALL          8
111 #define EXPR_TYPE_STRING        9
112 #define EXPR_TYPE_CAST          10
113
114 static char expr_list[4096];
115 static unsigned int next_expr_free = 0;
116
117 static struct expr* expr_alloc(void)
118 {
119     struct expr*        rtn;
120
121     rtn = (struct expr*)&expr_list[next_expr_free];
122
123     next_expr_free += sizeof(struct expr);
124     assert(next_expr_free < sizeof(expr_list));
125
126     return rtn;
127 }
128
129 void expr_free_all(void)
130 {
131     next_expr_free = 0;
132 }
133
134 struct expr* expr_alloc_typecast(struct type_expr_t* tet, struct expr* exp)
135 {
136     struct expr*        ex;
137
138     ex = expr_alloc();
139
140     ex->type            = EXPR_TYPE_CAST;
141     ex->un.cast.cast_to = *tet;
142     ex->un.cast.expr    = exp;
143     return ex;
144 }
145
146 struct expr* expr_alloc_internal_var(const char* name)
147 {
148     struct expr* ex;
149
150     ex = expr_alloc();
151
152     ex->type           = EXPR_TYPE_INTVAR;
153     ex->un.intvar.name = name;
154     return ex;
155 }
156
157 struct expr* expr_alloc_symbol(const char* name)
158 {
159     struct expr* ex;
160
161     ex = expr_alloc();
162
163     ex->type           = EXPR_TYPE_SYMBOL;
164     ex->un.symbol.name = name;
165     return ex;
166 }
167
168 struct expr* expr_alloc_sconstant(long int value)
169 {
170     struct expr*        ex;
171
172     ex = expr_alloc();
173
174     ex->type             = EXPR_TYPE_S_CONST;
175     ex->un.s_const.value = value;
176     return ex;
177 }
178
179 struct expr* expr_alloc_uconstant(long unsigned int value)
180 {
181     struct expr*        ex;
182
183     ex = expr_alloc();
184
185     ex->type             = EXPR_TYPE_U_CONST;
186     ex->un.u_const.value = value;
187     return ex;
188 }
189
190 struct expr* expr_alloc_string(const char* str)
191 {
192     struct expr*        ex;
193
194     ex = expr_alloc();
195
196     ex->type          = EXPR_TYPE_STRING;
197     ex->un.string.str = str;
198     return ex;
199 }
200
201 struct expr* expr_alloc_binary_op(int op_type, struct expr* exp1, struct expr* exp2)
202 {
203     struct expr*        ex;
204
205     ex = expr_alloc();
206
207     ex->type                = EXPR_TYPE_BINOP;
208     ex->un.binop.binop_type = op_type;
209     ex->un.binop.exp1       = exp1;
210     ex->un.binop.exp2       = exp2;
211     return ex;
212 }
213
214 struct expr* expr_alloc_unary_op(int op_type, struct expr* exp1)
215 {
216     struct expr*        ex;
217
218     ex = expr_alloc();
219
220     ex->type              = EXPR_TYPE_UNOP;
221     ex->un.unop.unop_type = op_type;
222     ex->un.unop.exp1      = exp1;
223     return ex;
224 }
225
226 struct expr* expr_alloc_struct(struct expr* exp, const char* element)
227 {
228     struct expr*        ex;
229
230     ex = expr_alloc();
231
232     ex->type                      = EXPR_TYPE_STRUCT;
233     ex->un.structure.exp1         = exp;
234     ex->un.structure.element_name = element;
235     return ex;
236 }
237
238 struct expr* expr_alloc_pstruct(struct expr* exp, const char* element)
239 {
240     struct expr*        ex;
241
242     ex = expr_alloc();
243
244     ex->type                      = EXPR_TYPE_PSTRUCT;
245     ex->un.structure.exp1         = exp;
246     ex->un.structure.element_name = element;
247     return ex;
248 }
249
250 struct expr* expr_alloc_func_call(const char* funcname, int nargs, ...)
251 {
252     struct expr*        ex;
253     va_list             ap;
254     int                 i;
255
256     ex = expr_alloc();
257
258     ex->type             = EXPR_TYPE_CALL;
259     ex->un.call.funcname = funcname;
260     ex->un.call.nargs    = nargs;
261
262     va_start(ap, nargs);
263     for (i = 0; i < nargs; i++)
264     {
265         ex->un.call.arg[i] = va_arg(ap, struct expr*);
266     }
267     va_end(ap);
268     return ex;
269 }
270
271 /******************************************************************
272  *              expr_eval
273  *
274  */
275 struct dbg_lvalue expr_eval(struct expr* exp)
276 {
277     struct dbg_lvalue                   rtn;
278     int                                 i;
279     struct dbg_lvalue                   exp1;
280     struct dbg_lvalue                   exp2;
281     DWORD64                             scale1, scale2, scale3;
282     struct dbg_type                     type1, type2;
283     DWORD                               tag;
284     const struct dbg_internal_var*      div;
285
286     rtn.cookie       = 0;
287     rtn.type.id      = dbg_itype_none;
288     rtn.type.module  = 0;
289     rtn.addr.Mode    = AddrModeFlat;
290     rtn.addr.Offset  = 0;
291     rtn.addr.Segment = 0;
292
293     switch (exp->type)
294     {
295     case EXPR_TYPE_CAST:
296         /* this is really brute force, we simply change the type... without 
297          * checking if this is right or not
298          */
299         rtn = expr_eval(exp->un.cast.expr);
300         switch (exp->un.cast.cast_to.type)
301         {
302         case type_expr_type_id:
303             if (exp->un.cast.cast_to.u.type.id == dbg_itype_none)
304             {
305                 dbg_printf("Can't cast to unknown type\n");
306                 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
307             }
308             rtn.type = exp->un.cast.cast_to.u.type;
309             break;
310         case type_expr_udt_class:
311         case type_expr_udt_struct:
312         case type_expr_udt_union:
313             rtn.type = types_find_type(rtn.type.module, exp->un.cast.cast_to.u.name,
314                                        SymTagUDT);
315             if (rtn.type.id == dbg_itype_none)
316             {
317                 dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name);
318                 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
319             }
320             break;
321         case type_expr_enumeration:
322             rtn.type = types_find_type(rtn.type.module, exp->un.cast.cast_to.u.name,
323                                        SymTagEnum);
324             if (rtn.type.id == dbg_itype_none)
325             {
326                 dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name);
327                 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
328             }
329             break;
330         default:
331             dbg_printf("Unsupported cast type %u\n", exp->un.cast.cast_to.type);
332             RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
333         }
334         for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
335         {
336             rtn.type = types_find_pointer(&rtn.type);
337             if (rtn.type.id == dbg_itype_none)
338             {
339                 dbg_printf("Cannot find pointer type\n");
340                 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
341             }
342         }
343         break;
344     case EXPR_TYPE_STRING:
345         rtn.cookie      = DLV_HOST;
346         rtn.type.id     = dbg_itype_astring;
347         rtn.type.module = 0;
348         rtn.addr.Offset = (ULONG_PTR)&exp->un.string.str;
349         break;
350     case EXPR_TYPE_U_CONST:
351         rtn.cookie      = DLV_HOST;
352         rtn.type.id     = dbg_itype_unsigned_long_int;
353         rtn.type.module = 0;
354         rtn.addr.Offset = (ULONG_PTR)&exp->un.u_const.value;
355         break;
356     case EXPR_TYPE_S_CONST:
357         rtn.cookie      = DLV_HOST;
358         rtn.type.id     = dbg_itype_signed_long_int;
359         rtn.type.module = 0;
360         rtn.addr.Offset = (ULONG_PTR)&exp->un.s_const.value;
361         break;
362     case EXPR_TYPE_SYMBOL:
363         switch (symbol_get_lvalue(exp->un.symbol.name, -1, &rtn, FALSE))
364         {
365         case sglv_found:
366             break;
367         case sglv_unknown:
368             RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
369             /* should never be here */
370         case sglv_aborted:
371             RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
372             /* should never be here */
373         }
374         break;
375     case EXPR_TYPE_PSTRUCT:
376         exp1 = expr_eval(exp->un.structure.exp1);
377         if (exp1.type.id == dbg_itype_none || !types_array_index(&exp1, 0, &rtn) ||
378             rtn.type.id == dbg_itype_none)
379             RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
380         if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
381                                     &exp->un.structure.result))
382         {
383             dbg_printf("%s\n", exp->un.structure.element_name);
384             RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
385         }
386         break;
387     case EXPR_TYPE_STRUCT:
388         exp1 = expr_eval(exp->un.structure.exp1);
389         if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
390         rtn = exp1;
391         if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
392                                     &exp->un.structure.result))
393         {
394             dbg_printf("%s\n", exp->un.structure.element_name);
395             RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
396         }
397         break;
398     case EXPR_TYPE_CALL:
399 #if 0
400         /*
401          * First, evaluate all of the arguments.  If any of them are not
402          * evaluable, then bail.
403          */
404         for (i = 0; i < exp->un.call.nargs; i++)
405         {
406             exp1 = expr_eval(exp->un.call.arg[i]);
407             if (exp1.type.id == dbg_itype_none)
408                 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
409             cexp[i] = types_extract_as_integer(&exp1);
410         }
411
412         /*
413          * Now look up the address of the function itself.
414          */
415         switch (symbol_get_lvalue(exp->un.call.funcname, -1, &rtn, FALSE))
416         {
417         case sglv_found:
418             break;
419         case sglv_unknown:
420             RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
421             /* should never be here */
422         case sglv_aborted:
423             RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
424             /* should never be here */
425         }
426
427         /* FIXME: NEWDBG NIY */
428         /* Anyway, I wonder how this could work depending on the calling order of
429          * the function (cdecl vs pascal for example)
430          */
431         int             (*fptr)();
432
433         fptr = (int (*)()) rtn.addr.off;
434         switch (exp->un.call.nargs)
435         {
436         case 0:
437             exp->un.call.result = (*fptr)();
438             break;
439         case 1:
440             exp->un.call.result = (*fptr)(cexp[0]);
441             break;
442         case 2:
443             exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
444             break;
445         case 3:
446             exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
447             break;
448         case 4:
449             exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
450             break;
451         case 5:
452             exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
453             break;
454         }
455 #else
456         dbg_printf("Function call no longer implemented\n");
457         /* would need to set up a call to this function, and then restore the current
458          * context afterwards...
459          */
460         exp->un.call.result = 0;
461 #endif
462         rtn.cookie = DLV_HOST;
463         /* get return type from function signature tupe */
464         types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type.id);
465         rtn.addr.Offset = (ULONG_PTR)&exp->un.call.result;
466         break;
467     case EXPR_TYPE_INTVAR:
468         rtn.cookie = DLV_HOST;
469         if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
470             RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
471         rtn.type.id     = div->typeid;
472         rtn.type.module = 0;
473         rtn.addr.Offset = (ULONG_PTR)div->pval;
474         break;
475     case EXPR_TYPE_BINOP:
476         rtn.cookie = DLV_HOST;
477         exp1 = expr_eval(exp->un.binop.exp1);
478         exp2 = expr_eval(exp->un.binop.exp2);
479         if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
480             RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
481         rtn.type.id = dbg_itype_signed_int;
482         rtn.type.module = 0;
483         rtn.addr.Offset = (ULONG_PTR)&exp->un.binop.result;
484         type1 = exp1.type;
485         type2 = exp2.type;
486         switch (exp->un.binop.binop_type)
487         {
488         case EXP_OP_ADD:
489             if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
490                 tag != SymTagPointerType ||
491                 !types_get_info(&exp1.type, TI_GET_TYPE, &type1.id))
492                 type1.id = dbg_itype_none;
493             if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
494                 tag != SymTagPointerType ||
495                 !types_get_info(&exp2.type, TI_GET_TYPE, &type2.id))
496                 type2.id = dbg_itype_none;
497             scale1 = 1;
498             scale2 = 1;
499             if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
500                 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
501             if (type1.id != dbg_itype_none)
502             {
503                 types_get_info(&type1, TI_GET_LENGTH, &scale2);
504                 rtn.type = exp1.type;
505             }
506             else if (type2.id != dbg_itype_none)
507             {
508                 types_get_info(&type2, TI_GET_LENGTH, &scale1);
509                 rtn.type = exp2.type;
510             }
511             exp->un.binop.result = types_extract_as_integer(&exp1) * (DWORD)scale1 +
512                 (DWORD)scale2 * types_extract_as_integer(&exp2);
513             break;
514         case EXP_OP_SUB:
515             if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
516                 tag != SymTagPointerType ||
517                 !types_get_info(&exp1.type, TI_GET_TYPE, &type1.id))
518                 type1.id = dbg_itype_none;
519             if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
520                 tag != SymTagPointerType ||
521                 !types_get_info(&exp2.type, TI_GET_TYPE, &type2.id))
522                 type2.id = dbg_itype_none;
523             scale1 = 1;
524             scale2 = 1;
525             scale3 = 1;
526             if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
527             {
528                 WINE_FIXME("This may fail (if module base address are wrongly calculated)\n");
529                 if (memcmp(&type1, &type2, sizeof(struct dbg_type)))
530                     RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
531                 types_get_info(&type1, TI_GET_LENGTH, &scale3);
532             }
533             else if (type1.id != dbg_itype_none)
534             {
535                 types_get_info(&type1, TI_GET_LENGTH, &scale2);
536                 rtn.type = exp1.type;
537             }
538             else if (type2.id != dbg_itype_none)
539             {
540                 types_get_info(&type2, TI_GET_LENGTH, &scale1);
541                 rtn.type = exp2.type;
542             }
543             exp->un.binop.result = (types_extract_as_integer(&exp1) * (DWORD)scale1 - 
544                                     types_extract_as_integer(&exp2) * (DWORD)scale2) / (DWORD)scale3;
545             break;
546         case EXP_OP_SEG:
547             rtn.type.id = dbg_itype_segptr;
548             rtn.type.module = 0;
549             be_cpu->build_addr(dbg_curr_thread->handle, &dbg_context, &rtn.addr,
550                                types_extract_as_integer(&exp1), types_extract_as_integer(&exp2));
551             break;
552         case EXP_OP_LOR:
553             exp->un.binop.result = (types_extract_as_integer(&exp1) || types_extract_as_integer(&exp2));
554             break;
555         case EXP_OP_LAND:
556             exp->un.binop.result = (types_extract_as_integer(&exp1) && types_extract_as_integer(&exp2));
557             break;
558         case EXP_OP_OR:
559             exp->un.binop.result = (types_extract_as_integer(&exp1) | types_extract_as_integer(&exp2));
560             break;
561         case EXP_OP_AND:
562             exp->un.binop.result = (types_extract_as_integer(&exp1) & types_extract_as_integer(&exp2));
563             break;
564         case EXP_OP_XOR:
565             exp->un.binop.result = (types_extract_as_integer(&exp1) ^ types_extract_as_integer(&exp2));
566             break;
567         case EXP_OP_EQ:
568             exp->un.binop.result = (types_extract_as_integer(&exp1) == types_extract_as_integer(&exp2));
569             break;
570         case EXP_OP_GT:
571             exp->un.binop.result = (types_extract_as_integer(&exp1) > types_extract_as_integer(&exp2));
572             break;
573         case EXP_OP_LT:
574             exp->un.binop.result = (types_extract_as_integer(&exp1) < types_extract_as_integer(&exp2));
575             break;
576         case EXP_OP_GE:
577             exp->un.binop.result = (types_extract_as_integer(&exp1) >= types_extract_as_integer(&exp2));
578             break;
579         case EXP_OP_LE:
580             exp->un.binop.result = (types_extract_as_integer(&exp1) <= types_extract_as_integer(&exp2));
581             break;
582         case EXP_OP_NE:
583             exp->un.binop.result = (types_extract_as_integer(&exp1) != types_extract_as_integer(&exp2));
584             break;
585         case EXP_OP_SHL:
586             exp->un.binop.result = ((unsigned long)types_extract_as_integer(&exp1) << types_extract_as_integer(&exp2));
587             break;
588         case EXP_OP_SHR:
589             exp->un.binop.result = ((unsigned long)types_extract_as_integer(&exp1) >> types_extract_as_integer(&exp2));
590             break;
591         case EXP_OP_MUL:
592             exp->un.binop.result = (types_extract_as_integer(&exp1) * types_extract_as_integer(&exp2));
593             break;
594         case EXP_OP_DIV:
595             if (types_extract_as_integer(&exp2) == 0) RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
596             exp->un.binop.result = (types_extract_as_integer(&exp1) / types_extract_as_integer(&exp2));
597             break;
598         case EXP_OP_REM:
599             if (types_extract_as_integer(&exp2) == 0) RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
600             exp->un.binop.result = (types_extract_as_integer(&exp1) % types_extract_as_integer(&exp2));
601             break;
602         case EXP_OP_ARR:
603             if (!types_array_index(&exp1, types_extract_as_integer(&exp2), &rtn))
604                 RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
605             break;
606         default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
607         }
608         break;
609     case EXPR_TYPE_UNOP:
610         rtn.cookie = DLV_HOST;
611         exp1 = expr_eval(exp->un.unop.exp1);
612         if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
613         rtn.addr.Offset = (ULONG_PTR)&exp->un.unop.result;
614         rtn.type.id     = dbg_itype_signed_int;
615         rtn.type.module = 0;
616         switch (exp->un.unop.unop_type)
617         {
618         case EXP_OP_NEG:
619             exp->un.unop.result = -types_extract_as_integer(&exp1);
620             break;
621         case EXP_OP_NOT:
622             exp->un.unop.result = !types_extract_as_integer(&exp1);
623             break;
624         case EXP_OP_LNOT:
625             exp->un.unop.result = ~types_extract_as_integer(&exp1);
626             break;
627         case EXP_OP_DEREF:
628             if (!types_array_index(&exp1, 0, &rtn))
629                 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
630             break;
631         case EXP_OP_FORCE_DEREF:
632             rtn = exp1;
633             if (exp1.cookie == DLV_TARGET)
634                 dbg_read_memory(memory_to_linear_addr(&exp1.addr), &rtn.addr.Offset, sizeof(rtn.addr.Offset));
635             break;
636         case EXP_OP_ADDR:
637             /* only do it on linear addresses */
638             if (exp1.addr.Mode != AddrModeFlat)
639                 RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
640             exp->un.unop.result = (ULONG_PTR)memory_to_linear_addr(&exp1.addr);
641             rtn.type = types_find_pointer(&exp1.type);
642             if (rtn.type.id == dbg_itype_none)
643                 RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
644             break;
645         default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
646         }
647         break;
648     default:
649         WINE_FIXME("Unexpected expression (%d).\n", exp->type);
650         RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
651         break;
652     }
653
654     return rtn;
655 }
656
657 int expr_print(const struct expr* exp)
658 {
659     int                 i;
660     struct dbg_type     type;
661
662     switch (exp->type)
663     {
664     case EXPR_TYPE_CAST:
665         WINE_FIXME("No longer supported (missing module base)\n");
666         dbg_printf("((");
667         switch (exp->un.cast.cast_to.type)
668         {
669         case type_expr_type_id:
670             type.module = 0;
671             type.id = exp->un.cast.cast_to.type;
672             types_print_type(&type, FALSE); break;
673         case type_expr_udt_class:
674             dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
675         case type_expr_udt_struct:
676             dbg_printf("struct %s", exp->un.cast.cast_to.u.name); break;
677         case type_expr_udt_union:
678             dbg_printf("union %s", exp->un.cast.cast_to.u.name); break;
679         case type_expr_enumeration:
680             dbg_printf("enum %s", exp->un.cast.cast_to.u.name); break;
681         }
682         for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
683             dbg_printf("*");
684         dbg_printf(")");
685         expr_print(exp->un.cast.expr);
686         dbg_printf(")");
687         break;
688     case EXPR_TYPE_INTVAR:
689         dbg_printf("$%s", exp->un.intvar.name);
690         break;
691     case EXPR_TYPE_U_CONST:
692         dbg_printf("%lu", exp->un.u_const.value);
693         break;
694     case EXPR_TYPE_S_CONST:
695         dbg_printf("%ld", exp->un.s_const.value);
696         break;
697     case EXPR_TYPE_STRING:
698         dbg_printf("\"%s\"", exp->un.string.str);
699         break;
700     case EXPR_TYPE_SYMBOL:
701         dbg_printf("%s" , exp->un.symbol.name);
702         break;
703     case EXPR_TYPE_PSTRUCT:
704         expr_print(exp->un.structure.exp1);
705         dbg_printf("->%s", exp->un.structure.element_name);
706         break;
707     case EXPR_TYPE_STRUCT:
708         expr_print(exp->un.structure.exp1);
709         dbg_printf(".%s", exp->un.structure.element_name);
710         break;
711     case EXPR_TYPE_CALL:
712         dbg_printf("%s(",exp->un.call.funcname);
713         for (i = 0; i < exp->un.call.nargs; i++)
714         {
715             expr_print(exp->un.call.arg[i]);
716             if (i != exp->un.call.nargs - 1) dbg_printf(", ");
717         }
718         dbg_printf(")");
719         break;
720     case EXPR_TYPE_BINOP:
721         dbg_printf("(");
722         expr_print(exp->un.binop.exp1);
723         switch (exp->un.binop.binop_type)
724         {
725         case EXP_OP_ADD:        dbg_printf(" + ");    break;
726         case EXP_OP_SUB:        dbg_printf(" - ");    break;
727         case EXP_OP_SEG:        dbg_printf(":");      break;
728         case EXP_OP_LOR:        dbg_printf(" || ");   break;
729         case EXP_OP_LAND:       dbg_printf(" && ");   break;
730         case EXP_OP_OR:         dbg_printf(" | ");    break;
731         case EXP_OP_AND:        dbg_printf(" & ");    break;
732         case EXP_OP_XOR:        dbg_printf(" ^ ");    break;
733         case EXP_OP_EQ:         dbg_printf(" == ");   break;
734         case EXP_OP_GT:         dbg_printf(" > ");    break;
735         case EXP_OP_LT:         dbg_printf(" < ");    break;
736         case EXP_OP_GE:         dbg_printf(" >= ");   break;
737         case EXP_OP_LE:         dbg_printf(" <= ");   break;
738         case EXP_OP_NE:         dbg_printf(" != ");   break;
739         case EXP_OP_SHL:        dbg_printf(" << ");   break;
740         case EXP_OP_SHR:        dbg_printf(" >> ");   break;
741         case EXP_OP_MUL:        dbg_printf(" * ");    break;
742         case EXP_OP_DIV:        dbg_printf(" / ");    break;
743         case EXP_OP_REM:        dbg_printf(" %% ");   break;
744         case EXP_OP_ARR:        dbg_printf("[");      break;
745         default:                                      break;
746         }
747         expr_print(exp->un.binop.exp2);
748         if (exp->un.binop.binop_type == EXP_OP_ARR) dbg_printf("]");
749         dbg_printf(")");
750         break;
751     case EXPR_TYPE_UNOP:
752         switch (exp->un.unop.unop_type)
753         {
754         case EXP_OP_NEG:        dbg_printf("-");      break;
755         case EXP_OP_NOT:        dbg_printf("!");      break;
756         case EXP_OP_LNOT:       dbg_printf("~");      break;
757         case EXP_OP_DEREF:      dbg_printf("*");      break;
758         case EXP_OP_ADDR:       dbg_printf("&");      break;
759         }
760         expr_print(exp->un.unop.exp1);
761         break;
762     default:
763         WINE_FIXME("Unexpected expression (%u).\n", exp->type);
764         RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
765         break;
766     }
767
768     return TRUE;
769 }
770
771 struct expr* expr_clone(const struct expr* exp, BOOL *local_binding)
772 {
773     int                 i;
774     struct expr*        rtn;
775
776     rtn = HeapAlloc(GetProcessHeap(), 0, sizeof(struct expr));
777
778     /*
779      * First copy the contents of the expression itself.
780      */
781     *rtn = *exp;
782
783     switch (exp->type)
784     {
785     case EXPR_TYPE_CAST:
786         rtn->un.cast.expr = expr_clone(exp->un.cast.expr, local_binding);
787         break;
788     case EXPR_TYPE_INTVAR:
789         rtn->un.intvar.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.intvar.name) + 1), exp->un.intvar.name);
790         break;
791     case EXPR_TYPE_U_CONST:
792     case EXPR_TYPE_S_CONST:
793         break;
794     case EXPR_TYPE_STRING:
795         rtn->un.string.str = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.string.str) + 1), exp->un.string.str);
796         break;
797     case EXPR_TYPE_SYMBOL:
798         rtn->un.symbol.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.symbol.name) + 1), exp->un.symbol.name);
799         if (local_binding && symbol_is_local(exp->un.symbol.name))
800             *local_binding = TRUE;
801         break;
802     case EXPR_TYPE_PSTRUCT:
803     case EXPR_TYPE_STRUCT:
804         rtn->un.structure.exp1 = expr_clone(exp->un.structure.exp1, local_binding);
805         rtn->un.structure.element_name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.structure.element_name) + 1), exp->un.structure.element_name);
806         break;
807     case EXPR_TYPE_CALL:
808         for (i = 0; i < exp->un.call.nargs; i++)
809         {
810             rtn->un.call.arg[i] = expr_clone(exp->un.call.arg[i], local_binding);
811         }
812         rtn->un.call.funcname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.call.funcname) + 1), exp->un.call.funcname);
813         break;
814     case EXPR_TYPE_BINOP:
815         rtn->un.binop.exp1 = expr_clone(exp->un.binop.exp1, local_binding);
816         rtn->un.binop.exp2 = expr_clone(exp->un.binop.exp2, local_binding);
817         break;
818     case EXPR_TYPE_UNOP:
819         rtn->un.unop.exp1 = expr_clone(exp->un.unop.exp1, local_binding);
820         break;
821     default:
822         WINE_FIXME("Unexpected expression (%u).\n", exp->type);
823         RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
824         break;
825     }
826
827     return rtn;
828 }
829
830
831 /*
832  * Recursively go through an expression tree and free all memory associated
833  * with it.
834  */
835 int expr_free(struct expr* exp)
836 {
837     int i;
838
839     switch (exp->type)
840     {
841     case EXPR_TYPE_CAST:
842         expr_free(exp->un.cast.expr);
843         break;
844     case EXPR_TYPE_INTVAR:
845         HeapFree(GetProcessHeap(), 0, (char*)exp->un.intvar.name);
846         break;
847     case EXPR_TYPE_U_CONST:
848     case EXPR_TYPE_S_CONST:
849         break;
850     case EXPR_TYPE_STRING:
851         HeapFree(GetProcessHeap(), 0, (char*)exp->un.string.str);
852         break;
853     case EXPR_TYPE_SYMBOL:
854         HeapFree(GetProcessHeap(), 0, (char*)exp->un.symbol.name);
855         break;
856     case EXPR_TYPE_PSTRUCT:
857     case EXPR_TYPE_STRUCT:
858         expr_free(exp->un.structure.exp1);
859         HeapFree(GetProcessHeap(), 0, (char*)exp->un.structure.element_name);
860         break;
861     case EXPR_TYPE_CALL:
862         for (i = 0; i < exp->un.call.nargs; i++)
863         {
864             expr_free(exp->un.call.arg[i]);
865         }
866         HeapFree(GetProcessHeap(), 0, (char*)exp->un.call.funcname);
867         break;
868     case EXPR_TYPE_BINOP:
869         expr_free(exp->un.binop.exp1);
870         expr_free(exp->un.binop.exp2);
871         break;
872     case EXPR_TYPE_UNOP:
873         expr_free(exp->un.unop.exp1);
874         break;
875     default:
876         WINE_FIXME("Unexpected expression (%u).\n", exp->type);
877         RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
878         break;
879     }
880
881     HeapFree(GetProcessHeap(), 0, exp);
882     return TRUE;
883 }