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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(winedbg
);
45 long unsigned int value
;
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(long int value
)
174 ex
->type
= EXPR_TYPE_S_CONST
;
175 ex
->un
.s_const
.value
= value
;
179 struct expr
* expr_alloc_uconstant(long 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
)
196 ex
->type
= EXPR_TYPE_STRING
;
197 ex
->un
.string
.str
= str
;
201 struct expr
* expr_alloc_binary_op(int op_type
, struct expr
* exp1
, struct expr
* exp2
)
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
;
214 struct expr
* expr_alloc_unary_op(int op_type
, struct expr
* exp1
)
220 ex
->type
= EXPR_TYPE_UNOP
;
221 ex
->un
.unop
.unop_type
= op_type
;
222 ex
->un
.unop
.exp1
= exp1
;
226 struct expr
* expr_alloc_struct(struct expr
* exp
, const char* element
)
232 ex
->type
= EXPR_TYPE_STRUCT
;
233 ex
->un
.structure
.exp1
= exp
;
234 ex
->un
.structure
.element_name
= element
;
238 struct expr
* expr_alloc_pstruct(struct expr
* exp
, const char* element
)
244 ex
->type
= EXPR_TYPE_PSTRUCT
;
245 ex
->un
.structure
.exp1
= exp
;
246 ex
->un
.structure
.element_name
= element
;
250 struct expr
* expr_alloc_func_call(const char* funcname
, int nargs
, ...)
258 ex
->type
= EXPR_TYPE_CALL
;
259 ex
->un
.call
.funcname
= funcname
;
260 ex
->un
.call
.nargs
= nargs
;
263 for (i
= 0; i
< nargs
; i
++)
265 ex
->un
.call
.arg
[i
] = va_arg(ap
, struct expr
*);
271 /******************************************************************
275 struct dbg_lvalue
expr_eval(struct expr
* exp
)
277 struct dbg_lvalue rtn
;
279 struct dbg_lvalue exp1
;
280 struct dbg_lvalue exp2
;
281 DWORD64 scale1
, scale2
, scale3
;
282 struct dbg_type type1
, type2
;
284 const struct dbg_internal_var
* div
;
287 rtn
.type
.id
= dbg_itype_none
;
289 rtn
.addr
.Mode
= AddrModeFlat
;
291 rtn
.addr
.Segment
= 0;
296 /* this is really brute force, we simply change the type... without
297 * checking if this is right or not
299 rtn
= expr_eval(exp
->un
.cast
.expr
);
300 switch (exp
->un
.cast
.cast_to
.type
)
302 case type_expr_type_id
:
303 if (exp
->un
.cast
.cast_to
.u
.type
.id
== dbg_itype_none
)
305 dbg_printf("Can't cast to unknown type\n");
306 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
308 rtn
.type
= exp
->un
.cast
.cast_to
.u
.type
;
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
,
315 if (rtn
.type
.id
== dbg_itype_none
)
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
);
321 case type_expr_enumeration
:
322 rtn
.type
= types_find_type(rtn
.type
.module
, exp
->un
.cast
.cast_to
.u
.name
,
324 if (rtn
.type
.id
== dbg_itype_none
)
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
);
331 dbg_printf("Unsupported cast type %u\n", exp
->un
.cast
.cast_to
.type
);
332 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
334 for (i
= 0; i
< exp
->un
.cast
.cast_to
.deref_count
; i
++)
336 rtn
.type
= types_find_pointer(&rtn
.type
);
337 if (rtn
.type
.id
== dbg_itype_none
)
339 dbg_printf("Cannot find pointer type\n");
340 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
344 case EXPR_TYPE_STRING
:
345 rtn
.cookie
= DLV_HOST
;
346 rtn
.type
.id
= dbg_itype_astring
;
348 rtn
.addr
.Offset
= (ULONG_PTR
)&exp
->un
.string
.str
;
350 case EXPR_TYPE_U_CONST
:
351 rtn
.cookie
= DLV_HOST
;
352 rtn
.type
.id
= dbg_itype_unsigned_long_int
;
354 rtn
.addr
.Offset
= (ULONG_PTR
)&exp
->un
.u_const
.value
;
356 case EXPR_TYPE_S_CONST
:
357 rtn
.cookie
= DLV_HOST
;
358 rtn
.type
.id
= dbg_itype_signed_long_int
;
360 rtn
.addr
.Offset
= (ULONG_PTR
)&exp
->un
.s_const
.value
;
362 case EXPR_TYPE_SYMBOL
:
363 switch (symbol_get_lvalue(exp
->un
.symbol
.name
, -1, &rtn
, FALSE
))
368 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
369 /* should never be here */
371 RaiseException(DEBUG_STATUS_ABORT
, 0, 0, NULL
);
372 /* should never be here */
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
))
383 dbg_printf("%s\n", exp
->un
.structure
.element_name
);
384 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
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
);
391 if (!types_udt_find_element(&rtn
, exp
->un
.structure
.element_name
,
392 &exp
->un
.structure
.result
))
394 dbg_printf("%s\n", exp
->un
.structure
.element_name
);
395 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
401 * First, evaluate all of the arguments. If any of them are not
402 * evaluable, then bail.
404 for (i
= 0; i
< exp
->un
.call
.nargs
; i
++)
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
);
413 * Now look up the address of the function itself.
415 switch (symbol_get_lvalue(exp
->un
.call
.funcname
, -1, &rtn
, FALSE
))
420 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
421 /* should never be here */
423 RaiseException(DEBUG_STATUS_ABORT
, 0, 0, NULL
);
424 /* should never be here */
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)
433 fptr
= (int (*)()) rtn
.addr
.off
;
434 switch (exp
->un
.call
.nargs
)
437 exp
->un
.call
.result
= (*fptr
)();
440 exp
->un
.call
.result
= (*fptr
)(cexp
[0]);
443 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1]);
446 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2]);
449 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3]);
452 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3], cexp
[4]);
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...
460 exp
->un
.call
.result
= 0;
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
;
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;
473 rtn
.addr
.Offset
= (ULONG_PTR
)div
->pval
;
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
;
483 rtn
.addr
.Offset
= (ULONG_PTR
)&exp
->un
.binop
.result
;
486 switch (exp
->un
.binop
.binop_type
)
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
;
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
)
503 types_get_info(&type1
, TI_GET_LENGTH
, &scale2
);
504 rtn
.type
= exp1
.type
;
506 else if (type2
.id
!= dbg_itype_none
)
508 types_get_info(&type2
, TI_GET_LENGTH
, &scale1
);
509 rtn
.type
= exp2
.type
;
511 exp
->un
.binop
.result
= types_extract_as_integer(&exp1
) * (DWORD
)scale1
+
512 (DWORD
)scale2
* types_extract_as_integer(&exp2
);
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
;
526 if (type1
.id
!= dbg_itype_none
&& type2
.id
!= dbg_itype_none
)
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
);
533 else if (type1
.id
!= dbg_itype_none
)
535 types_get_info(&type1
, TI_GET_LENGTH
, &scale2
);
536 rtn
.type
= exp1
.type
;
538 else if (type2
.id
!= dbg_itype_none
)
540 types_get_info(&type2
, TI_GET_LENGTH
, &scale1
);
541 rtn
.type
= exp2
.type
;
543 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) * (DWORD
)scale1
-
544 types_extract_as_integer(&exp2
) * (DWORD
)scale2
) / (DWORD
)scale3
;
547 rtn
.type
.id
= dbg_itype_segptr
;
549 be_cpu
->build_addr(dbg_curr_thread
->handle
, &dbg_context
, &rtn
.addr
,
550 types_extract_as_integer(&exp1
), types_extract_as_integer(&exp2
));
553 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) || types_extract_as_integer(&exp2
));
556 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) && types_extract_as_integer(&exp2
));
559 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) | types_extract_as_integer(&exp2
));
562 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) & types_extract_as_integer(&exp2
));
565 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) ^ types_extract_as_integer(&exp2
));
568 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) == types_extract_as_integer(&exp2
));
571 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) > types_extract_as_integer(&exp2
));
574 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) < types_extract_as_integer(&exp2
));
577 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) >= types_extract_as_integer(&exp2
));
580 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) <= types_extract_as_integer(&exp2
));
583 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) != types_extract_as_integer(&exp2
));
586 exp
->un
.binop
.result
= ((unsigned long)types_extract_as_integer(&exp1
) << types_extract_as_integer(&exp2
));
589 exp
->un
.binop
.result
= ((unsigned long)types_extract_as_integer(&exp1
) >> types_extract_as_integer(&exp2
));
592 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) * types_extract_as_integer(&exp2
));
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
));
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_array_index(&exp1
, types_extract_as_integer(&exp2
), &rtn
))
604 RaiseException(DEBUG_STATUS_CANT_DEREF
, 0, 0, NULL
);
606 default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
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
;
616 switch (exp
->un
.unop
.unop_type
)
619 exp
->un
.unop
.result
= -types_extract_as_integer(&exp1
);
622 exp
->un
.unop
.result
= !types_extract_as_integer(&exp1
);
625 exp
->un
.unop
.result
= ~types_extract_as_integer(&exp1
);
628 if (!types_array_index(&exp1
, 0, &rtn
))
629 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
631 case EXP_OP_FORCE_DEREF
:
633 if (exp1
.cookie
== DLV_TARGET
)
634 dbg_read_memory(memory_to_linear_addr(&exp1
.addr
), &rtn
.addr
.Offset
, sizeof(rtn
.addr
.Offset
));
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
);
645 default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
649 WINE_FIXME("Unexpected expression (%d).\n", exp
->type
);
650 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
657 BOOL
expr_print(const struct expr
* exp
)
660 struct dbg_type type
;
665 WINE_FIXME("No longer supported (missing module base)\n");
667 switch (exp
->un
.cast
.cast_to
.type
)
669 case type_expr_type_id
:
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;
682 for (i
= 0; i
< exp
->un
.cast
.cast_to
.deref_count
; i
++)
685 expr_print(exp
->un
.cast
.expr
);
688 case EXPR_TYPE_INTVAR
:
689 dbg_printf("$%s", exp
->un
.intvar
.name
);
691 case EXPR_TYPE_U_CONST
:
692 dbg_printf("%lu", exp
->un
.u_const
.value
);
694 case EXPR_TYPE_S_CONST
:
695 dbg_printf("%ld", exp
->un
.s_const
.value
);
697 case EXPR_TYPE_STRING
:
698 dbg_printf("\"%s\"", exp
->un
.string
.str
);
700 case EXPR_TYPE_SYMBOL
:
701 dbg_printf("%s" , exp
->un
.symbol
.name
);
703 case EXPR_TYPE_PSTRUCT
:
704 expr_print(exp
->un
.structure
.exp1
);
705 dbg_printf("->%s", exp
->un
.structure
.element_name
);
707 case EXPR_TYPE_STRUCT
:
708 expr_print(exp
->un
.structure
.exp1
);
709 dbg_printf(".%s", exp
->un
.structure
.element_name
);
712 dbg_printf("%s(",exp
->un
.call
.funcname
);
713 for (i
= 0; i
< exp
->un
.call
.nargs
; i
++)
715 expr_print(exp
->un
.call
.arg
[i
]);
716 if (i
!= exp
->un
.call
.nargs
- 1) dbg_printf(", ");
720 case EXPR_TYPE_BINOP
:
722 expr_print(exp
->un
.binop
.exp1
);
723 switch (exp
->un
.binop
.binop_type
)
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;
747 expr_print(exp
->un
.binop
.exp2
);
748 if (exp
->un
.binop
.binop_type
== EXP_OP_ARR
) dbg_printf("]");
752 switch (exp
->un
.unop
.unop_type
)
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;
760 expr_print(exp
->un
.unop
.exp1
);
763 WINE_FIXME("Unexpected expression (%u).\n", exp
->type
);
764 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
771 struct expr
* expr_clone(const struct expr
* exp
, BOOL
*local_binding
)
776 rtn
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct expr
));
779 * First copy the contents of the expression itself.
786 rtn
->un
.cast
.expr
= expr_clone(exp
->un
.cast
.expr
, local_binding
);
788 case EXPR_TYPE_INTVAR
:
789 rtn
->un
.intvar
.name
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp
->un
.intvar
.name
) + 1), exp
->un
.intvar
.name
);
791 case EXPR_TYPE_U_CONST
:
792 case EXPR_TYPE_S_CONST
:
794 case EXPR_TYPE_STRING
:
795 rtn
->un
.string
.str
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp
->un
.string
.str
) + 1), exp
->un
.string
.str
);
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
;
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
);
808 for (i
= 0; i
< exp
->un
.call
.nargs
; i
++)
810 rtn
->un
.call
.arg
[i
] = expr_clone(exp
->un
.call
.arg
[i
], local_binding
);
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
, local_binding
);
816 rtn
->un
.binop
.exp2
= expr_clone(exp
->un
.binop
.exp2
, local_binding
);
819 rtn
->un
.unop
.exp1
= expr_clone(exp
->un
.unop
.exp1
, local_binding
);
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 BOOL
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
);