2 * File expr.c - expression handling for Wine internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
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.
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.
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
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
80 struct type_expr_t cast_to;
87 const char* element_name;
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
114 static char expr_list[4096];
115 static unsigned int next_expr_free = 0;
117 static struct expr* expr_alloc(void)
121 rtn = (struct expr*)&expr_list[next_expr_free];
123 next_expr_free += sizeof(struct expr);
124 assert(next_expr_free < sizeof(expr_list));
129 void expr_free_all(void)
134 struct expr* expr_alloc_typecast(struct type_expr_t* tet, struct expr* exp)
140 ex->type = EXPR_TYPE_CAST;
141 ex->un.cast.cast_to = *tet;
142 ex->un.cast.expr = exp;
146 struct expr* expr_alloc_internal_var(const char* name)
152 ex->type = EXPR_TYPE_INTVAR;
153 ex->un.intvar.name = name;
157 struct expr* expr_alloc_symbol(const char* name)
163 ex->type = EXPR_TYPE_SYMBOL;
164 ex->un.symbol.name = name;
168 struct expr* expr_alloc_sconstant(int value)
174 ex->type = EXPR_TYPE_S_CONST;
175 ex->un.s_const.value = value;
179 struct expr* expr_alloc_uconstant(unsigned int value)
185 ex->type = EXPR_TYPE_U_CONST;
186 ex->un.u_const.value = value;
190 struct expr* expr_alloc_string(const char* str)
197 ex->type = EXPR_TYPE_STRING;
198 ex->un.string.str = str + 1;
199 if ((pnt = strrchr(ex->un.string.str, '"'))) *pnt = '\0';
203 struct expr* expr_alloc_binary_op(int op_type, struct expr* exp1, struct expr* exp2)
209 ex->type = EXPR_TYPE_BINOP;
210 ex->un.binop.binop_type = op_type;
211 ex->un.binop.exp1 = exp1;
212 ex->un.binop.exp2 = exp2;
216 struct expr* expr_alloc_unary_op(int op_type, struct expr* exp1)
222 ex->type = EXPR_TYPE_UNOP;
223 ex->un.unop.unop_type = op_type;
224 ex->un.unop.exp1 = exp1;
228 struct expr* expr_alloc_struct(struct expr* exp, const char* element)
234 ex->type = EXPR_TYPE_STRUCT;
235 ex->un.structure.exp1 = exp;
236 ex->un.structure.element_name = element;
240 struct expr* expr_alloc_pstruct(struct expr* exp, const char* element)
246 ex->type = EXPR_TYPE_PSTRUCT;
247 ex->un.structure.exp1 = exp;
248 ex->un.structure.element_name = element;
252 struct expr* expr_alloc_func_call(const char* funcname, int nargs, ...)
260 ex->type = EXPR_TYPE_CALL;
261 ex->un.call.funcname = funcname;
262 ex->un.call.nargs = nargs;
265 for (i = 0; i < nargs; i++)
267 ex->un.call.arg[i] = va_arg(ap, struct expr*);
273 /******************************************************************
277 struct dbg_lvalue expr_eval(struct expr* exp)
279 struct dbg_lvalue rtn;
281 struct dbg_lvalue exp1;
282 struct dbg_lvalue exp2;
283 unsigned int cexp[5];
284 DWORD scale1, scale2, scale3;
285 struct dbg_type type1, type2;
287 const struct dbg_internal_var* div;
290 rtn.type.id = dbg_itype_none;
292 rtn.addr.Mode = AddrModeFlat;
294 rtn.addr.Segment = 0;
299 /* this is really brute force, we simply change the type... without
300 * checking if this is right or not
302 rtn = expr_eval(exp->un.cast.expr);
303 switch (exp->un.cast.cast_to.type)
305 case type_expr_type_id:
306 if (exp->un.cast.cast_to.u.type.id == dbg_itype_none)
308 dbg_printf("Can't cast to unknown type\n");
309 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
311 rtn.type = exp->un.cast.cast_to.u.type;
313 case type_expr_udt_class:
314 case type_expr_udt_struct:
315 case type_expr_udt_union:
316 rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
317 exp->un.cast.cast_to.u.name, SymTagUDT);
318 if (rtn.type.id == dbg_itype_none)
320 dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name);
321 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
324 case type_expr_enumeration:
325 rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr),
326 exp->un.cast.cast_to.u.name, SymTagEnum);
327 if (rtn.type.id == dbg_itype_none)
329 dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name);
330 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
334 dbg_printf("Unsupported cast type %u\n", exp->un.cast.cast_to.type);
335 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
337 for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
339 rtn.type = types_find_pointer(&rtn.type);
340 if (rtn.type.id == dbg_itype_none)
342 dbg_printf("Cannot find pointer type\n");
343 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
347 case EXPR_TYPE_STRING:
348 rtn.cookie = DLV_HOST;
349 rtn.type.id = dbg_itype_astring;
351 rtn.addr.Offset = (unsigned int)&exp->un.string.str;
353 case EXPR_TYPE_U_CONST:
354 rtn.cookie = DLV_HOST;
355 rtn.type.id = dbg_itype_unsigned_int;
357 rtn.addr.Offset = (unsigned int)&exp->un.u_const.value;
359 case EXPR_TYPE_S_CONST:
360 rtn.cookie = DLV_HOST;
361 rtn.type.id = dbg_itype_signed_int;
363 rtn.addr.Offset = (unsigned int)&exp->un.s_const.value;
365 case EXPR_TYPE_SYMBOL:
366 switch (symbol_get_lvalue(exp->un.symbol.name, -1, &rtn, FALSE))
371 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
372 /* should never be here */
374 RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
375 /* should never be here */
378 case EXPR_TYPE_PSTRUCT:
379 exp1 = expr_eval(exp->un.structure.exp1);
380 if (exp1.type.id == dbg_itype_none || !types_deref(&exp1, &rtn) ||
381 rtn.type.id == dbg_itype_none)
382 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
383 if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
384 &exp->un.structure.result))
386 dbg_printf("%s\n", exp->un.structure.element_name);
387 RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
390 case EXPR_TYPE_STRUCT:
391 exp1 = expr_eval(exp->un.structure.exp1);
392 if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
394 if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
395 &exp->un.structure.result))
397 dbg_printf("%s\n", exp->un.structure.element_name);
398 RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
403 * First, evaluate all of the arguments. If any of them are not
404 * evaluable, then bail.
406 for (i = 0; i < exp->un.call.nargs; i++)
408 exp1 = expr_eval(exp->un.call.arg[i]);
409 if (exp1.type.id == dbg_itype_none)
410 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
411 cexp[i] = types_extract_as_integer(&exp1);
415 * Now look up the address of the function itself.
417 switch (symbol_get_lvalue(exp->un.call.funcname, -1, &rtn, FALSE))
422 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
423 /* should never be here */
425 RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
426 /* should never be here */
430 /* FIXME: NEWDBG NIY */
431 /* Anyway, I wonder how this could work depending on the calling order of
432 * the function (cdecl vs pascal for example)
436 fptr = (int (*)()) rtn.addr.off;
437 switch (exp->un.call.nargs)
440 exp->un.call.result = (*fptr)();
443 exp->un.call.result = (*fptr)(cexp[0]);
446 exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
449 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
452 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
455 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
459 dbg_printf("Function call no longer implemented\n");
460 /* would need to set up a call to this function, and then restore the current
461 * context afterwards...
463 exp->un.call.result = 0;
465 rtn.cookie = DLV_HOST;
466 /* get function signature type */
467 types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type);
468 /* and now, return type */
469 types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type);
470 rtn.addr.Offset = (unsigned int)&exp->un.call.result;
472 case EXPR_TYPE_INTVAR:
473 rtn.cookie = DLV_HOST;
474 if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
475 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
476 rtn.type.id = div->typeid;
478 rtn.addr.Offset = (unsigned int)div->pval;
480 case EXPR_TYPE_BINOP:
481 rtn.cookie = DLV_HOST;
482 exp1 = expr_eval(exp->un.binop.exp1);
483 exp2 = expr_eval(exp->un.binop.exp2);
484 if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
485 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
486 rtn.type.id = dbg_itype_signed_int;
488 rtn.addr.Offset = (unsigned int)&exp->un.binop.result;
489 switch (exp->un.binop.binop_type)
492 if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
493 tag != SymTagPointerType ||
494 !types_get_info(&exp1.type, TI_GET_TYPE, &type1))
495 type1.id = dbg_itype_none;
496 if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
497 tag != SymTagPointerType ||
498 !types_get_info(&exp2.type, TI_GET_TYPE, &type2))
499 type2.id = dbg_itype_none;
502 if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
503 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
504 if (type1.id != dbg_itype_none)
506 types_get_info(&type1, TI_GET_LENGTH, &scale2);
507 rtn.type = exp1.type;
509 else if (type2.id != dbg_itype_none)
511 types_get_info(&type2, TI_GET_LENGTH, &scale1);
512 rtn.type = exp2.type;
514 exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 +
515 scale2 * types_extract_as_integer(&exp2));
518 if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
519 tag != SymTagPointerType ||
520 !types_get_info(&exp1.type, TI_GET_TYPE, &type1))
521 type1.id = dbg_itype_none;
522 if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
523 tag != SymTagPointerType ||
524 !types_get_info(&exp2.type, TI_GET_TYPE, &type2))
525 type2.id = dbg_itype_none;
529 if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
531 WINE_FIXME("This may fail (if module base address are wrongly calculated)\n");
532 if (memcmp(&type1, &type2, sizeof(struct dbg_type)))
533 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
534 types_get_info(&type1, TI_GET_LENGTH, &scale3);
536 else if (type1.id != dbg_itype_none)
538 types_get_info(&type1, TI_GET_LENGTH, &scale2);
539 rtn.type = exp1.type;
541 else if (type2.id != dbg_itype_none)
543 types_get_info(&type2, TI_GET_LENGTH, &scale1);
544 rtn.type = exp2.type;
546 exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 -
547 types_extract_as_integer(&exp2) * scale2) / scale3;
550 rtn.type.id = dbg_itype_none;
552 rtn.addr.Mode = AddrMode1632;
553 rtn.addr.Segment = types_extract_as_integer(&exp1);
554 rtn.addr.Offset = types_extract_as_integer(&exp2);
557 exp->un.binop.result = (types_extract_as_integer(&exp1) || types_extract_as_integer(&exp2));
560 exp->un.binop.result = (types_extract_as_integer(&exp1) && types_extract_as_integer(&exp2));
563 exp->un.binop.result = (types_extract_as_integer(&exp1) | types_extract_as_integer(&exp2));
566 exp->un.binop.result = (types_extract_as_integer(&exp1) & types_extract_as_integer(&exp2));
569 exp->un.binop.result = (types_extract_as_integer(&exp1) ^ types_extract_as_integer(&exp2));
572 exp->un.binop.result = (types_extract_as_integer(&exp1) == types_extract_as_integer(&exp2));
575 exp->un.binop.result = (types_extract_as_integer(&exp1) > types_extract_as_integer(&exp2));
578 exp->un.binop.result = (types_extract_as_integer(&exp1) < types_extract_as_integer(&exp2));
581 exp->un.binop.result = (types_extract_as_integer(&exp1) >= types_extract_as_integer(&exp2));
584 exp->un.binop.result = (types_extract_as_integer(&exp1) <= types_extract_as_integer(&exp2));
587 exp->un.binop.result = (types_extract_as_integer(&exp1) != types_extract_as_integer(&exp2));
590 exp->un.binop.result = ((unsigned long)types_extract_as_integer(&exp1) << types_extract_as_integer(&exp2));
593 exp->un.binop.result = ((unsigned long)types_extract_as_integer(&exp1) >> types_extract_as_integer(&exp2));
596 exp->un.binop.result = (types_extract_as_integer(&exp1) * types_extract_as_integer(&exp2));
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));
603 if (types_extract_as_integer(&exp2) == 0) RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
604 exp->un.binop.result = (types_extract_as_integer(&exp1) % types_extract_as_integer(&exp2));
607 if (!types_array_index(&exp1, types_extract_as_integer(&exp2), &rtn))
608 RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
610 default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
614 rtn.cookie = DLV_HOST;
615 exp1 = expr_eval(exp->un.unop.exp1);
616 if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
617 rtn.addr.Offset = (unsigned int)&exp->un.unop.result;
618 rtn.type.id = dbg_itype_signed_int;
620 switch (exp->un.unop.unop_type)
623 exp->un.unop.result = -types_extract_as_integer(&exp1);
626 exp->un.unop.result = !types_extract_as_integer(&exp1);
629 exp->un.unop.result = ~types_extract_as_integer(&exp1);
632 if (!types_deref(&exp1, &rtn))
633 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
635 case EXP_OP_FORCE_DEREF:
637 if (exp1.cookie == DLV_TARGET)
638 dbg_read_memory(memory_to_linear_addr(&exp1.addr), &rtn.addr.Offset, sizeof(rtn.addr.Offset));
641 /* only do it on linear addresses */
642 if (exp1.addr.Mode != AddrModeFlat)
643 RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
644 exp->un.unop.result = (unsigned int)memory_to_linear_addr(&exp1.addr);
645 rtn.type = types_find_pointer(&exp1.type);
647 default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
651 WINE_FIXME("Unexpected expression (%d).\n", exp->type);
652 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
659 int expr_print(const struct expr* exp)
662 struct dbg_type type;
667 WINE_FIXME("No longer supported (missing module base)\n");
669 switch (exp->un.cast.cast_to.type)
671 case type_expr_type_id:
673 type.id = exp->un.cast.cast_to.type;
674 types_print_type(&type, FALSE); break;
675 case type_expr_udt_class:
676 dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
677 case type_expr_udt_struct:
678 dbg_printf("struct %s", exp->un.cast.cast_to.u.name); break;
679 case type_expr_udt_union:
680 dbg_printf("union %s", exp->un.cast.cast_to.u.name); break;
681 case type_expr_enumeration:
682 dbg_printf("enum %s", exp->un.cast.cast_to.u.name); break;
684 for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
687 expr_print(exp->un.cast.expr);
690 case EXPR_TYPE_INTVAR:
691 dbg_printf("$%s", exp->un.intvar.name);
693 case EXPR_TYPE_U_CONST:
694 dbg_printf("%u", exp->un.u_const.value);
696 case EXPR_TYPE_S_CONST:
697 dbg_printf("%d", exp->un.s_const.value);
699 case EXPR_TYPE_STRING:
700 dbg_printf("\"%s\"", exp->un.string.str);
702 case EXPR_TYPE_SYMBOL:
703 dbg_printf("%s" , exp->un.symbol.name);
705 case EXPR_TYPE_PSTRUCT:
706 expr_print(exp->un.structure.exp1);
707 dbg_printf("->%s", exp->un.structure.element_name);
709 case EXPR_TYPE_STRUCT:
710 expr_print(exp->un.structure.exp1);
711 dbg_printf(".%s", exp->un.structure.element_name);
714 dbg_printf("%s(",exp->un.call.funcname);
715 for (i = 0; i < exp->un.call.nargs; i++)
717 expr_print(exp->un.call.arg[i]);
718 if (i != exp->un.call.nargs - 1) dbg_printf(", ");
722 case EXPR_TYPE_BINOP:
724 expr_print(exp->un.binop.exp1);
725 switch (exp->un.binop.binop_type)
727 case EXP_OP_ADD: dbg_printf(" + "); break;
728 case EXP_OP_SUB: dbg_printf(" - "); break;
729 case EXP_OP_SEG: dbg_printf(":"); break;
730 case EXP_OP_LOR: dbg_printf(" || "); break;
731 case EXP_OP_LAND: dbg_printf(" && "); break;
732 case EXP_OP_OR: dbg_printf(" | "); break;
733 case EXP_OP_AND: dbg_printf(" & "); break;
734 case EXP_OP_XOR: dbg_printf(" ^ "); break;
735 case EXP_OP_EQ: dbg_printf(" == "); break;
736 case EXP_OP_GT: dbg_printf(" > "); break;
737 case EXP_OP_LT: dbg_printf(" < "); break;
738 case EXP_OP_GE: dbg_printf(" >= "); break;
739 case EXP_OP_LE: dbg_printf(" <= "); break;
740 case EXP_OP_NE: dbg_printf(" != "); break;
741 case EXP_OP_SHL: dbg_printf(" << "); break;
742 case EXP_OP_SHR: dbg_printf(" >> "); break;
743 case EXP_OP_MUL: dbg_printf(" * "); break;
744 case EXP_OP_DIV: dbg_printf(" / "); break;
745 case EXP_OP_REM: dbg_printf(" %% "); break;
746 case EXP_OP_ARR: dbg_printf("["); break;
749 expr_print(exp->un.binop.exp2);
750 if (exp->un.binop.binop_type == EXP_OP_ARR) dbg_printf("]");
754 switch (exp->un.unop.unop_type)
756 case EXP_OP_NEG: dbg_printf("-"); break;
757 case EXP_OP_NOT: dbg_printf("!"); break;
758 case EXP_OP_LNOT: dbg_printf("~"); break;
759 case EXP_OP_DEREF: dbg_printf("*"); break;
760 case EXP_OP_ADDR: dbg_printf("&"); break;
762 expr_print(exp->un.unop.exp1);
765 WINE_FIXME("Unexpected expression (%u).\n", exp->type);
766 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
773 struct expr* expr_clone(const struct expr* exp)
778 rtn = HeapAlloc(GetProcessHeap(), 0, sizeof(struct expr));
781 * First copy the contents of the expression itself.
788 rtn->un.cast.expr = expr_clone(exp->un.cast.expr);
790 case EXPR_TYPE_INTVAR:
791 rtn->un.intvar.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.intvar.name) + 1), exp->un.intvar.name);
793 case EXPR_TYPE_U_CONST:
794 case EXPR_TYPE_S_CONST:
796 case EXPR_TYPE_STRING:
797 rtn->un.string.str = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.string.str) + 1), exp->un.string.str);
799 case EXPR_TYPE_SYMBOL:
800 rtn->un.symbol.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.symbol.name) + 1), exp->un.symbol.name);
802 case EXPR_TYPE_PSTRUCT:
803 case EXPR_TYPE_STRUCT:
804 rtn->un.structure.exp1 = expr_clone(exp->un.structure.exp1);
805 rtn->un.structure.element_name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.structure.element_name) + 1), exp->un.structure.element_name);
808 for (i = 0; i < exp->un.call.nargs; i++)
810 rtn->un.call.arg[i] = expr_clone(exp->un.call.arg[i]);
812 rtn->un.call.funcname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.call.funcname) + 1), exp->un.call.funcname);
814 case EXPR_TYPE_BINOP:
815 rtn->un.binop.exp1 = expr_clone(exp->un.binop.exp1);
816 rtn->un.binop.exp2 = expr_clone(exp->un.binop.exp2);
819 rtn->un.unop.exp1 = expr_clone(exp->un.unop.exp1);
822 WINE_FIXME("Unexpected expression (%u).\n", exp->type);
823 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
832 * Recursively go through an expression tree and free all memory associated
835 int expr_free(struct expr* exp)
842 expr_free(exp->un.cast.expr);
844 case EXPR_TYPE_INTVAR:
845 HeapFree(GetProcessHeap(), 0, (char*)exp->un.intvar.name);
847 case EXPR_TYPE_U_CONST:
848 case EXPR_TYPE_S_CONST:
850 case EXPR_TYPE_STRING:
851 HeapFree(GetProcessHeap(), 0, (char*)exp->un.string.str);
853 case EXPR_TYPE_SYMBOL:
854 HeapFree(GetProcessHeap(), 0, (char*)exp->un.symbol.name);
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);
862 for (i = 0; i < exp->un.call.nargs; i++)
864 expr_free(exp->un.call.arg[i]);
866 HeapFree(GetProcessHeap(), 0, (char*)exp->un.call.funcname);
868 case EXPR_TYPE_BINOP:
869 expr_free(exp->un.binop.exp1);
870 expr_free(exp->un.binop.exp2);
873 expr_free(exp->un.unop.exp1);
876 WINE_FIXME("Unexpected expression (%u).\n", exp->type);
877 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
881 HeapFree(GetProcessHeap(), 0, exp);