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
;
286 DWORD linear1
, linear2
;
288 const struct dbg_internal_var
* div
;
290 rtn
.typeid = 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 linear1
= (DWORD
)memory_to_linear_addr(&rtn
.addr
);
304 switch (exp
->un
.cast
.cast_to
.type
)
306 case type_expr_type_id
:
307 if (exp
->un
.cast
.cast_to
.u
.typeid == dbg_itype_none
)
309 dbg_printf("Can't cast to unknown type\n");
310 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
312 rtn
.typeid = exp
->un
.cast
.cast_to
.u
.typeid;
314 case type_expr_udt_class
:
315 case type_expr_udt_struct
:
316 case type_expr_udt_union
:
317 rtn
.typeid = types_find_type(linear1
, exp
->un
.cast
.cast_to
.u
.name
, SymTagUDT
);
318 if (rtn
.typeid == 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
.typeid = types_find_type(linear1
, exp
->un
.cast
.cast_to
.u
.name
, SymTagEnum
);
326 if (rtn
.typeid == dbg_itype_none
)
328 dbg_printf("Can't cast to enumeration %s\n", exp
->un
.cast
.cast_to
.u
.name
);
329 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
333 dbg_printf("Unsupported cast type %u\n", exp
->un
.cast
.cast_to
.type
);
334 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
336 for (i
= 0; i
< exp
->un
.cast
.cast_to
.deref_count
; i
++)
338 rtn
.typeid = types_find_pointer(linear1
, rtn
.typeid);
339 if (rtn
.typeid == dbg_itype_none
)
341 dbg_printf("Cannot find pointer type\n");
342 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
346 case EXPR_TYPE_STRING
:
347 rtn
.typeid = dbg_itype_astring
;
348 rtn
.cookie
= DLV_HOST
;
349 rtn
.addr
.Offset
= (unsigned int)&exp
->un
.string
.str
;
351 case EXPR_TYPE_U_CONST
:
352 rtn
.typeid = dbg_itype_unsigned_int
;
353 rtn
.cookie
= DLV_HOST
;
354 rtn
.addr
.Offset
= (unsigned int)&exp
->un
.u_const
.value
;
356 case EXPR_TYPE_S_CONST
:
357 rtn
.typeid = dbg_itype_signed_int
;
358 rtn
.cookie
= DLV_HOST
;
359 rtn
.addr
.Offset
= (unsigned int)&exp
->un
.s_const
.value
;
361 case EXPR_TYPE_SYMBOL
:
362 switch (symbol_get_lvalue(exp
->un
.symbol
.name
, -1, &rtn
, FALSE
))
367 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
368 /* should never be here */
370 RaiseException(DEBUG_STATUS_ABORT
, 0, 0, NULL
);
371 /* should never be here */
374 case EXPR_TYPE_PSTRUCT
:
375 exp1
= expr_eval(exp
->un
.structure
.exp1
);
376 if (exp1
.typeid == dbg_itype_none
|| !types_deref(&exp1
, &rtn
) ||
377 rtn
.typeid == dbg_itype_none
)
378 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
379 if (!types_udt_find_element(&rtn
, exp
->un
.structure
.element_name
,
380 &exp
->un
.structure
.result
))
382 dbg_printf("%s\n", exp
->un
.structure
.element_name
);
383 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
386 case EXPR_TYPE_STRUCT
:
387 exp1
= expr_eval(exp
->un
.structure
.exp1
);
388 if (exp1
.typeid == dbg_itype_none
) RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
390 if (!types_udt_find_element(&rtn
, exp
->un
.structure
.element_name
,
391 &exp
->un
.structure
.result
))
393 dbg_printf("%s\n", exp
->un
.structure
.element_name
);
394 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
399 * First, evaluate all of the arguments. If any of them are not
400 * evaluable, then bail.
402 for (i
= 0; i
< exp
->un
.call
.nargs
; i
++)
404 exp1
= expr_eval(exp
->un
.call
.arg
[i
]);
405 if (exp1
.typeid == dbg_itype_none
)
406 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
407 cexp
[i
] = types_extract_as_integer(&exp1
);
411 * Now look up the address of the function itself.
413 switch (symbol_get_lvalue(exp
->un
.call
.funcname
, -1, &rtn
, FALSE
))
418 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
419 /* should never be here */
421 RaiseException(DEBUG_STATUS_ABORT
, 0, 0, NULL
);
422 /* should never be here */
426 /* FIXME: NEWDBG NIY */
427 /* Anyway, I wonder how this could work depending on the calling order of
428 * the function (cdecl vs pascal for example)
432 fptr
= (int (*)()) rtn
.addr
.off
;
433 switch (exp
->un
.call
.nargs
)
436 exp
->un
.call
.result
= (*fptr
)();
439 exp
->un
.call
.result
= (*fptr
)(cexp
[0]);
442 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1]);
445 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2]);
448 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3]);
451 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3], cexp
[4]);
455 dbg_printf("Function call no longer implemented\n");
456 /* would need to set up a call to this function, and then restore the current
457 * context afterwards...
459 exp
->un
.call
.result
= 0;
461 linear1
= (DWORD
)memory_to_linear_addr(&rtn
.addr
);
462 /* get function signature type */
463 types_get_info(linear1
, rtn
.typeid, TI_GET_TYPE
, &rtn
.typeid);
464 /* and now, return type */
465 types_get_info(linear1
, rtn
.typeid, TI_GET_TYPE
, &rtn
.typeid);
466 rtn
.cookie
= DLV_HOST
;
467 rtn
.addr
.Mode
= AddrModeFlat
;
468 rtn
.addr
.Offset
= (unsigned int)&exp
->un
.call
.result
;
470 case EXPR_TYPE_INTVAR
:
471 if (!(div
= dbg_get_internal_var(exp
->un
.intvar
.name
)))
472 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
473 rtn
.cookie
= DLV_HOST
;
474 rtn
.typeid = div
->typeid;
475 rtn
.addr
.Offset
= (unsigned int)div
->pval
;
477 case EXPR_TYPE_BINOP
:
478 exp1
= expr_eval(exp
->un
.binop
.exp1
);
479 exp2
= expr_eval(exp
->un
.binop
.exp2
);
480 rtn
.cookie
= DLV_HOST
;
481 if (exp1
.typeid == dbg_itype_none
|| exp2
.typeid == dbg_itype_none
)
482 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
483 linear1
= (DWORD
)memory_to_linear_addr(&exp1
.addr
);
484 linear2
= (DWORD
)memory_to_linear_addr(&exp2
.addr
);
485 rtn
.typeid = dbg_itype_signed_int
;
486 rtn
.addr
.Offset
= (unsigned int)&exp
->un
.binop
.result
;
487 switch (exp
->un
.binop
.binop_type
)
490 if (!types_get_info(linear1
, exp1
.typeid, TI_GET_SYMTAG
, &tag
) ||
491 tag
!= SymTagPointerType
||
492 !types_get_info(linear1
, exp1
.typeid, TI_GET_TYPE
, &type1
))
493 type1
= dbg_itype_none
;
494 if (!types_get_info(linear1
, exp2
.typeid, TI_GET_SYMTAG
, &tag
) ||
495 tag
!= SymTagPointerType
||
496 !types_get_info(linear1
, exp2
.typeid, TI_GET_TYPE
, &type2
))
497 type2
= dbg_itype_none
;
500 if (type1
!= dbg_itype_none
&& type2
!= dbg_itype_none
)
501 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
502 if (type1
!= dbg_itype_none
)
504 types_get_info(linear1
, type1
, TI_GET_LENGTH
, &scale2
);
505 rtn
.typeid = exp1
.typeid;
507 else if (type2
!= dbg_itype_none
)
509 types_get_info(linear2
, type2
, TI_GET_LENGTH
, &scale1
);
510 rtn
.typeid = exp2
.typeid;
512 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) * scale1
+
513 scale2
* types_extract_as_integer(&exp2
));
516 if (!types_get_info(linear1
, exp1
.typeid, TI_GET_SYMTAG
, &tag
) ||
517 tag
!= SymTagPointerType
||
518 !types_get_info(linear1
, exp1
.typeid, TI_GET_TYPE
, &type1
))
519 type1
= dbg_itype_none
;
520 if (!types_get_info(linear2
, exp2
.typeid, TI_GET_SYMTAG
, &tag
) ||
521 tag
!= SymTagPointerType
||
522 !types_get_info(linear2
, exp2
.typeid, TI_GET_TYPE
, &type2
))
523 type2
= dbg_itype_none
;
527 if (type1
!= dbg_itype_none
&& type2
!= dbg_itype_none
)
529 if (type1
!= type2
) RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
530 types_get_info(linear1
, type1
, TI_GET_LENGTH
, &scale3
);
532 else if (type1
!= dbg_itype_none
)
534 types_get_info(linear1
, type1
, TI_GET_LENGTH
, &scale2
);
535 rtn
.typeid = exp1
.typeid;
537 else if (type2
!= dbg_itype_none
)
539 types_get_info(linear2
, type2
, TI_GET_LENGTH
, &scale1
);
540 rtn
.typeid = exp2
.typeid;
542 exp
->un
.binop
.result
= (types_extract_as_integer(&exp1
) * scale1
-
543 types_extract_as_integer(&exp2
) * scale2
) / scale3
;
546 rtn
.cookie
= DLV_TARGET
;
547 rtn
.typeid = dbg_itype_none
;
548 rtn
.addr
.Mode
= AddrMode1632
;
549 rtn
.addr
.Segment
= types_extract_as_integer(&exp1
);
550 rtn
.addr
.Offset
= 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 exp1
= expr_eval(exp
->un
.unop
.exp1
);
611 if (exp1
.typeid == dbg_itype_none
) RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
612 rtn
.cookie
= DLV_HOST
;
613 rtn
.addr
.Offset
= (unsigned int)&exp
->un
.unop
.result
;
614 rtn
.typeid = dbg_itype_signed_int
;
615 switch (exp
->un
.unop
.unop_type
)
618 exp
->un
.unop
.result
= -types_extract_as_integer(&exp1
);
621 exp
->un
.unop
.result
= !types_extract_as_integer(&exp1
);
624 exp
->un
.unop
.result
= ~types_extract_as_integer(&exp1
);
627 /* FIXME: this is currently buggy.
628 * there is no way to tell were the deref:ed value is...
630 * x is a pointer to struct s, x being on the stack
631 * => exp1 is target, result is target
632 * x is a pointer to struct s, x being optimized into a reg
633 * => exp1 is host, result is target
634 * x is a pointer to internal variable x
635 * => exp1 is host, result is host
636 * so we force DLV_TARGET, because dereferencing pointers to
637 * internal variables is very unlikely. a correct fix would be
640 if (!types_deref(&exp1
, &rtn
))
641 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
643 case EXP_OP_FORCE_DEREF
:
645 if (exp1
.cookie
== DLV_TARGET
)
646 dbg_read_memory(memory_to_linear_addr(&exp1
.addr
), &rtn
.addr
.Offset
, sizeof(rtn
.addr
.Offset
));
649 /* only do it on linear addresses */
650 if (exp1
.addr
.Mode
!= AddrModeFlat
)
651 RaiseException(DEBUG_STATUS_CANT_DEREF
, 0, 0, NULL
);
652 exp
->un
.unop
.result
= (unsigned int)memory_to_linear_addr(&exp1
.addr
);
653 rtn
.typeid = types_find_pointer(exp
->un
.unop
.result
, exp1
.typeid);
655 default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
659 WINE_FIXME("Unexpected expression (%d).\n", exp
->type
);
660 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
664 assert(rtn
.cookie
== DLV_TARGET
|| rtn
.cookie
== DLV_HOST
);
669 int expr_print(const struct expr
* exp
)
676 WINE_FIXME("No longer supported (missing module base)\n");
678 switch (exp
->un
.cast
.cast_to
.type
)
680 case type_expr_type_id
:
681 types_print_type(0, exp
->un
.cast
.cast_to
.type
, FALSE
); break;
682 case type_expr_udt_class
:
683 dbg_printf("class %s", exp
->un
.cast
.cast_to
.u
.name
); break;
684 case type_expr_udt_struct
:
685 dbg_printf("struct %s", exp
->un
.cast
.cast_to
.u
.name
); break;
686 case type_expr_udt_union
:
687 dbg_printf("union %s", exp
->un
.cast
.cast_to
.u
.name
); break;
688 case type_expr_enumeration
:
689 dbg_printf("enum %s", exp
->un
.cast
.cast_to
.u
.name
); break;
691 for (i
= 0; i
< exp
->un
.cast
.cast_to
.deref_count
; i
++)
694 expr_print(exp
->un
.cast
.expr
);
697 case EXPR_TYPE_INTVAR
:
698 dbg_printf("$%s", exp
->un
.intvar
.name
);
700 case EXPR_TYPE_U_CONST
:
701 dbg_printf("%u", exp
->un
.u_const
.value
);
703 case EXPR_TYPE_S_CONST
:
704 dbg_printf("%d", exp
->un
.s_const
.value
);
706 case EXPR_TYPE_STRING
:
707 dbg_printf("\"%s\"", exp
->un
.string
.str
);
709 case EXPR_TYPE_SYMBOL
:
710 dbg_printf("%s" , exp
->un
.symbol
.name
);
712 case EXPR_TYPE_PSTRUCT
:
713 expr_print(exp
->un
.structure
.exp1
);
714 dbg_printf("->%s", exp
->un
.structure
.element_name
);
716 case EXPR_TYPE_STRUCT
:
717 expr_print(exp
->un
.structure
.exp1
);
718 dbg_printf(".%s", exp
->un
.structure
.element_name
);
721 dbg_printf("%s(",exp
->un
.call
.funcname
);
722 for (i
= 0; i
< exp
->un
.call
.nargs
; i
++)
724 expr_print(exp
->un
.call
.arg
[i
]);
725 if (i
!= exp
->un
.call
.nargs
- 1) dbg_printf(", ");
729 case EXPR_TYPE_BINOP
:
731 expr_print(exp
->un
.binop
.exp1
);
732 switch (exp
->un
.binop
.binop_type
)
734 case EXP_OP_ADD
: dbg_printf(" + "); break;
735 case EXP_OP_SUB
: dbg_printf(" - "); break;
736 case EXP_OP_SEG
: dbg_printf(":"); break;
737 case EXP_OP_LOR
: dbg_printf(" || "); break;
738 case EXP_OP_LAND
: dbg_printf(" && "); break;
739 case EXP_OP_OR
: dbg_printf(" | "); break;
740 case EXP_OP_AND
: dbg_printf(" & "); break;
741 case EXP_OP_XOR
: dbg_printf(" ^ "); break;
742 case EXP_OP_EQ
: dbg_printf(" == "); break;
743 case EXP_OP_GT
: dbg_printf(" > "); break;
744 case EXP_OP_LT
: dbg_printf(" < "); break;
745 case EXP_OP_GE
: dbg_printf(" >= "); break;
746 case EXP_OP_LE
: dbg_printf(" <= "); break;
747 case EXP_OP_NE
: dbg_printf(" != "); break;
748 case EXP_OP_SHL
: dbg_printf(" << "); break;
749 case EXP_OP_SHR
: dbg_printf(" >> "); break;
750 case EXP_OP_MUL
: dbg_printf(" * "); break;
751 case EXP_OP_DIV
: dbg_printf(" / "); break;
752 case EXP_OP_REM
: dbg_printf(" %% "); break;
753 case EXP_OP_ARR
: dbg_printf("["); break;
756 expr_print(exp
->un
.binop
.exp2
);
757 if (exp
->un
.binop
.binop_type
== EXP_OP_ARR
) dbg_printf("]");
761 switch (exp
->un
.unop
.unop_type
)
763 case EXP_OP_NEG
: dbg_printf("-"); break;
764 case EXP_OP_NOT
: dbg_printf("!"); break;
765 case EXP_OP_LNOT
: dbg_printf("~"); break;
766 case EXP_OP_DEREF
: dbg_printf("*"); break;
767 case EXP_OP_ADDR
: dbg_printf("&"); break;
769 expr_print(exp
->un
.unop
.exp1
);
772 WINE_FIXME("Unexpected expression (%u).\n", exp
->type
);
773 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
780 struct expr
* expr_clone(const struct expr
* exp
)
785 rtn
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct expr
));
788 * First copy the contents of the expression itself.
795 rtn
->un
.cast
.expr
= expr_clone(exp
->un
.cast
.expr
);
797 case EXPR_TYPE_INTVAR
:
798 rtn
->un
.intvar
.name
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp
->un
.intvar
.name
) + 1), exp
->un
.intvar
.name
);
800 case EXPR_TYPE_U_CONST
:
801 case EXPR_TYPE_S_CONST
:
803 case EXPR_TYPE_STRING
:
804 rtn
->un
.string
.str
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp
->un
.string
.str
) + 1), exp
->un
.string
.str
);
806 case EXPR_TYPE_SYMBOL
:
807 rtn
->un
.symbol
.name
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp
->un
.symbol
.name
) + 1), exp
->un
.symbol
.name
);
809 case EXPR_TYPE_PSTRUCT
:
810 case EXPR_TYPE_STRUCT
:
811 rtn
->un
.structure
.exp1
= expr_clone(exp
->un
.structure
.exp1
);
812 rtn
->un
.structure
.element_name
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp
->un
.structure
.element_name
) + 1), exp
->un
.structure
.element_name
);
815 for (i
= 0; i
< exp
->un
.call
.nargs
; i
++)
817 rtn
->un
.call
.arg
[i
] = expr_clone(exp
->un
.call
.arg
[i
]);
819 rtn
->un
.call
.funcname
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp
->un
.call
.funcname
) + 1), exp
->un
.call
.funcname
);
821 case EXPR_TYPE_BINOP
:
822 rtn
->un
.binop
.exp1
= expr_clone(exp
->un
.binop
.exp1
);
823 rtn
->un
.binop
.exp2
= expr_clone(exp
->un
.binop
.exp2
);
826 rtn
->un
.unop
.exp1
= expr_clone(exp
->un
.unop
.exp1
);
829 WINE_FIXME("Unexpected expression (%u).\n", exp
->type
);
830 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
839 * Recursively go through an expression tree and free all memory associated
842 int expr_free(struct expr
* exp
)
849 expr_free(exp
->un
.cast
.expr
);
851 case EXPR_TYPE_INTVAR
:
852 HeapFree(GetProcessHeap(), 0, (char*)exp
->un
.intvar
.name
);
854 case EXPR_TYPE_U_CONST
:
855 case EXPR_TYPE_S_CONST
:
857 case EXPR_TYPE_STRING
:
858 HeapFree(GetProcessHeap(), 0, (char*)exp
->un
.string
.str
);
860 case EXPR_TYPE_SYMBOL
:
861 HeapFree(GetProcessHeap(), 0, (char*)exp
->un
.symbol
.name
);
863 case EXPR_TYPE_PSTRUCT
:
864 case EXPR_TYPE_STRUCT
:
865 expr_free(exp
->un
.structure
.exp1
);
866 HeapFree(GetProcessHeap(), 0, (char*)exp
->un
.structure
.element_name
);
869 for (i
= 0; i
< exp
->un
.call
.nargs
; i
++)
871 expr_free(exp
->un
.call
.arg
[i
]);
873 HeapFree(GetProcessHeap(), 0, (char*)exp
->un
.call
.funcname
);
875 case EXPR_TYPE_BINOP
:
876 expr_free(exp
->un
.binop
.exp1
);
877 expr_free(exp
->un
.binop
.exp2
);
880 expr_free(exp
->un
.unop
.exp1
);
883 WINE_FIXME("Unexpected expression (%u).\n", exp
->type
);
884 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
888 HeapFree(GetProcessHeap(), 0, exp
);