Authors: Chris Morgan <cmorgan@wpi.edu>, James Abbatiello <abbeyj@wpi.edu>
[wine] / debugger / expr.c
1 /*
2  * File expr.c - expression handling for Wine internal debugger.
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  *
6  */
7
8 #include "config.h"
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <assert.h>
13 #include "wine/winbase16.h"
14 #include "task.h"
15 #include "debugger.h"
16 #include "expr.h"
17
18 #include <stdarg.h>
19
20 struct expr
21 {
22   unsigned int  perm;
23   unsigned int  type:31;
24   union
25   {
26     struct
27     {
28       int value;
29     } constant;
30
31     struct
32     {
33       const char * str;
34     } string;
35
36     struct
37     {
38       unsigned int value;
39     } u_const;
40
41     struct
42     {
43       const char * name;
44     } symbol;
45
46     struct
47     {
48       enum debug_regs reg;
49       int             result;
50     } rgister;
51
52     struct
53     {
54       int unop_type;
55       struct expr * exp1;
56       int             result;
57     } unop;
58
59     struct
60     {
61       int binop_type;
62       int result;
63       struct expr * exp1;
64       struct expr * exp2;
65     } binop;
66
67     struct
68     {
69       struct datatype * cast;
70       struct expr     * expr;
71     } cast;
72
73     struct
74     {
75       struct expr * exp1;
76       const char * element_name;
77       int result;
78     } structure;
79
80     struct
81     {
82       struct expr * base;
83       struct expr * index;
84     } array;
85
86     struct
87     {
88       const char  * funcname;
89       int           nargs;
90       int           result;
91       struct expr * arg[5];
92     } call;
93
94   } un;
95 };
96
97 #define EXPR_TYPE_CONST         0
98 #define EXPR_TYPE_US_CONST      1
99 #define EXPR_TYPE_SYMBOL        2
100 #define EXPR_TYPE_REGISTER      3
101 #define EXPR_TYPE_BINOP         4
102 #define EXPR_TYPE_UNOP          5
103 #define EXPR_TYPE_STRUCT        6
104 #define EXPR_TYPE_PSTRUCT       7
105 #define EXPR_TYPE_ARRAY         8
106 #define EXPR_TYPE_CALL          9
107 #define EXPR_TYPE_STRING        10
108 #define EXPR_TYPE_CAST          11
109
110 static char expr_list[4096];
111 static int next_expr_free = 0;
112
113 /*
114  * This is how we turn an expression address into the actual value.
115  * This works well in the 32 bit domain - not sure at all about the
116  * 16 bit world.
117  */
118 #define VAL(_exp)       DEBUG_GetExprValue(&_exp, NULL)
119
120 static
121 struct expr *
122 DEBUG_GetFreeExpr()
123 {
124   struct expr * rtn;
125
126   rtn =  (struct expr *) &expr_list[next_expr_free];
127
128   next_expr_free += sizeof(struct expr);
129   assert(next_expr_free < sizeof(expr_list));
130
131   return rtn;
132 }
133
134 void
135 DEBUG_FreeExprMem()
136 {
137   next_expr_free = 0;
138 }
139
140 struct expr *
141 DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
142 {
143   struct expr * ex;
144
145   ex = DEBUG_GetFreeExpr();
146
147   ex->type        = EXPR_TYPE_CAST;
148   ex->un.cast.cast = dt;
149   ex->un.cast.expr = exp;
150   return ex;
151 }
152
153 struct expr *
154 DEBUG_RegisterExpr(enum debug_regs regno)
155 {
156   struct expr * ex;
157
158   ex = DEBUG_GetFreeExpr();
159
160   ex->type        = EXPR_TYPE_REGISTER;
161   ex->un.rgister.reg = regno;
162   return ex;
163 }
164
165 struct expr *
166 DEBUG_SymbolExpr(const char * name)
167 {
168   struct expr * ex;
169
170   ex = DEBUG_GetFreeExpr();
171
172   ex->type        = EXPR_TYPE_SYMBOL;
173   ex->un.symbol.name = name;
174   return ex;
175 }
176
177 struct expr *
178 DEBUG_ConstExpr(int value)
179 {
180   struct expr * ex;
181
182   ex = DEBUG_GetFreeExpr();
183
184   ex->type        = EXPR_TYPE_CONST;
185   ex->un.constant.value = value;
186   return ex;
187 }
188
189 struct expr *
190 DEBUG_StringExpr(const char * str)
191 {
192   struct expr * ex;
193   char * pnt;
194   ex = DEBUG_GetFreeExpr();
195
196   ex->type        = EXPR_TYPE_STRING;
197   ex->un.string.str = str+1;
198   pnt = strrchr(ex->un.string.str, '"');
199   if( pnt != NULL )
200     {
201       *pnt =  '\0';
202     }
203   return ex;
204 }
205
206 struct expr *
207 DEBUG_USConstExpr(unsigned int value)
208 {
209   struct expr * ex;
210
211   ex = DEBUG_GetFreeExpr();
212
213   ex->type           = EXPR_TYPE_CONST;
214   ex->un.u_const.value = value;
215   return ex;
216 }
217
218 struct expr *
219 DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
220 {
221   struct expr * ex;
222
223   ex = DEBUG_GetFreeExpr();
224
225   ex->type           = EXPR_TYPE_BINOP;
226   ex->un.binop.binop_type = operator_type;
227   ex->un.binop.exp1     = exp1;
228   ex->un.binop.exp2     = exp2;
229   return ex;
230 }
231
232 struct expr *
233 DEBUG_UnopExpr(int operator_type, struct expr * exp1)
234 {
235   struct expr * ex;
236
237   ex = DEBUG_GetFreeExpr();
238
239   ex->type           = EXPR_TYPE_UNOP;
240   ex->un.unop.unop_type = operator_type;
241   ex->un.unop.exp1      = exp1;
242   return ex;
243 }
244
245 struct expr *
246 DEBUG_StructExpr(struct expr * exp, const char * element)
247 {
248   struct expr * ex;
249
250   ex = DEBUG_GetFreeExpr();
251
252   ex->type           = EXPR_TYPE_STRUCT;
253   ex->un.structure.exp1 = exp;
254   ex->un.structure.element_name = element;
255   return ex;
256 }
257
258 struct expr *
259 DEBUG_StructPExpr(struct expr * exp, const char * element)
260 {
261   struct expr * ex;
262
263   ex = DEBUG_GetFreeExpr();
264
265   ex->type           = EXPR_TYPE_PSTRUCT;
266   ex->un.structure.exp1 = exp;
267   ex->un.structure.element_name = element;
268   return ex;
269 }
270
271 struct expr *
272 DEBUG_CallExpr(const char * funcname, int nargs, ...)
273 {
274   struct expr * ex;
275   va_list ap;
276   int i;
277
278   ex = DEBUG_GetFreeExpr();
279
280   ex->type           = EXPR_TYPE_CALL;
281   ex->un.call.funcname = funcname;
282   ex->un.call.nargs = nargs;
283
284   va_start(ap, nargs);
285   for(i=0; i < nargs; i++)
286     {
287       ex->un.call.arg[i] = va_arg(ap, struct expr *);
288     }
289   va_end(ap);
290   return ex;
291 }
292
293 DBG_ADDR
294 DEBUG_EvalExpr(struct expr * exp)
295 {
296   DBG_ADDR      rtn;
297   int           i;
298   DBG_ADDR      exp1;
299   DBG_ADDR      exp2;
300   unsigned int  cexp[5];
301   int           (*fptr)();
302   int               scale1;
303   int               scale2;
304   int               scale3;
305   struct datatype * type1;
306   struct datatype * type2;
307
308   rtn.type = NULL;
309   rtn.off = NULL;
310   rtn.seg = NULL;
311
312   switch(exp->type)
313     {
314     case EXPR_TYPE_CAST:
315       rtn = DEBUG_EvalExpr(exp->un.cast.expr);
316       rtn.type = exp->un.cast.cast;
317       break;
318     case EXPR_TYPE_STRING:
319       rtn.type = DEBUG_TypeString;
320       rtn.off = (unsigned int) &exp->un.string.str;
321       rtn.seg = 0;
322       break;
323     case EXPR_TYPE_CONST:
324       rtn.type = DEBUG_TypeIntConst;
325       rtn.off = (unsigned int) &exp->un.constant.value;
326       rtn.seg = 0;
327       break;
328     case EXPR_TYPE_US_CONST:
329       rtn.type = DEBUG_TypeUSInt;
330       rtn.off = (unsigned int) &exp->un.u_const.value;
331       rtn.seg = 0;
332       break;
333     case EXPR_TYPE_SYMBOL:
334       if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE ) )
335         {
336           rtn.type = NULL;
337           rtn.off = 0;
338           rtn.seg = 0;
339         };
340       break;
341     case EXPR_TYPE_PSTRUCT:
342       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
343       if( exp1.type == NULL )
344         {
345           break;
346         }
347       rtn.off = DEBUG_TypeDerefPointer(&exp1, &type1);
348       if( type1 == NULL )
349         {
350           break;
351         }
352       rtn.type = type1;
353       DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
354                               &exp->un.structure.result);
355       break;
356     case EXPR_TYPE_STRUCT:
357       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
358       if( exp1.type == NULL )
359         {
360           break;
361         }
362       rtn = exp1;
363       DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
364                               &exp->un.structure.result);
365       break;
366     case EXPR_TYPE_CALL:
367       /*
368        * First, evaluate all of the arguments.  If any of them are not
369        * evaluable, then bail.
370        */
371       for(i=0; i < exp->un.call.nargs; i++)
372         {
373           exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
374           if( exp1.type == NULL )
375             {
376               return rtn;
377             }
378           cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
379         }
380
381       /*
382        * Now look up the address of the function itself.
383        */
384       if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
385         {
386           fprintf(stderr, "Failed to find symbol\n");
387           break;
388         }
389
390       fptr = (int (*)()) rtn.off;
391       switch(exp->un.call.nargs)
392         {
393         case 0:
394           exp->un.call.result = (*fptr)();
395           break;
396         case 1:
397           exp->un.call.result = (*fptr)(cexp[0]);
398           break;
399         case 2:
400           exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
401           break;
402         case 3:
403           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
404           break;
405         case 4:
406           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
407           break;
408         case 5:
409           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
410           break;
411         }
412       rtn.type = DEBUG_TypeInt;
413       rtn.off = (unsigned int) &exp->un.call.result;
414       break;
415     case EXPR_TYPE_REGISTER:
416       rtn.type = DEBUG_TypeIntConst;
417       exp->un.rgister.result = DEBUG_GetRegister(exp->un.rgister.reg);
418       rtn.off = (unsigned int) &exp->un.rgister.result;
419       if( exp->un.rgister.reg == REG_EIP )
420           rtn.seg = CS_reg(&DEBUG_context);
421       else
422           rtn.seg = DS_reg(&DEBUG_context);
423       DBG_FIX_ADDR_SEG( &rtn, 0 );
424       break;
425     case EXPR_TYPE_BINOP:
426       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
427       exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
428       if( exp1.type == NULL || exp2.type == NULL )
429         {
430           break;
431         }
432       if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
433         {
434           rtn.type = exp1.type;
435         }
436       else
437         {
438           rtn.type = DEBUG_TypeInt;
439         }
440       rtn.off = (unsigned int) &exp->un.binop.result;
441       switch(exp->un.binop.binop_type)
442         {
443         case EXP_OP_ADD:
444           type1 = DEBUG_GetPointerType(exp1.type);
445           type2 = DEBUG_GetPointerType(exp2.type);
446           scale1 = 1;
447           scale2 = 1;
448           if( type1 != NULL && type2 != NULL )
449             {
450               break;
451             }
452           else if( type1 != NULL )
453             {
454               scale2 = DEBUG_GetObjectSize(type1);
455               rtn.type = exp1.type;
456             }
457           else if( type2 != NULL )
458             {
459               scale1 = DEBUG_GetObjectSize(type2);
460               rtn.type = exp2.type;
461             }
462           rtn.seg = 0;
463           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
464           break;
465         case EXP_OP_SUB:
466           type1 = DEBUG_GetPointerType(exp1.type);
467           type2 = DEBUG_GetPointerType(exp2.type);
468           scale1 = 1;
469           scale2 = 1;
470           scale3 = 1;
471           if( type1 != NULL && type2 != NULL )
472             {
473               if( type1 != type2 )
474                 {
475                   break;
476                 }
477               scale3 = DEBUG_GetObjectSize(type1);
478             }
479           else if( type1 != NULL )
480             {
481               scale2 = DEBUG_GetObjectSize(type1);
482               rtn.type = exp1.type;
483             }
484
485           else if( type2 != NULL )
486             {
487               scale1 = DEBUG_GetObjectSize(type2);
488               rtn.type = exp2.type;
489             }
490           rtn.seg = 0;
491           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
492           break;
493         case EXP_OP_SEG:
494           rtn.seg = VAL(exp1);
495           exp->un.binop.result = VAL(exp2);
496           if (ISV86(&DEBUG_context)) {
497             TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
498             rtn.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16;
499             GlobalUnlock16( GetCurrentTask() );
500           }
501           break;
502         case EXP_OP_LOR:
503           rtn.seg = 0;
504           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
505           break;
506         case EXP_OP_LAND:
507           rtn.seg = 0;
508           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
509           break;
510         case EXP_OP_OR:
511           rtn.seg = 0;
512           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
513           break;
514         case EXP_OP_AND:
515           rtn.seg = 0;
516           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
517           break;
518         case EXP_OP_XOR:
519           rtn.seg = 0;
520           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
521           break;
522         case EXP_OP_EQ:
523           rtn.seg = 0;
524           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
525           break;
526         case EXP_OP_GT:
527           rtn.seg = 0;
528           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
529           break;
530         case EXP_OP_LT:
531           rtn.seg = 0;
532           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
533           break;
534         case EXP_OP_GE:
535           rtn.seg = 0;
536           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
537           break;
538         case EXP_OP_LE:
539           rtn.seg = 0;
540           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
541           break;
542         case EXP_OP_NE:
543           rtn.seg = 0;
544           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
545           break;
546         case EXP_OP_SHL:
547           rtn.seg = 0;
548           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
549           break;
550         case EXP_OP_SHR:
551           rtn.seg = 0;
552           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
553           break;
554         case EXP_OP_MUL:
555           rtn.seg = 0;
556           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
557           break;
558         case EXP_OP_DIV:
559           if( VAL(exp2) != 0 )
560             {
561               rtn.seg = 0;
562               exp->un.binop.result = (VAL(exp1) / VAL(exp2));
563             }
564           else
565             {
566               rtn.seg = 0;
567               rtn.type = NULL;
568               rtn.off = 0;
569             }
570           break;
571         case EXP_OP_REM:
572           if( VAL(exp2) != 0 )
573             {
574               rtn.seg = 0;
575               exp->un.binop.result = (VAL(exp1) % VAL(exp2));
576             }
577           else
578             {
579               rtn.seg = 0;
580               rtn.type = NULL;
581               rtn.off = 0;
582             }
583           break;
584         case EXP_OP_ARR:
585           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
586           break;
587         default:
588           break;
589         }
590       break;
591     case EXPR_TYPE_UNOP:
592       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
593       if( exp1.type == NULL )
594         {
595           break;
596         }
597       rtn.off = (unsigned int) &exp->un.unop.result;
598       if( exp1.type == DEBUG_TypeIntConst )
599         {
600           rtn.type = exp1.type;
601         }
602       else
603         {
604           rtn.type = DEBUG_TypeInt;
605         }
606       switch(exp->un.unop.unop_type)
607         {
608         case EXP_OP_NEG:
609           rtn.seg = 0;
610           exp->un.unop.result = -VAL(exp1);
611           break;
612         case EXP_OP_NOT:
613           rtn.seg = 0;
614           exp->un.unop.result = !VAL(exp1);
615           break;
616         case EXP_OP_LNOT:
617           rtn.seg = 0;
618           exp->un.unop.result = ~VAL(exp1);
619           break;
620         case EXP_OP_DEREF:
621           rtn.seg = 0;
622           rtn.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
623           break;
624         case EXP_OP_FORCE_DEREF:
625           rtn.seg = exp1.seg;
626           rtn.off = *(unsigned int *) exp1.off;
627           break;
628         case EXP_OP_ADDR:
629           rtn.seg = 0;
630           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
631           exp->un.unop.result = exp1.off;
632           break;
633         }
634       break;
635     default:
636       fprintf(stderr,"Unexpected expression.\n");
637       exit(123);
638       break;
639     }
640
641   return rtn;
642 }
643
644
645 int
646 DEBUG_DisplayExpr(struct expr * exp)
647 {
648   int           i;
649
650
651   switch(exp->type)
652     {
653     case EXPR_TYPE_CAST:
654       fprintf(stderr, "((");
655       DEBUG_PrintTypeCast(exp->un.cast.cast);
656       fprintf(stderr, ")");
657       DEBUG_DisplayExpr(exp->un.cast.expr);
658       fprintf(stderr, ")");
659       break;
660     case EXPR_TYPE_REGISTER:
661       DEBUG_PrintRegister(exp->un.rgister.reg);
662       break;
663     case EXPR_TYPE_US_CONST:
664       fprintf(stderr, "%ud", exp->un.u_const.value);
665       break;
666     case EXPR_TYPE_CONST:
667       fprintf(stderr, "%d", exp->un.u_const.value);
668       break;
669     case EXPR_TYPE_STRING:
670       fprintf(stderr, "\"%s\"", exp->un.string.str);
671       break;
672     case EXPR_TYPE_SYMBOL:
673       fprintf(stderr, "%s" , exp->un.symbol.name);
674       break;
675     case EXPR_TYPE_PSTRUCT:
676       DEBUG_DisplayExpr(exp->un.structure.exp1);
677       fprintf(stderr, "->%s", exp->un.structure.element_name);
678       break;
679     case EXPR_TYPE_STRUCT:
680       DEBUG_DisplayExpr(exp->un.structure.exp1);
681       fprintf(stderr, ".%s", exp->un.structure.element_name);
682       break;
683     case EXPR_TYPE_CALL:
684       /*
685        * First, evaluate all of the arguments.  If any of them are not
686        * evaluable, then bail.
687        */
688       fprintf(stderr, "%s(",exp->un.call.funcname);
689       for(i=0; i < exp->un.call.nargs; i++)
690         {
691           DEBUG_DisplayExpr(exp->un.call.arg[i]);
692           if( i != exp->un.call.nargs - 1 )
693             {
694               fprintf(stderr, ", ");
695             }
696         }
697       fprintf(stderr, ")");
698       break;
699     case EXPR_TYPE_BINOP:
700       fprintf(stderr, "( ");
701       DEBUG_DisplayExpr(exp->un.binop.exp1);
702       switch(exp->un.binop.binop_type)
703         {
704         case EXP_OP_ADD:
705           fprintf(stderr, " + ");
706           break;
707         case EXP_OP_SUB:
708           fprintf(stderr, " - ");
709           break;
710         case EXP_OP_SEG:
711           fprintf(stderr, ":");
712           break;
713         case EXP_OP_LOR:
714           fprintf(stderr, " || ");
715           break;
716         case EXP_OP_LAND:
717           fprintf(stderr, " && ");
718           break;
719         case EXP_OP_OR:
720           fprintf(stderr, " | ");
721           break;
722         case EXP_OP_AND:
723           fprintf(stderr, " & ");
724           break;
725         case EXP_OP_XOR:
726           fprintf(stderr, " ^ ");
727           break;
728         case EXP_OP_EQ:
729           fprintf(stderr, " == ");
730           break;
731         case EXP_OP_GT:
732           fprintf(stderr, " > ");
733           break;
734         case EXP_OP_LT:
735           fprintf(stderr, " < ");
736           break;
737         case EXP_OP_GE:
738           fprintf(stderr, " >= ");
739           break;
740         case EXP_OP_LE:
741           fprintf(stderr, " <= ");
742           break;
743         case EXP_OP_NE:
744           fprintf(stderr, " != ");
745           break;
746         case EXP_OP_SHL:
747           fprintf(stderr, " << ");
748           break;
749         case EXP_OP_SHR:
750           fprintf(stderr, " >> ");
751           break;
752         case EXP_OP_MUL:
753           fprintf(stderr, " * ");
754           break;
755         case EXP_OP_DIV:
756           fprintf(stderr, " / ");
757           break;
758         case EXP_OP_REM:
759           fprintf(stderr, " %% ");
760           break;
761         case EXP_OP_ARR:
762           fprintf(stderr, "[");
763           break;
764         default:
765           break;
766         }
767       DEBUG_DisplayExpr(exp->un.binop.exp2);
768       if( exp->un.binop.binop_type == EXP_OP_ARR )
769         {
770           fprintf(stderr, "]");
771         }
772       fprintf(stderr, " )");
773       break;
774     case EXPR_TYPE_UNOP:
775       switch(exp->un.unop.unop_type)
776         {
777         case EXP_OP_NEG:
778           fprintf(stderr, "-");
779           break;
780         case EXP_OP_NOT:
781           fprintf(stderr, "!");
782           break;
783         case EXP_OP_LNOT:
784           fprintf(stderr, "~");
785           break;
786         case EXP_OP_DEREF:
787           fprintf(stderr, "*");
788           break;
789         case EXP_OP_ADDR:
790           fprintf(stderr, "&");
791           break;
792         }
793       DEBUG_DisplayExpr(exp->un.unop.exp1);
794       break;
795     default:
796       fprintf(stderr,"Unexpected expression.\n");
797       exit(123);
798       break;
799     }
800
801   return TRUE;
802 }
803
804 struct expr *
805 DEBUG_CloneExpr(struct expr * exp)
806 {
807   int           i;
808   struct expr * rtn;
809
810   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
811
812   /*
813    * First copy the contents of the expression itself.
814    */
815   *rtn = *exp;
816
817
818   switch(exp->type)
819     {
820     case EXPR_TYPE_CAST:
821       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
822       break;
823     case EXPR_TYPE_REGISTER:
824     case EXPR_TYPE_US_CONST:
825     case EXPR_TYPE_CONST:
826       break;
827     case EXPR_TYPE_STRING:
828       rtn->un.string.str = DBG_strdup(exp->un.string.str);
829       break;
830     case EXPR_TYPE_SYMBOL:
831       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
832       break;
833     case EXPR_TYPE_PSTRUCT:
834     case EXPR_TYPE_STRUCT:
835       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
836       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
837       break;
838     case EXPR_TYPE_CALL:
839       /*
840        * First, evaluate all of the arguments.  If any of them are not
841        * evaluable, then bail.
842        */
843       for(i=0; i < exp->un.call.nargs; i++)
844         {
845           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
846         }
847       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
848       break;
849     case EXPR_TYPE_BINOP:
850       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
851       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
852       break;
853     case EXPR_TYPE_UNOP:
854       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
855       break;
856     default:
857       fprintf(stderr,"Unexpected expression.\n");
858       exit(123);
859       break;
860     }
861
862   return rtn;
863 }
864
865
866 /*
867  * Recursively go through an expression tree and free all memory associated
868  * with it.
869  */
870 int
871 DEBUG_FreeExpr(struct expr * exp)
872 {
873   int i;
874
875   switch(exp->type)
876     {
877     case EXPR_TYPE_CAST:
878       DEBUG_FreeExpr(exp->un.cast.expr);
879       break;
880     case EXPR_TYPE_REGISTER:
881     case EXPR_TYPE_US_CONST:
882     case EXPR_TYPE_CONST:
883       break;
884     case EXPR_TYPE_STRING:
885       DBG_free((char *) exp->un.string.str);
886       break;
887     case EXPR_TYPE_SYMBOL:
888       DBG_free((char *) exp->un.symbol.name);
889       break;
890     case EXPR_TYPE_PSTRUCT:
891     case EXPR_TYPE_STRUCT:
892       DEBUG_FreeExpr(exp->un.structure.exp1);
893       DBG_free((char *) exp->un.structure.element_name);
894       break;
895     case EXPR_TYPE_CALL:
896       /*
897        * First, evaluate all of the arguments.  If any of them are not
898        * evaluable, then bail.
899        */
900       for(i=0; i < exp->un.call.nargs; i++)
901         {
902           DEBUG_FreeExpr(exp->un.call.arg[i]);
903         }
904       DBG_free((char *) exp->un.call.funcname);
905       break;
906     case EXPR_TYPE_BINOP:
907       DEBUG_FreeExpr(exp->un.binop.exp1);
908       DEBUG_FreeExpr(exp->un.binop.exp2);
909       break;
910     case EXPR_TYPE_UNOP:
911       DEBUG_FreeExpr(exp->un.unop.exp1);
912       break;
913     default:
914       fprintf(stderr,"Unexpected expression.\n");
915       exit(123);
916       break;
917     }
918
919   DBG_free(exp);
920   return TRUE;
921 }