2 * File expr.c - expression handling for Wine internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
12 #include "wine/winbase16.h"
66 struct datatype
* cast
;
73 const char * element_name
;
85 const char * funcname
;
94 #define EXPR_TYPE_CONST 0
95 #define EXPR_TYPE_US_CONST 1
96 #define EXPR_TYPE_SYMBOL 2
97 #define EXPR_TYPE_INTVAR 3
98 #define EXPR_TYPE_BINOP 4
99 #define EXPR_TYPE_UNOP 5
100 #define EXPR_TYPE_STRUCT 6
101 #define EXPR_TYPE_PSTRUCT 7
102 #define EXPR_TYPE_ARRAY 8
103 #define EXPR_TYPE_CALL 9
104 #define EXPR_TYPE_STRING 10
105 #define EXPR_TYPE_CAST 11
107 static char expr_list
[4096];
108 static unsigned int next_expr_free
= 0;
111 * This is how we turn an expression address into the actual value.
112 * This works well in the 32 bit domain - not sure at all about the
115 #define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
119 DEBUG_GetFreeExpr(void)
123 rtn
= (struct expr
*) &expr_list
[next_expr_free
];
125 next_expr_free
+= sizeof(struct expr
);
126 assert(next_expr_free
< sizeof(expr_list
));
132 DEBUG_FreeExprMem(void)
138 DEBUG_TypeCastExpr(struct datatype
* dt
, struct expr
* exp
)
142 ex
= DEBUG_GetFreeExpr();
144 ex
->type
= EXPR_TYPE_CAST
;
145 ex
->un
.cast
.cast
= dt
;
146 ex
->un
.cast
.expr
= exp
;
151 DEBUG_IntVarExpr(const char* name
)
155 ex
= DEBUG_GetFreeExpr();
157 ex
->type
= EXPR_TYPE_INTVAR
;
158 ex
->un
.intvar
.name
= name
;
163 DEBUG_SymbolExpr(const char * name
)
167 ex
= DEBUG_GetFreeExpr();
169 ex
->type
= EXPR_TYPE_SYMBOL
;
170 ex
->un
.symbol
.name
= name
;
175 DEBUG_ConstExpr(int value
)
179 ex
= DEBUG_GetFreeExpr();
181 ex
->type
= EXPR_TYPE_CONST
;
182 ex
->un
.constant
.value
= value
;
187 DEBUG_StringExpr(const char * str
)
191 ex
= DEBUG_GetFreeExpr();
193 ex
->type
= EXPR_TYPE_STRING
;
194 ex
->un
.string
.str
= str
+1;
195 pnt
= strrchr(ex
->un
.string
.str
, '"');
204 DEBUG_USConstExpr(unsigned int value
)
208 ex
= DEBUG_GetFreeExpr();
210 ex
->type
= EXPR_TYPE_CONST
;
211 ex
->un
.u_const
.value
= value
;
216 DEBUG_BinopExpr(int operator_type
, struct expr
* exp1
, struct expr
* exp2
)
220 ex
= DEBUG_GetFreeExpr();
222 ex
->type
= EXPR_TYPE_BINOP
;
223 ex
->un
.binop
.binop_type
= operator_type
;
224 ex
->un
.binop
.exp1
= exp1
;
225 ex
->un
.binop
.exp2
= exp2
;
230 DEBUG_UnopExpr(int operator_type
, struct expr
* exp1
)
234 ex
= DEBUG_GetFreeExpr();
236 ex
->type
= EXPR_TYPE_UNOP
;
237 ex
->un
.unop
.unop_type
= operator_type
;
238 ex
->un
.unop
.exp1
= exp1
;
243 DEBUG_StructExpr(struct expr
* exp
, const char * element
)
247 ex
= DEBUG_GetFreeExpr();
249 ex
->type
= EXPR_TYPE_STRUCT
;
250 ex
->un
.structure
.exp1
= exp
;
251 ex
->un
.structure
.element_name
= element
;
256 DEBUG_StructPExpr(struct expr
* exp
, const char * element
)
260 ex
= DEBUG_GetFreeExpr();
262 ex
->type
= EXPR_TYPE_PSTRUCT
;
263 ex
->un
.structure
.exp1
= exp
;
264 ex
->un
.structure
.element_name
= element
;
269 DEBUG_CallExpr(const char * funcname
, int nargs
, ...)
275 ex
= DEBUG_GetFreeExpr();
277 ex
->type
= EXPR_TYPE_CALL
;
278 ex
->un
.call
.funcname
= funcname
;
279 ex
->un
.call
.nargs
= nargs
;
282 for(i
=0; i
< nargs
; i
++)
284 ex
->un
.call
.arg
[i
] = va_arg(ap
, struct expr
*);
290 DBG_VALUE
DEBUG_EvalExpr(struct expr
* exp
)
296 unsigned int cexp
[5];
300 struct datatype
* type1
;
301 struct datatype
* type2
;
304 rtn
.cookie
= DV_INVALID
;
311 rtn
= DEBUG_EvalExpr(exp
->un
.cast
.expr
);
312 rtn
.type
= exp
->un
.cast
.cast
;
313 if (DEBUG_GetType(rtn
.type
) == DT_POINTER
)
314 rtn
.cookie
= DV_TARGET
;
316 case EXPR_TYPE_STRING
:
317 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_STRING
);
318 rtn
.cookie
= DV_HOST
;
319 rtn
.addr
.off
= (unsigned int) &exp
->un
.string
.str
;
322 case EXPR_TYPE_CONST
:
323 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_CONST_INT
);
324 rtn
.cookie
= DV_HOST
;
325 rtn
.addr
.off
= (unsigned int) &exp
->un
.constant
.value
;
328 case EXPR_TYPE_US_CONST
:
329 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_USHORTINT
);
330 rtn
.cookie
= DV_HOST
;
331 rtn
.addr
.off
= (unsigned int) &exp
->un
.u_const
.value
;
334 case EXPR_TYPE_SYMBOL
:
335 if( !DEBUG_GetSymbolValue(exp
->un
.symbol
.name
, -1, &rtn
, FALSE
) )
337 DEBUG_Printf(DBG_CHN_MESG
, "%s\n", exp
->un
.symbol
.name
);
338 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
341 case EXPR_TYPE_PSTRUCT
:
342 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
343 if( exp1
.type
== NULL
)
345 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
347 rtn
.cookie
= DV_TARGET
;
348 rtn
.addr
.off
= DEBUG_TypeDerefPointer(&exp1
, &rtn
.type
);
349 if( rtn
.type
== NULL
)
351 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
353 if (!DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
354 &exp
->un
.structure
.result
))
356 DEBUG_Printf(DBG_CHN_MESG
, "%s\n", exp
->un
.structure
.element_name
);
357 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
361 case EXPR_TYPE_STRUCT
:
362 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
363 if( exp1
.type
== NULL
)
365 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
368 if (!DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
369 &exp
->un
.structure
.result
))
371 DEBUG_Printf(DBG_CHN_MESG
, "%s\n", exp
->un
.structure
.element_name
);
372 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
377 * First, evaluate all of the arguments. If any of them are not
378 * evaluable, then bail.
380 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
382 exp1
= DEBUG_EvalExpr(exp
->un
.call
.arg
[i
]);
383 if( exp1
.type
== NULL
)
387 cexp
[i
] = DEBUG_GetExprValue(&exp1
, NULL
);
391 * Now look up the address of the function itself.
393 if( !DEBUG_GetSymbolValue(exp
->un
.call
.funcname
, -1, &rtn
, FALSE
) )
395 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
399 /* FIXME: NEWDBG NIY */
400 /* Anyway, I wonder how this could work depending on the calling order of
401 * the function (cdecl vs pascal for example)
405 fptr
= (int (*)()) rtn
.addr
.off
;
406 switch(exp
->un
.call
.nargs
)
409 exp
->un
.call
.result
= (*fptr
)();
412 exp
->un
.call
.result
= (*fptr
)(cexp
[0]);
415 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1]);
418 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2]);
421 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3]);
424 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3], cexp
[4]);
428 DEBUG_Printf(DBG_CHN_MESG
, "Function call no longer implemented\n");
429 /* would need to set up a call to this function, and then restore the current
430 * context afterwards...
432 exp
->un
.call
.result
= 0;
434 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_INT
);
435 rtn
.cookie
= DV_HOST
;
436 rtn
.addr
.off
= (unsigned int) &exp
->un
.call
.result
;
439 case EXPR_TYPE_INTVAR
:
442 DBG_INTVAR
* div
= DEBUG_GetIntVar(exp
->un
.intvar
.name
);
444 if (!div
) RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
445 rtn
.cookie
= DV_HOST
;
446 rtn
.type
= div
->type
;
447 rtn
.addr
.off
= (unsigned int)div
->pval
;
448 /* EPP FIXME rtn.addr.seg = ?? */
451 case EXPR_TYPE_BINOP
:
452 exp1
= DEBUG_EvalExpr(exp
->un
.binop
.exp1
);
453 exp2
= DEBUG_EvalExpr(exp
->un
.binop
.exp2
);
454 rtn
.cookie
= DV_HOST
;
455 if( exp1
.type
== NULL
|| exp2
.type
== NULL
)
457 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
459 if( exp1
.type
== DEBUG_GetBasicType(DT_BASIC_CONST_INT
) &&
460 exp2
.type
== DEBUG_GetBasicType(DT_BASIC_CONST_INT
) )
462 rtn
.type
= exp1
.type
;
466 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_INT
);
469 rtn
.addr
.off
= (unsigned int) &exp
->un
.binop
.result
;
470 switch(exp
->un
.binop
.binop_type
)
473 type1
= DEBUG_GetPointerType(exp1
.type
);
474 type2
= DEBUG_GetPointerType(exp2
.type
);
477 if( type1
!= NULL
&& type2
!= NULL
)
479 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
481 else if( type1
!= NULL
)
483 scale2
= DEBUG_GetObjectSize(type1
);
484 rtn
.type
= exp1
.type
;
486 else if( type2
!= NULL
)
488 scale1
= DEBUG_GetObjectSize(type2
);
489 rtn
.type
= exp2
.type
;
491 exp
->un
.binop
.result
= (VAL(exp1
) * scale1
+ scale2
* VAL(exp2
));
494 type1
= DEBUG_GetPointerType(exp1
.type
);
495 type2
= DEBUG_GetPointerType(exp2
.type
);
499 if( type1
!= NULL
&& type2
!= NULL
)
503 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
505 scale3
= DEBUG_GetObjectSize(type1
);
507 else if( type1
!= NULL
)
509 scale2
= DEBUG_GetObjectSize(type1
);
510 rtn
.type
= exp1
.type
;
513 else if( type2
!= NULL
)
515 scale1
= DEBUG_GetObjectSize(type2
);
516 rtn
.type
= exp2
.type
;
518 exp
->un
.binop
.result
= (VAL(exp1
) - VAL(exp2
)) / scale3
;
521 rtn
.cookie
= DV_TARGET
;
523 rtn
.addr
.seg
= VAL(exp1
);
524 rtn
.addr
.off
= VAL(exp2
);
527 exp
->un
.binop
.result
= (VAL(exp1
) || VAL(exp2
));
530 exp
->un
.binop
.result
= (VAL(exp1
) && VAL(exp2
));
533 exp
->un
.binop
.result
= (VAL(exp1
) | VAL(exp2
));
536 exp
->un
.binop
.result
= (VAL(exp1
) & VAL(exp2
));
539 exp
->un
.binop
.result
= (VAL(exp1
) ^ VAL(exp2
));
542 exp
->un
.binop
.result
= (VAL(exp1
) == VAL(exp2
));
545 exp
->un
.binop
.result
= (VAL(exp1
) > VAL(exp2
));
548 exp
->un
.binop
.result
= (VAL(exp1
) < VAL(exp2
));
551 exp
->un
.binop
.result
= (VAL(exp1
) >= VAL(exp2
));
554 exp
->un
.binop
.result
= (VAL(exp1
) <= VAL(exp2
));
557 exp
->un
.binop
.result
= (VAL(exp1
) != VAL(exp2
));
560 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) << VAL(exp2
));
563 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) >> VAL(exp2
));
566 exp
->un
.binop
.result
= (VAL(exp1
) * VAL(exp2
));
571 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
573 exp
->un
.binop
.result
= (VAL(exp1
) / VAL(exp2
));
578 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
580 exp
->un
.binop
.result
= (VAL(exp1
) % VAL(exp2
));
583 DEBUG_ArrayIndex(&exp1
, &rtn
, VAL(exp2
));
586 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
591 exp1
= DEBUG_EvalExpr(exp
->un
.unop
.exp1
);
592 rtn
.cookie
= DV_HOST
;
593 if( exp1
.type
== NULL
)
595 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
598 rtn
.addr
.off
= (unsigned int) &exp
->un
.unop
.result
;
599 if( exp1
.type
== DEBUG_GetBasicType(DT_BASIC_CONST_INT
) )
601 rtn
.type
= exp1
.type
;
605 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_INT
);
607 switch(exp
->un
.unop
.unop_type
)
610 exp
->un
.unop
.result
= -VAL(exp1
);
613 exp
->un
.unop
.result
= !VAL(exp1
);
616 exp
->un
.unop
.result
= ~VAL(exp1
);
619 /* FIXME: this is currently buggy.
620 * there is no way to tell were the deref:ed value is...
622 * x is a pointer to struct s, x being on the stack
623 * => exp1 is target, result is target
624 * x is a pointer to struct s, x being optimized into a reg
625 * => exp1 is host, result is target
626 * x is a pointer to internal variable x
627 * => exp1 is host, result is host
628 * so we force DV_TARGET, because dereferencing pointers to
629 * internal variables is very unlikely. a correct fix would be
632 rtn
.cookie
= DV_TARGET
;
633 rtn
.addr
.off
= (unsigned int) DEBUG_TypeDerefPointer(&exp1
, &rtn
.type
);
636 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
639 case EXP_OP_FORCE_DEREF
:
640 rtn
.cookie
= exp1
.cookie
;
641 rtn
.addr
.seg
= exp1
.addr
.seg
;
642 if (exp1
.cookie
== DV_TARGET
)
643 DEBUG_READ_MEM((void*)exp1
.addr
.off
, &rtn
.addr
.off
, sizeof(rtn
.addr
.off
));
645 memcpy(&rtn
.addr
.off
, (void*)exp1
.addr
.off
, sizeof(rtn
.addr
.off
));
648 /* FIXME: even for a 16 bit entity ? */
649 rtn
.type
= DEBUG_FindOrMakePointerType(exp1
.type
);
650 exp
->un
.unop
.result
= exp1
.addr
.off
;
653 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
657 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression (%d).\n", exp
->type
);
658 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
662 assert(rtn
.cookie
== DV_TARGET
|| rtn
.cookie
== DV_HOST
);
669 DEBUG_DisplayExpr(const struct expr
* exp
)
676 DEBUG_Printf(DBG_CHN_MESG
, "((");
677 DEBUG_PrintTypeCast(exp
->un
.cast
.cast
);
678 DEBUG_Printf(DBG_CHN_MESG
, ")");
679 DEBUG_DisplayExpr(exp
->un
.cast
.expr
);
680 DEBUG_Printf(DBG_CHN_MESG
, ")");
682 case EXPR_TYPE_INTVAR
:
683 DEBUG_Printf(DBG_CHN_MESG
, "$%s", exp
->un
.intvar
.name
);
685 case EXPR_TYPE_US_CONST
:
686 DEBUG_Printf(DBG_CHN_MESG
, "%ud", exp
->un
.u_const
.value
);
688 case EXPR_TYPE_CONST
:
689 DEBUG_Printf(DBG_CHN_MESG
, "%d", exp
->un
.u_const
.value
);
691 case EXPR_TYPE_STRING
:
692 DEBUG_Printf(DBG_CHN_MESG
, "\"%s\"", exp
->un
.string
.str
);
694 case EXPR_TYPE_SYMBOL
:
695 DEBUG_Printf(DBG_CHN_MESG
, "%s" , exp
->un
.symbol
.name
);
697 case EXPR_TYPE_PSTRUCT
:
698 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
699 DEBUG_Printf(DBG_CHN_MESG
, "->%s", exp
->un
.structure
.element_name
);
701 case EXPR_TYPE_STRUCT
:
702 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
703 DEBUG_Printf(DBG_CHN_MESG
, ".%s", exp
->un
.structure
.element_name
);
706 DEBUG_Printf(DBG_CHN_MESG
, "%s(",exp
->un
.call
.funcname
);
707 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
709 DEBUG_DisplayExpr(exp
->un
.call
.arg
[i
]);
710 if( i
!= exp
->un
.call
.nargs
- 1 )
712 DEBUG_Printf(DBG_CHN_MESG
, ", ");
715 DEBUG_Printf(DBG_CHN_MESG
, ")");
717 case EXPR_TYPE_BINOP
:
718 DEBUG_Printf(DBG_CHN_MESG
, "( ");
719 DEBUG_DisplayExpr(exp
->un
.binop
.exp1
);
720 switch(exp
->un
.binop
.binop_type
)
723 DEBUG_Printf(DBG_CHN_MESG
, " + ");
726 DEBUG_Printf(DBG_CHN_MESG
, " - ");
729 DEBUG_Printf(DBG_CHN_MESG
, ":");
732 DEBUG_Printf(DBG_CHN_MESG
, " || ");
735 DEBUG_Printf(DBG_CHN_MESG
, " && ");
738 DEBUG_Printf(DBG_CHN_MESG
, " | ");
741 DEBUG_Printf(DBG_CHN_MESG
, " & ");
744 DEBUG_Printf(DBG_CHN_MESG
, " ^ ");
747 DEBUG_Printf(DBG_CHN_MESG
, " == ");
750 DEBUG_Printf(DBG_CHN_MESG
, " > ");
753 DEBUG_Printf(DBG_CHN_MESG
, " < ");
756 DEBUG_Printf(DBG_CHN_MESG
, " >= ");
759 DEBUG_Printf(DBG_CHN_MESG
, " <= ");
762 DEBUG_Printf(DBG_CHN_MESG
, " != ");
765 DEBUG_Printf(DBG_CHN_MESG
, " << ");
768 DEBUG_Printf(DBG_CHN_MESG
, " >> ");
771 DEBUG_Printf(DBG_CHN_MESG
, " * ");
774 DEBUG_Printf(DBG_CHN_MESG
, " / ");
777 DEBUG_Printf(DBG_CHN_MESG
, " %% ");
780 DEBUG_Printf(DBG_CHN_MESG
, "[");
785 DEBUG_DisplayExpr(exp
->un
.binop
.exp2
);
786 if( exp
->un
.binop
.binop_type
== EXP_OP_ARR
)
788 DEBUG_Printf(DBG_CHN_MESG
, "]");
790 DEBUG_Printf(DBG_CHN_MESG
, " )");
793 switch(exp
->un
.unop
.unop_type
)
796 DEBUG_Printf(DBG_CHN_MESG
, "-");
799 DEBUG_Printf(DBG_CHN_MESG
, "!");
802 DEBUG_Printf(DBG_CHN_MESG
, "~");
805 DEBUG_Printf(DBG_CHN_MESG
, "*");
808 DEBUG_Printf(DBG_CHN_MESG
, "&");
811 DEBUG_DisplayExpr(exp
->un
.unop
.exp1
);
814 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
815 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
823 DEBUG_CloneExpr(const struct expr
* exp
)
828 rtn
= (struct expr
*) DBG_alloc(sizeof(struct expr
));
831 * First copy the contents of the expression itself.
839 rtn
->un
.cast
.expr
= DEBUG_CloneExpr(exp
->un
.cast
.expr
);
841 case EXPR_TYPE_INTVAR
:
842 rtn
->un
.intvar
.name
= DBG_strdup(exp
->un
.intvar
.name
);
844 case EXPR_TYPE_US_CONST
:
845 case EXPR_TYPE_CONST
:
847 case EXPR_TYPE_STRING
:
848 rtn
->un
.string
.str
= DBG_strdup(exp
->un
.string
.str
);
850 case EXPR_TYPE_SYMBOL
:
851 rtn
->un
.symbol
.name
= DBG_strdup(exp
->un
.symbol
.name
);
853 case EXPR_TYPE_PSTRUCT
:
854 case EXPR_TYPE_STRUCT
:
855 rtn
->un
.structure
.exp1
= DEBUG_CloneExpr(exp
->un
.structure
.exp1
);
856 rtn
->un
.structure
.element_name
= DBG_strdup(exp
->un
.structure
.element_name
);
859 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
861 rtn
->un
.call
.arg
[i
] = DEBUG_CloneExpr(exp
->un
.call
.arg
[i
]);
863 rtn
->un
.call
.funcname
= DBG_strdup(exp
->un
.call
.funcname
);
865 case EXPR_TYPE_BINOP
:
866 rtn
->un
.binop
.exp1
= DEBUG_CloneExpr(exp
->un
.binop
.exp1
);
867 rtn
->un
.binop
.exp2
= DEBUG_CloneExpr(exp
->un
.binop
.exp2
);
870 rtn
->un
.unop
.exp1
= DEBUG_CloneExpr(exp
->un
.unop
.exp1
);
873 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
874 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
883 * Recursively go through an expression tree and free all memory associated
887 DEBUG_FreeExpr(struct expr
* exp
)
894 DEBUG_FreeExpr(exp
->un
.cast
.expr
);
896 case EXPR_TYPE_INTVAR
:
897 DBG_free((char *) exp
->un
.intvar
.name
);
899 case EXPR_TYPE_US_CONST
:
900 case EXPR_TYPE_CONST
:
902 case EXPR_TYPE_STRING
:
903 DBG_free((char *) exp
->un
.string
.str
);
905 case EXPR_TYPE_SYMBOL
:
906 DBG_free((char *) exp
->un
.symbol
.name
);
908 case EXPR_TYPE_PSTRUCT
:
909 case EXPR_TYPE_STRUCT
:
910 DEBUG_FreeExpr(exp
->un
.structure
.exp1
);
911 DBG_free((char *) exp
->un
.structure
.element_name
);
914 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
916 DEBUG_FreeExpr(exp
->un
.call
.arg
[i
]);
918 DBG_free((char *) exp
->un
.call
.funcname
);
920 case EXPR_TYPE_BINOP
:
921 DEBUG_FreeExpr(exp
->un
.binop
.exp1
);
922 DEBUG_FreeExpr(exp
->un
.binop
.exp2
);
925 DEBUG_FreeExpr(exp
->un
.unop
.exp1
);
928 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
929 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);