compiler/pass15; ide/debugger: Fixed evaluation of class("abc" + 1) and indexing...
[sdk] / ide / src / debugger / debugTools.ec
1 import "ide"
2
3 static void CarryExpressionError(Expression exp, Expression expError)
4 {
5    Expression temp { };
6
7    // This function assumes that expError is contained within exp,
8    // and therefore these types will be freed when freeing the old contents
9    // of the expression we're carying into.
10
11    if(expError.destType) expError.destType.refCount++;
12    if(expError.expType) expError.expType.refCount++;
13
14    *temp = *expError;
15
16    // -- Careful: this could be problematic as FreeExpContents will free the contents of expError
17    // Nulling things that may be freed now, but this is all overly messy/complex
18    switch(expError.type)
19    {
20       case symbolErrorExp:
21          expError.identifier = null;
22          break;
23       case memoryErrorExp:
24          expError.constant = null;
25          break;
26       case memberSymbolErrorExp:
27          expError.member.exp = null;
28          expError.member.member = null;
29          break;
30    }
31
32    /*
33    Identifier identifier = expError.identifier;
34    expError.identifier = null;
35    FreeExpContents(exp);
36    exp.identifier = identifier;
37    exp.type = expError.type;
38    */
39    if(exp.expType) FreeType(exp.expType);
40    if(exp.destType) FreeType(exp.destType);
41    FreeExpContents(exp);
42    *exp = *temp; //*expError;
43    delete temp;
44    // memset(expError, 0, sizeof(class Expression));
45 }
46
47 static char GetGdbFormatChar(Type type)
48 {
49 //          x : Regard the bits of the value as an integer, and print the integer in hexadecimal.
50 //          d : Print as integer in signed decimal.
51 //          u : Print as integer in unsigned decimal.
52 //          o : Print as integer in octal.
53 //          t : Print as integer in binary. The letter `t' stands for "two". (4)
54 //          a : Print as an address, both absolute in hexadecimal and as an offset from the nearest preceding symbol. You can use this format used to discover where (in what function) an unknown address is located:
55 //          c : Regard as an integer and print it as a character constant. This prints both the numerical value and its character representation. The character representation is replaced with the octal escape `\nnn' for characters outside the 7-bit ASCII range.
56 //          f : Regard the bits of the value as a floating point number and print using typical floating point syntax.
57    if(!type)
58       return 'x';
59
60    switch(type.kind)
61    {
62       case charType:
63          //return 'c';
64       case shortType:
65       case intType:
66       case longType:
67       case int64Type:
68          if(type.isSigned)
69             return 'd';
70          else
71             return 'u';
72       case floatType:
73          return 'f';
74       case doubleType:
75          return 'f';
76       case structType:
77       case unionType:
78       case functionType:
79       case arrayType:
80          // return 'u';
81          return 0;
82       case ellipsisType:
83       case enumType:
84       case methodType:
85       case vaListType:
86       // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
87       case dummyType:
88          break;
89       case classType:
90       case pointerType:
91          return 'x';
92    }
93    return 'x';
94 }
95
96 /*static */bool ExpressionIsError(Expression exp)
97 {
98    return (exp.type == dereferenceErrorExp || exp.type == symbolErrorExp ||
99          exp.type == memberSymbolErrorExp || exp.type == memoryErrorExp || exp.type == unknownErrorExp ||
100          exp.type == noDebuggerErrorExp);
101 }
102
103 void DebugComputeExpression(Expression exp)
104 {
105 #ifdef _DEBUG
106    char expString[1024] = "";
107    //char temp[1024];
108    //if(inCompiler)
109       PrintExpression(exp, expString);
110    // printf("%s (exp.type = %s)\n", expString, exp.type.OnGetString(temp, null, null));
111 #endif
112    switch(exp.type)
113    {
114       case identifierExp:
115       {
116          Expression prev = exp.prev, next = exp.next;
117          char * evaluation = null;
118          ExpressionType evalError = dummyExp;
119          Expression expNew;
120          TypeKind kind = dummyType;
121          Type dataType = exp.expType;
122
123          char temp[1024];
124          uint64 address;
125          bool hasAddress;
126          bool isPointer = false;
127
128          if(dataType && dataType.kind == classType && dataType._class.registered)
129          {
130             Class _class = dataType._class.registered;
131             if(_class.type == bitClass || _class.type == unitClass || _class.type == enumClass)
132             {
133                if(!_class.dataType)
134                   _class.dataType = ProcessTypeString(_class.dataTypeString, false);
135                dataType = _class.dataType;
136             }
137             else if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass) // Added systemClass here for Instance
138             {
139                isPointer = true;
140             }
141          }
142          else if(dataType && dataType.kind == classType && !dataType._class.registered)
143             isPointer = true;
144          if(dataType)
145             kind = dataType.kind;
146          else
147             exp.type = symbolErrorExp;
148          temp[0] = '\0';
149          switch(kind)
150          {
151             case intPtrType: case intSizeType: case _BoolType:
152             case charType: case shortType: case intType: case int64Type: case longType: case floatType: case doubleType:
153             case enumType:
154             case arrayType:
155             case structType:
156             case pointerType:
157             case unionType:
158                sprintf(temp, "&%s", exp.identifier.string);
159                break;
160             case classType:
161                if(exp.byReference && dataType._class && dataType._class.registered && dataType._class.registered.type == structClass)
162                // if(!dataType._class || !dataType._class.registered || dataType._class.registered.type != structClass || exp.byReference)
163                   strcpy(temp, exp.identifier.string);
164                else
165                   sprintf(temp, "&%s", exp.identifier.string);
166                break;
167             case functionType:
168             case ellipsisType:
169             case methodType:
170             case vaListType:
171             // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
172             case dummyType:
173                break;
174          }
175          if(temp[0])
176          {
177             evaluation = Debugger::EvaluateExpression(temp, &evalError);
178             if(evaluation)
179             {
180                address = _strtoui64(evaluation, null, 0);
181                //delete evaluation;
182                //evaluation = null;
183             }
184             else
185                address = 0;
186             hasAddress = true;
187          }
188          else
189             hasAddress = false;
190
191          if(evalError == dummyExp)
192          {
193             switch(kind)
194             {
195                case charType:
196                   delete evaluation;
197                   evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
198                   if(evaluation)
199                   {
200                      //int c, len;
201                      char * temp;
202                      temp = strstr(evaluation, " '");
203                      //len = strlen(temp);
204                      if(temp)
205                         temp[0] = '\0';
206                      {/*
207                         for(c = 0; c < len; c++)
208                            temp[c] = ' ';
209                         eString_TrimRSpaces(evaluation, evaluation);
210                      */}
211                   }
212                   break;
213                case shortType:
214                case intType:
215                case longType:
216                case intPtrType:
217                case intSizeType:
218                case _BoolType:
219                case int64Type:
220                case floatType:
221                case doubleType:
222                case enumType:
223                case pointerType:
224                   delete evaluation;
225                   evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
226                   if(evaluation)
227                   {
228                      if(kind == pointerType)
229                      {
230                         uint64 value;
231                         value = _strtoui64(evaluation, null, 0);
232                         delete evaluation;
233                         evaluation = PrintHexUInt64(value);
234                      }
235                   }
236                   break;
237                case classType:
238                   if(isPointer)
239                   {
240                      int size;
241                      char format;
242                      delete evaluation;
243                      //evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
244                      size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
245                      format = GetGdbFormatChar(exp.expType);
246                      evaluation = Debugger::ReadMemory(address, size, format, &evalError);
247                      if(evaluation)
248                         StripQuotes(evaluation, evaluation);
249                   }
250                   break;
251                case structType:
252                case unionType:
253                case functionType:
254                   //evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
255                   delete evaluation;
256                   break;
257                case arrayType:
258                {
259                   // for classType  --> if(_class.type == structClass) ?
260                   //char temp[1024];
261                   //sprintf(temp, "&%s", exp.identifier.string);
262                   //evaluation = Debugger::EvaluateExpression(temp, &evalError);
263                   break;
264                }
265                case ellipsisType:
266                case methodType:
267                case vaListType:
268                // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
269                case dummyType:
270                   delete evaluation;
271                   evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
272                   break;
273             }
274          }
275          switch(evalError)
276          {
277             case dummyExp:
278                if(evaluation)
279                {
280                   //expNew = ParseExpressionString(evaluation);
281                   expNew = MkExpConstant(evaluation);
282                   //printf("Evaluation = %s\n", evaluation);
283                   delete evaluation;
284                   expNew.destType = exp.expType;
285
286                   // WHY EXACTLY MUST WE PROCESS THIS EXPRESSION TYPE AGAIN ? ADDED THIS FOR 0x00000000
287                   if(exp.expType && (exp.expType.kind == pointerType || exp.expType.kind == classType) && expNew.destType)
288                   {
289                      expNew.expType = expNew.destType;
290                      expNew.destType.refCount++;
291                   }
292                   else
293                      ProcessExpressionType(expNew);
294                   FreeType(exp.destType);
295                   FreeExpContents(exp);
296
297                   DebugComputeExpression(expNew);
298                   expNew.prev = prev;
299                   expNew.next = next;
300                   expNew.isConstant = true;
301                   expNew.address = address;
302                   expNew.hasAddress = hasAddress;
303                   *exp = *expNew;
304                   delete expNew;
305                }
306                else
307                {
308                   // Unhandled code path, evaluation is null
309                   FreeExpContents(exp);
310                   exp.type = unknownErrorExp;
311                }
312                break;
313             case symbolErrorExp:
314                // Keep the identifier
315                exp.type = evalError;
316                break;
317             default:
318                FreeExpContents(exp);
319                exp.type = evalError;
320                break;
321          }
322          break;
323       }
324       case instanceExp:
325       {
326          ComputeInstantiation(exp);
327          break;
328       }
329       /*
330       case constantExp:
331          break;
332       */
333       case opExp:
334       {
335          Expression expError = null;
336          Expression exp1, exp2 = null;
337          Operand op1 = { 0 }, op2 = { 0 };
338
339          /*
340          if(exp.op.op == '&' || exp.op.op == '*')
341          {
342             if(!exp.op.exp1 && exp.op.exp2)
343             {
344                if(exp.op.exp2.type == identifierExp)
345                {
346                   Expression prev = exp.prev, next = exp.next;
347                   char * evaluation = null;
348                   ExpressionType evalError = dummyExp;
349                   Expression expNew;
350                   char temp[1024];
351                   sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.identifier.string);
352                   evaluation = Debugger::EvaluateExpression(temp, &evalError);
353                   if(evalError != dummyExp)
354                   {
355                      exp.type = evalError;
356                      exp.constant = CopyString("");
357                   }
358                   else if(evaluation)
359                   {
360                      expNew = ParseExpressionString(evaluation);
361                      delete evaluation;
362                      expNew.destType = exp.expType;
363                      FreeType(exp.destType);
364                      FreeExpContents(exp);
365                      ProcessExpressionType(expNew);
366                      DebugComputeExpression(expNew);
367                      expNew.prev = prev;
368                      expNew.next = next;
369                      expNew.isConstant = true;
370                      *exp = *expNew;
371                      delete expNew;
372                   }
373                   else
374                      exp.type = ExpUnknownError;
375                   break;
376                }
377                //else
378                {
379                   uint64 address;
380                   int size;
381                   char format;
382                   if(exp.op.op == '*')
383                   {
384                   DebugComputeExpression(exp.op.exp2);
385                   size = ComputeTypeSize(exp.op.exp2.expType);
386                   format = GetGdbFormatChar(exp.op.exp2.expType);
387                   GetInt(exp.op.exp2, &address);
388                   //sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.constant);
389                   evaluation = Debug_ReadMemory(address, size, format, &evalError);
390                   }
391                   else
392                      evalError = ExpUnknownError;
393                }
394             }
395          }
396          */
397
398          // We don't care about operations with only exp2 (INC_OP, DEC_OP...)
399          if(exp.op.exp2)
400          {
401             Expression e = exp.op.exp2;
402
403             while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
404             {
405                if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
406                {
407                   if(e.type == extensionCompoundExp)
408                      e = ((Statement)e.compound.compound.statements->last).expressions->last;
409                   else
410                      e = e.list->last;
411                }
412                else if(e.type == castExp)
413                   e = e.cast.exp;
414             }
415             if(exp.op.op == TokenType::sizeOf && e && e.expType)
416             {
417                if(e.type == stringExp && e.string)
418                {
419                   char * string = e.string;
420                   int len = strlen(string);
421                   char * tmp = new char[len-2+1];
422                   len = UnescapeString(tmp, string + 1, len - 2);
423                   delete tmp;
424                   FreeExpContents(exp);
425                   exp.type = constantExp;
426                   exp.constant = PrintUInt(len + 1);
427                }
428                else
429                {
430                   Type type = e.expType;
431                   type.refCount++;
432                   FreeExpContents(exp);
433                   exp.type = constantExp;
434                   exp.constant = PrintUInt(ComputeTypeSize(type));
435                   FreeType(type);
436                }
437                break;
438             }
439             else
440             {
441                DebugComputeExpression(exp.op.exp2);
442                if(ExpressionIsError(exp.op.exp2))
443                   expError = exp.op.exp2;
444             }
445          }
446          if(!expError)
447          {
448             if(exp.op.exp1)
449             {
450                DebugComputeExpression(exp.op.exp1);
451                if(ExpressionIsError(exp.op.exp1))
452                   expError = exp.op.exp1;
453                else
454                {
455                   if(exp.op.exp2)
456                   {
457                      if(ExpressionIsError(exp.op.exp2))
458                         expError = exp.op.exp2;
459                      else
460                      {
461                         exp1 = exp.op.exp1;
462                         exp2 = exp.op.exp2;
463                         op1 = GetOperand(exp1);
464                         if(op1.type) op1.type.refCount++;
465                         op2 = GetOperand(exp2);
466                         if(op2.type) op2.type.refCount++;
467                      }
468                   }
469                }
470             }
471             else if(exp.op.exp2)
472             {
473                if(ExpressionIsError(exp.op.exp2))
474                   expError = exp.op.exp2;
475                else
476                {
477                   exp1 = exp.op.exp2;
478                   if(exp.op.op == '&' || exp.op.op == '*')
479                   {
480                      Expression prev = exp1.prev, next = exp1.next;
481                      Expression expNew;
482                      ExpressionType evalError = dummyExp;
483                      char * evaluation = null;
484                      if(exp.op.op == '&')
485                      {
486                         if(exp1.hasAddress)
487                         {
488                            char * temp;
489                            //sprintf(temp, "%u", exp1.address);
490                            temp = PrintHexUInt64(exp1.address);
491                            expNew = ParseExpressionString(temp);
492                            delete temp;
493                            //expNew.address = exp1.address;
494                            expNew.expType = exp.expType;
495                            /*
496                            expNew.destType = exp.expType;
497                            expNew.destType.refCount++;
498                            */
499                            FreeType(exp.destType);
500                            FreeExpContents(exp);
501                            ProcessExpressionType(expNew);
502                            DebugComputeExpression(expNew);
503                            expNew.prev = prev;
504                            expNew.next = next;
505                            expNew.isConstant = true;
506                            *exp = *expNew;
507                            delete expNew;
508                         }
509                         else
510                            exp1.address = 0;
511                      }
512                      else if(exp.op.op == '*')
513                      {
514                         if(!exp.expType)
515                         {
516                            delete evaluation;
517                            FreeExpContents(exp1);
518                            exp1.type = dereferenceErrorExp;
519                            expError = exp1;
520                         }
521                         else
522                         {
523                            uint64 address;
524                            int size;
525                            char format;
526                            if(exp1.expType.kind == structType)
527                               address = exp1.address;
528                            else
529                               GetUInt64(exp1, &address);
530                            size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
531                            format = GetGdbFormatChar(exp.expType);
532                            if(format)
533                            {
534                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
535                               switch(evalError)
536                               {
537                                  case dummyExp:
538                                     if(evaluation)
539                                     {
540                                        expNew = ParseExpressionString(evaluation);
541                                        expNew.address = address;
542                                        expNew.hasAddress = true;
543                                        delete evaluation;
544                                        expNew.destType = exp.expType;
545                                        FreeType(exp.destType);
546                                        FreeExpContents(exp);
547                                        ProcessExpressionType(expNew);
548                                        DebugComputeExpression(expNew);
549                                        expNew.prev = prev;
550                                        expNew.next = next;
551                                        expNew.isConstant = true;
552                                        *exp = *expNew;
553                                        delete expNew;
554                                     }
555                                     else
556                                     {
557                                        // Unhandled code path, evaluation is null
558                                        FreeExpContents(exp);
559                                        exp.type = unknownErrorExp;
560                                     }
561                                     break;
562                                  case memoryErrorExp:
563                                     delete evaluation;
564                                     FreeExpContents(exp1);
565                                     exp1.type = evalError;
566                                     exp1.constant = PrintHexUInt64(address);
567                                     expError = exp1;
568                                     break;
569                                  default:
570                                     delete evaluation;
571                                     FreeExpContents(exp1);
572                                     exp1.type = evalError;
573                                     expError = exp1;
574                                     break;
575
576                               }
577                            }
578                            else
579                            {
580                               FreeExpContents(exp1);
581                               exp1.type = unknownErrorExp;  // Not supported yet, generate error to fallback to GDB printout
582                               expError = exp1;
583                            }
584                         }
585                      }
586                   }
587                   else
588                      op1 = GetOperand(exp1);
589                   if(op1.type) op1.type.refCount++;
590                }
591             }
592          }
593          if(expError)
594             CarryExpressionError(exp, expError);
595          else if(exp.type == opExp)
596          {
597             // TODO: check condition
598             if((exp.op.op == '+' || exp.op.op == '-') && op1.type && op2.type &&
599                (op1.type.kind == arrayType || op1.type.kind == pointerType) && op2.type.kind == intType)
600             {
601                // TODO: Do pointer operations
602                if(exp1.expType && exp1.expType.type)
603                {
604                   if(exp1.type == stringExp)
605                   {
606                      uint64 offset = (exp.op.op == '+') ? op2.i64 : -op2.i64;
607                      String newString = null;
608                      if(exp1.string)
609                      {
610                         int len = strlen(exp1.string) - 2;
611                         char * tmp = OffsetEscapedString(exp1.string + 1, len, (int)offset);
612                         if(tmp)
613                         {
614                            len -= tmp - (exp1.string + 1);
615                            newString = new char[2 + len];
616                            newString[0] = '\"';
617                            memcpy(newString + 1, tmp, len);
618                            newString[1 + len] = '\"';
619                            newString[1 + len + 1] = 0;
620                         }
621                      }
622                      FreeExpContents(exp);
623                      if(newString)
624                      {
625                         exp.type = stringExp;
626                         exp.string = newString;
627                      }
628                      else
629                         exp.type = dereferenceErrorExp;
630                   }
631                   else
632                   {
633                      uint size = ComputeTypeSize(exp1.expType.type);
634                      if(size)
635                      {
636                         op1.ui64 /= exp1.expType.type.size;
637                         CallOperator(exp, exp1, exp2, op1, op2);
638                         if(exp.type == constantExp)
639                         {
640                            exp.address = _strtoui64(exp.constant, null, 0);
641                            exp.address *= size;
642                            if(op1.type.kind == arrayType)
643                               exp.hasAddress = true;
644                         }
645                      }
646                   }
647                }
648             }
649             else
650             {
651                if((exp1 && exp1.type == stringExp) || (exp2 && exp2.type == stringExp))
652                {
653                   FreeExpContents(exp);
654                   exp.type = unknownErrorExp;   // We should have an invalid operands error
655                }
656                else
657                   CallOperator(exp, exp1, exp2, op1, op2);
658             }
659             if(op1.type) FreeType(op1.type);
660             if(op2.type) FreeType(op2.type);
661             exp.isConstant = true;
662          }
663          break;
664       }
665       case bracketsExp:
666       {
667          Expression e, n;
668          //for(
669          //   e = (*exp.list).first, n = e ? e.next : null;
670          //   e;
671          //   e = n, n = n?(n.next) : null)
672
673          for(e = exp.list->first; e; e = n)
674          {
675             n = e.next;
676             if(!n)
677             {
678                OldList * list = exp.list;
679                DebugComputeExpression(e);
680                //if(ExpressionIsError(e)) //.type == ExpSymbolError
681                //   CarryExpressionError(exp, e);
682                //FreeExpContents(exp);
683                FreeType(exp.expType);
684                FreeType(exp.destType);
685                *exp = *e;
686                delete e;
687                delete list;
688             }
689             else
690             {
691                FreeExpression(e);
692             }
693          }
694          break;
695       }
696       case indexExp:
697       {
698          int size;
699          char format;
700          Expression e;
701          exp.isConstant = true;
702
703          DebugComputeExpression(exp.index.exp);
704          if(ExpressionIsError(exp.index.exp)) //.type == ExpSymbolError
705             CarryExpressionError(exp, exp.index.exp);
706          else
707          {
708             Expression prev = exp.prev, next = exp.next;
709             char * evaluation = null;
710             ExpressionType evalError = dummyExp;
711
712             if(!exp.index.exp.isConstant)
713                exp.isConstant = false;
714
715             // int r[0]
716             // 4 == size = ComputeTypeSize(exp.expType);
717             // 0 == size = ComputeTypeSize(exp.expType.arrayType);
718             // 4 == size = ComputeTypeSize(exp.index.exp.expType);
719             // 0 == size = ComputeTypeSize(exp.index.exp.expType.arrayType);
720
721             size = ComputeTypeSize(exp.expType);
722             if(exp.expType && exp.expType.type && exp.expType.kind == arrayType)
723                // For multilevels arrays
724                format = 'x';
725             else
726                format = GetGdbFormatChar(exp.expType);
727
728             for(e = exp.index.index->first; e; e = e.next)
729             {
730                DebugComputeExpression(e);
731                if(ExpressionIsError(e)) //.type == ExpSymbolError
732                {
733                   CarryExpressionError(exp, e);
734                   break;
735                }
736                if(!e.next)
737                {
738                   // Check if this type is int
739                }
740                if(!e.isConstant)
741                   exp.isConstant = false;
742             }
743             if(!ExpressionIsError(exp))
744             {
745                // Is this necessary here? pass15 had done this already...
746                if(exp.expType) FreeType(exp.expType);
747                exp.expType = Dereference(exp.index.exp.expType);
748
749                if(!exp.expType)
750                {
751                   delete evaluation;
752                   FreeExpContents(exp);
753                   exp.type = dereferenceErrorExp;
754                }
755                else if(exp.index.index && exp.index.index->last && ((Expression)exp.index.index->last) && ((Expression)exp.index.index->last).expType)
756                {
757                   Type type = ((Expression)exp.index.index->last).expType;
758                   if(type.kind == intType || type.kind == charType || type.kind == shortType || type.kind == int64Type || type.kind == intPtrType ||
759                      type.kind == intSizeType || type.kind == longType || type.kind == _BoolType || type.kind == enumType ||
760                         (type.kind == classType && type._class && type._class.registered &&
761                            type._class.registered.type == enumClass))
762                   {
763                      uint64 address = 0, offset = 0;
764                      Expression expNew, last = (Expression)exp.index.index->last;
765                      //GetUInt(exp.index.exp, &address);
766
767                      // TOFIX: Check if it has address: TESTING
768                      if(exp.index.exp.hasAddress && (exp.index.exp.expType.kind == arrayType))
769                         address = exp.index.exp.address;
770                      else if(exp.index.exp.type == constantExp)
771                         GetUInt64(exp.index.exp, &address);
772
773                      GetUInt64(last, &offset);
774                      //size = ComputeTypeSize(exp.expType.arrayType); //exp.expType.arrayType.size;
775                      address += offset * size;
776                      if(exp.index.exp.type == stringExp)
777                      {
778                         String string = exp.index.exp.string;
779                         bool valid = false;
780                         char ch = 0;
781                         char * tmp = null;
782                         if(string)
783                         {
784                            int len = string ? strlen(string) : 0;
785                            tmp = new char[len-2+1];
786                            len = UnescapeString(tmp, string + 1, len - 2);
787                            if(len >= 0 && offset <= len)
788                            {
789                               ch = offset < len ? tmp[offset] : 0;
790                               valid = true;
791                            }
792                            delete tmp;
793                         }
794                         FreeExpContents(exp);
795                         if(valid)
796                         {
797                            exp.type = constantExp;
798                            exp.constant = PrintChar(ch);
799                         }
800                         else
801                            exp.type = dereferenceErrorExp;
802                      }
803                      else if(exp.expType.kind == arrayType)
804                      {
805                         FreeExpContents(exp);
806                         exp.type = constantExp;
807                         exp.isConstant = true;
808                         exp.constant = PrintHexUInt64(address);
809                         exp.address = address;
810                         exp.hasAddress = true;
811                      }
812                      else
813                      {
814                         evaluation = Debugger::ReadMemory(address, size, format, &evalError);
815                         switch(evalError)
816                         {
817                            case dummyExp:
818                               if(evaluation)
819                               {
820                                  expNew = ParseExpressionString(evaluation);
821                                  delete evaluation;
822                                  expNew.destType = exp.expType;
823                                  FreeType(exp.destType);
824                                  FreeExpContents(exp);
825                                  ProcessExpressionType(expNew);
826                                  DebugComputeExpression(expNew);
827
828                                  // TOFIX: Only for Array Types
829                                  expNew.address = address;
830
831                                  expNew.hasAddress = true;
832                                  expNew.prev = prev;
833                                  expNew.next = next;
834                                  expNew.isConstant = true;
835                                  *exp = *expNew;
836                                  delete expNew;
837                               }
838                               else
839                               {
840                                  // Unhandled code path, evaluation is null
841                                  FreeExpContents(exp);
842                                  exp.type = unknownErrorExp;
843                               }
844                               break;
845                            case memoryErrorExp:
846                               delete evaluation;
847                               FreeExpContents(exp);
848                               exp.type = evalError;
849                               exp.constant = PrintHexUInt64(address);
850                               break;
851                            default:
852                               delete evaluation;
853                               FreeExpContents(exp);
854                               exp.type = evalError;
855                               break;
856                         }
857                      }
858                   }
859                }
860             }
861          }
862          break;
863       }
864       case memberExp:
865       {
866          Expression memberExp = exp.member.exp;
867          Identifier memberID = exp.member.member;
868          //Class _class;
869          Property prop = null;
870          DataMember member = null;
871          Class convertTo = null;
872          uint offset = 0;  // THIS WASN'T INITIALIZED... IS IT ALWAYS SET?
873
874          Type type; // = memberExp.expType;
875          DebugComputeExpression(memberExp);
876          type = memberExp.expType;
877          if(ExpressionIsError(memberExp))
878             CarryExpressionError(exp, memberExp);
879          else if(type)
880          {
881             // _class = (memberID && memberID.classSym) ? memberID.classSym.registered : ((type.kind == classType && type._class) ? type._class.registered : null);
882             Class _class = (exp.member.member && exp.member.member.classSym) ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
883             if(!_class)
884             {
885                char string[256] = "";
886                Symbol classSym;
887                PrintTypeNoConst(type, string, false, true);
888                classSym = FindClass(string);
889                _class = classSym ? classSym.registered : null;
890             }
891
892             if(memberID && _class)
893             {
894                /*
895                prop = eClass_FindProperty(_class, memberID.string);
896                if(!prop)
897                   member = eClass_FindDataMember(_class, memberID.string);
898                */
899                // member = eClass_FindDataMember(_class, memberID.string);
900                member = eClass_FindDataMemberAndOffset(_class, memberID.string, &offset, _class.module.application, null, null);
901                if(!member)
902                   prop = eClass_FindProperty(_class, memberID.string, _class.module.application);
903             }
904             if(!prop && !member && _class && memberID)
905             {
906                Symbol classSym = FindClass(memberID.string);
907                convertTo = _class;
908                _class = classSym ? classSym.registered : null;
909                if(_class)
910                   prop = eClass_FindProperty(_class, convertTo.name, _class.module.application);
911             }
912
913             //DebugComputeExpression(memberExp);
914             if(ExpressionIsError(memberExp))
915                CarryExpressionError(exp, memberExp);
916             else
917             {
918                if(prop)
919                {
920                   if(prop.compiled)
921                   {
922                      Type type = prop.dataType;
923                      // TODO: Assuming same base type for units...
924                      if(_class.type == unitClass)
925                      {
926                         if(type.kind == classType)
927                         {
928                            Class _class = type._class.registered;
929                            if(_class.type == unitClass)
930                            {
931                               if(!_class.dataType)
932                                  _class.dataType = ProcessTypeString(_class.dataTypeString, false);
933                               type = _class.dataType;
934                            }
935                         }
936                         switch(type.kind)
937                         {
938                            case floatType:
939                            {
940                               float value;
941                               float (*Get)(float) = (void *)prop.Get;
942                               GetFloat(memberExp, &value);
943                               exp.constant = PrintFloat(Get ? Get(value) : value);
944                               exp.type = constantExp;
945                               break;
946                            }
947                            case doubleType:
948                            {
949                               double value;
950                               double (*Get)(double);
951                               GetDouble(memberExp, &value);
952
953                               if(convertTo)
954                                  Get = (void *)prop.Set;
955                               else
956                                  Get = (void *)prop.Get;
957                               exp.constant = PrintDouble(Get ? Get(value) : value);
958                               exp.type = constantExp;
959                               break;
960                            }
961                         }
962                      }
963                      else
964                      {
965                         if(convertTo)
966                         {
967                            Expression value = memberExp;
968                            Type type = prop.dataType;
969                            if(_class.type == structClass)
970                            {
971                               switch(type.kind)
972                               {
973                                  case classType:
974                                  {
975                                     Class propertyClass = type._class.registered;
976                                     if(propertyClass.type == structClass && value.type == instanceExp)
977                                     {
978                                        void (*Set)(void *, void *) = (void *)prop.Set;
979                                        exp.instance = Instantiation
980                                        {
981                                           data = new0 byte[_class.structSize];
982                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
983                                           loc = exp.loc;
984                                           exp.type = instanceExp;
985                                        };
986                                        Set(exp.instance.data, value.instance.data);
987                                        PopulateInstance(exp.instance);
988                                     }
989                                     break;
990                                  }
991                                  case intType:
992                                  {
993                                     int intValue;
994                                     void (*Set)(void *, int) = (void *)prop.Set;
995
996                                     exp.instance = Instantiation
997                                     {
998                                        data = new0 byte[_class.structSize];
999                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1000                                        loc = exp.loc;
1001                                     };
1002                                     exp.type = instanceExp;
1003
1004                                     GetInt(value, &intValue);
1005
1006                                     Set(exp.instance.data, intValue);
1007                                     PopulateInstance(exp.instance);
1008                                     break;
1009                                  }
1010                                  case int64Type:
1011                                  {
1012                                     int64 intValue;
1013                                     void (*Set)(void *, int64) = (void *)prop.Set;
1014
1015                                     exp.instance = Instantiation
1016                                     {
1017                                        data = new0 byte[_class.structSize];
1018                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1019                                        loc = exp.loc;
1020                                     };
1021                                     exp.type = instanceExp;
1022
1023                                     GetInt64(value, &intValue);
1024
1025                                     Set(exp.instance.data, intValue);
1026                                     PopulateInstance(exp.instance);
1027                                     break;
1028                                  }
1029                                  case doubleType:
1030                                  {
1031                                     double doubleValue;
1032                                     void (*Set)(void *, double) = (void *)prop.Set;
1033
1034                                     exp.instance = Instantiation
1035                                     {
1036                                        data = new0 byte[_class.structSize];
1037                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1038                                        loc = exp.loc;
1039                                     };
1040                                     exp.type = instanceExp;
1041
1042                                     GetDouble(value, &doubleValue);
1043
1044                                     Set(exp.instance.data, doubleValue);
1045                                     PopulateInstance(exp.instance);
1046                                     break;
1047                                  }
1048                               }
1049                            }
1050                            else if(_class.type == bitClass)
1051                            {
1052                               switch(type.kind)
1053                               {
1054                                  case classType:
1055                                  {
1056                                     Class propertyClass = type._class.registered;
1057                                     if(propertyClass.type == structClass && value.instance.data)
1058                                     {
1059                                        unsigned int (*Set)(void *) = (void *)prop.Set;
1060                                        unsigned int bits = Set(value.instance.data);
1061                                        exp.constant = PrintHexUInt(bits);
1062                                        exp.type = constantExp;
1063                                        break;
1064                                     }
1065                                     else if(_class.type == bitClass)
1066                                     {
1067                                        unsigned int value;
1068                                        unsigned int (*Set)(unsigned int) = (void *)prop.Set;
1069                                        unsigned int bits;
1070
1071                                        GetUInt(memberExp, &value);
1072                                        bits = Set(value);
1073                                        exp.constant = PrintHexUInt(bits);
1074                                        exp.type = constantExp;
1075                                     }
1076                                  }
1077                               }
1078                            }
1079                         }
1080                         else
1081                         {
1082                            if(_class.type == bitClass)
1083                            {
1084                               uint value;
1085                               GetUInt(memberExp, &value);
1086
1087                               switch(type.kind)
1088                               {
1089                                  case classType:
1090                                  {
1091                                     Class _class = type._class.registered;
1092                                     if(_class.type == structClass)
1093                                     {
1094                                        void (*Get)(unsigned int, void *) = (void *)prop.Get;
1095
1096                                        exp.instance = Instantiation
1097                                        {
1098                                           data = new0 byte[_class.structSize];
1099                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
1100                                           loc = exp.loc;
1101                                        };
1102                                        //exp.instance.fullSet = true;
1103                                        exp.type = instanceExp;
1104                                        Get(value, exp.instance.data);
1105                                        PopulateInstance(exp.instance);
1106                                     }
1107                                     else if(_class.type == bitClass)
1108                                     {
1109                                        unsigned int (*Get)(unsigned int) = (void *)prop.Get;
1110                                        uint64 bits = Get(value);
1111                                        exp.constant = PrintHexUInt64(bits);
1112                                        exp.type = constantExp;
1113                                     }
1114                                     break;
1115                                  }
1116                               }
1117                            }
1118                            else if(_class.type == structClass)
1119                            {
1120                               char * value = (memberExp.type == instanceExp ) ? memberExp.instance.data : null;
1121                               switch(type.kind)
1122                               {
1123                                  case classType:
1124                                  {
1125                                     Class _class = type._class.registered;
1126                                     if(_class.type == structClass && value)
1127                                     {
1128                                        void (*Get)(void *, void *) = (void *)prop.Get;
1129
1130                                        exp.instance = Instantiation
1131                                        {
1132                                           data = new0 byte[_class.structSize];
1133                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
1134                                           loc = exp.loc;
1135                                        };
1136                                        //exp.instance.fullSet = true;
1137                                        exp.type = instanceExp;
1138                                        Get(value, exp.instance.data);
1139                                        PopulateInstance(exp.instance);
1140                                     }
1141                                     break;
1142                                  }
1143                               }
1144                            }
1145                            /*else
1146                            {
1147                               char * value = memberExp.instance.data;
1148                               switch(type.kind)
1149                               {
1150                                  case classType:
1151                                  {
1152                                     Class _class = type._class.registered;
1153                                     if(_class.type == normalClass)
1154                                     {
1155                                        void *(*Get)(void *) = (void *)prop.Get;
1156
1157                                        exp.instance = Instantiation
1158                                        {
1159                                           data = Get(value, exp.instance.data);     ?????
1160                                           _class = MkSpecifierName(_class.name); //MkClassName(_class.name);
1161                                           loc = exp.loc;
1162                                        };
1163                                        exp.type = instanceExp;
1164                                     }
1165                                     break;
1166                                  }
1167                               }
1168                            }
1169                            */
1170                         }
1171                      }
1172                   }
1173                   else
1174                   {
1175                      exp.isConstant = false;
1176                   }
1177                }
1178                else if(member)
1179                {
1180                   if(memberExp.hasAddress || memberExp.type == constantExp)
1181                   //if(memberExp.expType && memberExp.expType.kind == intType)  // && !exp.index.exp.expType.isSigned
1182                   {
1183                      if(_class.type == bitClass)
1184                      {
1185                         if(memberExp.type == constantExp)
1186                         {
1187                            // Unfinished business...
1188                            BitMember bitMember = (BitMember)member;
1189                            uint64 bits;
1190                            GetUInt64(memberExp, &bits);
1191                            bits &= bitMember.mask;
1192                            bits >>= bitMember.pos;
1193
1194                            FreeExpression(exp.member.exp);
1195                            FreeIdentifier(exp.member.member);
1196
1197                            exp.constant = PrintUInt64(bits);
1198
1199                            exp.isConstant = true;
1200                            exp.type = constantExp;
1201                            exp.hasAddress = false;
1202                         }
1203                      }
1204                      else
1205                      {
1206                         char * evaluation = null;
1207                         ExpressionType evalError = dummyExp;
1208                         uint64 address;
1209                         Expression prev = exp.prev, next = exp.next;
1210                         char format;
1211                         int size;
1212                         Expression expNew;
1213                         TypeKind kind = dummyType;
1214                         Type dataType = member.dataType;
1215
1216                         if(!dataType)
1217                            dataType = member.dataType = ProcessTypeString(member.dataTypeString, false);
1218
1219                         if(dataType.kind == classType && dataType._class.registered &&
1220                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1221                         {
1222                            if(dataType._class.registered.dataTypeString)
1223                               dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
1224                            dataType = dataType._class.registered.dataType;
1225                            if(!dataType)
1226                               dataType = ProcessTypeString("int", false);
1227                         }
1228
1229                         size = ComputeTypeSize(member.dataType);
1230
1231                         format = GetGdbFormatChar(dataType);
1232                         //if(memberExp.address)
1233                         {
1234                            //GetInt(memberExp, &address);
1235                            //offset = member.offset;
1236
1237                            // TESTING NOHEAD HERE?
1238                            if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass)
1239                               offset += member._class.offset;
1240
1241                            // VERIFY THIS: (trying to fix primitive.type)
1242                            // if(memberExp.type == constantExp)
1243                            if(memberExp.hasAddress && (_class.type != normalClass && _class.type != noHeadClass && _class.type != systemClass))
1244                               address = memberExp.address;
1245                            else if(memberExp.type == constantExp)
1246                               GetUInt64(memberExp, &address);
1247                            else
1248                            {
1249                               address = 0;
1250                               GetUInt64(memberExp, &address);
1251                               //printf("Unhandled !!\n");
1252
1253                               //printf("memberExp.hasAddress = %d\n", memberExp.hasAddress);
1254                               //printf("memberExp.type = %d\n", memberExp.type);
1255                               //printf("_class.name = %s, _class.type = %d\n", _class.name, _class.type);
1256                            }
1257
1258                            address += offset;
1259
1260                            if((dataType.kind == classType && dataType._class &&
1261                                  (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
1262                               (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
1263                            {
1264                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1265                               if(evalError != dummyExp)
1266                               {
1267                                  exp.type = evalError;
1268                                  exp.constant = PrintHexUInt64(address);
1269                               }
1270                               else if(evaluation)
1271                               {
1272                                  //printf("evaluation = %s\n", evaluation);
1273                                  expNew = ParseExpressionString(evaluation);
1274                                  delete evaluation;
1275                                  expNew.destType = exp.expType;
1276                                  if(exp.expType)
1277                                     exp.expType.refCount++;
1278                                  //FreeType(memberExp.destType);
1279                                  FreeType(exp.expType);
1280                                  FreeType(exp.destType);
1281                                  FreeExpContents(exp);
1282                                  ProcessExpressionType(expNew);
1283                                  DebugComputeExpression(expNew);
1284                                  expNew.prev = prev;
1285                                  expNew.next = next;
1286                                  expNew.isConstant = true;
1287                                  expNew.address = address;
1288                                  expNew.hasAddress = true;
1289                                  *exp = *expNew;
1290                                  delete expNew;
1291                               }
1292                               else
1293                                  exp.type = unknownErrorExp;
1294                            }
1295                            else
1296                            {
1297                               // TESTING THIS HERE...
1298                               exp.type = constantExp;
1299                               exp.constant = PrintHexUInt64(address);
1300
1301                               exp.address = address;
1302                               exp.hasAddress = true;
1303                               exp.isConstant = true;
1304                            }
1305                         }
1306                      }
1307                      //else
1308                      //   exp.type = ExpUnknownError;
1309
1310                      //FreeExpContents(exp);
1311                      //exp.constant = PrintUInt64(value);
1312                      //exp.type = constantExp;
1313                   }
1314                }
1315                else
1316                {
1317                   if(type && (type.kind == structType || type.kind == unionType))
1318                   {
1319                      uint offset = 0;
1320                      Type memberType = exp.member.member ? FindMemberAndOffset(type, exp.member.member.string, &offset) : null;
1321                      if(memberType)
1322                      {
1323                         char * evaluation = null;
1324                         ExpressionType evalError = dummyExp;
1325                         uint64 address;
1326                         Expression prev = exp.prev, next = exp.next;
1327                         char format;
1328                         int size = memberType.size;
1329                         Expression expNew;
1330                         Type dataType = memberType;
1331                         TypeKind kind = dummyType;
1332
1333                         if(dataType.kind == classType && dataType._class.registered &&
1334                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1335                            dataType = dataType._class.registered.dataType;
1336
1337                         format = GetGdbFormatChar(dataType);
1338
1339                         if(memberExp.hasAddress)
1340                            address = memberExp.address;
1341                         else if(memberExp.type == constantExp)
1342                            GetUInt64(memberExp, &address);
1343
1344                         address += offset;
1345
1346                         if((dataType.kind == classType && dataType._class &&
1347                               (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
1348                            (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
1349                         {
1350                            evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1351                            if(evalError != dummyExp)
1352                            {
1353                               exp.type = evalError;
1354                               exp.constant = PrintHexUInt64(address);
1355                            }
1356                            else if(evaluation)
1357                            {
1358                               expNew = ParseExpressionString(evaluation);
1359                               delete evaluation;
1360                               expNew.destType = exp.expType;
1361                               if(exp.expType)
1362                                  exp.expType.refCount++;
1363                               //FreeType(memberExp.destType);
1364                               FreeType(exp.expType);
1365                               FreeType(exp.destType);
1366                               FreeExpContents(exp);
1367                               ProcessExpressionType(expNew);
1368                               DebugComputeExpression(expNew);
1369                               expNew.prev = prev;
1370                               expNew.next = next;
1371                               expNew.isConstant = true;
1372                               expNew.address = address;
1373                               expNew.hasAddress = true;
1374                               *exp = *expNew;
1375                               delete expNew;
1376                            }
1377                            else
1378                               exp.type = unknownErrorExp;
1379                         }
1380                         else
1381                         {
1382                            FreeExpContents(exp);
1383
1384                            // TESTING THIS HERE...
1385                            exp.type = constantExp;
1386                            exp.constant = PrintHexUInt64(address);
1387
1388                            exp.address = address;
1389                            exp.hasAddress = true;
1390                            exp.isConstant = true;
1391                         }
1392                      }
1393                      else
1394                         exp.type = memberSymbolErrorExp;
1395                   }
1396                   else
1397                      exp.type = memberSymbolErrorExp;
1398                }
1399             }
1400
1401             //if(exp.type != memberExp)
1402             {
1403                //FreeExpression(memberExp);
1404                //FreeIdentifier(memberID);
1405             }
1406          }
1407          else
1408          {
1409             exp.type = memberSymbolErrorExp;
1410          }
1411          break;
1412       }
1413       case typeSizeExp:
1414       {
1415          Type type = ProcessType(exp.typeName.qualifiers, exp.typeName.declarator);
1416          FreeExpContents(exp);
1417          exp.constant = PrintUInt(ComputeTypeSize(type));
1418          exp.type = constantExp;
1419          FreeType(type);
1420          break;
1421       }
1422       case classSizeExp:
1423       {
1424          Symbol classSym = FindClass(exp._class.name);
1425          if(classSym && classSym.registered)
1426          {
1427             //exp.constant = PrintUInt(classSym.registered.size);
1428             //exp.type = constantExp;
1429
1430             char className[1024];
1431             sprintf(className, "__ecereClass_%s", classSym.string);
1432             FreeExpContents(exp);
1433             exp.type = pointerExp;
1434             exp.member.exp = MkExpIdentifier(MkIdentifier(className));
1435             exp.member.member = MkIdentifier("size");
1436          }
1437          break;
1438       }
1439       case castExp:
1440       {
1441          DebugComputeExpression(exp.cast.exp);
1442
1443          if(ExpressionIsError(exp.cast.exp)) //.type == ExpSymbolError
1444             CarryExpressionError(exp, exp.cast.exp);
1445          else
1446          {
1447             exp.hasAddress = exp.cast.exp.hasAddress;
1448             exp.address = exp.cast.exp.address;
1449             if(exp.cast.exp.type == constantExp && exp.expType)
1450             {
1451                Type type = exp.expType;
1452                if(type.kind == classType && type._class && type._class.registered)
1453                {
1454                   Class _class = type._class.registered;
1455                   if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
1456                   {
1457                      if(!_class.dataType)
1458                         _class.dataType = ProcessTypeString(_class.dataTypeString, false);
1459                      type = _class.dataType;
1460                   }
1461                }
1462
1463                switch(type.kind)
1464                {
1465                   case charType:
1466                      if(type.isSigned)
1467                      {
1468                         char value;
1469                         GetChar(exp.cast.exp, &value);
1470                         FreeExpContents(exp);
1471                         exp.constant = PrintChar(value);
1472                         exp.type = constantExp;
1473                         exp.isConstant = true;
1474                      }
1475                      else
1476                      {
1477                         unsigned char value;
1478                         GetUChar(exp.cast.exp, &value);
1479                         FreeExpContents(exp);
1480                         exp.constant = PrintUChar(value);
1481                         exp.type = constantExp;
1482                         exp.isConstant = true;
1483                      }
1484                      break;
1485                   case shortType:
1486                      if(type.isSigned)
1487                      {
1488                         short value;
1489                         GetShort(exp.cast.exp, &value);
1490                         FreeExpContents(exp);
1491                         exp.constant = PrintShort(value);
1492                         exp.type = constantExp;
1493                         exp.isConstant = true;
1494                      }
1495                      else
1496                      {
1497                         unsigned short value;
1498                         GetUShort(exp.cast.exp, &value);
1499                         FreeExpContents(exp);
1500                         exp.constant = PrintUShort(value);
1501                         exp.type = constantExp;
1502                         exp.isConstant = true;
1503                      }
1504                      break;
1505                   case intType:
1506                      if(type.isSigned)
1507                      {
1508                         int value;
1509                         GetInt(exp.cast.exp, &value);
1510                         FreeExpContents(exp);
1511                         exp.constant = PrintInt(value);
1512                         exp.type = constantExp;
1513                         exp.isConstant = true;
1514                      }
1515                      else
1516                      {
1517                         unsigned int value;
1518                         GetUInt(exp.cast.exp, &value);
1519                         FreeExpContents(exp);
1520                         exp.constant = PrintUInt(value);
1521                         exp.type = constantExp;
1522                         exp.isConstant = true;
1523                      }
1524                      break;
1525                   case int64Type:
1526                      if(type.isSigned)
1527                      {
1528                         int64 value;
1529                         GetInt64(exp.cast.exp, &value);
1530                         FreeExpContents(exp);
1531                         exp.constant = PrintInt64(value);
1532                         exp.type = constantExp;
1533                         exp.isConstant = true;
1534                      }
1535                      else
1536                      {
1537                         uint64 value;
1538                         GetUInt64(exp.cast.exp, &value);
1539                         FreeExpContents(exp);
1540                         exp.constant = PrintUInt64(value);
1541                         exp.type = constantExp;
1542                         exp.isConstant = true;
1543                      }
1544                      break;
1545                   case pointerType:
1546                   case classType:
1547                   {
1548                      uint64 value;
1549                      GetUInt64(exp.cast.exp, &value);
1550                      FreeExpContents(exp);
1551                      if(type.kind == pointerType || type.kind == classType)
1552                         exp.constant = PrintHexUInt64(value);
1553                      else
1554                         exp.constant = PrintUInt64(value);
1555                      exp.type = constantExp;
1556                      exp.isConstant = true;
1557                      break;
1558                   }
1559                   case floatType:
1560                   {
1561                      float value;
1562                      GetFloat(exp.cast.exp, &value);
1563                      FreeExpContents(exp);
1564                      exp.constant = PrintFloat(value);
1565                      exp.type = constantExp;
1566                      exp.isConstant = true;
1567                      break;
1568                   }
1569                   case doubleType:
1570                   {
1571                      double value;
1572                      GetDouble(exp.cast.exp, &value);
1573                      FreeExpContents(exp);
1574                      exp.constant = PrintDouble(value);
1575                      exp.type = constantExp;
1576                      exp.isConstant = true;
1577                      break;
1578                   }
1579                }
1580             }
1581          }
1582          break;
1583       }
1584       case conditionExp:
1585       {
1586          if(exp.cond.cond)
1587          {
1588             DebugComputeExpression(exp.cond.cond);
1589
1590             if(ExpressionIsError(exp.cond.cond))
1591                CarryExpressionError(exp, exp.cond.cond);
1592             else if(exp.cond.cond.type == constantExp && exp.cond.cond.constant)
1593             {
1594                Expression e = null;
1595                if(strtol(exp.cond.cond.constant, null, 0))
1596                {
1597                   for(e = exp.cond.exp ? exp.cond.exp->first : null; e; e = e.next)
1598                   {
1599                      DebugComputeExpression(e);
1600                      if(!e.next) break;
1601                   }
1602                   if(e)
1603                   {
1604                      if(ExpressionIsError(e))
1605                      {
1606                         CarryExpressionError(exp, e);
1607                         e = null;
1608                      }
1609                      else
1610                         exp.cond.exp->Remove(e);
1611                   }
1612                }
1613                else
1614                {
1615                   e = exp.cond.elseExp;
1616                   if(e)
1617                   {
1618                      DebugComputeExpression(e);
1619                      if(ExpressionIsError(e))
1620                      {
1621                         CarryExpressionError(exp, e);
1622                         e = null;
1623                      }
1624                      else
1625                         exp.cond.elseExp = null;
1626                   }
1627                }
1628                if(e)
1629                {
1630                   FreeType(exp.expType);
1631                   FreeType(exp.destType);
1632                   e.prev = exp.prev;
1633                   e.next = exp.next;
1634                   FreeExpContents(exp);
1635                   *exp = *e;
1636                   delete e;
1637                }
1638                else if(!ExpressionIsError(exp))
1639                {
1640                   FreeExpContents(exp);
1641                   exp.type = unknownErrorExp;
1642                }
1643             }
1644             else
1645             {
1646                FreeExpContents(exp);
1647                exp.type = unknownErrorExp;
1648             }
1649          }
1650          else
1651          {
1652             FreeExpContents(exp);
1653             exp.type = unknownErrorExp;
1654          }
1655          break;
1656       }
1657    }
1658 }