compiler/libec; ide/debugger: Fixed sizeof((char *)"abc")
[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)
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             }
413             if(exp.op.op == TokenType::sizeOf && e && e.expType)
414             {
415                if(e.type == stringExp && e.string)
416                {
417                   char * string = e.string;
418                   int len = strlen(string);
419                   char * tmp = new char[len-2+1];
420                   len = UnescapeString(tmp, string + 1, len - 2);
421                   delete tmp;
422                   FreeExpContents(exp);
423                   exp.type = constantExp;
424                   exp.constant = PrintUInt(len + 1);
425                }
426                else
427                {
428                   Type type = e.expType;
429                   type.refCount++;
430                   FreeExpContents(exp);
431                   exp.type = constantExp;
432                   exp.constant = PrintUInt(ComputeTypeSize(type));
433                   FreeType(type);
434                }
435                break;
436             }
437             else
438             {
439                DebugComputeExpression(exp.op.exp2);
440                if(ExpressionIsError(exp.op.exp2))
441                   expError = exp.op.exp2;
442             }
443          }
444          if(!expError)
445          {
446             if(exp.op.exp1)
447             {
448                DebugComputeExpression(exp.op.exp1);
449                if(ExpressionIsError(exp.op.exp1))
450                   expError = exp.op.exp1;
451                else
452                {
453                   if(exp.op.exp2)
454                   {
455                      if(ExpressionIsError(exp.op.exp2))
456                         expError = exp.op.exp2;
457                      else
458                      {
459                         exp1 = exp.op.exp1;
460                         exp2 = exp.op.exp2;
461                         op1 = GetOperand(exp1);
462                         if(op1.type) op1.type.refCount++;
463                         op2 = GetOperand(exp2);
464                         if(op2.type) op2.type.refCount++;
465                      }
466                   }
467                }
468             }
469             else if(exp.op.exp2)
470             {
471                if(ExpressionIsError(exp.op.exp2))
472                   expError = exp.op.exp2;
473                else
474                {
475                   exp1 = exp.op.exp2;
476                   if(exp.op.op == '&' || exp.op.op == '*')
477                   {
478                      Expression prev = exp1.prev, next = exp1.next;
479                      Expression expNew;
480                      ExpressionType evalError = dummyExp;
481                      char * evaluation = null;
482                      if(exp.op.op == '&')
483                      {
484                         if(exp1.hasAddress)
485                         {
486                            char * temp;
487                            //sprintf(temp, "%u", exp1.address);
488                            temp = PrintHexUInt64(exp1.address);
489                            expNew = ParseExpressionString(temp);
490                            delete temp;
491                            //expNew.address = exp1.address;
492                            expNew.expType = exp.expType;
493                            /*
494                            expNew.destType = exp.expType;
495                            expNew.destType.refCount++;
496                            */
497                            FreeType(exp.destType);
498                            FreeExpContents(exp);
499                            ProcessExpressionType(expNew);
500                            DebugComputeExpression(expNew);
501                            expNew.prev = prev;
502                            expNew.next = next;
503                            expNew.isConstant = true;
504                            *exp = *expNew;
505                            delete expNew;
506                         }
507                         else
508                            exp1.address = 0;
509                      }
510                      else if(exp.op.op == '*')
511                      {
512                         if(!exp.expType)
513                         {
514                            delete evaluation;
515                            FreeExpContents(exp1);
516                            exp1.type = dereferenceErrorExp;
517                            expError = exp1;
518                         }
519                         else
520                         {
521                            uint64 address;
522                            int size;
523                            char format;
524                            if(exp1.expType.kind == structType)
525                               address = exp1.address;
526                            else
527                               GetUInt64(exp1, &address);
528                            size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
529                            format = GetGdbFormatChar(exp.expType);
530                            if(format)
531                            {
532                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
533                               switch(evalError)
534                               {
535                                  case dummyExp:
536                                     if(evaluation)
537                                     {
538                                        expNew = ParseExpressionString(evaluation);
539                                        expNew.address = address;
540                                        expNew.hasAddress = true;
541                                        delete evaluation;
542                                        expNew.destType = exp.expType;
543                                        FreeType(exp.destType);
544                                        FreeExpContents(exp);
545                                        ProcessExpressionType(expNew);
546                                        DebugComputeExpression(expNew);
547                                        expNew.prev = prev;
548                                        expNew.next = next;
549                                        expNew.isConstant = true;
550                                        *exp = *expNew;
551                                        delete expNew;
552                                     }
553                                     else
554                                     {
555                                        // Unhandled code path, evaluation is null
556                                        FreeExpContents(exp);
557                                        exp.type = unknownErrorExp;
558                                     }
559                                     break;
560                                  case memoryErrorExp:
561                                     delete evaluation;
562                                     FreeExpContents(exp1);
563                                     exp1.type = evalError;
564                                     exp1.constant = PrintHexUInt64(address);
565                                     expError = exp1;
566                                     break;
567                                  default:
568                                     delete evaluation;
569                                     FreeExpContents(exp1);
570                                     exp1.type = evalError;
571                                     expError = exp1;
572                                     break;
573
574                               }
575                            }
576                            else
577                            {
578                               FreeExpContents(exp1);
579                               exp1.type = unknownErrorExp;  // Not supported yet, generate error to fallback to GDB printout
580                               expError = exp1;
581                            }
582                         }
583                      }
584                   }
585                   else
586                      op1 = GetOperand(exp1);
587                   if(op1.type) op1.type.refCount++;
588                }
589             }
590          }
591          if(expError)
592             CarryExpressionError(exp, expError);
593          else if(exp.type == opExp)
594          {
595             // TODO: check condition
596             if((exp.op.op == '+' || exp.op.op == '-') && op1.type && op2.type &&
597                (op1.type.kind == arrayType || op1.type.kind == pointerType) && op2.type.kind == intType)
598             {
599                // TODO: Do pointer operations
600                if(exp1.expType && exp1.expType.type)
601                {
602                   if(exp1.type == stringExp)
603                   {
604                      uint64 offset = (exp.op.op == '+') ? op2.i64 : -op2.i64;
605                      String newString = null;
606                      if(exp1.string)
607                      {
608                         int len = strlen(exp1.string) - 2;
609                         char * tmp = OffsetEscapedString(exp1.string + 1, len, (int)offset);
610                         if(tmp)
611                         {
612                            len -= tmp - (exp1.string + 1);
613                            newString = new char[2 + len];
614                            newString[0] = '\"';
615                            memcpy(newString + 1, tmp, len);
616                            newString[1 + len] = '\"';
617                            newString[1 + len + 1] = 0;
618                         }
619                      }
620                      FreeExpContents(exp);
621                      if(newString)
622                      {
623                         exp.type = stringExp;
624                         exp.string = newString;
625                      }
626                      else
627                         exp.type = dereferenceErrorExp;
628                   }
629                   else
630                   {
631                      uint size = ComputeTypeSize(exp1.expType.type);
632                      if(size)
633                      {
634                         op1.ui64 /= exp1.expType.type.size;
635                         CallOperator(exp, exp1, exp2, op1, op2);
636                         if(exp.type == constantExp)
637                         {
638                            exp.address = _strtoui64(exp.constant, null, 0);
639                            exp.address *= size;
640                            if(op1.type.kind == arrayType)
641                               exp.hasAddress = true;
642                         }
643                      }
644                   }
645                }
646             }
647             else
648             {
649                if((exp1 && exp1.type == stringExp) || (exp2 && exp2.type == stringExp))
650                {
651                   FreeExpContents(exp);
652                   exp.type = unknownErrorExp;   // We should have an invalid operands error
653                }
654                else
655                   CallOperator(exp, exp1, exp2, op1, op2);
656             }
657             if(op1.type) FreeType(op1.type);
658             if(op2.type) FreeType(op2.type);
659             exp.isConstant = true;
660          }
661          break;
662       }
663       case bracketsExp:
664       {
665          Expression e, n;
666          //for(
667          //   e = (*exp.list).first, n = e ? e.next : null;
668          //   e;
669          //   e = n, n = n?(n.next) : null)
670
671          for(e = exp.list->first; e; e = n)
672          {
673             n = e.next;
674             if(!n)
675             {
676                OldList * list = exp.list;
677                DebugComputeExpression(e);
678                //if(ExpressionIsError(e)) //.type == ExpSymbolError
679                //   CarryExpressionError(exp, e);
680                //FreeExpContents(exp);
681                FreeType(exp.expType);
682                FreeType(exp.destType);
683                *exp = *e;
684                delete e;
685                delete list;
686             }
687             else
688             {
689                FreeExpression(e);
690             }
691          }
692          break;
693       }
694       case indexExp:
695       {
696          int size;
697          char format;
698          Expression e;
699          exp.isConstant = true;
700
701          DebugComputeExpression(exp.index.exp);
702          if(ExpressionIsError(exp.index.exp)) //.type == ExpSymbolError
703             CarryExpressionError(exp, exp.index.exp);
704          else
705          {
706             Expression prev = exp.prev, next = exp.next;
707             char * evaluation = null;
708             ExpressionType evalError = dummyExp;
709
710             if(!exp.index.exp.isConstant)
711                exp.isConstant = false;
712
713             // int r[0]
714             // 4 == size = ComputeTypeSize(exp.expType);
715             // 0 == size = ComputeTypeSize(exp.expType.arrayType);
716             // 4 == size = ComputeTypeSize(exp.index.exp.expType);
717             // 0 == size = ComputeTypeSize(exp.index.exp.expType.arrayType);
718
719             size = ComputeTypeSize(exp.expType);
720             if(exp.expType && exp.expType.type && exp.expType.kind == arrayType)
721                // For multilevels arrays
722                format = 'x';
723             else
724                format = GetGdbFormatChar(exp.expType);
725
726             for(e = exp.index.index->first; e; e = e.next)
727             {
728                DebugComputeExpression(e);
729                if(ExpressionIsError(e)) //.type == ExpSymbolError
730                {
731                   CarryExpressionError(exp, e);
732                   break;
733                }
734                if(!e.next)
735                {
736                   // Check if this type is int
737                }
738                if(!e.isConstant)
739                   exp.isConstant = false;
740             }
741             if(!ExpressionIsError(exp))
742             {
743                // Is this necessary here? pass15 had done this already...
744                if(exp.expType) FreeType(exp.expType);
745                exp.expType = Dereference(exp.index.exp.expType);
746
747                if(!exp.expType)
748                {
749                   delete evaluation;
750                   FreeExpContents(exp);
751                   exp.type = dereferenceErrorExp;
752                }
753                else if(exp.index.index && exp.index.index->last && ((Expression)exp.index.index->last) && ((Expression)exp.index.index->last).expType)
754                {
755                   Type type = ((Expression)exp.index.index->last).expType;
756                   if(type.kind == intType || type.kind == charType || type.kind == shortType || type.kind == int64Type || type.kind == intPtrType ||
757                      type.kind == intSizeType || type.kind == longType || type.kind == _BoolType || type.kind == enumType ||
758                         (type.kind == classType && type._class && type._class.registered &&
759                            type._class.registered.type == enumClass))
760                   {
761                      uint64 address = 0, offset = 0;
762                      Expression expNew, last = (Expression)exp.index.index->last;
763                      //GetUInt(exp.index.exp, &address);
764
765                      // TOFIX: Check if it has address: TESTING
766                      if(exp.index.exp.hasAddress && (exp.index.exp.expType.kind == arrayType))
767                         address = exp.index.exp.address;
768                      else if(exp.index.exp.type == constantExp)
769                         GetUInt64(exp.index.exp, &address);
770
771                      GetUInt64(last, &offset);
772                      //size = ComputeTypeSize(exp.expType.arrayType); //exp.expType.arrayType.size;
773                      address += offset * size;
774                      if(exp.index.exp.type == stringExp)
775                      {
776                         String string = exp.index.exp.string;
777                         bool valid = false;
778                         char ch = 0;
779                         char * tmp = null;
780                         if(string)
781                         {
782                            int len = string ? strlen(string) : 0;
783                            tmp = new char[len-2+1];
784                            len = UnescapeString(tmp, string + 1, len - 2);
785                            if(len >= 0 && offset <= len)
786                            {
787                               ch = offset < len ? tmp[offset] : 0;
788                               valid = true;
789                            }
790                            delete tmp;
791                         }
792                         FreeExpContents(exp);
793                         if(valid)
794                         {
795                            exp.type = constantExp;
796                            exp.constant = PrintChar(ch);
797                         }
798                         else
799                            exp.type = dereferenceErrorExp;
800                      }
801                      else if(exp.expType.kind == arrayType)
802                      {
803                         FreeExpContents(exp);
804                         exp.type = constantExp;
805                         exp.isConstant = true;
806                         exp.constant = PrintHexUInt64(address);
807                         exp.address = address;
808                         exp.hasAddress = true;
809                      }
810                      else
811                      {
812                         evaluation = Debugger::ReadMemory(address, size, format, &evalError);
813                         switch(evalError)
814                         {
815                            case dummyExp:
816                               if(evaluation)
817                               {
818                                  expNew = ParseExpressionString(evaluation);
819                                  delete evaluation;
820                                  expNew.destType = exp.expType;
821                                  FreeType(exp.destType);
822                                  FreeExpContents(exp);
823                                  ProcessExpressionType(expNew);
824                                  DebugComputeExpression(expNew);
825
826                                  // TOFIX: Only for Array Types
827                                  expNew.address = address;
828
829                                  expNew.hasAddress = true;
830                                  expNew.prev = prev;
831                                  expNew.next = next;
832                                  expNew.isConstant = true;
833                                  *exp = *expNew;
834                                  delete expNew;
835                               }
836                               else
837                               {
838                                  // Unhandled code path, evaluation is null
839                                  FreeExpContents(exp);
840                                  exp.type = unknownErrorExp;
841                               }
842                               break;
843                            case memoryErrorExp:
844                               delete evaluation;
845                               FreeExpContents(exp);
846                               exp.type = evalError;
847                               exp.constant = PrintHexUInt64(address);
848                               break;
849                            default:
850                               delete evaluation;
851                               FreeExpContents(exp);
852                               exp.type = evalError;
853                               break;
854                         }
855                      }
856                   }
857                }
858             }
859          }
860          break;
861       }
862       case memberExp:
863       {
864          Expression memberExp = exp.member.exp;
865          Identifier memberID = exp.member.member;
866          //Class _class;
867          Property prop = null;
868          DataMember member = null;
869          Class convertTo = null;
870          uint offset = 0;  // THIS WASN'T INITIALIZED... IS IT ALWAYS SET?
871
872          Type type; // = memberExp.expType;
873          DebugComputeExpression(memberExp);
874          type = memberExp.expType;
875          if(ExpressionIsError(memberExp))
876             CarryExpressionError(exp, memberExp);
877          else if(type)
878          {
879             // _class = (memberID && memberID.classSym) ? memberID.classSym.registered : ((type.kind == classType && type._class) ? type._class.registered : null);
880             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);
881             if(!_class)
882             {
883                char string[256] = "";
884                Symbol classSym;
885                PrintTypeNoConst(type, string, false, true);
886                classSym = FindClass(string);
887                _class = classSym ? classSym.registered : null;
888             }
889
890             if(memberID && _class)
891             {
892                /*
893                prop = eClass_FindProperty(_class, memberID.string);
894                if(!prop)
895                   member = eClass_FindDataMember(_class, memberID.string);
896                */
897                // member = eClass_FindDataMember(_class, memberID.string);
898                member = eClass_FindDataMemberAndOffset(_class, memberID.string, &offset, _class.module.application, null, null);
899                if(!member)
900                   prop = eClass_FindProperty(_class, memberID.string, _class.module.application);
901             }
902             if(!prop && !member && _class && memberID)
903             {
904                Symbol classSym = FindClass(memberID.string);
905                convertTo = _class;
906                _class = classSym ? classSym.registered : null;
907                if(_class)
908                   prop = eClass_FindProperty(_class, convertTo.name, _class.module.application);
909             }
910
911             //DebugComputeExpression(memberExp);
912             if(ExpressionIsError(memberExp))
913                CarryExpressionError(exp, memberExp);
914             else
915             {
916                if(prop)
917                {
918                   if(prop.compiled)
919                   {
920                      Type type = prop.dataType;
921                      // TODO: Assuming same base type for units...
922                      if(_class.type == unitClass)
923                      {
924                         if(type.kind == classType)
925                         {
926                            Class _class = type._class.registered;
927                            if(_class.type == unitClass)
928                            {
929                               if(!_class.dataType)
930                                  _class.dataType = ProcessTypeString(_class.dataTypeString, false);
931                               type = _class.dataType;
932                            }
933                         }
934                         switch(type.kind)
935                         {
936                            case floatType:
937                            {
938                               float value;
939                               float (*Get)(float) = (void *)prop.Get;
940                               GetFloat(memberExp, &value);
941                               exp.constant = PrintFloat(Get ? Get(value) : value);
942                               exp.type = constantExp;
943                               break;
944                            }
945                            case doubleType:
946                            {
947                               double value;
948                               double (*Get)(double);
949                               GetDouble(memberExp, &value);
950
951                               if(convertTo)
952                                  Get = (void *)prop.Set;
953                               else
954                                  Get = (void *)prop.Get;
955                               exp.constant = PrintDouble(Get ? Get(value) : value);
956                               exp.type = constantExp;
957                               break;
958                            }
959                         }
960                      }
961                      else
962                      {
963                         if(convertTo)
964                         {
965                            Expression value = memberExp;
966                            Type type = prop.dataType;
967                            if(_class.type == structClass)
968                            {
969                               switch(type.kind)
970                               {
971                                  case classType:
972                                  {
973                                     Class propertyClass = type._class.registered;
974                                     if(propertyClass.type == structClass && value.type == instanceExp)
975                                     {
976                                        void (*Set)(void *, void *) = (void *)prop.Set;
977                                        exp.instance = Instantiation
978                                        {
979                                           data = new0 byte[_class.structSize];
980                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
981                                           loc = exp.loc;
982                                           exp.type = instanceExp;
983                                        };
984                                        Set(exp.instance.data, value.instance.data);
985                                        PopulateInstance(exp.instance);
986                                     }
987                                     break;
988                                  }
989                                  case intType:
990                                  {
991                                     int intValue;
992                                     void (*Set)(void *, int) = (void *)prop.Set;
993
994                                     exp.instance = Instantiation
995                                     {
996                                        data = new0 byte[_class.structSize];
997                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
998                                        loc = exp.loc;
999                                     };
1000                                     exp.type = instanceExp;
1001
1002                                     GetInt(value, &intValue);
1003
1004                                     Set(exp.instance.data, intValue);
1005                                     PopulateInstance(exp.instance);
1006                                     break;
1007                                  }
1008                                  case int64Type:
1009                                  {
1010                                     int64 intValue;
1011                                     void (*Set)(void *, int64) = (void *)prop.Set;
1012
1013                                     exp.instance = Instantiation
1014                                     {
1015                                        data = new0 byte[_class.structSize];
1016                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1017                                        loc = exp.loc;
1018                                     };
1019                                     exp.type = instanceExp;
1020
1021                                     GetInt64(value, &intValue);
1022
1023                                     Set(exp.instance.data, intValue);
1024                                     PopulateInstance(exp.instance);
1025                                     break;
1026                                  }
1027                                  case doubleType:
1028                                  {
1029                                     double doubleValue;
1030                                     void (*Set)(void *, double) = (void *)prop.Set;
1031
1032                                     exp.instance = Instantiation
1033                                     {
1034                                        data = new0 byte[_class.structSize];
1035                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1036                                        loc = exp.loc;
1037                                     };
1038                                     exp.type = instanceExp;
1039
1040                                     GetDouble(value, &doubleValue);
1041
1042                                     Set(exp.instance.data, doubleValue);
1043                                     PopulateInstance(exp.instance);
1044                                     break;
1045                                  }
1046                               }
1047                            }
1048                            else if(_class.type == bitClass)
1049                            {
1050                               switch(type.kind)
1051                               {
1052                                  case classType:
1053                                  {
1054                                     Class propertyClass = type._class.registered;
1055                                     if(propertyClass.type == structClass && value.instance.data)
1056                                     {
1057                                        unsigned int (*Set)(void *) = (void *)prop.Set;
1058                                        unsigned int bits = Set(value.instance.data);
1059                                        exp.constant = PrintHexUInt(bits);
1060                                        exp.type = constantExp;
1061                                        break;
1062                                     }
1063                                     else if(_class.type == bitClass)
1064                                     {
1065                                        unsigned int value;
1066                                        unsigned int (*Set)(unsigned int) = (void *)prop.Set;
1067                                        unsigned int bits;
1068
1069                                        GetUInt(memberExp, &value);
1070                                        bits = Set(value);
1071                                        exp.constant = PrintHexUInt(bits);
1072                                        exp.type = constantExp;
1073                                     }
1074                                  }
1075                               }
1076                            }
1077                         }
1078                         else
1079                         {
1080                            if(_class.type == bitClass)
1081                            {
1082                               uint value;
1083                               GetUInt(memberExp, &value);
1084
1085                               switch(type.kind)
1086                               {
1087                                  case classType:
1088                                  {
1089                                     Class _class = type._class.registered;
1090                                     if(_class.type == structClass)
1091                                     {
1092                                        void (*Get)(unsigned int, void *) = (void *)prop.Get;
1093
1094                                        exp.instance = Instantiation
1095                                        {
1096                                           data = new0 byte[_class.structSize];
1097                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
1098                                           loc = exp.loc;
1099                                        };
1100                                        //exp.instance.fullSet = true;
1101                                        exp.type = instanceExp;
1102                                        Get(value, exp.instance.data);
1103                                        PopulateInstance(exp.instance);
1104                                     }
1105                                     else if(_class.type == bitClass)
1106                                     {
1107                                        unsigned int (*Get)(unsigned int) = (void *)prop.Get;
1108                                        uint64 bits = Get(value);
1109                                        exp.constant = PrintHexUInt64(bits);
1110                                        exp.type = constantExp;
1111                                     }
1112                                     break;
1113                                  }
1114                               }
1115                            }
1116                            else if(_class.type == structClass)
1117                            {
1118                               char * value = (memberExp.type == instanceExp ) ? memberExp.instance.data : null;
1119                               switch(type.kind)
1120                               {
1121                                  case classType:
1122                                  {
1123                                     Class _class = type._class.registered;
1124                                     if(_class.type == structClass && value)
1125                                     {
1126                                        void (*Get)(void *, void *) = (void *)prop.Get;
1127
1128                                        exp.instance = Instantiation
1129                                        {
1130                                           data = new0 byte[_class.structSize];
1131                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
1132                                           loc = exp.loc;
1133                                        };
1134                                        //exp.instance.fullSet = true;
1135                                        exp.type = instanceExp;
1136                                        Get(value, exp.instance.data);
1137                                        PopulateInstance(exp.instance);
1138                                     }
1139                                     break;
1140                                  }
1141                               }
1142                            }
1143                            /*else
1144                            {
1145                               char * value = memberExp.instance.data;
1146                               switch(type.kind)
1147                               {
1148                                  case classType:
1149                                  {
1150                                     Class _class = type._class.registered;
1151                                     if(_class.type == normalClass)
1152                                     {
1153                                        void *(*Get)(void *) = (void *)prop.Get;
1154
1155                                        exp.instance = Instantiation
1156                                        {
1157                                           data = Get(value, exp.instance.data);     ?????
1158                                           _class = MkSpecifierName(_class.name); //MkClassName(_class.name);
1159                                           loc = exp.loc;
1160                                        };
1161                                        exp.type = instanceExp;
1162                                     }
1163                                     break;
1164                                  }
1165                               }
1166                            }
1167                            */
1168                         }
1169                      }
1170                   }
1171                   else
1172                   {
1173                      exp.isConstant = false;
1174                   }
1175                }
1176                else if(member)
1177                {
1178                   if(memberExp.hasAddress || memberExp.type == constantExp)
1179                   //if(memberExp.expType && memberExp.expType.kind == intType)  // && !exp.index.exp.expType.isSigned
1180                   {
1181                      if(_class.type == bitClass)
1182                      {
1183                         if(memberExp.type == constantExp)
1184                         {
1185                            // Unfinished business...
1186                            BitMember bitMember = (BitMember)member;
1187                            uint64 bits;
1188                            GetUInt64(memberExp, &bits);
1189                            bits &= bitMember.mask;
1190                            bits >>= bitMember.pos;
1191
1192                            FreeExpression(exp.member.exp);
1193                            FreeIdentifier(exp.member.member);
1194
1195                            exp.constant = PrintUInt64(bits);
1196
1197                            exp.isConstant = true;
1198                            exp.type = constantExp;
1199                            exp.hasAddress = false;
1200                         }
1201                      }
1202                      else
1203                      {
1204                         char * evaluation = null;
1205                         ExpressionType evalError = dummyExp;
1206                         uint64 address;
1207                         Expression prev = exp.prev, next = exp.next;
1208                         char format;
1209                         int size;
1210                         Expression expNew;
1211                         TypeKind kind = dummyType;
1212                         Type dataType = member.dataType;
1213
1214                         if(!dataType)
1215                            dataType = member.dataType = ProcessTypeString(member.dataTypeString, false);
1216
1217                         if(dataType.kind == classType && dataType._class.registered &&
1218                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1219                         {
1220                            if(dataType._class.registered.dataTypeString)
1221                               dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
1222                            dataType = dataType._class.registered.dataType;
1223                            if(!dataType)
1224                               dataType = ProcessTypeString("int", false);
1225                         }
1226
1227                         size = ComputeTypeSize(member.dataType);
1228
1229                         format = GetGdbFormatChar(dataType);
1230                         //if(memberExp.address)
1231                         {
1232                            //GetInt(memberExp, &address);
1233                            //offset = member.offset;
1234
1235                            // TESTING NOHEAD HERE?
1236                            if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass)
1237                               offset += member._class.offset;
1238
1239                            // VERIFY THIS: (trying to fix primitive.type)
1240                            // if(memberExp.type == constantExp)
1241                            if(memberExp.hasAddress && (_class.type != normalClass && _class.type != noHeadClass && _class.type != systemClass))
1242                               address = memberExp.address;
1243                            else if(memberExp.type == constantExp)
1244                               GetUInt64(memberExp, &address);
1245                            else
1246                            {
1247                               address = 0;
1248                               GetUInt64(memberExp, &address);
1249                               //printf("Unhandled !!\n");
1250
1251                               //printf("memberExp.hasAddress = %d\n", memberExp.hasAddress);
1252                               //printf("memberExp.type = %d\n", memberExp.type);
1253                               //printf("_class.name = %s, _class.type = %d\n", _class.name, _class.type);
1254                            }
1255
1256                            address += offset;
1257
1258                            if((dataType.kind == classType && dataType._class &&
1259                                  (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
1260                               (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
1261                            {
1262                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1263                               if(evalError != dummyExp)
1264                               {
1265                                  exp.type = evalError;
1266                                  exp.constant = PrintHexUInt64(address);
1267                               }
1268                               else if(evaluation)
1269                               {
1270                                  //printf("evaluation = %s\n", evaluation);
1271                                  expNew = ParseExpressionString(evaluation);
1272                                  delete evaluation;
1273                                  expNew.destType = exp.expType;
1274                                  if(exp.expType)
1275                                     exp.expType.refCount++;
1276                                  //FreeType(memberExp.destType);
1277                                  FreeType(exp.expType);
1278                                  FreeType(exp.destType);
1279                                  FreeExpContents(exp);
1280                                  ProcessExpressionType(expNew);
1281                                  DebugComputeExpression(expNew);
1282                                  expNew.prev = prev;
1283                                  expNew.next = next;
1284                                  expNew.isConstant = true;
1285                                  expNew.address = address;
1286                                  expNew.hasAddress = true;
1287                                  *exp = *expNew;
1288                                  delete expNew;
1289                               }
1290                               else
1291                                  exp.type = unknownErrorExp;
1292                            }
1293                            else
1294                            {
1295                               // TESTING THIS HERE...
1296                               exp.type = constantExp;
1297                               exp.constant = PrintHexUInt64(address);
1298
1299                               exp.address = address;
1300                               exp.hasAddress = true;
1301                               exp.isConstant = true;
1302                            }
1303                         }
1304                      }
1305                      //else
1306                      //   exp.type = ExpUnknownError;
1307
1308                      //FreeExpContents(exp);
1309                      //exp.constant = PrintUInt64(value);
1310                      //exp.type = constantExp;
1311                   }
1312                }
1313                else
1314                {
1315                   if(type && (type.kind == structType || type.kind == unionType))
1316                   {
1317                      uint offset = 0;
1318                      Type memberType = exp.member.member ? FindMemberAndOffset(type, exp.member.member.string, &offset) : null;
1319                      if(memberType)
1320                      {
1321                         char * evaluation = null;
1322                         ExpressionType evalError = dummyExp;
1323                         uint64 address;
1324                         Expression prev = exp.prev, next = exp.next;
1325                         char format;
1326                         int size = memberType.size;
1327                         Expression expNew;
1328                         Type dataType = memberType;
1329                         TypeKind kind = dummyType;
1330
1331                         if(dataType.kind == classType && dataType._class.registered &&
1332                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1333                            dataType = dataType._class.registered.dataType;
1334
1335                         format = GetGdbFormatChar(dataType);
1336
1337                         if(memberExp.hasAddress)
1338                            address = memberExp.address;
1339                         else if(memberExp.type == constantExp)
1340                            GetUInt64(memberExp, &address);
1341
1342                         address += offset;
1343
1344                         if((dataType.kind == classType && dataType._class &&
1345                               (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
1346                            (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
1347                         {
1348                            evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1349                            if(evalError != dummyExp)
1350                            {
1351                               exp.type = evalError;
1352                               exp.constant = PrintHexUInt64(address);
1353                            }
1354                            else if(evaluation)
1355                            {
1356                               expNew = ParseExpressionString(evaluation);
1357                               delete evaluation;
1358                               expNew.destType = exp.expType;
1359                               if(exp.expType)
1360                                  exp.expType.refCount++;
1361                               //FreeType(memberExp.destType);
1362                               FreeType(exp.expType);
1363                               FreeType(exp.destType);
1364                               FreeExpContents(exp);
1365                               ProcessExpressionType(expNew);
1366                               DebugComputeExpression(expNew);
1367                               expNew.prev = prev;
1368                               expNew.next = next;
1369                               expNew.isConstant = true;
1370                               expNew.address = address;
1371                               expNew.hasAddress = true;
1372                               *exp = *expNew;
1373                               delete expNew;
1374                            }
1375                            else
1376                               exp.type = unknownErrorExp;
1377                         }
1378                         else
1379                         {
1380                            FreeExpContents(exp);
1381
1382                            // TESTING THIS HERE...
1383                            exp.type = constantExp;
1384                            exp.constant = PrintHexUInt64(address);
1385
1386                            exp.address = address;
1387                            exp.hasAddress = true;
1388                            exp.isConstant = true;
1389                         }
1390                      }
1391                      else
1392                         exp.type = memberSymbolErrorExp;
1393                   }
1394                   else
1395                      exp.type = memberSymbolErrorExp;
1396                }
1397             }
1398
1399             //if(exp.type != memberExp)
1400             {
1401                //FreeExpression(memberExp);
1402                //FreeIdentifier(memberID);
1403             }
1404          }
1405          else
1406          {
1407             exp.type = memberSymbolErrorExp;
1408          }
1409          break;
1410       }
1411       case typeSizeExp:
1412       {
1413          Type type = ProcessType(exp.typeName.qualifiers, exp.typeName.declarator);
1414          FreeExpContents(exp);
1415          exp.constant = PrintUInt(ComputeTypeSize(type));
1416          exp.type = constantExp;
1417          FreeType(type);
1418          break;
1419       }
1420       case classSizeExp:
1421       {
1422          Symbol classSym = FindClass(exp._class.name);
1423          if(classSym && classSym.registered)
1424          {
1425             //exp.constant = PrintUInt(classSym.registered.size);
1426             //exp.type = constantExp;
1427
1428             char className[1024];
1429             sprintf(className, "__ecereClass_%s", classSym.string);
1430             FreeExpContents(exp);
1431             exp.type = pointerExp;
1432             exp.member.exp = MkExpIdentifier(MkIdentifier(className));
1433             exp.member.member = MkIdentifier("size");
1434          }
1435          break;
1436       }
1437       case castExp:
1438       {
1439          DebugComputeExpression(exp.cast.exp);
1440
1441          if(ExpressionIsError(exp.cast.exp)) //.type == ExpSymbolError
1442             CarryExpressionError(exp, exp.cast.exp);
1443          else
1444          {
1445             exp.hasAddress = exp.cast.exp.hasAddress;
1446             exp.address = exp.cast.exp.address;
1447             if(exp.cast.exp.type == constantExp && exp.expType)
1448             {
1449                Type type = exp.expType;
1450                if(type.kind == classType && type._class && type._class.registered)
1451                {
1452                   Class _class = type._class.registered;
1453                   if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
1454                   {
1455                      if(!_class.dataType)
1456                         _class.dataType = ProcessTypeString(_class.dataTypeString, false);
1457                      type = _class.dataType;
1458                   }
1459                }
1460
1461                switch(type.kind)
1462                {
1463                   case charType:
1464                      if(type.isSigned)
1465                      {
1466                         char value;
1467                         GetChar(exp.cast.exp, &value);
1468                         FreeExpContents(exp);
1469                         exp.constant = PrintChar(value);
1470                         exp.type = constantExp;
1471                         exp.isConstant = true;
1472                      }
1473                      else
1474                      {
1475                         unsigned char value;
1476                         GetUChar(exp.cast.exp, &value);
1477                         FreeExpContents(exp);
1478                         exp.constant = PrintUChar(value);
1479                         exp.type = constantExp;
1480                         exp.isConstant = true;
1481                      }
1482                      break;
1483                   case shortType:
1484                      if(type.isSigned)
1485                      {
1486                         short value;
1487                         GetShort(exp.cast.exp, &value);
1488                         FreeExpContents(exp);
1489                         exp.constant = PrintShort(value);
1490                         exp.type = constantExp;
1491                         exp.isConstant = true;
1492                      }
1493                      else
1494                      {
1495                         unsigned short value;
1496                         GetUShort(exp.cast.exp, &value);
1497                         FreeExpContents(exp);
1498                         exp.constant = PrintUShort(value);
1499                         exp.type = constantExp;
1500                         exp.isConstant = true;
1501                      }
1502                      break;
1503                   case intType:
1504                      if(type.isSigned)
1505                      {
1506                         int value;
1507                         GetInt(exp.cast.exp, &value);
1508                         FreeExpContents(exp);
1509                         exp.constant = PrintInt(value);
1510                         exp.type = constantExp;
1511                         exp.isConstant = true;
1512                      }
1513                      else
1514                      {
1515                         unsigned int value;
1516                         GetUInt(exp.cast.exp, &value);
1517                         FreeExpContents(exp);
1518                         exp.constant = PrintUInt(value);
1519                         exp.type = constantExp;
1520                         exp.isConstant = true;
1521                      }
1522                      break;
1523                   case int64Type:
1524                      if(type.isSigned)
1525                      {
1526                         int64 value;
1527                         GetInt64(exp.cast.exp, &value);
1528                         FreeExpContents(exp);
1529                         exp.constant = PrintInt64(value);
1530                         exp.type = constantExp;
1531                         exp.isConstant = true;
1532                      }
1533                      else
1534                      {
1535                         uint64 value;
1536                         GetUInt64(exp.cast.exp, &value);
1537                         FreeExpContents(exp);
1538                         exp.constant = PrintUInt64(value);
1539                         exp.type = constantExp;
1540                         exp.isConstant = true;
1541                      }
1542                      break;
1543                   case pointerType:
1544                   case classType:
1545                   {
1546                      uint64 value;
1547                      GetUInt64(exp.cast.exp, &value);
1548                      FreeExpContents(exp);
1549                      if(type.kind == pointerType || type.kind == classType)
1550                         exp.constant = PrintHexUInt64(value);
1551                      else
1552                         exp.constant = PrintUInt64(value);
1553                      exp.type = constantExp;
1554                      exp.isConstant = true;
1555                      break;
1556                   }
1557                   case floatType:
1558                   {
1559                      float value;
1560                      GetFloat(exp.cast.exp, &value);
1561                      FreeExpContents(exp);
1562                      exp.constant = PrintFloat(value);
1563                      exp.type = constantExp;
1564                      exp.isConstant = true;
1565                      break;
1566                   }
1567                   case doubleType:
1568                   {
1569                      double value;
1570                      GetDouble(exp.cast.exp, &value);
1571                      FreeExpContents(exp);
1572                      exp.constant = PrintDouble(value);
1573                      exp.type = constantExp;
1574                      exp.isConstant = true;
1575                      break;
1576                   }
1577                }
1578             }
1579          }
1580          break;
1581       }
1582       case conditionExp:
1583       {
1584          if(exp.cond.cond)
1585          {
1586             DebugComputeExpression(exp.cond.cond);
1587
1588             if(ExpressionIsError(exp.cond.cond))
1589                CarryExpressionError(exp, exp.cond.cond);
1590             else if(exp.cond.cond.type == constantExp && exp.cond.cond.constant)
1591             {
1592                Expression e = null;
1593                if(strtol(exp.cond.cond.constant, null, 0))
1594                {
1595                   for(e = exp.cond.exp ? exp.cond.exp->first : null; e; e = e.next)
1596                   {
1597                      DebugComputeExpression(e);
1598                      if(!e.next) break;
1599                   }
1600                   if(e)
1601                   {
1602                      if(ExpressionIsError(e))
1603                      {
1604                         CarryExpressionError(exp, e);
1605                         e = null;
1606                      }
1607                      else
1608                         exp.cond.exp->Remove(e);
1609                   }
1610                }
1611                else
1612                {
1613                   e = exp.cond.elseExp;
1614                   if(e)
1615                   {
1616                      DebugComputeExpression(e);
1617                      if(ExpressionIsError(e))
1618                      {
1619                         CarryExpressionError(exp, e);
1620                         e = null;
1621                      }
1622                      else
1623                         exp.cond.elseExp = null;
1624                   }
1625                }
1626                if(e)
1627                {
1628                   FreeType(exp.expType);
1629                   FreeType(exp.destType);
1630                   e.prev = exp.prev;
1631                   e.next = exp.next;
1632                   FreeExpContents(exp);
1633                   *exp = *e;
1634                   delete e;
1635                }
1636                else if(!ExpressionIsError(exp))
1637                {
1638                   FreeExpContents(exp);
1639                   exp.type = unknownErrorExp;
1640                }
1641             }
1642             else
1643             {
1644                FreeExpContents(exp);
1645                exp.type = unknownErrorExp;
1646             }
1647          }
1648          else
1649          {
1650             FreeExpContents(exp);
1651             exp.type = unknownErrorExp;
1652          }
1653          break;
1654       }
1655    }
1656 }