blob: 2144a44b98ba797bb01c347b88132abafd8f93cb [file] [log] [blame]
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001/*
2 * File expr.c - expression handling for Wine internal debugger.
3 *
4 * Copyright (C) 1997, Eric Youngdale.
5 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Alexandre Julliardc6c09441997-01-12 18:32:19 +000019 */
20
Marcus Meissnerb0d52b01999-02-28 19:59:00 +000021#include "config.h"
Alexandre Julliardc6c09441997-01-12 18:32:19 +000022#include <stdlib.h>
Alexandre Julliardc6c09441997-01-12 18:32:19 +000023#include <string.h>
Marcus Meissner88354d91999-10-24 20:44:38 +000024#include "winbase.h"
Marcus Meissner317af321999-02-17 13:51:06 +000025#include "wine/winbase16.h"
Alexandre Julliardc6c09441997-01-12 18:32:19 +000026#include "debugger.h"
Alexandre Julliardc6c09441997-01-12 18:32:19 +000027#include "expr.h"
28
29#include <stdarg.h>
30
31struct expr
32{
33 unsigned int perm;
34 unsigned int type:31;
35 union
36 {
37 struct
38 {
39 int value;
40 } constant;
41
42 struct
43 {
44 const char * str;
45 } string;
46
47 struct
48 {
49 unsigned int value;
50 } u_const;
51
52 struct
53 {
54 const char * name;
55 } symbol;
56
57 struct
58 {
Eric Pouech04c16b82000-04-30 12:21:15 +000059 const char * name;
60 } intvar;
Alexandre Julliardc6c09441997-01-12 18:32:19 +000061
62 struct
63 {
64 int unop_type;
65 struct expr * exp1;
66 int result;
67 } unop;
68
69 struct
70 {
71 int binop_type;
72 int result;
73 struct expr * exp1;
74 struct expr * exp2;
75 } binop;
76
77 struct
78 {
Alexandre Julliard01d63461997-01-20 19:43:45 +000079 struct datatype * cast;
80 struct expr * expr;
81 } cast;
82
83 struct
84 {
Alexandre Julliardc6c09441997-01-12 18:32:19 +000085 struct expr * exp1;
86 const char * element_name;
87 int result;
88 } structure;
89
90 struct
91 {
92 struct expr * base;
93 struct expr * index;
94 } array;
95
96 struct
97 {
98 const char * funcname;
99 int nargs;
100 int result;
101 struct expr * arg[5];
102 } call;
103
104 } un;
105};
106
107#define EXPR_TYPE_CONST 0
108#define EXPR_TYPE_US_CONST 1
109#define EXPR_TYPE_SYMBOL 2
Eric Pouech04c16b82000-04-30 12:21:15 +0000110#define EXPR_TYPE_INTVAR 3
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000111#define EXPR_TYPE_BINOP 4
112#define EXPR_TYPE_UNOP 5
113#define EXPR_TYPE_STRUCT 6
114#define EXPR_TYPE_PSTRUCT 7
115#define EXPR_TYPE_ARRAY 8
116#define EXPR_TYPE_CALL 9
117#define EXPR_TYPE_STRING 10
Alexandre Julliard01d63461997-01-20 19:43:45 +0000118#define EXPR_TYPE_CAST 11
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000119
120static char expr_list[4096];
Joerg Mayerd18140c2000-12-26 01:28:51 +0000121static unsigned int next_expr_free = 0;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000122
123/*
124 * This is how we turn an expression address into the actual value.
125 * This works well in the 32 bit domain - not sure at all about the
126 * 16 bit world.
127 */
128#define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
129
130static
131struct expr *
Eric Pouechd33bcb62000-03-15 19:57:20 +0000132DEBUG_GetFreeExpr(void)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000133{
134 struct expr * rtn;
135
136 rtn = (struct expr *) &expr_list[next_expr_free];
137
138 next_expr_free += sizeof(struct expr);
Eric Pouech3b50d211999-05-24 08:14:30 +0000139 assert(next_expr_free < sizeof(expr_list));
140
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000141 return rtn;
142}
143
144void
Eric Pouechd33bcb62000-03-15 19:57:20 +0000145DEBUG_FreeExprMem(void)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000146{
147 next_expr_free = 0;
148}
149
Alexandre Julliard01d63461997-01-20 19:43:45 +0000150struct expr *
151DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
152{
153 struct expr * ex;
154
155 ex = DEBUG_GetFreeExpr();
156
157 ex->type = EXPR_TYPE_CAST;
158 ex->un.cast.cast = dt;
159 ex->un.cast.expr = exp;
160 return ex;
161}
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000162
163struct expr *
Eric Pouech04c16b82000-04-30 12:21:15 +0000164DEBUG_IntVarExpr(const char* name)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000165{
166 struct expr * ex;
167
168 ex = DEBUG_GetFreeExpr();
169
Eric Pouech04c16b82000-04-30 12:21:15 +0000170 ex->type = EXPR_TYPE_INTVAR;
171 ex->un.intvar.name = name;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000172 return ex;
173}
174
175struct expr *
176DEBUG_SymbolExpr(const char * name)
177{
178 struct expr * ex;
179
180 ex = DEBUG_GetFreeExpr();
181
182 ex->type = EXPR_TYPE_SYMBOL;
183 ex->un.symbol.name = name;
184 return ex;
185}
186
187struct expr *
188DEBUG_ConstExpr(int value)
189{
190 struct expr * ex;
191
192 ex = DEBUG_GetFreeExpr();
193
194 ex->type = EXPR_TYPE_CONST;
195 ex->un.constant.value = value;
196 return ex;
197}
198
199struct expr *
200DEBUG_StringExpr(const char * str)
201{
202 struct expr * ex;
203 char * pnt;
204 ex = DEBUG_GetFreeExpr();
205
206 ex->type = EXPR_TYPE_STRING;
207 ex->un.string.str = str+1;
208 pnt = strrchr(ex->un.string.str, '"');
209 if( pnt != NULL )
210 {
211 *pnt = '\0';
212 }
213 return ex;
214}
215
216struct expr *
217DEBUG_USConstExpr(unsigned int value)
218{
219 struct expr * ex;
220
221 ex = DEBUG_GetFreeExpr();
222
223 ex->type = EXPR_TYPE_CONST;
224 ex->un.u_const.value = value;
225 return ex;
226}
227
228struct expr *
229DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
230{
231 struct expr * ex;
232
233 ex = DEBUG_GetFreeExpr();
234
235 ex->type = EXPR_TYPE_BINOP;
236 ex->un.binop.binop_type = operator_type;
237 ex->un.binop.exp1 = exp1;
238 ex->un.binop.exp2 = exp2;
239 return ex;
240}
241
242struct expr *
243DEBUG_UnopExpr(int operator_type, struct expr * exp1)
244{
245 struct expr * ex;
246
247 ex = DEBUG_GetFreeExpr();
248
249 ex->type = EXPR_TYPE_UNOP;
250 ex->un.unop.unop_type = operator_type;
251 ex->un.unop.exp1 = exp1;
252 return ex;
253}
254
255struct expr *
256DEBUG_StructExpr(struct expr * exp, const char * element)
257{
258 struct expr * ex;
259
260 ex = DEBUG_GetFreeExpr();
261
262 ex->type = EXPR_TYPE_STRUCT;
263 ex->un.structure.exp1 = exp;
264 ex->un.structure.element_name = element;
265 return ex;
266}
267
268struct expr *
269DEBUG_StructPExpr(struct expr * exp, const char * element)
270{
271 struct expr * ex;
272
273 ex = DEBUG_GetFreeExpr();
274
275 ex->type = EXPR_TYPE_PSTRUCT;
276 ex->un.structure.exp1 = exp;
277 ex->un.structure.element_name = element;
278 return ex;
279}
280
281struct expr *
282DEBUG_CallExpr(const char * funcname, int nargs, ...)
283{
284 struct expr * ex;
285 va_list ap;
286 int i;
287
288 ex = DEBUG_GetFreeExpr();
289
290 ex->type = EXPR_TYPE_CALL;
291 ex->un.call.funcname = funcname;
292 ex->un.call.nargs = nargs;
293
294 va_start(ap, nargs);
295 for(i=0; i < nargs; i++)
296 {
297 ex->un.call.arg[i] = va_arg(ap, struct expr *);
298 }
299 va_end(ap);
300 return ex;
301}
302
Eric Pouechd33bcb62000-03-15 19:57:20 +0000303DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000304{
Eric Pouechd33bcb62000-03-15 19:57:20 +0000305 DBG_VALUE rtn;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000306 int i;
Eric Pouechd33bcb62000-03-15 19:57:20 +0000307 DBG_VALUE exp1;
308 DBG_VALUE exp2;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000309 unsigned int cexp[5];
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000310 int scale1;
311 int scale2;
312 int scale3;
313 struct datatype * type1;
314 struct datatype * type2;
315
316 rtn.type = NULL;
Peter Hunnisett856aefa2000-07-08 12:45:44 +0000317 rtn.cookie = DV_INVALID;
Eric Pouechd33bcb62000-03-15 19:57:20 +0000318 rtn.addr.off = 0;
319 rtn.addr.seg = 0;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000320
321 switch(exp->type)
322 {
Alexandre Julliard01d63461997-01-20 19:43:45 +0000323 case EXPR_TYPE_CAST:
324 rtn = DEBUG_EvalExpr(exp->un.cast.expr);
325 rtn.type = exp->un.cast.cast;
Eric Pouechd33bcb62000-03-15 19:57:20 +0000326 if (DEBUG_GetType(rtn.type) == DT_POINTER)
327 rtn.cookie = DV_TARGET;
Alexandre Julliard01d63461997-01-20 19:43:45 +0000328 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000329 case EXPR_TYPE_STRING:
Eric Pouech02ecb682001-12-21 20:29:58 +0000330 rtn.type = DEBUG_GetBasicType(DT_BASIC_STRING);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000331 rtn.cookie = DV_HOST;
332 rtn.addr.off = (unsigned int) &exp->un.string.str;
333 rtn.addr.seg = 0;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000334 break;
335 case EXPR_TYPE_CONST:
Eric Pouech02ecb682001-12-21 20:29:58 +0000336 rtn.type = DEBUG_GetBasicType(DT_BASIC_CONST_INT);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000337 rtn.cookie = DV_HOST;
338 rtn.addr.off = (unsigned int) &exp->un.constant.value;
339 rtn.addr.seg = 0;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000340 break;
341 case EXPR_TYPE_US_CONST:
Eric Pouech02ecb682001-12-21 20:29:58 +0000342 rtn.type = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000343 rtn.cookie = DV_HOST;
344 rtn.addr.off = (unsigned int) &exp->un.u_const.value;
345 rtn.addr.seg = 0;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000346 break;
347 case EXPR_TYPE_SYMBOL:
Eric Pouech527eea92000-03-08 16:44:54 +0000348 if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
Eric Pouech38f2be42001-08-15 17:40:31 +0000349 {
350 DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.symbol.name);
351 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
352 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000353 break;
354 case EXPR_TYPE_PSTRUCT:
355 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
356 if( exp1.type == NULL )
357 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000358 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000359 }
Eric Pouechd33bcb62000-03-15 19:57:20 +0000360 rtn.cookie = DV_TARGET;
Eric Pouech38f2be42001-08-15 17:40:31 +0000361 rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &rtn.type);
362 if( rtn.type == NULL )
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000363 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000364 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000365 }
Eric Pouech38f2be42001-08-15 17:40:31 +0000366 if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
367 &exp->un.structure.result))
368 {
369 DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
370 RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
371 }
372
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000373 break;
374 case EXPR_TYPE_STRUCT:
375 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
376 if( exp1.type == NULL )
Eric Pouech38f2be42001-08-15 17:40:31 +0000377 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000378 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Eric Pouech38f2be42001-08-15 17:40:31 +0000379 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000380 rtn = exp1;
Eric Pouech38f2be42001-08-15 17:40:31 +0000381 if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
382 &exp->un.structure.result))
383 {
384 DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
385 RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
386 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000387 break;
388 case EXPR_TYPE_CALL:
389 /*
390 * First, evaluate all of the arguments. If any of them are not
391 * evaluable, then bail.
392 */
393 for(i=0; i < exp->un.call.nargs; i++)
394 {
395 exp1 = DEBUG_EvalExpr(exp->un.call.arg[i]);
396 if( exp1.type == NULL )
397 {
398 return rtn;
399 }
400 cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
401 }
402
403 /*
404 * Now look up the address of the function itself.
405 */
406 if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
407 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000408 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
Eric Pouech3b50d211999-05-24 08:14:30 +0000409 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000410
Eric Pouech527eea92000-03-08 16:44:54 +0000411#if 0
412 /* FIXME: NEWDBG NIY */
413 /* Anyway, I wonder how this could work depending on the calling order of
414 * the function (cdecl vs pascal for example)
415 */
416 int (*fptr)();
417
Eric Pouechd33bcb62000-03-15 19:57:20 +0000418 fptr = (int (*)()) rtn.addr.off;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000419 switch(exp->un.call.nargs)
420 {
421 case 0:
422 exp->un.call.result = (*fptr)();
423 break;
424 case 1:
425 exp->un.call.result = (*fptr)(cexp[0]);
426 break;
427 case 2:
428 exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
429 break;
430 case 3:
431 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
432 break;
433 case 4:
434 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
435 break;
436 case 5:
437 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
438 break;
439 }
Eric Pouech527eea92000-03-08 16:44:54 +0000440#else
Eric Poueche5efa0c2000-04-13 19:31:58 +0000441 DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
Eric Pouech527eea92000-03-08 16:44:54 +0000442 /* would need to set up a call to this function, and then restore the current
443 * context afterwards...
444 */
445 exp->un.call.result = 0;
446#endif
Eric Pouech02ecb682001-12-21 20:29:58 +0000447 rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000448 rtn.cookie = DV_HOST;
449 rtn.addr.off = (unsigned int) &exp->un.call.result;
Eric Pouech527eea92000-03-08 16:44:54 +0000450
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000451 break;
Eric Pouech04c16b82000-04-30 12:21:15 +0000452 case EXPR_TYPE_INTVAR:
453 {
454
455 DBG_INTVAR* div = DEBUG_GetIntVar(exp->un.intvar.name);
456
457 if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
458 rtn.cookie = DV_HOST;
459 rtn.type = div->type;
460 rtn.addr.off = (unsigned int)div->pval;
461 /* EPP FIXME rtn.addr.seg = ?? */
462 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000463 break;
464 case EXPR_TYPE_BINOP:
465 exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
466 exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000467 rtn.cookie = DV_HOST;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000468 if( exp1.type == NULL || exp2.type == NULL )
469 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000470 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000471 }
Eric Pouech02ecb682001-12-21 20:29:58 +0000472 if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) &&
473 exp2.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000474 {
475 rtn.type = exp1.type;
476 }
477 else
478 {
Eric Pouech02ecb682001-12-21 20:29:58 +0000479 rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000480 }
Eric Pouechd33bcb62000-03-15 19:57:20 +0000481 rtn.addr.seg = 0;
482 rtn.addr.off = (unsigned int) &exp->un.binop.result;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000483 switch(exp->un.binop.binop_type)
484 {
485 case EXP_OP_ADD:
486 type1 = DEBUG_GetPointerType(exp1.type);
487 type2 = DEBUG_GetPointerType(exp2.type);
488 scale1 = 1;
489 scale2 = 1;
490 if( type1 != NULL && type2 != NULL )
491 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000492 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000493 }
494 else if( type1 != NULL )
495 {
496 scale2 = DEBUG_GetObjectSize(type1);
497 rtn.type = exp1.type;
498 }
499 else if( type2 != NULL )
500 {
501 scale1 = DEBUG_GetObjectSize(type2);
502 rtn.type = exp2.type;
503 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000504 exp->un.binop.result = (VAL(exp1) * scale1 + scale2 * VAL(exp2));
505 break;
506 case EXP_OP_SUB:
507 type1 = DEBUG_GetPointerType(exp1.type);
508 type2 = DEBUG_GetPointerType(exp2.type);
509 scale1 = 1;
510 scale2 = 1;
511 scale3 = 1;
512 if( type1 != NULL && type2 != NULL )
513 {
514 if( type1 != type2 )
515 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000516 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000517 }
518 scale3 = DEBUG_GetObjectSize(type1);
519 }
520 else if( type1 != NULL )
521 {
522 scale2 = DEBUG_GetObjectSize(type1);
523 rtn.type = exp1.type;
524 }
525
526 else if( type2 != NULL )
527 {
528 scale1 = DEBUG_GetObjectSize(type2);
529 rtn.type = exp2.type;
530 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000531 exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
532 break;
533 case EXP_OP_SEG:
Eric Pouechd33bcb62000-03-15 19:57:20 +0000534 rtn.cookie = DV_TARGET;
Eric Pouech71189b52000-07-25 12:51:56 +0000535 rtn.type = NULL;
Eric Pouechd33bcb62000-03-15 19:57:20 +0000536 rtn.addr.seg = VAL(exp1);
Eric Pouech71189b52000-07-25 12:51:56 +0000537 rtn.addr.off = VAL(exp2);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000538 break;
539 case EXP_OP_LOR:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000540 exp->un.binop.result = (VAL(exp1) || VAL(exp2));
541 break;
542 case EXP_OP_LAND:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000543 exp->un.binop.result = (VAL(exp1) && VAL(exp2));
544 break;
545 case EXP_OP_OR:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000546 exp->un.binop.result = (VAL(exp1) | VAL(exp2));
547 break;
548 case EXP_OP_AND:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000549 exp->un.binop.result = (VAL(exp1) & VAL(exp2));
550 break;
551 case EXP_OP_XOR:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000552 exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
553 break;
554 case EXP_OP_EQ:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000555 exp->un.binop.result = (VAL(exp1) == VAL(exp2));
556 break;
557 case EXP_OP_GT:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000558 exp->un.binop.result = (VAL(exp1) > VAL(exp2));
559 break;
560 case EXP_OP_LT:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000561 exp->un.binop.result = (VAL(exp1) < VAL(exp2));
562 break;
563 case EXP_OP_GE:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000564 exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
565 break;
566 case EXP_OP_LE:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000567 exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
568 break;
569 case EXP_OP_NE:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000570 exp->un.binop.result = (VAL(exp1) != VAL(exp2));
571 break;
572 case EXP_OP_SHL:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000573 exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
574 break;
575 case EXP_OP_SHR:
Alexandre Julliard17216f51997-10-12 16:30:17 +0000576 exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000577 break;
578 case EXP_OP_MUL:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000579 exp->un.binop.result = (VAL(exp1) * VAL(exp2));
580 break;
581 case EXP_OP_DIV:
Eric Pouechd33bcb62000-03-15 19:57:20 +0000582 if( VAL(exp2) == 0 )
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000583 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000584 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000585 }
Eric Pouechd33bcb62000-03-15 19:57:20 +0000586 exp->un.binop.result = (VAL(exp1) / VAL(exp2));
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000587 break;
588 case EXP_OP_REM:
Eric Pouechd33bcb62000-03-15 19:57:20 +0000589 if( VAL(exp2) == 0 )
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000590 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000591 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000592 }
Eric Pouechd33bcb62000-03-15 19:57:20 +0000593 exp->un.binop.result = (VAL(exp1) % VAL(exp2));
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000594 break;
595 case EXP_OP_ARR:
596 DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
597 break;
598 default:
Eric Pouechd33bcb62000-03-15 19:57:20 +0000599 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000600 break;
601 }
602 break;
603 case EXPR_TYPE_UNOP:
604 exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000605 rtn.cookie = DV_HOST;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000606 if( exp1.type == NULL )
607 {
Eric Pouechd33bcb62000-03-15 19:57:20 +0000608 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000609 }
Eric Pouechd33bcb62000-03-15 19:57:20 +0000610 rtn.addr.seg = 0;
611 rtn.addr.off = (unsigned int) &exp->un.unop.result;
Eric Pouech02ecb682001-12-21 20:29:58 +0000612 if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000613 {
614 rtn.type = exp1.type;
615 }
616 else
617 {
Eric Pouech02ecb682001-12-21 20:29:58 +0000618 rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000619 }
Eric Pouech3b50d211999-05-24 08:14:30 +0000620 switch(exp->un.unop.unop_type)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000621 {
622 case EXP_OP_NEG:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000623 exp->un.unop.result = -VAL(exp1);
624 break;
625 case EXP_OP_NOT:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000626 exp->un.unop.result = !VAL(exp1);
627 break;
628 case EXP_OP_LNOT:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000629 exp->un.unop.result = ~VAL(exp1);
630 break;
631 case EXP_OP_DEREF:
Eric Pouech52d10c92000-12-01 20:45:24 +0000632 /* FIXME: this is currently buggy.
633 * there is no way to tell were the deref:ed value is...
634 * for example:
635 * x is a pointer to struct s, x being on the stack
636 * => exp1 is target, result is target
637 * x is a pointer to struct s, x being optimized into a reg
638 * => exp1 is host, result is target
639 * x is a pointer to internal variable x
640 * => exp1 is host, result is host
641 * so we force DV_TARGET, because dereferencing pointers to
642 * internal variables is very unlikely. a correct fix would be
643 * rather large.
644 */
645 rtn.cookie = DV_TARGET;
Eric Pouechd33bcb62000-03-15 19:57:20 +0000646 rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
647 if (!rtn.type)
648 {
649 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
650 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000651 break;
652 case EXP_OP_FORCE_DEREF:
Eric Pouechd33bcb62000-03-15 19:57:20 +0000653 rtn.cookie = exp1.cookie;
654 rtn.addr.seg = exp1.addr.seg;
655 if (exp1.cookie == DV_TARGET)
656 DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
657 else
658 memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000659 break;
660 case EXP_OP_ADDR:
Eric Pouechd33bcb62000-03-15 19:57:20 +0000661 /* FIXME: even for a 16 bit entity ? */
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000662 rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000663 exp->un.unop.result = exp1.addr.off;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000664 break;
Eric Pouechd33bcb62000-03-15 19:57:20 +0000665 default:
666 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000667 }
668 break;
669 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000670 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
Eric Pouechd33bcb62000-03-15 19:57:20 +0000671 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000672 break;
673 }
674
Eric Pouechd33bcb62000-03-15 19:57:20 +0000675 assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
676
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000677 return rtn;
678}
679
680
681int
Eric Pouechd33bcb62000-03-15 19:57:20 +0000682DEBUG_DisplayExpr(const struct expr * exp)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000683{
684 int i;
685
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000686 switch(exp->type)
687 {
Alexandre Julliard01d63461997-01-20 19:43:45 +0000688 case EXPR_TYPE_CAST:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000689 DEBUG_Printf(DBG_CHN_MESG, "((");
Alexandre Julliard01d63461997-01-20 19:43:45 +0000690 DEBUG_PrintTypeCast(exp->un.cast.cast);
Eric Poueche5efa0c2000-04-13 19:31:58 +0000691 DEBUG_Printf(DBG_CHN_MESG, ")");
Alexandre Julliard01d63461997-01-20 19:43:45 +0000692 DEBUG_DisplayExpr(exp->un.cast.expr);
Eric Poueche5efa0c2000-04-13 19:31:58 +0000693 DEBUG_Printf(DBG_CHN_MESG, ")");
Alexandre Julliard01d63461997-01-20 19:43:45 +0000694 break;
Eric Pouech04c16b82000-04-30 12:21:15 +0000695 case EXPR_TYPE_INTVAR:
696 DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000697 break;
698 case EXPR_TYPE_US_CONST:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000699 DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000700 break;
701 case EXPR_TYPE_CONST:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000702 DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000703 break;
704 case EXPR_TYPE_STRING:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000705 DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000706 break;
707 case EXPR_TYPE_SYMBOL:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000708 DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000709 break;
710 case EXPR_TYPE_PSTRUCT:
711 DEBUG_DisplayExpr(exp->un.structure.exp1);
Eric Poueche5efa0c2000-04-13 19:31:58 +0000712 DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000713 break;
714 case EXPR_TYPE_STRUCT:
715 DEBUG_DisplayExpr(exp->un.structure.exp1);
Eric Poueche5efa0c2000-04-13 19:31:58 +0000716 DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000717 break;
718 case EXPR_TYPE_CALL:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000719 DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000720 for(i=0; i < exp->un.call.nargs; i++)
721 {
722 DEBUG_DisplayExpr(exp->un.call.arg[i]);
723 if( i != exp->un.call.nargs - 1 )
724 {
Eric Poueche5efa0c2000-04-13 19:31:58 +0000725 DEBUG_Printf(DBG_CHN_MESG, ", ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000726 }
727 }
Eric Poueche5efa0c2000-04-13 19:31:58 +0000728 DEBUG_Printf(DBG_CHN_MESG, ")");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000729 break;
730 case EXPR_TYPE_BINOP:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000731 DEBUG_Printf(DBG_CHN_MESG, "( ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000732 DEBUG_DisplayExpr(exp->un.binop.exp1);
733 switch(exp->un.binop.binop_type)
734 {
735 case EXP_OP_ADD:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000736 DEBUG_Printf(DBG_CHN_MESG, " + ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000737 break;
738 case EXP_OP_SUB:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000739 DEBUG_Printf(DBG_CHN_MESG, " - ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000740 break;
741 case EXP_OP_SEG:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000742 DEBUG_Printf(DBG_CHN_MESG, ":");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000743 break;
744 case EXP_OP_LOR:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000745 DEBUG_Printf(DBG_CHN_MESG, " || ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000746 break;
747 case EXP_OP_LAND:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000748 DEBUG_Printf(DBG_CHN_MESG, " && ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000749 break;
750 case EXP_OP_OR:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000751 DEBUG_Printf(DBG_CHN_MESG, " | ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000752 break;
753 case EXP_OP_AND:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000754 DEBUG_Printf(DBG_CHN_MESG, " & ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000755 break;
756 case EXP_OP_XOR:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000757 DEBUG_Printf(DBG_CHN_MESG, " ^ ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000758 break;
759 case EXP_OP_EQ:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000760 DEBUG_Printf(DBG_CHN_MESG, " == ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000761 break;
762 case EXP_OP_GT:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000763 DEBUG_Printf(DBG_CHN_MESG, " > ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000764 break;
765 case EXP_OP_LT:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000766 DEBUG_Printf(DBG_CHN_MESG, " < ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000767 break;
768 case EXP_OP_GE:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000769 DEBUG_Printf(DBG_CHN_MESG, " >= ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000770 break;
771 case EXP_OP_LE:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000772 DEBUG_Printf(DBG_CHN_MESG, " <= ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000773 break;
774 case EXP_OP_NE:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000775 DEBUG_Printf(DBG_CHN_MESG, " != ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000776 break;
777 case EXP_OP_SHL:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000778 DEBUG_Printf(DBG_CHN_MESG, " << ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000779 break;
780 case EXP_OP_SHR:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000781 DEBUG_Printf(DBG_CHN_MESG, " >> ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000782 break;
783 case EXP_OP_MUL:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000784 DEBUG_Printf(DBG_CHN_MESG, " * ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000785 break;
786 case EXP_OP_DIV:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000787 DEBUG_Printf(DBG_CHN_MESG, " / ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000788 break;
789 case EXP_OP_REM:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000790 DEBUG_Printf(DBG_CHN_MESG, " %% ");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000791 break;
792 case EXP_OP_ARR:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000793 DEBUG_Printf(DBG_CHN_MESG, "[");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000794 break;
795 default:
796 break;
797 }
798 DEBUG_DisplayExpr(exp->un.binop.exp2);
799 if( exp->un.binop.binop_type == EXP_OP_ARR )
800 {
Eric Poueche5efa0c2000-04-13 19:31:58 +0000801 DEBUG_Printf(DBG_CHN_MESG, "]");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000802 }
Eric Poueche5efa0c2000-04-13 19:31:58 +0000803 DEBUG_Printf(DBG_CHN_MESG, " )");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000804 break;
805 case EXPR_TYPE_UNOP:
Eric Pouech3b50d211999-05-24 08:14:30 +0000806 switch(exp->un.unop.unop_type)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000807 {
808 case EXP_OP_NEG:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000809 DEBUG_Printf(DBG_CHN_MESG, "-");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000810 break;
811 case EXP_OP_NOT:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000812 DEBUG_Printf(DBG_CHN_MESG, "!");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000813 break;
814 case EXP_OP_LNOT:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000815 DEBUG_Printf(DBG_CHN_MESG, "~");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000816 break;
817 case EXP_OP_DEREF:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000818 DEBUG_Printf(DBG_CHN_MESG, "*");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000819 break;
820 case EXP_OP_ADDR:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000821 DEBUG_Printf(DBG_CHN_MESG, "&");
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000822 break;
823 }
824 DEBUG_DisplayExpr(exp->un.unop.exp1);
825 break;
826 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000827 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
Eric Pouechd33bcb62000-03-15 19:57:20 +0000828 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000829 break;
830 }
831
832 return TRUE;
833}
834
835struct expr *
Eric Pouechd33bcb62000-03-15 19:57:20 +0000836DEBUG_CloneExpr(const struct expr * exp)
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000837{
838 int i;
839 struct expr * rtn;
840
Ove Kaavendda17c61999-04-25 12:24:42 +0000841 rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000842
843 /*
844 * First copy the contents of the expression itself.
845 */
846 *rtn = *exp;
847
848
849 switch(exp->type)
850 {
Alexandre Julliard01d63461997-01-20 19:43:45 +0000851 case EXPR_TYPE_CAST:
852 rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
853 break;
Eric Pouech04c16b82000-04-30 12:21:15 +0000854 case EXPR_TYPE_INTVAR:
855 rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
856 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000857 case EXPR_TYPE_US_CONST:
858 case EXPR_TYPE_CONST:
859 break;
860 case EXPR_TYPE_STRING:
Ove Kaavendda17c61999-04-25 12:24:42 +0000861 rtn->un.string.str = DBG_strdup(exp->un.string.str);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000862 break;
863 case EXPR_TYPE_SYMBOL:
Ove Kaavendda17c61999-04-25 12:24:42 +0000864 rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000865 break;
866 case EXPR_TYPE_PSTRUCT:
867 case EXPR_TYPE_STRUCT:
868 rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
Ove Kaavendda17c61999-04-25 12:24:42 +0000869 rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000870 break;
871 case EXPR_TYPE_CALL:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000872 for(i=0; i < exp->un.call.nargs; i++)
873 {
874 rtn->un.call.arg[i] = DEBUG_CloneExpr(exp->un.call.arg[i]);
875 }
Ove Kaavendda17c61999-04-25 12:24:42 +0000876 rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000877 break;
878 case EXPR_TYPE_BINOP:
879 rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
880 rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
881 break;
882 case EXPR_TYPE_UNOP:
883 rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
884 break;
885 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000886 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
Eric Pouechd33bcb62000-03-15 19:57:20 +0000887 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000888 break;
889 }
890
891 return rtn;
892}
893
894
895/*
896 * Recursively go through an expression tree and free all memory associated
897 * with it.
898 */
899int
900DEBUG_FreeExpr(struct expr * exp)
901{
902 int i;
903
904 switch(exp->type)
905 {
Alexandre Julliard01d63461997-01-20 19:43:45 +0000906 case EXPR_TYPE_CAST:
907 DEBUG_FreeExpr(exp->un.cast.expr);
908 break;
Eric Pouech04c16b82000-04-30 12:21:15 +0000909 case EXPR_TYPE_INTVAR:
910 DBG_free((char *) exp->un.intvar.name);
911 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000912 case EXPR_TYPE_US_CONST:
913 case EXPR_TYPE_CONST:
914 break;
915 case EXPR_TYPE_STRING:
Ove Kaavendda17c61999-04-25 12:24:42 +0000916 DBG_free((char *) exp->un.string.str);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000917 break;
918 case EXPR_TYPE_SYMBOL:
Ove Kaavendda17c61999-04-25 12:24:42 +0000919 DBG_free((char *) exp->un.symbol.name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000920 break;
921 case EXPR_TYPE_PSTRUCT:
922 case EXPR_TYPE_STRUCT:
923 DEBUG_FreeExpr(exp->un.structure.exp1);
Ove Kaavendda17c61999-04-25 12:24:42 +0000924 DBG_free((char *) exp->un.structure.element_name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000925 break;
926 case EXPR_TYPE_CALL:
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000927 for(i=0; i < exp->un.call.nargs; i++)
928 {
929 DEBUG_FreeExpr(exp->un.call.arg[i]);
930 }
Ove Kaavendda17c61999-04-25 12:24:42 +0000931 DBG_free((char *) exp->un.call.funcname);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000932 break;
933 case EXPR_TYPE_BINOP:
934 DEBUG_FreeExpr(exp->un.binop.exp1);
935 DEBUG_FreeExpr(exp->un.binop.exp2);
936 break;
937 case EXPR_TYPE_UNOP:
938 DEBUG_FreeExpr(exp->un.unop.exp1);
939 break;
940 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +0000941 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
Eric Pouechd33bcb62000-03-15 19:57:20 +0000942 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000943 break;
944 }
945
Ove Kaavendda17c61999-04-25 12:24:42 +0000946 DBG_free(exp);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000947 return TRUE;
948}