2 * File expr.c - expression handling for Wine internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
12 #include "wine/winbase16.h"
67 struct datatype
* cast
;
74 const char * element_name
;
86 const char * funcname
;
95 #define EXPR_TYPE_CONST 0
96 #define EXPR_TYPE_US_CONST 1
97 #define EXPR_TYPE_SYMBOL 2
98 #define EXPR_TYPE_INTVAR 3
99 #define EXPR_TYPE_BINOP 4
100 #define EXPR_TYPE_UNOP 5
101 #define EXPR_TYPE_STRUCT 6
102 #define EXPR_TYPE_PSTRUCT 7
103 #define EXPR_TYPE_ARRAY 8
104 #define EXPR_TYPE_CALL 9
105 #define EXPR_TYPE_STRING 10
106 #define EXPR_TYPE_CAST 11
108 static char expr_list
[4096];
109 static int next_expr_free
= 0;
112 * This is how we turn an expression address into the actual value.
113 * This works well in the 32 bit domain - not sure at all about the
116 #define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
120 DEBUG_GetFreeExpr(void)
124 rtn
= (struct expr
*) &expr_list
[next_expr_free
];
126 next_expr_free
+= sizeof(struct expr
);
127 assert(next_expr_free
< sizeof(expr_list
));
133 DEBUG_FreeExprMem(void)
139 DEBUG_TypeCastExpr(struct datatype
* dt
, struct expr
* exp
)
143 ex
= DEBUG_GetFreeExpr();
145 ex
->type
= EXPR_TYPE_CAST
;
146 ex
->un
.cast
.cast
= dt
;
147 ex
->un
.cast
.expr
= exp
;
152 DEBUG_IntVarExpr(const char* name
)
156 ex
= DEBUG_GetFreeExpr();
158 ex
->type
= EXPR_TYPE_INTVAR
;
159 ex
->un
.intvar
.name
= name
;
164 DEBUG_SymbolExpr(const char * name
)
168 ex
= DEBUG_GetFreeExpr();
170 ex
->type
= EXPR_TYPE_SYMBOL
;
171 ex
->un
.symbol
.name
= name
;
176 DEBUG_ConstExpr(int value
)
180 ex
= DEBUG_GetFreeExpr();
182 ex
->type
= EXPR_TYPE_CONST
;
183 ex
->un
.constant
.value
= value
;
188 DEBUG_StringExpr(const char * str
)
192 ex
= DEBUG_GetFreeExpr();
194 ex
->type
= EXPR_TYPE_STRING
;
195 ex
->un
.string
.str
= str
+1;
196 pnt
= strrchr(ex
->un
.string
.str
, '"');
205 DEBUG_USConstExpr(unsigned int value
)
209 ex
= DEBUG_GetFreeExpr();
211 ex
->type
= EXPR_TYPE_CONST
;
212 ex
->un
.u_const
.value
= value
;
217 DEBUG_BinopExpr(int operator_type
, struct expr
* exp1
, struct expr
* exp2
)
221 ex
= DEBUG_GetFreeExpr();
223 ex
->type
= EXPR_TYPE_BINOP
;
224 ex
->un
.binop
.binop_type
= operator_type
;
225 ex
->un
.binop
.exp1
= exp1
;
226 ex
->un
.binop
.exp2
= exp2
;
231 DEBUG_UnopExpr(int operator_type
, struct expr
* exp1
)
235 ex
= DEBUG_GetFreeExpr();
237 ex
->type
= EXPR_TYPE_UNOP
;
238 ex
->un
.unop
.unop_type
= operator_type
;
239 ex
->un
.unop
.exp1
= exp1
;
244 DEBUG_StructExpr(struct expr
* exp
, const char * element
)
248 ex
= DEBUG_GetFreeExpr();
250 ex
->type
= EXPR_TYPE_STRUCT
;
251 ex
->un
.structure
.exp1
= exp
;
252 ex
->un
.structure
.element_name
= element
;
257 DEBUG_StructPExpr(struct expr
* exp
, const char * element
)
261 ex
= DEBUG_GetFreeExpr();
263 ex
->type
= EXPR_TYPE_PSTRUCT
;
264 ex
->un
.structure
.exp1
= exp
;
265 ex
->un
.structure
.element_name
= element
;
270 DEBUG_CallExpr(const char * funcname
, int nargs
, ...)
276 ex
= DEBUG_GetFreeExpr();
278 ex
->type
= EXPR_TYPE_CALL
;
279 ex
->un
.call
.funcname
= funcname
;
280 ex
->un
.call
.nargs
= nargs
;
283 for(i
=0; i
< nargs
; i
++)
285 ex
->un
.call
.arg
[i
] = va_arg(ap
, struct expr
*);
291 DBG_VALUE
DEBUG_EvalExpr(struct expr
* exp
)
297 unsigned int cexp
[5];
301 struct datatype
* type1
;
302 struct datatype
* type2
;
305 rtn
.cookie
= DV_INVALID
;
312 rtn
= DEBUG_EvalExpr(exp
->un
.cast
.expr
);
313 rtn
.type
= exp
->un
.cast
.cast
;
314 if (DEBUG_GetType(rtn
.type
) == DT_POINTER
)
315 rtn
.cookie
= DV_TARGET
;
317 case EXPR_TYPE_STRING
:
318 rtn
.type
= DEBUG_TypeString
;
319 rtn
.cookie
= DV_HOST
;
320 rtn
.addr
.off
= (unsigned int) &exp
->un
.string
.str
;
323 case EXPR_TYPE_CONST
:
324 rtn
.type
= DEBUG_TypeIntConst
;
325 rtn
.cookie
= DV_HOST
;
326 rtn
.addr
.off
= (unsigned int) &exp
->un
.constant
.value
;
329 case EXPR_TYPE_US_CONST
:
330 rtn
.type
= DEBUG_TypeUSInt
;
331 rtn
.cookie
= DV_HOST
;
332 rtn
.addr
.off
= (unsigned int) &exp
->un
.u_const
.value
;
335 case EXPR_TYPE_SYMBOL
:
336 if( !DEBUG_GetSymbolValue(exp
->un
.symbol
.name
, -1, &rtn
, FALSE
) )
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
, &type1
);
351 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
354 DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
355 &exp
->un
.structure
.result
);
357 case EXPR_TYPE_STRUCT
:
358 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
359 if( exp1
.type
== NULL
)
361 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
364 DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
365 &exp
->un
.structure
.result
);
369 * First, evaluate all of the arguments. If any of them are not
370 * evaluable, then bail.
372 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
374 exp1
= DEBUG_EvalExpr(exp
->un
.call
.arg
[i
]);
375 if( exp1
.type
== NULL
)
379 cexp
[i
] = DEBUG_GetExprValue(&exp1
, NULL
);
383 * Now look up the address of the function itself.
385 if( !DEBUG_GetSymbolValue(exp
->un
.call
.funcname
, -1, &rtn
, FALSE
) )
387 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
391 /* FIXME: NEWDBG NIY */
392 /* Anyway, I wonder how this could work depending on the calling order of
393 * the function (cdecl vs pascal for example)
397 fptr
= (int (*)()) rtn
.addr
.off
;
398 switch(exp
->un
.call
.nargs
)
401 exp
->un
.call
.result
= (*fptr
)();
404 exp
->un
.call
.result
= (*fptr
)(cexp
[0]);
407 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1]);
410 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2]);
413 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3]);
416 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3], cexp
[4]);
420 DEBUG_Printf(DBG_CHN_MESG
, "Function call no longer implemented\n");
421 /* would need to set up a call to this function, and then restore the current
422 * context afterwards...
424 exp
->un
.call
.result
= 0;
426 rtn
.type
= DEBUG_TypeInt
;
427 rtn
.cookie
= DV_HOST
;
428 rtn
.addr
.off
= (unsigned int) &exp
->un
.call
.result
;
431 case EXPR_TYPE_INTVAR
:
434 DBG_INTVAR
* div
= DEBUG_GetIntVar(exp
->un
.intvar
.name
);
436 if (!div
) RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
437 rtn
.cookie
= DV_HOST
;
438 rtn
.type
= div
->type
;
439 rtn
.addr
.off
= (unsigned int)div
->pval
;
440 /* EPP FIXME rtn.addr.seg = ?? */
443 case EXPR_TYPE_BINOP
:
444 exp1
= DEBUG_EvalExpr(exp
->un
.binop
.exp1
);
445 exp2
= DEBUG_EvalExpr(exp
->un
.binop
.exp2
);
446 rtn
.cookie
= DV_HOST
;
447 if( exp1
.type
== NULL
|| exp2
.type
== NULL
)
449 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
451 if( exp1
.type
== DEBUG_TypeIntConst
&& exp2
.type
== DEBUG_TypeIntConst
)
453 rtn
.type
= exp1
.type
;
457 rtn
.type
= DEBUG_TypeInt
;
460 rtn
.addr
.off
= (unsigned int) &exp
->un
.binop
.result
;
461 switch(exp
->un
.binop
.binop_type
)
464 type1
= DEBUG_GetPointerType(exp1
.type
);
465 type2
= DEBUG_GetPointerType(exp2
.type
);
468 if( type1
!= NULL
&& type2
!= NULL
)
470 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
472 else if( type1
!= NULL
)
474 scale2
= DEBUG_GetObjectSize(type1
);
475 rtn
.type
= exp1
.type
;
477 else if( type2
!= NULL
)
479 scale1
= DEBUG_GetObjectSize(type2
);
480 rtn
.type
= exp2
.type
;
482 exp
->un
.binop
.result
= (VAL(exp1
) * scale1
+ scale2
* VAL(exp2
));
485 type1
= DEBUG_GetPointerType(exp1
.type
);
486 type2
= DEBUG_GetPointerType(exp2
.type
);
490 if( type1
!= NULL
&& type2
!= NULL
)
494 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
496 scale3
= DEBUG_GetObjectSize(type1
);
498 else if( type1
!= NULL
)
500 scale2
= DEBUG_GetObjectSize(type1
);
501 rtn
.type
= exp1
.type
;
504 else if( type2
!= NULL
)
506 scale1
= DEBUG_GetObjectSize(type2
);
507 rtn
.type
= exp2
.type
;
509 exp
->un
.binop
.result
= (VAL(exp1
) - VAL(exp2
)) / scale3
;
512 rtn
.cookie
= DV_TARGET
;
514 rtn
.addr
.seg
= VAL(exp1
);
515 rtn
.addr
.off
= VAL(exp2
);
518 exp
->un
.binop
.result
= (VAL(exp1
) || VAL(exp2
));
521 exp
->un
.binop
.result
= (VAL(exp1
) && VAL(exp2
));
524 exp
->un
.binop
.result
= (VAL(exp1
) | 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
= ((unsigned) VAL(exp1
) << VAL(exp2
));
554 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) >> VAL(exp2
));
557 exp
->un
.binop
.result
= (VAL(exp1
) * VAL(exp2
));
562 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
564 exp
->un
.binop
.result
= (VAL(exp1
) / VAL(exp2
));
569 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
571 exp
->un
.binop
.result
= (VAL(exp1
) % VAL(exp2
));
574 DEBUG_ArrayIndex(&exp1
, &rtn
, VAL(exp2
));
577 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
582 exp1
= DEBUG_EvalExpr(exp
->un
.unop
.exp1
);
583 rtn
.cookie
= DV_HOST
;
584 if( exp1
.type
== NULL
)
586 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
589 rtn
.addr
.off
= (unsigned int) &exp
->un
.unop
.result
;
590 if( exp1
.type
== DEBUG_TypeIntConst
)
592 rtn
.type
= exp1
.type
;
596 rtn
.type
= DEBUG_TypeInt
;
598 switch(exp
->un
.unop
.unop_type
)
601 exp
->un
.unop
.result
= -VAL(exp1
);
604 exp
->un
.unop
.result
= !VAL(exp1
);
607 exp
->un
.unop
.result
= ~VAL(exp1
);
610 /* FIXME: this is currently buggy.
611 * there is no way to tell were the deref:ed value is...
613 * x is a pointer to struct s, x being on the stack
614 * => exp1 is target, result is target
615 * x is a pointer to struct s, x being optimized into a reg
616 * => exp1 is host, result is target
617 * x is a pointer to internal variable x
618 * => exp1 is host, result is host
619 * so we force DV_TARGET, because dereferencing pointers to
620 * internal variables is very unlikely. a correct fix would be
623 rtn
.cookie
= DV_TARGET
;
624 rtn
.addr
.off
= (unsigned int) DEBUG_TypeDerefPointer(&exp1
, &rtn
.type
);
627 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
630 case EXP_OP_FORCE_DEREF
:
631 rtn
.cookie
= exp1
.cookie
;
632 rtn
.addr
.seg
= exp1
.addr
.seg
;
633 if (exp1
.cookie
== DV_TARGET
)
634 DEBUG_READ_MEM((void*)exp1
.addr
.off
, &rtn
.addr
.off
, sizeof(rtn
.addr
.off
));
636 memcpy(&rtn
.addr
.off
, (void*)exp1
.addr
.off
, sizeof(rtn
.addr
.off
));
639 /* FIXME: even for a 16 bit entity ? */
640 rtn
.cookie
= DV_TARGET
;
641 rtn
.type
= DEBUG_FindOrMakePointerType(exp1
.type
);
642 exp
->un
.unop
.result
= exp1
.addr
.off
;
645 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
649 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression (%d).\n", exp
->type
);
650 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
654 assert(rtn
.cookie
== DV_TARGET
|| rtn
.cookie
== DV_HOST
);
661 DEBUG_DisplayExpr(const struct expr
* exp
)
668 DEBUG_Printf(DBG_CHN_MESG
, "((");
669 DEBUG_PrintTypeCast(exp
->un
.cast
.cast
);
670 DEBUG_Printf(DBG_CHN_MESG
, ")");
671 DEBUG_DisplayExpr(exp
->un
.cast
.expr
);
672 DEBUG_Printf(DBG_CHN_MESG
, ")");
674 case EXPR_TYPE_INTVAR
:
675 DEBUG_Printf(DBG_CHN_MESG
, "$%s", exp
->un
.intvar
.name
);
677 case EXPR_TYPE_US_CONST
:
678 DEBUG_Printf(DBG_CHN_MESG
, "%ud", exp
->un
.u_const
.value
);
680 case EXPR_TYPE_CONST
:
681 DEBUG_Printf(DBG_CHN_MESG
, "%d", exp
->un
.u_const
.value
);
683 case EXPR_TYPE_STRING
:
684 DEBUG_Printf(DBG_CHN_MESG
, "\"%s\"", exp
->un
.string
.str
);
686 case EXPR_TYPE_SYMBOL
:
687 DEBUG_Printf(DBG_CHN_MESG
, "%s" , exp
->un
.symbol
.name
);
689 case EXPR_TYPE_PSTRUCT
:
690 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
691 DEBUG_Printf(DBG_CHN_MESG
, "->%s", exp
->un
.structure
.element_name
);
693 case EXPR_TYPE_STRUCT
:
694 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
695 DEBUG_Printf(DBG_CHN_MESG
, ".%s", exp
->un
.structure
.element_name
);
698 DEBUG_Printf(DBG_CHN_MESG
, "%s(",exp
->un
.call
.funcname
);
699 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
701 DEBUG_DisplayExpr(exp
->un
.call
.arg
[i
]);
702 if( i
!= exp
->un
.call
.nargs
- 1 )
704 DEBUG_Printf(DBG_CHN_MESG
, ", ");
707 DEBUG_Printf(DBG_CHN_MESG
, ")");
709 case EXPR_TYPE_BINOP
:
710 DEBUG_Printf(DBG_CHN_MESG
, "( ");
711 DEBUG_DisplayExpr(exp
->un
.binop
.exp1
);
712 switch(exp
->un
.binop
.binop_type
)
715 DEBUG_Printf(DBG_CHN_MESG
, " + ");
718 DEBUG_Printf(DBG_CHN_MESG
, " - ");
721 DEBUG_Printf(DBG_CHN_MESG
, ":");
724 DEBUG_Printf(DBG_CHN_MESG
, " || ");
727 DEBUG_Printf(DBG_CHN_MESG
, " && ");
730 DEBUG_Printf(DBG_CHN_MESG
, " | ");
733 DEBUG_Printf(DBG_CHN_MESG
, " & ");
736 DEBUG_Printf(DBG_CHN_MESG
, " ^ ");
739 DEBUG_Printf(DBG_CHN_MESG
, " == ");
742 DEBUG_Printf(DBG_CHN_MESG
, " > ");
745 DEBUG_Printf(DBG_CHN_MESG
, " < ");
748 DEBUG_Printf(DBG_CHN_MESG
, " >= ");
751 DEBUG_Printf(DBG_CHN_MESG
, " <= ");
754 DEBUG_Printf(DBG_CHN_MESG
, " != ");
757 DEBUG_Printf(DBG_CHN_MESG
, " << ");
760 DEBUG_Printf(DBG_CHN_MESG
, " >> ");
763 DEBUG_Printf(DBG_CHN_MESG
, " * ");
766 DEBUG_Printf(DBG_CHN_MESG
, " / ");
769 DEBUG_Printf(DBG_CHN_MESG
, " %% ");
772 DEBUG_Printf(DBG_CHN_MESG
, "[");
777 DEBUG_DisplayExpr(exp
->un
.binop
.exp2
);
778 if( exp
->un
.binop
.binop_type
== EXP_OP_ARR
)
780 DEBUG_Printf(DBG_CHN_MESG
, "]");
782 DEBUG_Printf(DBG_CHN_MESG
, " )");
785 switch(exp
->un
.unop
.unop_type
)
788 DEBUG_Printf(DBG_CHN_MESG
, "-");
791 DEBUG_Printf(DBG_CHN_MESG
, "!");
794 DEBUG_Printf(DBG_CHN_MESG
, "~");
797 DEBUG_Printf(DBG_CHN_MESG
, "*");
800 DEBUG_Printf(DBG_CHN_MESG
, "&");
803 DEBUG_DisplayExpr(exp
->un
.unop
.exp1
);
806 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
807 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
815 DEBUG_CloneExpr(const struct expr
* exp
)
820 rtn
= (struct expr
*) DBG_alloc(sizeof(struct expr
));
823 * First copy the contents of the expression itself.
831 rtn
->un
.cast
.expr
= DEBUG_CloneExpr(exp
->un
.cast
.expr
);
833 case EXPR_TYPE_INTVAR
:
834 rtn
->un
.intvar
.name
= DBG_strdup(exp
->un
.intvar
.name
);
836 case EXPR_TYPE_US_CONST
:
837 case EXPR_TYPE_CONST
:
839 case EXPR_TYPE_STRING
:
840 rtn
->un
.string
.str
= DBG_strdup(exp
->un
.string
.str
);
842 case EXPR_TYPE_SYMBOL
:
843 rtn
->un
.symbol
.name
= DBG_strdup(exp
->un
.symbol
.name
);
845 case EXPR_TYPE_PSTRUCT
:
846 case EXPR_TYPE_STRUCT
:
847 rtn
->un
.structure
.exp1
= DEBUG_CloneExpr(exp
->un
.structure
.exp1
);
848 rtn
->un
.structure
.element_name
= DBG_strdup(exp
->un
.structure
.element_name
);
851 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
853 rtn
->un
.call
.arg
[i
] = DEBUG_CloneExpr(exp
->un
.call
.arg
[i
]);
855 rtn
->un
.call
.funcname
= DBG_strdup(exp
->un
.call
.funcname
);
857 case EXPR_TYPE_BINOP
:
858 rtn
->un
.binop
.exp1
= DEBUG_CloneExpr(exp
->un
.binop
.exp1
);
859 rtn
->un
.binop
.exp2
= DEBUG_CloneExpr(exp
->un
.binop
.exp2
);
862 rtn
->un
.unop
.exp1
= DEBUG_CloneExpr(exp
->un
.unop
.exp1
);
865 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
866 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
875 * Recursively go through an expression tree and free all memory associated
879 DEBUG_FreeExpr(struct expr
* exp
)
886 DEBUG_FreeExpr(exp
->un
.cast
.expr
);
888 case EXPR_TYPE_INTVAR
:
889 DBG_free((char *) exp
->un
.intvar
.name
);
891 case EXPR_TYPE_US_CONST
:
892 case EXPR_TYPE_CONST
:
894 case EXPR_TYPE_STRING
:
895 DBG_free((char *) exp
->un
.string
.str
);
897 case EXPR_TYPE_SYMBOL
:
898 DBG_free((char *) exp
->un
.symbol
.name
);
900 case EXPR_TYPE_PSTRUCT
:
901 case EXPR_TYPE_STRUCT
:
902 DEBUG_FreeExpr(exp
->un
.structure
.exp1
);
903 DBG_free((char *) exp
->un
.structure
.element_name
);
906 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
908 DEBUG_FreeExpr(exp
->un
.call
.arg
[i
]);
910 DBG_free((char *) exp
->un
.call
.funcname
);
912 case EXPR_TYPE_BINOP
:
913 DEBUG_FreeExpr(exp
->un
.binop
.exp1
);
914 DEBUG_FreeExpr(exp
->un
.binop
.exp2
);
917 DEBUG_FreeExpr(exp
->un
.unop
.exp1
);
920 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
921 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);