ecere/gui/Window: Prevent uninitialized values if base Window methods not overridden...
[sdk] / ide / src / debugger / debugTools.ec
1 import "ide"
2
3 static Map<String, uintptr> oneArgFns
4 { [
5    { "sqrt", (uintptr)sqrt },
6    { "log", (uintptr)log },
7    { "log10", (uintptr)log10 },
8    { "sin", (uintptr)sin },
9    { "cos", (uintptr)cos },
10    { "tan", (uintptr)tan },
11    { "asin", (uintptr)asin },
12    { "acos", (uintptr)acos },
13    { "atan", (uintptr)atan },
14    { "sinh", (uintptr)sinh },
15    { "cosh", (uintptr)cosh },
16    { "tanh", (uintptr)tanh },
17    { "asinh", (uintptr)asinh },
18    { "acosh", (uintptr)acosh },
19    { "atanh", (uintptr)atanh },
20    { "exp", (uintptr)exp },
21    { "floor", (uintptr)floor },
22    { "ceil", (uintptr)ceil },
23    { "fabs", (uintptr)sqrt }
24 ] };
25
26 static Map<String, uintptr> twoArgFns
27 { [
28    { "pow", (uintptr)pow },
29    { "atan2", (uintptr)atan2 },
30    { "fmod", (uintptr)fmod }
31 ] };
32
33 static void CarryExpressionError(Expression exp, Expression expError)
34 {
35    Expression temp { };
36
37    // This function assumes that expError is contained within exp,
38    // and therefore these types will be freed when freeing the old contents
39    // of the expression we're carying into.
40
41    if(expError.destType) expError.destType.refCount++;
42    if(expError.expType) expError.expType.refCount++;
43
44    *temp = *expError;
45
46    // -- Careful: this could be problematic as FreeExpContents will free the contents of expError
47    // Nulling things that may be freed now, but this is all overly messy/complex
48    switch(expError.type)
49    {
50       case functionCallErrorExp:
51          expError.call.exp = null;
52          expError.call.arguments = null;
53          break;
54       case symbolErrorExp:
55          expError.identifier = null;
56          break;
57       case memoryErrorExp:
58          expError.constant = null;
59          break;
60       case memberPropertyErrorExp:
61       case memberSymbolErrorExp:
62          expError.member.exp = null;
63          expError.member.member = null;
64          break;
65    }
66
67    /*
68    Identifier identifier = expError.identifier;
69    expError.identifier = null;
70    FreeExpContents(exp);
71    exp.identifier = identifier;
72    exp.type = expError.type;
73    */
74    if(exp.expType) FreeType(exp.expType);
75    if(exp.destType) FreeType(exp.destType);
76    FreeExpContents(exp);
77    *exp = *temp; //*expError;
78    delete temp;
79    // memset(expError, 0, sizeof(class Expression));
80 }
81
82 static char GetGdbFormatChar(Type type)
83 {
84 //          x : Regard the bits of the value as an integer, and print the integer in hexadecimal.
85 //          d : Print as integer in signed decimal.
86 //          u : Print as integer in unsigned decimal.
87 //          o : Print as integer in octal.
88 //          t : Print as integer in binary. The letter `t' stands for "two". (4)
89 //          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:
90 //          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.
91 //          f : Regard the bits of the value as a floating point number and print using typical floating point syntax.
92    if(!type)
93       return 'x';
94
95    switch(type.kind)
96    {
97       case charType:
98          //return 'c';
99       case shortType:
100       case intType:
101       case longType:
102       case int64Type:
103          if(type.isSigned)
104             return 'd';
105          else
106             return 'u';
107       case floatType:
108          return 'f';
109       case doubleType:
110          return 'f';
111       case structType:
112       case unionType:
113       case functionType:
114       case arrayType:
115          // return 'u';
116          return 0;
117       case ellipsisType:
118       case enumType:
119       case methodType:
120       case vaListType:
121       // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
122       case dummyType:
123          break;
124       case classType:
125       case pointerType:
126          return 'x';
127    }
128    return 'x';
129 }
130
131 /*static */bool ExpressionIsError(Expression exp)
132 {
133    return (exp.type == dereferenceErrorExp || exp.type == symbolErrorExp ||
134          exp.type == memberSymbolErrorExp || exp.type == memoryErrorExp || exp.type == unknownErrorExp ||
135          exp.type == noDebuggerErrorExp || exp.type == memberPropertyErrorExp || exp.type == functionCallErrorExp || exp.type == divideBy0ErrorExp);
136 }
137
138 char * DebugPrintFloat(float result)
139 {
140    char temp[350];
141    result.OnGetString(temp, null, null);
142    if(!strchr(temp, '.'))
143       strcat(temp, ".");
144    strcat(temp, "f");
145    return CopyString(temp);
146 }
147
148 char * DebugPrintDouble(double result)
149 {
150    char temp[350];
151    result.OnGetString(temp, null, null);
152    if(!strchr(temp, '.'))
153       strcat(temp, ".0");
154    return CopyString(temp);
155 }
156
157 void DebugComputeExpression(Expression exp)
158 {
159 #ifdef _DEBUG
160    char expString[1024] = "";
161    //char temp[1024];
162    //if(inCompiler)
163       PrintExpression(exp, expString);
164    // printf("%s (exp.type = %s)\n", expString, exp.type.OnGetString(temp, null, null));
165 #endif
166    switch(exp.type)
167    {
168       case identifierExp:
169       {
170          Expression prev = exp.prev, next = exp.next;
171          char * evaluation = null;
172          ExpressionType evalError = dummyExp;
173          Expression expNew;
174          TypeKind kind = dummyType;
175          Type dataType = exp.expType;
176          uint64 address = 0;
177          bool hasAddress;
178          bool isPointer = false;
179          bool evaluate = false;
180          bool evaluateAddress = false;
181          String idString = null;
182          if(exp.identifier.string)
183          {
184             const String start = (exp.identifier.string[0] == ':' && exp.identifier.string[1] == ':') ? exp.identifier.string + 2 : exp.identifier.string;
185             if(strstr(start, "::"))
186             {
187                char prefix[] = "__ecereNameSpace__";
188                int len = strlen(start);
189                idString = new char[len + sizeof(prefix)];
190                memcpy(idString, prefix, sizeof(prefix) - 1);
191                memcpy(idString + sizeof(prefix) - 1, start, len + 1);
192                ChangeCh(idString + sizeof(prefix) - 1, ':', '_');
193             }
194             else
195                idString = CopyString(exp.identifier.string);
196          }
197
198          if(dataType && dataType.kind == classType && dataType._class.registered)
199          {
200             Class _class = dataType._class.registered;
201             if(_class.type == bitClass || _class.type == unitClass || _class.type == enumClass)
202             {
203                if(!_class.dataType)
204                   _class.dataType = ProcessTypeString(_class.dataTypeString, false);
205                dataType = _class.dataType;
206             }
207             else if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass) // Added systemClass here for Instance
208             {
209                isPointer = true;
210             }
211          }
212          else if(dataType && dataType.kind == classType && !dataType._class.registered)
213             isPointer = true;
214          if(dataType)
215             kind = dataType.kind;
216          else
217          {
218             exp.type = symbolErrorExp;
219             evalError = symbolErrorExp;
220          }
221          switch(kind)
222          {
223             case intPtrType: case intSizeType: case _BoolType:
224             case charType: case shortType: case intType: case int64Type: case longType: case floatType: case doubleType:
225             case enumType:
226             case arrayType:
227             case structType:
228             case pointerType:
229             case unionType:
230                evaluate = true;
231                evaluateAddress = true;
232                break;
233             case classType:
234                if(exp.byReference && dataType._class && dataType._class.registered && dataType._class.registered.type == structClass)
235                // if(!dataType._class || !dataType._class.registered || dataType._class.registered.type != structClass || exp.byReference)
236                   evaluateAddress = false;
237                else
238                   evaluateAddress = true;
239                evaluate = true;
240                break;
241             case functionType:
242             case ellipsisType:
243             case methodType:
244             case vaListType:
245             // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
246             case dummyType:
247                break;
248          }
249          if(evaluate)
250          {
251             char temp[1024];
252             if(evaluateAddress)
253             {
254                temp[0] = '&';
255                strcpy(temp + 1, idString);
256             }
257             else
258                strcpy(temp, idString);
259
260             evaluation = Debugger::EvaluateExpression(temp, &evalError);
261             if(evaluation)
262             {
263                address = _strtoui64(evaluation, null, 0);
264                //delete evaluation;
265                //evaluation = null;
266             }
267             else
268                address = 0;
269             hasAddress = true;
270          }
271          else
272             hasAddress = false;
273
274          if(evalError == dummyExp)
275          {
276             switch(kind)
277             {
278                case charType:
279                   delete evaluation;
280                   evaluation = Debugger::EvaluateExpression(idString, &evalError);
281                   if(evaluation)
282                   {
283                      //int c, len;
284                      char * temp;
285                      temp = strstr(evaluation, " '");
286                      //len = strlen(temp);
287                      if(temp)
288                         temp[0] = '\0';
289                      {/*
290                         for(c = 0; c < len; c++)
291                            temp[c] = ' ';
292                         eString_TrimRSpaces(evaluation, evaluation);
293                      */}
294                   }
295                   break;
296                case shortType:
297                case intType:
298                case longType:
299                case intPtrType:
300                case intSizeType:
301                case _BoolType:
302                case int64Type:
303                case floatType:
304                case doubleType:
305                case enumType:
306                case pointerType:
307                   delete evaluation;
308                   evaluation = Debugger::EvaluateExpression(idString, &evalError);
309                   if(evaluation)
310                   {
311                      if(kind == pointerType)
312                      {
313                         uint64 value;
314                         value = _strtoui64(evaluation, null, 0);
315                         delete evaluation;
316                         evaluation = PrintHexUInt64(value);
317                      }
318                   }
319                   break;
320                case classType:
321                   if(isPointer)
322                   {
323                      int size;
324                      char format;
325                      delete evaluation;
326                      //evaluation = Debugger::EvaluateExpression(idString, &evalError);
327                      size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
328                      format = GetGdbFormatChar(exp.expType);
329                      evaluation = Debugger::ReadMemory(address, size, format, &evalError);
330                      if(evaluation)
331                         StripQuotes(evaluation, evaluation);
332                   }
333                   break;
334                case structType:
335                case unionType:
336                case functionType:
337                   //evaluation = Debugger::EvaluateExpression(idString, &evalError);
338                   delete evaluation;
339                   break;
340                case arrayType:
341                {
342                   // for classType  --> if(_class.type == structClass) ?
343                   //char temp[1024];
344                   //sprintf(temp, "&%s", idString);
345                   //evaluation = Debugger::EvaluateExpression(temp, &evalError);
346                   break;
347                }
348                case ellipsisType:
349                case methodType:
350                case vaListType:
351                // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
352                case dummyType:
353                   delete evaluation;
354                   evaluation = Debugger::EvaluateExpression(idString, &evalError);
355                   break;
356             }
357          }
358          switch(evalError)
359          {
360             case dummyExp:
361                if(evaluation && (exp.type != symbolErrorExp || !exp.identifier || !idString || strcmp(evaluation, idString)))
362                {
363                   char * lt = strchr(evaluation, '<');
364                   if(lt) *lt = 0;
365
366                   // Going back to parsing the expression string so as to catch inf/-inf/nan/-nan etc.
367                   expNew = ParseExpressionString(evaluation);
368                   //expNew = MkExpConstant(evaluation);
369                   //printf("Evaluation = %s\n", evaluation);
370                   delete evaluation;
371                   expNew.destType = exp.expType;
372
373                   // WHY EXACTLY MUST WE PROCESS THIS EXPRESSION TYPE AGAIN ? ADDED THIS FOR 0x00000000
374                   if(exp.expType && (exp.expType.kind == pointerType || exp.expType.kind == classType) && expNew.destType)
375                   {
376                      expNew.expType = expNew.destType;
377                      expNew.destType.refCount++;
378                      // For negative values parsed as opExp
379                      if(expNew.type == opExp && expNew.op.op == '-' && !expNew.op.exp1 && expNew.op.exp2)
380                      {
381                         expNew.op.exp2.expType = expNew.destType;
382                         expNew.destType.refCount++;
383                         expNew.op.exp2.isConstant = true;
384                      }
385                   }
386                   else
387                      ProcessExpressionType(expNew);
388                   FreeType(exp.destType);
389                   FreeExpContents(exp);
390
391                   DebugComputeExpression(expNew);
392                   expNew.prev = prev;
393                   expNew.next = next;
394                   expNew.isConstant = true;
395                   expNew.address = address;
396                   expNew.hasAddress = hasAddress;
397                   *exp = *expNew;
398                   delete expNew;
399                }
400                else
401                {
402                   // Unhandled code path, evaluation is null
403                   FreeExpContents(exp);
404                   exp.type = unknownErrorExp;
405                }
406                break;
407             case symbolErrorExp:
408                // Keep the identifier
409                exp.type = evalError;
410                break;
411             default:
412                FreeExpContents(exp);
413                exp.type = evalError;
414                break;
415          }
416          break;
417       }
418       case instanceExp:
419       {
420          Instantiation inst = exp.instance;
421          MembersInit members;
422          Symbol classSym = inst._class ? inst._class.symbol : null; // FindClass(inst._class.name);
423          Class _class = classSym ? classSym.registered : null;
424          DataMember curMember = null;
425          Class curClass = null;
426          DataMember subMemberStack[256];
427          int subMemberStackPos = 0;
428          uint64 bits = 0;
429
430          if(_class && (_class.type == structClass || _class.type == normalClass || _class.type == noHeadClass ))
431          {
432             // Don't recompute the instantiation...
433             // Non Simple classes will have become constants by now
434             if(inst.data)
435                return;
436
437             if(_class.type == normalClass || _class.type == noHeadClass)
438             {
439                inst.data = (byte *)eInstance_New(_class);
440                if(_class.type == normalClass)
441                   ((Instance)inst.data)._refCount++;
442             }
443             else
444                inst.data = new0 byte[_class.structSize];
445          }
446
447          if(inst.members)
448          {
449             for(members = inst.members->first; members; members = members.next)
450             {
451                switch(members.type)
452                {
453                   case dataMembersInit:
454                   {
455                      if(members.dataMembers)
456                      {
457                         MemberInit member;
458                         for(member = members.dataMembers->first; member; member = member.next)
459                         {
460                            Identifier ident = member.identifiers ? member.identifiers->first : null;
461                            bool found = false;
462
463                            Property prop = null;
464                            DataMember dataMember = null;
465                            uint dataMemberOffset;
466
467                            if(!ident)
468                            {
469                               eClass_FindNextMember(_class, &curClass, &curMember, subMemberStack, &subMemberStackPos);
470                               if(curMember)
471                               {
472                                  if(curMember.isProperty)
473                                  {
474                                     prop = (Property)curMember; // TOFIX: (eC II ? THe mss
475                                  }
476                                  else
477                                  {
478                                     dataMember = curMember;
479
480                                     // CHANGED THIS HERE
481                                     eClass_FindDataMemberAndOffset(_class, dataMember.name, &dataMemberOffset, GetPrivateModule(), null, null);
482
483                                     // 2013/17/29 -- It seems that this was missing here!
484                                     if(_class.type == normalClass)
485                                        dataMemberOffset += _class.base.structSize;
486                                     // dataMemberOffset = dataMember.offset;
487                                  }
488                                  found = true;
489                               }
490                            }
491                            else
492                            {
493                               prop = eClass_FindProperty(_class, ident.string, GetPrivateModule());
494                               if(prop)
495                               {
496                                  found = true;
497                                  if(prop.memberAccess == publicAccess)
498                                  {
499                                     curMember = (DataMember)prop;
500                                     curClass = prop._class;
501                                  }
502                               }
503                               else
504                               {
505                                  DataMember _subMemberStack[256];
506                                  int _subMemberStackPos = 0;
507
508                                  // FILL MEMBER STACK
509                                  dataMember = eClass_FindDataMemberAndOffset(_class, ident.string, &dataMemberOffset, GetPrivateModule(), _subMemberStack, &_subMemberStackPos);
510
511                                  if(dataMember)
512                                  {
513                                     found = true;
514                                     if(dataMember.memberAccess == publicAccess)
515                                     {
516                                        curMember = dataMember;
517                                        curClass = dataMember._class;
518                                        memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
519                                        subMemberStackPos = _subMemberStackPos;
520                                     }
521                                  }
522                               }
523                            }
524
525                            if(found && member.initializer && member.initializer.type == expInitializer)
526                            {
527                               Expression value = member.initializer.exp;
528                               Type type = null;
529                               bool deepMember = false;
530                               if(prop)
531                               {
532                                  type = prop.dataType;
533                               }
534                               else if(dataMember)
535                               {
536                                  if(!dataMember.dataType)
537                                     dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
538
539                                  type = dataMember.dataType;
540                               }
541
542                               if(ident && ident.next)
543                               {
544                                  deepMember = true;
545
546                                  // for(; ident && type; ident = ident.next)
547                                  for(ident = ident.next; ident && type; ident = ident.next)
548                                  {
549                                     if(type.kind == classType)
550                                     {
551                                        prop = eClass_FindProperty(type._class.registered,
552                                           ident.string, GetPrivateModule());
553                                        if(prop)
554                                           type = prop.dataType;
555                                        else
556                                        {
557                                           dataMember = eClass_FindDataMemberAndOffset(type._class.registered,
558                                              ident.string, &dataMemberOffset, GetPrivateModule(), null, null);
559                                           if(dataMember)
560                                              type = dataMember.dataType;
561                                        }
562                                     }
563                                     else if(type.kind == structType || type.kind == unionType)
564                                     {
565                                        Type memberType;
566                                        for(memberType = type.members.first; memberType; memberType = memberType.next)
567                                        {
568                                           if(!strcmp(memberType.name, ident.string))
569                                           {
570                                              type = memberType;
571                                              break;
572                                           }
573                                        }
574                                     }
575                                  }
576                               }
577                               if(value)
578                               {
579                                  FreeType(value.destType);
580                                  value.destType = type;
581                                  if(type) type.refCount++;
582                                  DebugComputeExpression(value);
583                               }
584                               if(!deepMember && type && value && (_class.type == structClass || _class.type == normalClass || _class.type == noHeadClass /*&& value.expType.kind == type.kind*/))
585                               {
586                                  if(type.kind == classType)
587                                  {
588                                     Class _class = type._class.registered;
589                                     if(_class.type == bitClass || _class.type == unitClass ||
590                                        _class.type == enumClass)
591                                     {
592                                        if(!_class.dataType)
593                                           _class.dataType = ProcessTypeString(_class.dataTypeString, false);
594                                        type = _class.dataType;
595                                     }
596                                  }
597
598                                  if(dataMember)
599                                  {
600                                     void * ptr = inst.data + dataMemberOffset;
601
602                                     if(value.type == constantExp)
603                                     {
604                                        switch(type.kind)
605                                        {
606                                           case intType:
607                                           {
608                                              GetInt(value, (int*)ptr);
609                                              break;
610                                           }
611                                           case int64Type:
612                                           {
613                                              GetInt64(value, (int64*)ptr);
614                                              break;
615                                           }
616                                           case intPtrType:
617                                           {
618                                              GetIntPtr(value, (intptr*)ptr);
619                                              break;
620                                           }
621                                           case intSizeType:
622                                           {
623                                              GetIntSize(value, (intsize*)ptr);
624                                              break;
625                                           }
626                                           case floatType:
627                                           {
628                                              GetFloat(value, (float*)ptr);
629                                              break;
630                                           }
631                                           case doubleType:
632                                           {
633                                              GetDouble(value, (double *)ptr);
634                                              break;
635                                           }
636                                        }
637                                     }
638                                     else if(value.type == instanceExp)
639                                     {
640                                        if(type.kind == classType)
641                                        {
642                                           Class _class = type._class.registered;
643                                           if(_class.type == structClass)
644                                           {
645                                              ComputeTypeSize(type);
646                                              if(value.instance.data)
647                                                 memcpy(ptr, value.instance.data, type.size);
648                                           }
649                                        }
650                                     }
651                                  }
652                                  else if(prop)
653                                  {
654                                     if(value.type == instanceExp && value.instance.data)
655                                     {
656                                        if(type.kind == classType)
657                                        {
658                                           Class _class = type._class.registered;
659                                           if(_class && (_class.type != normalClass || eClass_IsDerived(((Instance)value.instance.data)._class, _class)))
660                                           {
661                                              void (*Set)(void *, void *) = (void *)prop.Set;
662                                              Set(inst.data, value.instance.data);
663                                              PopulateInstance(inst);
664                                           }
665                                        }
666                                     }
667                                     else if(value.type == constantExp)
668                                     {
669                                        switch(type.kind)
670                                        {
671                                           case doubleType:
672                                           {
673                                              void (*Set)(void *, double) = (void *)prop.Set;
674                                              Set(inst.data, strtod(value.constant, null) );
675                                              break;
676                                           }
677                                           case floatType:
678                                           {
679                                              void (*Set)(void *, float) = (void *)prop.Set;
680                                              Set(inst.data, (float)(strtod(value.constant, null)));
681                                              break;
682                                           }
683                                           case intType:
684                                           {
685                                              void (*Set)(void *, int) = (void *)prop.Set;
686                                              Set(inst.data, (int)strtol(value.constant, null, 0));
687                                              break;
688                                           }
689                                           case int64Type:
690                                           {
691                                              void (*Set)(void *, int64) = (void *)prop.Set;
692                                              Set(inst.data, _strtoi64(value.constant, null, 0));
693                                              break;
694                                           }
695                                           case intPtrType:
696                                           {
697                                              void (*Set)(void *, intptr) = (void *)prop.Set;
698                                              Set(inst.data, (intptr)_strtoi64(value.constant, null, 0));
699                                              break;
700                                           }
701                                           case intSizeType:
702                                           {
703                                              void (*Set)(void *, intsize) = (void *)prop.Set;
704                                              Set(inst.data, (intsize)_strtoi64(value.constant, null, 0));
705                                              break;
706                                           }
707                                        }
708                                     }
709                                     else if(value.type == stringExp)
710                                     {
711                                        char temp[1024];
712                                        ReadString(temp, value.string);
713                                        ((void (*)(void *, void *))(void *)prop.Set)(inst.data, temp);
714                                     }
715                                  }
716                               }
717                               else if(!deepMember && type && _class.type == unitClass)
718                               {
719                                  if(prop)
720                                  {
721                                     // Only support converting units to units for now...
722                                     if(value.type == constantExp)
723                                     {
724                                        if(type.kind == classType)
725                                        {
726                                           Class _class = type._class.registered;
727                                           if(_class.type == unitClass)
728                                           {
729                                              if(!_class.dataType)
730                                                 _class.dataType = ProcessTypeString(_class.dataTypeString, false);
731                                              type = _class.dataType;
732                                           }
733                                        }
734                                        // TODO: Assuming same base type for units...
735                                        switch(type.kind)
736                                        {
737                                           case floatType:
738                                           {
739                                              float fValue;
740                                              float (*Set)(float) = (void *)prop.Set;
741                                              GetFloat(member.initializer.exp, &fValue);
742                                              exp.constant = DebugPrintFloat(Set(fValue));
743                                              exp.type = constantExp;
744                                              break;
745                                           }
746                                           case doubleType:
747                                           {
748                                              double dValue;
749                                              double (*Set)(double) = (void *)prop.Set;
750                                              GetDouble(member.initializer.exp, &dValue);
751                                              exp.constant = DebugPrintDouble(Set(dValue));
752                                              exp.type = constantExp;
753                                              break;
754                                           }
755                                        }
756                                     }
757                                  }
758                               }
759                               else if(!deepMember && type && _class.type == bitClass)
760                               {
761                                  if(prop)
762                                  {
763                                     if(value.type == instanceExp && value.instance.data)
764                                     {
765                                        unsigned int (*Set)(void *) = (void *)prop.Set;
766                                        bits = Set(value.instance.data);
767                                     }
768                                     else if(value.type == constantExp)
769                                     {
770                                     }
771                                  }
772                                  else if(dataMember)
773                                  {
774                                     BitMember bitMember = (BitMember) dataMember;
775                                     Type type;
776                                     int part = 0;
777                                     GetInt(value, &part);
778                                     bits = (bits & ~bitMember.mask);
779                                     if(!bitMember.dataType)
780                                        bitMember.dataType = ProcessTypeString(bitMember.dataTypeString, false);
781
782                                     type = bitMember.dataType;
783
784                                     if(type.kind == classType && type._class && type._class.registered)
785                                     {
786                                        if(!type._class.registered.dataType)
787                                           type._class.registered.dataType = ProcessTypeString(type._class.registered.dataTypeString, false);
788                                        type = type._class.registered.dataType;
789                                     }
790
791                                     switch(type.kind)
792                                     {
793                                        case _BoolType:
794                                        case charType:
795                                           if(type.isSigned)
796                                              bits |= ((char)part << bitMember.pos);
797                                           else
798                                              bits |= ((unsigned char)part << bitMember.pos);
799                                           break;
800                                        case shortType:
801                                           if(type.isSigned)
802                                              bits |= ((short)part << bitMember.pos);
803                                           else
804                                              bits |= ((unsigned short)part << bitMember.pos);
805                                           break;
806                                        case intType:
807                                        case longType:
808                                           if(type.isSigned)
809                                              bits |= ((int)part << bitMember.pos);
810                                           else
811                                              bits |= ((unsigned int)part << bitMember.pos);
812                                           break;
813                                        case int64Type:
814                                           if(type.isSigned)
815                                              bits |= ((int64)part << bitMember.pos);
816                                           else
817                                              bits |= ((uint64)part << bitMember.pos);
818                                           break;
819                                        case intPtrType:
820                                           if(type.isSigned)
821                                           {
822                                              bits |= ((intptr)part << bitMember.pos);
823                                           }
824                                           else
825                                           {
826                                              bits |= ((uintptr)part << bitMember.pos);
827                                           }
828                                           break;
829                                        case intSizeType:
830                                           if(type.isSigned)
831                                           {
832                                              bits |= ((ssize_t)(intsize)part << bitMember.pos);
833                                           }
834                                           else
835                                           {
836                                              bits |= ((size_t) (uintsize)part << bitMember.pos);
837                                           }
838                                           break;
839                                     }
840                                  }
841                               }
842                            }
843                            else
844                            {
845                               if(_class && _class.type == unitClass)
846                               {
847                                  DebugComputeExpression(member.initializer.exp);
848                                  exp.constant = member.initializer.exp.constant;
849                                  exp.type = constantExp;
850
851                                  member.initializer.exp.constant = null;
852                               }
853                            }
854                         }
855                      }
856                      break;
857                   }
858                }
859             }
860          }
861          if(_class && _class.type == bitClass)
862          {
863             exp.constant = PrintHexUInt(bits);
864             exp.type = constantExp;
865          }
866          if(exp.type != instanceExp)
867          {
868             FreeInstance(inst);
869          }
870          break;
871       }
872       /*
873       case constantExp:
874          break;
875       */
876       case opExp:
877       {
878          Expression expError = null;
879          Expression exp1 = null, exp2 = null;
880          Operand op1 = { 0 }, op2 = { 0 };
881
882          /*
883          if(exp.op.op == '&' || exp.op.op == '*')
884          {
885             if(!exp.op.exp1 && exp.op.exp2)
886             {
887                if(exp.op.exp2.type == identifierExp)
888                {
889                   Expression prev = exp.prev, next = exp.next;
890                   char * evaluation = null;
891                   ExpressionType evalError = dummyExp;
892                   Expression expNew;
893                   char temp[1024];
894                   sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.identifier.string);
895                   evaluation = Debugger::EvaluateExpression(temp, &evalError);
896                   if(evalError != dummyExp)
897                   {
898                      exp.type = evalError;
899                      exp.constant = CopyString("");
900                   }
901                   else if(evaluation)
902                   {
903                      expNew = ParseExpressionString(evaluation);
904                      delete evaluation;
905                      expNew.destType = exp.expType;
906                      FreeType(exp.destType);
907                      FreeExpContents(exp);
908                      ProcessExpressionType(expNew);
909                      DebugComputeExpression(expNew);
910                      expNew.prev = prev;
911                      expNew.next = next;
912                      expNew.isConstant = true;
913                      *exp = *expNew;
914                      delete expNew;
915                   }
916                   else
917                      exp.type = ExpUnknownError;
918                   break;
919                }
920                //else
921                {
922                   uint64 address;
923                   int size;
924                   char format;
925                   if(exp.op.op == '*')
926                   {
927                   DebugComputeExpression(exp.op.exp2);
928                   size = ComputeTypeSize(exp.op.exp2.expType);
929                   format = GetGdbFormatChar(exp.op.exp2.expType);
930                   GetInt(exp.op.exp2, &address);
931                   //sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.constant);
932                   evaluation = Debug_ReadMemory(address, size, format, &evalError);
933                   }
934                   else
935                      evalError = ExpUnknownError;
936                }
937             }
938          }
939          */
940
941          // We don't care about operations with only exp2 (INC_OP, DEC_OP...)
942          if(exp.op.exp2)
943          {
944             Expression e = exp.op.exp2;
945
946             while((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list)
947             {
948                if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
949                {
950                   if(e.type == extensionCompoundExp)
951                      e = ((Statement)e.compound.compound.statements->last).expressions->last;
952                   else
953                      e = e.list->last;
954                }
955             }
956             if(exp.op.op == TokenType::sizeOf && e && e.expType)
957             {
958                if(e.type == stringExp && e.string)
959                {
960                   char * string = e.string;
961                   int len = strlen(string);
962                   char * tmp = new char[len-2+1];
963                   len = UnescapeString(tmp, string + 1, len - 2);
964                   delete tmp;
965                   FreeExpContents(exp);
966                   exp.type = constantExp;
967                   exp.constant = PrintUInt(len + 1);
968                }
969                else
970                {
971                   Type type = e.expType;
972                   type.refCount++;
973                   FreeExpContents(exp);
974                   exp.type = constantExp;
975                   exp.constant = PrintUInt(ComputeTypeSize(type));
976                   FreeType(type);
977                }
978                break;
979             }
980             else
981             {
982                DebugComputeExpression(exp.op.exp2);
983                if(ExpressionIsError(exp.op.exp2))
984                   expError = exp.op.exp2;
985             }
986          }
987          if(!expError)
988          {
989             if(exp.op.exp1)
990             {
991                DebugComputeExpression(exp.op.exp1);
992                if(ExpressionIsError(exp.op.exp1))
993                   expError = exp.op.exp1;
994                else
995                {
996                   if(exp.op.exp2)
997                   {
998                      if(ExpressionIsError(exp.op.exp2))
999                         expError = exp.op.exp2;
1000                      else
1001                      {
1002                         exp1 = exp.op.exp1;
1003                         exp2 = exp.op.exp2;
1004                         op1 = GetOperand(exp1);
1005                         if(op1.type) op1.type.refCount++;
1006                         op2 = GetOperand(exp2);
1007                         if(op2.type) op2.type.refCount++;
1008                      }
1009                   }
1010                   else
1011                   {
1012                      exp1 = exp.op.exp1;
1013                      op1 = GetOperand(exp1);
1014                      if(op1.type) op1.type.refCount++;
1015                   }
1016                }
1017             }
1018             else if(exp.op.exp2)
1019             {
1020                if(ExpressionIsError(exp.op.exp2))
1021                   expError = exp.op.exp2;
1022                else
1023                {
1024                   exp1 = exp.op.exp2;
1025                   if(exp.op.op == '&' || exp.op.op == '*')
1026                   {
1027                      Expression prev = exp1.prev, next = exp1.next;
1028                      Expression expNew;
1029                      ExpressionType evalError = dummyExp;
1030                      char * evaluation = null;
1031                      if(exp.op.op == '&')
1032                      {
1033                         if(exp1.hasAddress)
1034                         {
1035                            char * temp;
1036                            //sprintf(temp, "%u", exp1.address);
1037                            temp = PrintHexUInt64(exp1.address);
1038                            expNew = ParseExpressionString(temp);
1039                            delete temp;
1040                            //expNew.address = exp1.address;
1041                            expNew.expType = exp.expType;
1042                            /*
1043                            expNew.destType = exp.expType;
1044                            expNew.destType.refCount++;
1045                            */
1046                            FreeType(exp.destType);
1047                            FreeExpContents(exp);
1048                            ProcessExpressionType(expNew);
1049                            DebugComputeExpression(expNew);
1050                            expNew.prev = prev;
1051                            expNew.next = next;
1052                            expNew.isConstant = true;
1053                            *exp = *expNew;
1054                            delete expNew;
1055                         }
1056                         else
1057                            exp1.address = 0;
1058                      }
1059                      else if(exp.op.op == '*')
1060                      {
1061                         // TODO: Common pathway for * and [ ]
1062                         if(!exp.expType)
1063                         {
1064                            delete evaluation;
1065                            FreeExpContents(exp1);
1066                            exp1.type = dereferenceErrorExp;
1067                            expError = exp1;
1068                         }
1069                         else
1070                         {
1071                            uint64 address = 0;
1072                            int size;
1073                            char format;
1074                            Expression e = exp1;
1075                            uint offset = 0;
1076                            bool gotAddress = false;
1077                            Type dataType;
1078
1079                            while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
1080                            {
1081                               if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
1082                               {
1083                                  if(e.type == extensionCompoundExp)
1084                                     e = ((Statement)e.compound.compound.statements->last).expressions->last;
1085                                  else
1086                                     e = e.list->last;
1087                               }
1088                               else if(e.type == castExp)
1089                                  e = e.cast.exp;
1090                            }
1091
1092                            if(e.expType.kind == structType)
1093                            {
1094                               address = exp1.address;
1095                               gotAddress = true;
1096                            }
1097                            else
1098                               gotAddress = GetUInt64(e, &address);
1099
1100                            dataType = exp.expType;
1101                            if(dataType && dataType.kind == classType && dataType._class.registered &&
1102                                  (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1103                            {
1104                               if(!dataType._class.registered.dataType && dataType._class.registered.dataTypeString)
1105                                  dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
1106                               dataType = dataType._class.registered.dataType;
1107                            }
1108
1109                            size = ComputeTypeSize(dataType); //exp.expType.arrayType.size;
1110                            if(dataType && dataType.type && dataType.kind == arrayType)
1111                               // For multilevels arrays
1112                               format = 'x';
1113                            else
1114                               format = GetGdbFormatChar(dataType);
1115                            while(e.type == opExp && e.op.op == '+' && e.op.exp1 && e.op.exp2)
1116                            {
1117                               Expression e1 = e.op.exp1, e2 = e.op.exp2;
1118                               while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
1119                               {
1120                                  if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
1121                                  {
1122                                     if(e1.type == extensionCompoundExp)
1123                                        e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
1124                                     else
1125                                        e1 = e1.list->last;
1126                                  }
1127                                  else if(e1.type == castExp)
1128                                     e1 = e1.cast.exp;
1129                               }
1130                               while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
1131                               {
1132                                  if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
1133                                  {
1134                                     if(e2.type == extensionCompoundExp)
1135                                        e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
1136                                     else
1137                                        e2 = e2.list->last;
1138                                  }
1139                                  else if(e2.type == castExp)
1140                                     e2 = e2.cast.exp;
1141                               }
1142
1143                               if((e1.type == stringExp || e1.type == opExp) && e.op.exp2.isConstant && e.op.exp2.expType && e.op.exp2.expType.kind == intType)
1144                               {
1145                                  offset += strtol(e.op.exp2.constant, null, 0);
1146                                  e = e1;
1147                               }
1148                               else if((e2.type == stringExp || e2.type == opExp) && e.op.exp1.isConstant && e.op.exp1.expType && e.op.exp1.expType.kind == intType)
1149                               {
1150                                  offset += strtol(e.op.exp1.constant, null, 0);
1151                                  e = e2;
1152                               }
1153                               else
1154                                   break;
1155                            }
1156
1157                            if(e.type == stringExp)
1158                            {
1159                               char * tmp = null;
1160                               String string = e.string;
1161                               bool valid = false;
1162                               Type expType = exp1.expType.type;
1163                               if(expType) expType.refCount++;
1164
1165                               if(string)
1166                               {
1167                                  int len = string ? strlen(string) : 0;
1168                                  tmp = new char[len-2+1];
1169                                  len = UnescapeString(tmp, string + 1, len - 2);
1170                                  if(len >= 0 && offset * size + size-1 <= len)
1171                                     valid = true;
1172                               }
1173
1174                               FreeExpContents(exp);
1175                               if(!valid)
1176                                  exp.type = dereferenceErrorExp;
1177                               else if(expType)
1178                               {
1179                                  exp.type = constantExp;
1180                                  exp.isConstant = true;
1181                                  switch(expType.kind)
1182                                  {
1183                                     case charType:   exp.constant = expType.isSigned ? PrintChar(((char *)tmp)[offset]) : PrintUChar(((byte *)tmp)[offset]); break;
1184                                     case shortType:  exp.constant = expType.isSigned ? PrintShort(((short *)tmp)[offset]) : PrintUShort(((uint16 *)tmp)[offset]); break;
1185                                     case intType:    exp.constant = expType.isSigned ? PrintInt(((int *)tmp)[offset]) : PrintUInt(((uint *)tmp)[offset]); break;
1186                                     case int64Type:  exp.constant = expType.isSigned ? PrintInt64(((int64 *)tmp)[offset]) : PrintUInt64(((uint64 *)tmp)[offset]); break;
1187                                     case floatType:  exp.constant = DebugPrintFloat(((float *)tmp)[offset]); break;
1188                                     case doubleType: exp.constant = DebugPrintDouble(((double *)tmp)[offset]); break;
1189                                     default:
1190                                        exp.type = unknownErrorExp;
1191                                  }
1192                               }
1193                               else
1194                                  exp.type = unknownErrorExp;
1195                               FreeType(expType);
1196                               delete tmp;
1197                            }
1198                            else if(gotAddress && exp.expType.kind == arrayType)
1199                            {
1200                               FreeExpContents(exp);
1201                               exp.type = constantExp;
1202                               exp.isConstant = true;
1203                               exp.constant = PrintHexUInt64(address);
1204                               exp.address = address;
1205                               exp.hasAddress = true;
1206                            }
1207                            else if(gotAddress && format)
1208                            {
1209                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1210                               switch(evalError)
1211                               {
1212                                  case dummyExp:
1213                                     if(evaluation)
1214                                     {
1215                                        expNew = ParseExpressionString(evaluation);
1216                                        expNew.address = address;
1217                                        expNew.hasAddress = true;
1218                                        delete evaluation;
1219                                        expNew.destType = exp.expType;
1220                                        FreeType(exp.destType);
1221                                        FreeExpContents(exp);
1222                                        ProcessExpressionType(expNew);
1223                                        DebugComputeExpression(expNew);
1224                                        expNew.prev = prev;
1225                                        expNew.next = next;
1226                                        expNew.isConstant = true;
1227                                        *exp = *expNew;
1228                                        delete expNew;
1229                                     }
1230                                     else
1231                                     {
1232                                        // Unhandled code path, evaluation is null
1233                                        FreeExpContents(exp);
1234                                        exp.type = unknownErrorExp;
1235                                     }
1236                                     break;
1237                                  case memoryErrorExp:
1238                                     delete evaluation;
1239                                     FreeExpContents(exp1);
1240                                     exp1.type = evalError;
1241                                     exp1.constant = PrintHexUInt64(address);
1242                                     expError = exp1;
1243                                     break;
1244                                  default:
1245                                     delete evaluation;
1246                                     FreeExpContents(exp1);
1247                                     exp1.type = evalError;
1248                                     expError = exp1;
1249                                     break;
1250                               }
1251                            }
1252                            else
1253                            {
1254                               FreeExpContents(exp1);
1255                               exp1.type = unknownErrorExp;  // Not supported yet, generate error to fallback to GDB printout
1256                               expError = exp1;
1257                            }
1258                         }
1259                      }
1260                   }
1261                   else
1262                      op1 = GetOperand(exp1);
1263                   if(op1.type) op1.type.refCount++;
1264                }
1265             }
1266          }
1267          if(expError)
1268             CarryExpressionError(exp, expError);
1269          else if(exp.type == opExp)
1270          {
1271             if(exp1 && exp2 && exp1.expType && exp2.expType &&
1272                ((exp1.expType.kind == pointerType || exp1.expType.kind == arrayType) ||
1273                 (exp2.expType.kind == pointerType || exp2.expType.kind == arrayType)))
1274             {
1275                bool valid = false;
1276                if((exp.op.op == '+' || exp.op.op == '-') && (op2.type || op1.type))
1277                {
1278                   Expression e1 = exp1, e2 = exp2;
1279                   while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
1280                   {
1281                      if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
1282                      {
1283                         if(e1.type == extensionCompoundExp)
1284                            e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
1285                         else
1286                            e1 = e1.list->last;
1287                      }
1288                      else if(e1.type == castExp)
1289                         e1 = e1.cast.exp;
1290                   }
1291                   while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
1292                   {
1293                      if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
1294                      {
1295                         if(e2.type == extensionCompoundExp)
1296                            e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
1297                         else
1298                            e2 = e2.list->last;
1299                      }
1300                      else if(e2.type == castExp)
1301                         e2 = e2.cast.exp;
1302                   }
1303
1304                   if((e1.type == stringExp && op2.type && op2.type.kind == intType) || (e2.type == stringExp && op1.type && op1.type.kind == intType))
1305                   {
1306                      uint64 offset = ((exp.op.op == '+') ? 1 : -1) * (e1.type == stringExp ? op2.i64 : op1.i64);
1307                      String newString = null;
1308                      Expression e = e1.type == stringExp ? e1 : e2;
1309                      if(e.string)
1310                      {
1311                         int len = strlen(e.string) - 2;
1312                         char * tmp = OffsetEscapedString(e.string + 1, len, (int)offset);
1313                         if(tmp)
1314                         {
1315                            len -= tmp - (e.string + 1);
1316                            newString = new char[2 + len + 1];
1317                            newString[0] = '\"';
1318                            memcpy(newString + 1, tmp, len);
1319                            newString[1 + len] = '\"';
1320                            newString[1 + len + 1] = 0;
1321                         }
1322                      }
1323                      valid = true;
1324                      FreeExpContents(exp);
1325                      if(newString)
1326                      {
1327                         exp.type = stringExp;
1328                         exp.string = newString;
1329                      }
1330                      else
1331                         exp.type = dereferenceErrorExp;
1332                   }
1333                   // Can't add 2 pointers...
1334                   else if(exp.op.op != '+' ||
1335                      !((exp1.expType.kind == pointerType || exp1.expType.kind == arrayType) &&
1336                        (exp2.expType.kind == pointerType || exp2.expType.kind == arrayType)))
1337                   {
1338                      bool op1IsPointer = exp1.expType.kind == pointerType || exp1.expType.kind == arrayType;
1339                      bool op2IsPointer = exp2.expType.kind == pointerType || exp2.expType.kind == arrayType;
1340                      bool addressResult = !op1IsPointer || !op2IsPointer;
1341                      uint size = 0;
1342                      valid = true;
1343                      if(op1IsPointer)
1344                         size = ComputeTypeSize(exp1.expType.type);
1345                      else if(op2IsPointer)
1346                         size = ComputeTypeSize(exp2.expType.type);
1347
1348                      if(addressResult && size)
1349                      {
1350                        if(op1IsPointer) op2.ui64 *= size;
1351                        else if(op1IsPointer) op1.ui64 *= size;
1352                      }
1353
1354                      CallOperator(exp, exp1, exp2, op1, op2);
1355                      if(exp.type == constantExp)
1356                      {
1357                         if(addressResult)
1358                         {
1359                            exp.address = _strtoui64(exp.constant, null, 0);
1360                            delete exp.constant;
1361                            exp.constant = PrintHexUInt64(exp.address);
1362                            if(op1.type.kind == arrayType || op2.type.kind == arrayType)
1363                               exp.hasAddress = true;
1364                         }
1365                         else
1366                         {
1367                            int64 v = _strtoi64(exp.constant, null, 0);
1368                            if(size) v /= size;
1369                            delete exp.constant;
1370                            exp.constant = PrintInt(v);
1371                         }
1372                      }
1373                   }
1374                }
1375                if(!valid)
1376                {
1377                   FreeExpContents(exp);
1378                   exp.type = unknownErrorExp;   // We should have an invalid operands error
1379                }
1380             }
1381             else
1382             {
1383                if(!exp2 && exp1 && exp1.type == constantExp && exp1.constant && !strcmp(exp1.constant, "nan") && exp.op.op == '-')
1384                {
1385                   FreeExpContents(exp);
1386                   exp.constant = CopyString("-nan");
1387                   exp.type = constantExp;
1388                }
1389                else
1390                {
1391                   if((exp.op.op == '/' || exp.op.op == '%') && op2.kind != doubleType && op1.kind != doubleType && op2.kind != floatType && op1.kind != floatType &&
1392                      (((op2.kind == int64Type || op2.kind == intPtrType || op2.kind == intSizeType) && !op2.i64) ||
1393                      (op2.kind == intType && !op2.i) || (op2.kind == shortType && !op2.s) || (op2.kind == charType && !op2.c)))
1394                   {
1395                      FreeExpContents(exp);
1396                      exp.type = divideBy0ErrorExp;
1397                   }
1398                   else
1399                      CallOperator(exp, exp1, exp2, op1, op2);
1400                }
1401             }
1402             FreeType(op1.type);
1403             FreeType(op2.type);
1404             if(exp.type == constantExp)
1405                exp.isConstant = true;
1406          }
1407          break;
1408       }
1409       case bracketsExp:
1410       {
1411          Expression e, n;
1412          //for(
1413          //   e = (*exp.list).first, n = e ? e.next : null;
1414          //   e;
1415          //   e = n, n = n?(n.next) : null)
1416
1417          for(e = exp.list->first; e; e = n)
1418          {
1419             n = e.next;
1420             if(!n)
1421             {
1422                OldList * list = exp.list;
1423                DebugComputeExpression(e);
1424                //if(ExpressionIsError(e)) //.type == ExpSymbolError
1425                //   CarryExpressionError(exp, e);
1426                //FreeExpContents(exp);
1427                FreeType(exp.expType);
1428                FreeType(exp.destType);
1429                *exp = *e;
1430                delete e;
1431                delete list;
1432             }
1433             else
1434             {
1435                FreeExpression(e);
1436             }
1437          }
1438          break;
1439       }
1440       case indexExp:
1441       {
1442          int size;
1443          char format;
1444          Expression e;
1445          exp.isConstant = true;
1446
1447          DebugComputeExpression(exp.index.exp);
1448          if(ExpressionIsError(exp.index.exp)) //.type == ExpSymbolError
1449             CarryExpressionError(exp, exp.index.exp);
1450          else
1451          {
1452             Expression prev = exp.prev, next = exp.next;
1453             char * evaluation = null;
1454             ExpressionType evalError = dummyExp;
1455             Type dataType = exp.index.exp.expType ? exp.index.exp.expType.type : null;
1456
1457             if(!exp.index.exp.isConstant)
1458                exp.isConstant = false;
1459
1460             // int r[0]
1461             // 4 == size = ComputeTypeSize(exp.expType);
1462             // 0 == size = ComputeTypeSize(exp.expType.arrayType);
1463             // 4 == size = ComputeTypeSize(exp.index.exp.expType);
1464             // 0 == size = ComputeTypeSize(exp.index.exp.expType.arrayType);
1465
1466             if(dataType && dataType.kind == classType && dataType._class.registered &&
1467                   (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1468             {
1469                if(!dataType._class.registered.dataType && dataType._class.registered.dataTypeString)
1470                   dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
1471                dataType = dataType._class.registered.dataType;
1472             }
1473
1474             size = ComputeTypeSize(dataType);
1475             if(dataType && dataType.type && dataType.kind == arrayType)
1476                // For multilevels arrays
1477                format = 'x';
1478             else
1479                format = GetGdbFormatChar(dataType);
1480
1481             for(e = exp.index.index->first; e; e = e.next)
1482             {
1483                DebugComputeExpression(e);
1484                if(ExpressionIsError(e)) //.type == ExpSymbolError
1485                {
1486                   CarryExpressionError(exp, e);
1487                   break;
1488                }
1489                if(!e.next)
1490                {
1491                   // Check if this type is int
1492                }
1493                if(!e.isConstant)
1494                   exp.isConstant = false;
1495             }
1496             if(!ExpressionIsError(exp))
1497             {
1498                // Is this necessary here? pass15 had done this already...
1499                if(exp.expType) FreeType(exp.expType);
1500                exp.expType = Dereference(exp.index.exp.expType);
1501
1502                if(!exp.expType)
1503                {
1504                   delete evaluation;
1505                   FreeExpContents(exp);
1506                   exp.type = dereferenceErrorExp;
1507                }
1508                else if(exp.index.index && exp.index.index->last && ((Expression)exp.index.index->last) && ((Expression)exp.index.index->last).expType)
1509                {
1510                   Type type = ((Expression)exp.index.index->last).expType;
1511                   if(type.kind == intType || type.kind == charType || type.kind == shortType || type.kind == int64Type || type.kind == intPtrType ||
1512                      type.kind == intSizeType || type.kind == longType || type.kind == _BoolType || type.kind == enumType ||
1513                         (type.kind == classType && type._class && type._class.registered &&
1514                            type._class.registered.type == enumClass))
1515                   {
1516                      bool gotAddress = false;
1517                      uint64 address = 0, offset = 0;
1518                      Expression expNew, last = (Expression)exp.index.index->last;
1519                      Expression e = exp.index.exp;
1520
1521                      while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
1522                      {
1523                         if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
1524                         {
1525                            if(e.type == extensionCompoundExp)
1526                               e = ((Statement)e.compound.compound.statements->last).expressions->last;
1527                            else
1528                               e = e.list->last;
1529                         }
1530                         else if(e.type == castExp)
1531                            e = e.cast.exp;
1532                      }
1533
1534                      //GetUInt(exp.index.exp, &address);
1535
1536                      GetUInt64(last, &offset);
1537
1538                      // TOFIX: Check if it has address: TESTING
1539                      if(exp.index.exp.hasAddress && exp.index.exp.expType.kind == arrayType)
1540                      {
1541                         address = exp.index.exp.address;
1542                         gotAddress = true;
1543                      }
1544                      else if(exp.index.exp.type == constantExp)
1545                         gotAddress = GetUInt64(exp.index.exp, &address);
1546
1547                      while(e.type == opExp && e.op.op == '+' && e.op.exp1 && e.op.exp2)
1548                      {
1549                         Expression e1 = e.op.exp1, e2 = e.op.exp2;
1550                         while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
1551                         {
1552                            if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
1553                            {
1554                               if(e1.type == extensionCompoundExp)
1555                                  e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
1556                               else
1557                                  e1 = e1.list->last;
1558                            }
1559                            else if(e1.type == castExp)
1560                               e1 = e1.cast.exp;
1561                         }
1562                         while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
1563                         {
1564                            if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
1565                            {
1566                               if(e2.type == extensionCompoundExp)
1567                                  e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
1568                               else
1569                                  e2 = e2.list->last;
1570                            }
1571                            else if(e2.type == castExp)
1572                               e2 = e2.cast.exp;
1573                         }
1574
1575                         if((e1.type == stringExp || e1.type == opExp) && e.op.exp2.isConstant && e.op.exp2.expType && e.op.exp2.expType.kind == intType)
1576                         {
1577                            offset += strtol(e.op.exp2.constant, null, 0);
1578                            e = e1;
1579                         }
1580                         else if((e2.type == stringExp || e2.type == opExp) && e.op.exp1.isConstant && e.op.exp1.expType && e.op.exp1.expType.kind == intType)
1581                         {
1582                            offset += strtol(e.op.exp1.constant, null, 0);
1583                            e = e2;
1584                         }
1585                         else
1586                             break;
1587                      }
1588
1589                      //size = ComputeTypeSize(exp.expType.arrayType); //exp.expType.arrayType.size;
1590                      address += offset * size;
1591
1592                      if(e.type == stringExp)
1593                      {
1594                         char * tmp = null;
1595                         String string = e.string;
1596                         bool valid = false;
1597                         Type expType = exp.index.exp.expType.type;
1598                         if(expType) expType.refCount++;
1599
1600                         if(string)
1601                         {
1602                            int len = string ? strlen(string) : 0;
1603                            tmp = new char[len-2+1];
1604                            len = UnescapeString(tmp, string + 1, len - 2);
1605                            if(len >= 0 && offset * size + size-1 <= len)
1606                               valid = true;
1607                         }
1608
1609                         FreeExpContents(exp);
1610                         if(!valid)
1611                            exp.type = dereferenceErrorExp;
1612                         else if(expType)
1613                         {
1614                            exp.type = constantExp;
1615                            exp.isConstant = true;
1616                            switch(expType.kind)
1617                            {
1618                               case charType:   exp.constant = expType.isSigned ? PrintChar(((char *)tmp)[offset]) : PrintUChar(((byte *)tmp)[offset]); break;
1619                               case shortType:  exp.constant = expType.isSigned ? PrintShort(((short *)tmp)[offset]) : PrintUShort(((uint16 *)tmp)[offset]); break;
1620                               case intType:    exp.constant = expType.isSigned ? PrintInt(((int *)tmp)[offset]) : PrintUInt(((uint *)tmp)[offset]); break;
1621                               case int64Type:  exp.constant = expType.isSigned ? PrintInt64(((int64 *)tmp)[offset]) : PrintUInt64(((uint64 *)tmp)[offset]); break;
1622                               case floatType:  exp.constant = DebugPrintFloat(((float *)tmp)[offset]); break;
1623                               case doubleType: exp.constant = DebugPrintDouble(((double *)tmp)[offset]); break;
1624                               default:
1625                                  exp.type = unknownErrorExp;
1626                            }
1627                         }
1628                         else
1629                            exp.type = unknownErrorExp;
1630                         FreeType(expType);
1631                         delete tmp;
1632                      }
1633                      else if(gotAddress && exp.expType.kind == arrayType)
1634                      {
1635                         FreeExpContents(exp);
1636                         exp.type = constantExp;
1637                         exp.isConstant = true;
1638                         exp.constant = PrintHexUInt64(address);
1639                         exp.address = address;
1640                         exp.hasAddress = true;
1641                      }
1642                      else if(gotAddress)
1643                      {
1644                         evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1645                         switch(evalError)
1646                         {
1647                            case dummyExp:
1648                               if(evaluation)
1649                               {
1650                                  expNew = ParseExpressionString(evaluation);
1651                                  delete evaluation;
1652                                  expNew.destType = exp.expType;
1653                                  FreeType(exp.destType);
1654                                  FreeExpContents(exp);
1655                                  ProcessExpressionType(expNew);
1656                                  DebugComputeExpression(expNew);
1657
1658                                  // TOFIX: Only for Array Types
1659                                  expNew.address = address;
1660
1661                                  expNew.hasAddress = true;
1662                                  expNew.prev = prev;
1663                                  expNew.next = next;
1664                                  expNew.isConstant = true;
1665                                  *exp = *expNew;
1666                                  delete expNew;
1667                               }
1668                               else
1669                               {
1670                                  // Unhandled code path, evaluation is null
1671                                  FreeExpContents(exp);
1672                                  exp.type = unknownErrorExp;
1673                               }
1674                               break;
1675                            case memoryErrorExp:
1676                               delete evaluation;
1677                               FreeExpContents(exp);
1678                               exp.type = evalError;
1679                               exp.constant = PrintHexUInt64(address);
1680                               break;
1681                            default:
1682                               delete evaluation;
1683                               FreeExpContents(exp);
1684                               exp.type = evalError;
1685                               break;
1686                         }
1687                      }
1688                      else
1689                      {
1690                         FreeExpContents(exp);
1691                         exp.type = unknownErrorExp;
1692                      }
1693                   }
1694                }
1695             }
1696          }
1697          break;
1698       }
1699       case callExp:
1700       {
1701          Expression callExp = exp.call.exp;
1702          Identifier id = (callExp && callExp.type == identifierExp) ? callExp.identifier : null;
1703          bool resolved = false;
1704          if(id && id.string)
1705          {
1706             if(!strcmp(id.string, "nan") || !strcmp(id.string, "inf"))
1707             {
1708                String s = id.string;
1709                id.string = null;
1710                FreeExpContents(exp);
1711                exp.type = constantExp;
1712                exp.constant = s;
1713                resolved = true;
1714             }
1715             else if(exp.call.arguments)
1716             {
1717                if(exp.call.arguments->count == 1)
1718                {
1719                   double (* fn1)(double) = (void *)oneArgFns[id.string];
1720                   if(fn1)
1721                   {
1722                      Expression arg = exp.call.arguments->first;
1723                      DebugComputeExpression(arg);
1724                      if(ExpressionIsError(arg))
1725                         CarryExpressionError(exp, arg);
1726                      else if(arg.isConstant && arg.type == constantExp)
1727                      {
1728                         double v;
1729                         if(GetDouble(arg, &v))
1730                         {
1731                            FreeExpContents(exp);
1732                            exp.type = constantExp;
1733                            v = fn1(v);
1734                            exp.constant = DebugPrintDouble(v);
1735                            exp.isConstant = true;
1736                            resolved = true;
1737                         }
1738                      }
1739                   }
1740                }
1741                else if(exp.call.arguments->count == 2)
1742                {
1743                   double (* fn2)(double, double) = (void *)twoArgFns[id.string];
1744                   if(fn2)
1745                   {
1746                      Expression arg1 = exp.call.arguments->first;
1747                      Expression arg2 = exp.call.arguments->last;
1748                      DebugComputeExpression(arg1);
1749                      DebugComputeExpression(arg2);
1750                      if(ExpressionIsError(arg1))
1751                         CarryExpressionError(exp, arg1);
1752                      else if(ExpressionIsError(arg2))
1753                         CarryExpressionError(exp, arg2);
1754                      else if(arg1.isConstant && arg1.type == constantExp && arg2.isConstant && arg2.type == constantExp)
1755                      {
1756                         double v1, v2;
1757                         if(GetDouble(arg1, &v1) && GetDouble(arg2, &v2))
1758                         {
1759                            FreeExpContents(exp);
1760                            exp.type = constantExp;
1761                            v1 = fn2(v1, v2);
1762                            exp.constant = DebugPrintDouble(v1);
1763                            exp.isConstant = true;
1764                            resolved = true;
1765                         }
1766                      }
1767                   }
1768                }
1769             }
1770          }
1771          if(!resolved)
1772             exp.type = functionCallErrorExp;
1773          break;
1774       }
1775       case memberExp:
1776       {
1777          Expression memberExp = exp.member.exp;
1778          Identifier memberID = exp.member.member;
1779          //Class _class;
1780          Property prop = null;
1781          DataMember member = null;
1782          Class convertTo = null;
1783          uint offset = 0;  // THIS WASN'T INITIALIZED... IS IT ALWAYS SET?
1784
1785          Type type; // = memberExp.expType;
1786          DebugComputeExpression(memberExp);
1787          type = memberExp.expType;
1788          if(ExpressionIsError(memberExp))
1789             CarryExpressionError(exp, memberExp);
1790          else if(type)
1791          {
1792             // _class = (memberID && memberID.classSym) ? memberID.classSym.registered : ((type.kind == classType && type._class) ? type._class.registered : null);
1793             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);
1794             if(!_class)
1795             {
1796                char string[256] = "";
1797                Symbol classSym;
1798                PrintTypeNoConst(type, string, false, true);
1799                classSym = FindClass(string);
1800                _class = classSym ? classSym.registered : null;
1801             }
1802
1803             if(memberID && _class)
1804             {
1805                /*
1806                prop = eClass_FindProperty(_class, memberID.string);
1807                if(!prop)
1808                   member = eClass_FindDataMember(_class, memberID.string);
1809                */
1810                // member = eClass_FindDataMember(_class, memberID.string);
1811                member = eClass_FindDataMemberAndOffset(_class, memberID.string, &offset, _class.module.application, null, null);
1812                if(!member)
1813                   prop = eClass_FindProperty(_class, memberID.string, _class.module.application);
1814             }
1815             if(!prop && !member && _class && memberID)
1816             {
1817                Symbol classSym = FindClass(memberID.string);
1818                convertTo = _class;
1819                _class = classSym ? classSym.registered : null;
1820                if(_class)
1821                   prop = eClass_FindProperty(_class, convertTo.fullName, _class.module.application);
1822             }
1823
1824             //DebugComputeExpression(memberExp);
1825             if(ExpressionIsError(memberExp))
1826                CarryExpressionError(exp, memberExp);
1827             else
1828             {
1829                if(exp.member.memberType == methodMember)
1830                {
1831                   FreeExpContents(exp);
1832                   exp.type = unknownErrorExp;
1833                }
1834                else if(prop)
1835                {
1836                   bool supported = false;
1837                   if(prop.compiled)
1838                   {
1839                      Type type = prop.dataType;
1840                      // TODO: Assuming same base type for units...
1841                      if(_class.type == unitClass)
1842                      {
1843                         if(type.kind == classType)
1844                         {
1845                            Class _class = type._class.registered;
1846                            if(_class.type == unitClass)
1847                            {
1848                               if(!_class.dataType)
1849                                  _class.dataType = ProcessTypeString(_class.dataTypeString, false);
1850                               type = _class.dataType;
1851                            }
1852                         }
1853                         switch(type.kind)
1854                         {
1855                            case floatType:
1856                            {
1857                               float value;
1858                               float (*Get)(float) = (convertTo ? (void *)prop.Set : (void *)prop.Get);
1859                               GetFloat(memberExp, &value);
1860
1861                               FreeExpContents(exp);
1862                               exp.constant = DebugPrintFloat(Get ? Get(value) : value);
1863                               exp.type = constantExp;
1864                               exp.isConstant = true;
1865                               supported = true;
1866                               break;
1867                            }
1868                            case doubleType:
1869                            {
1870                               double value;
1871                               double (*Get)(double) = (convertTo ? (void *)prop.Set : (void *)prop.Get);
1872                               GetDouble(memberExp, &value);
1873
1874                               FreeExpContents(exp);
1875                               exp.constant = DebugPrintDouble(Get ? Get(value) : value);
1876                               exp.isConstant = true;
1877                               exp.type = constantExp;
1878                               supported = true;
1879                               break;
1880                            }
1881                         }
1882                      }
1883                      else
1884                      {
1885                         if(convertTo)
1886                         {
1887                            Expression value = memberExp;
1888                            Type type = prop.dataType;
1889                            exp.member.exp = null;
1890
1891                            if(_class.type == structClass)
1892                            {
1893                               switch(type.kind)
1894                               {
1895                                  case classType:
1896                                  {
1897                                     Class propertyClass = type._class.registered;
1898                                     if(propertyClass.type == structClass && value.type == instanceExp)
1899                                     {
1900                                        void (*Set)(void *, void *) = (void *)prop.Set;
1901                                        FreeExpContents(exp);
1902                                        exp.instance = Instantiation
1903                                        {
1904                                           data = new0 byte[_class.structSize];
1905                                           _class = MkSpecifierName(_class.name);
1906                                           loc = exp.loc;
1907                                        };
1908                                        exp.type = instanceExp;
1909
1910                                        Set(exp.instance.data, value.instance.data);
1911                                        PopulateInstance(exp.instance);
1912                                        supported = true;
1913                                     }
1914                                     break;
1915                                  }
1916                                  case intType:
1917                                  {
1918                                     int intValue;
1919                                     void (*Set)(void *, int) = (void *)prop.Set;
1920
1921                                     GetInt(value, &intValue);
1922                                     FreeExpContents(exp);
1923                                     exp.instance = Instantiation
1924                                     {
1925                                        data = new0 byte[_class.structSize];
1926                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1927                                        loc = exp.loc;
1928                                     };
1929                                     exp.type = instanceExp;
1930
1931                                     Set(exp.instance.data, intValue);
1932                                     PopulateInstance(exp.instance);
1933                                     supported = true;
1934                                     break;
1935                                  }
1936                                  case int64Type:
1937                                  {
1938                                     int64 intValue;
1939                                     void (*Set)(void *, int64) = (void *)prop.Set;
1940
1941                                     GetInt64(value, &intValue);
1942                                     FreeExpContents(exp);
1943                                     exp.instance = Instantiation
1944                                     {
1945                                        data = new0 byte[_class.structSize];
1946                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1947                                        loc = exp.loc;
1948                                     };
1949                                     exp.type = instanceExp;
1950
1951                                     Set(exp.instance.data, intValue);
1952                                     PopulateInstance(exp.instance);
1953                                     supported = true;
1954                                     break;
1955                                  }
1956                                  case floatType:
1957                                  {
1958                                     float floatValue;
1959                                     void (*Set)(void *, float) = (void *)prop.Set;
1960
1961                                     GetFloat(value, &floatValue);
1962                                     FreeExpContents(exp);
1963                                     exp.instance = Instantiation
1964                                     {
1965                                        data = new0 byte[_class.structSize];
1966                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1967                                        loc = exp.loc;
1968                                     };
1969                                     exp.type = instanceExp;
1970
1971                                     Set(exp.instance.data, floatValue);
1972                                     PopulateInstance(exp.instance);
1973                                     supported = true;
1974                                     break;
1975                                  }
1976                                  case doubleType:
1977                                  {
1978                                     double doubleValue;
1979                                     void (*Set)(void *, double) = (void *)prop.Set;
1980
1981                                     GetDouble(value, &doubleValue);
1982                                     FreeExpContents(exp);
1983                                     exp.instance = Instantiation
1984                                     {
1985                                        data = new0 byte[_class.structSize];
1986                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1987                                        loc = exp.loc;
1988                                     };
1989                                     exp.type = instanceExp;
1990
1991                                     Set(exp.instance.data, doubleValue);
1992                                     PopulateInstance(exp.instance);
1993                                     supported = true;
1994                                     break;
1995                                  }
1996                               }
1997                            }
1998                            else if(_class.type == bitClass)
1999                            {
2000                               switch(type.kind)
2001                               {
2002                                  case classType:
2003                                  {
2004                                     Class propertyClass = type._class.registered;
2005                                     if(propertyClass.type == structClass && value.instance.data)
2006                                     {
2007                                        unsigned int (*Set)(void *) = (void *)prop.Set;
2008                                        unsigned int bits = Set(value.instance.data);
2009                                        FreeExpContents(exp);
2010                                        exp.constant = PrintHexUInt(bits);
2011                                        exp.type = constantExp;
2012                                        supported = true;
2013                                        break;
2014                                     }
2015                                     else if(_class.type == bitClass)
2016                                     {
2017                                        unsigned int value;
2018                                        unsigned int (*Set)(unsigned int) = (void *)prop.Set;
2019                                        unsigned int bits;
2020
2021                                        GetUInt(memberExp, &value);
2022                                        bits = Set(value);
2023                                        FreeExpContents(exp);
2024                                        exp.constant = PrintHexUInt(bits);
2025                                        exp.type = constantExp;
2026                                        supported = true;
2027                                     }
2028                                  }
2029                               }
2030                            }
2031                            FreeExpression(value);
2032                         }
2033                         else
2034                         {
2035                            if(_class.type == bitClass)
2036                            {
2037                               uint value;
2038                               GetUInt(memberExp, &value);
2039
2040                               switch(type.kind)
2041                               {
2042                                  case classType:
2043                                  {
2044                                     Class _class = type._class.registered;
2045                                     if(_class.type == structClass)
2046                                     {
2047                                        void (*Get)(unsigned int, void *) = (void *)prop.Get;
2048
2049                                        FreeExpContents(exp);
2050                                        exp.instance = Instantiation
2051                                        {
2052                                           data = new0 byte[_class.structSize];
2053                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
2054                                           loc = exp.loc;
2055                                        };
2056                                        //exp.instance.fullSet = true;
2057                                        exp.type = instanceExp;
2058                                        Get(value, exp.instance.data);
2059                                        PopulateInstance(exp.instance);
2060                                        supported = true;
2061                                     }
2062                                     else if(_class.type == bitClass)
2063                                     {
2064                                        unsigned int (*Get)(unsigned int) = (void *)prop.Get;
2065                                        uint64 bits = Get(value);
2066                                        exp.constant = PrintHexUInt64(bits);
2067                                        exp.type = constantExp;
2068                                        supported = true;
2069                                     }
2070                                     break;
2071                                  }
2072                               }
2073                            }
2074                            else if(_class.type == structClass)
2075                            {
2076                               byte * value = (memberExp.type == instanceExp ) ? memberExp.instance.data : null;
2077                               if(value)
2078                                  memberExp.instance.data = null;
2079
2080                               switch(type.kind)
2081                               {
2082                                  case classType:
2083                                  {
2084                                     Class _class = type._class.registered;
2085                                     if(_class.type == structClass && value)
2086                                     {
2087                                        void (*Get)(void *, void *) = (void *)prop.Get;
2088
2089                                        FreeExpContents(exp);
2090                                        exp.instance = Instantiation
2091                                        {
2092                                           data = new0 byte[_class.structSize];
2093                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
2094                                           loc = exp.loc;
2095                                        };
2096                                        //exp.instance.fullSet = true;
2097                                        exp.type = instanceExp;
2098                                        Get(value, exp.instance.data);
2099                                        PopulateInstance(exp.instance);
2100                                        supported = true;
2101                                     }
2102                                     break;
2103                                  }
2104                               }
2105
2106                               delete value;
2107                            }
2108                            /*else
2109                            {
2110                               char * value = memberExp.instance.data;
2111                               switch(type.kind)
2112                               {
2113                                  case classType:
2114                                  {
2115                                     Class _class = type._class.registered;
2116                                     if(_class.type == normalClass)
2117                                     {
2118                                        void *(*Get)(void *) = (void *)prop.Get;
2119
2120                                        FreeExpContents(exp);
2121                                        exp.instance = Instantiation
2122                                        {
2123                                           data = Get(value, exp.instance.data);     ?????
2124                                           _class = MkSpecifierName(_class.name); //MkClassName(_class.name);
2125                                           loc = exp.loc;
2126                                        };
2127                                        exp.type = instanceExp;
2128                                     }
2129                                     break;
2130                                  }
2131                               }
2132                            }
2133                            */
2134                         }
2135                      }
2136                   }
2137                   if(!supported)
2138                   {
2139                      exp.type = memberPropertyErrorExp;
2140                      exp.isConstant = false;
2141                   }
2142                }
2143                else if(member)
2144                {
2145                   if(memberExp.hasAddress || memberExp.type == constantExp || (memberExp.type == instanceExp && memberExp.instance && memberExp.instance.data))
2146                   //if(memberExp.expType && memberExp.expType.kind == intType)  // && !exp.index.exp.expType.isSigned
2147                   {
2148                      if(_class.type == bitClass)
2149                      {
2150                         if(memberExp.type == constantExp)
2151                         {
2152                            // Unfinished business...
2153                            BitMember bitMember = (BitMember)member;
2154                            uint64 bits = 0;
2155                            GetUInt64(memberExp, &bits);
2156                            bits &= bitMember.mask;
2157                            bits >>= bitMember.pos;
2158
2159                            FreeExpression(exp.member.exp);
2160                            FreeIdentifier(exp.member.member);
2161
2162                            exp.constant = PrintUInt64(bits);
2163
2164                            exp.isConstant = true;
2165                            exp.type = constantExp;
2166                            exp.hasAddress = false;
2167                         }
2168                      }
2169                      else
2170                      {
2171                         char * evaluation = null;
2172                         ExpressionType evalError = dummyExp;
2173                         bool gotAddress = false;
2174                         uint64 address = 0;
2175                         Expression prev = exp.prev, next = exp.next;
2176                         char format;
2177                         int size;
2178                         Expression expNew;
2179                         Type dataType = member.dataType;
2180
2181                         if(!dataType)
2182                            dataType = member.dataType = ProcessTypeString(member.dataTypeString, false);
2183
2184                         if(dataType && dataType.kind == classType && dataType._class.registered &&
2185                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
2186                         {
2187                            if(!dataType._class.registered.dataType && dataType._class.registered.dataTypeString)
2188                               dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
2189                            dataType = dataType._class.registered.dataType;
2190                            if(!dataType)
2191                               dataType = ProcessTypeString("int", false);
2192                         }
2193
2194                         size = ComputeTypeSize(member.dataType);
2195
2196                         format = GetGdbFormatChar(dataType);
2197                         //if(memberExp.address)
2198                         {
2199                            //GetInt(memberExp, &address);
2200                            //offset = member.offset;
2201
2202                            // TESTING NOHEAD HERE?
2203                            if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass)
2204                               offset += member._class.offset;
2205
2206                            // VERIFY THIS: (trying to fix primitive.type)
2207                            // if(memberExp.type == constantExp)
2208                            if(memberExp.hasAddress && (_class.type != normalClass && _class.type != noHeadClass && _class.type != systemClass))
2209                            {
2210                               address = memberExp.address;
2211                               gotAddress = true;
2212                            }
2213                            else if(memberExp.type == constantExp)
2214                               gotAddress = GetUInt64(memberExp, &address);
2215                            else
2216                            {
2217                               gotAddress = GetUInt64(memberExp, &address);
2218                               //printf("Unhandled !!\n");
2219
2220                               //printf("memberExp.hasAddress = %d\n", memberExp.hasAddress);
2221                               //printf("memberExp.type = %d\n", memberExp.type);
2222                               //printf("_class.name = %s, _class.type = %d\n", _class.name, _class.type);
2223                            }
2224
2225                            address += offset;
2226
2227                            if(memberExp.type == instanceExp)
2228                            {
2229                               String constant = null;
2230                               byte * data = memberExp.instance.data + offset;
2231                               switch(dataType.kind)
2232                               {
2233                                  case charType:
2234                                     if(dataType.isSigned)
2235                                        constant = PrintChar(*(char *)data);
2236                                     else
2237                                        constant = PrintUChar(*(byte *)data);
2238                                     break;
2239                                  case shortType:
2240                                     if(dataType.isSigned)
2241                                        constant = PrintShort(*(short *)data);
2242                                     else
2243                                        constant = PrintUShort(*(uint16 *)data);
2244                                     break;
2245                                  case intType:
2246                                     if(dataType.isSigned)
2247                                        constant = PrintInt(*(int *)data);
2248                                     else
2249                                        constant = PrintUInt(*(uint *)data);
2250                                     break;
2251                                  case longType:
2252                                  case int64Type:
2253                                     if(dataType.isSigned)
2254                                        constant = PrintInt64(*(int64 *)data);
2255                                     else
2256                                        constant = PrintUInt64(*(uint64 *)data);
2257                                     break;
2258                                  case floatType: constant = DebugPrintFloat(*(float *)data); break;
2259                                  case doubleType: constant = DebugPrintDouble(*(double *)data); break;
2260                               }
2261                               if(constant)
2262                               {
2263                                  FreeExpContents(exp);
2264                                  exp.constant = constant;
2265                                  exp.type = constantExp;
2266                                  exp.isConstant = true;
2267                               }
2268                               else
2269                                  exp.type = unknownErrorExp;
2270                            }
2271                            else if(!gotAddress)
2272                            {
2273                               FreeExpContents(exp);
2274                               exp.type = unknownErrorExp;
2275                            }
2276                            else if((dataType.kind == classType && dataType._class &&
2277                                  (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
2278                               (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
2279                            {
2280                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
2281                               if(evalError != dummyExp)
2282                               {
2283                                  exp.type = evalError;
2284                                  exp.constant = PrintHexUInt64(address);
2285                               }
2286                               else if(evaluation)
2287                               {
2288                                  //printf("evaluation = %s\n", evaluation);
2289                                  expNew = ParseExpressionString(evaluation);
2290                                  delete evaluation;
2291                                  expNew.destType = exp.expType;
2292                                  if(exp.expType)
2293                                  {
2294                                     exp.expType.refCount++;
2295                                     if(exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == unitClass)
2296                                     {
2297                                        expNew.expType = exp.expType;
2298                                        exp.expType.refCount++;
2299                                     }
2300                                  }
2301                                  //FreeType(memberExp.destType);
2302                                  FreeType(exp.expType);
2303                                  FreeType(exp.destType);
2304                                  FreeExpContents(exp);
2305                                  ProcessExpressionType(expNew);
2306                                  DebugComputeExpression(expNew);
2307                                  expNew.prev = prev;
2308                                  expNew.next = next;
2309                                  expNew.isConstant = true;
2310                                  expNew.address = address;
2311                                  expNew.hasAddress = true;
2312                                  *exp = *expNew;
2313                                  delete expNew;
2314                               }
2315                               else
2316                               {
2317                                  FreeExpContents(exp);
2318                                  exp.type = unknownErrorExp;
2319                               }
2320                            }
2321                            else
2322                            {
2323                               // TESTING THIS HERE...
2324                               exp.type = constantExp;
2325                               exp.constant = PrintHexUInt64(address);
2326
2327                               exp.address = address;
2328                               exp.hasAddress = true;
2329                               exp.isConstant = true;
2330                            }
2331                         }
2332                      }
2333                      //else
2334                      //   exp.type = ExpUnknownError;
2335
2336                      //FreeExpContents(exp);
2337                      //exp.constant = PrintUInt64(value);
2338                      //exp.type = constantExp;
2339                   }
2340                }
2341                else
2342                {
2343                   if(type && (type.kind == structType || type.kind == unionType))
2344                   {
2345                      uint offset = 0;
2346                      Type memberType = exp.member.member ? FindMemberAndOffset(type, exp.member.member.string, &offset) : null;
2347                      if(memberType)
2348                      {
2349                         char * evaluation = null;
2350                         ExpressionType evalError = dummyExp;
2351                         uint64 address = 0;
2352                         bool gotAddress = false;
2353                         Expression prev = exp.prev, next = exp.next;
2354                         char format;
2355                         int size = memberType.size;
2356                         Expression expNew;
2357                         Type dataType = memberType;
2358
2359                         if(dataType.kind == classType && dataType._class.registered &&
2360                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
2361                         {
2362                            if(dataType._class.registered.dataTypeString && !dataType._class.registered.dataType)
2363                               dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
2364                            dataType = dataType._class.registered.dataType;
2365                         }
2366
2367                         format = GetGdbFormatChar(dataType);
2368
2369                         if(memberExp.hasAddress)
2370                         {
2371                            address = memberExp.address;
2372                            gotAddress = true;
2373                         }
2374                         else if(memberExp.type == constantExp)
2375                            gotAddress = GetUInt64(memberExp, &address);
2376
2377                         address += offset;
2378
2379                         if(!gotAddress)
2380                         {
2381                            FreeExpContents(exp);
2382                            exp.type = unknownErrorExp;
2383                         }
2384                         else if((dataType.kind == classType && dataType._class &&
2385                               (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
2386                            (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
2387                         {
2388                            evaluation = Debugger::ReadMemory(address, size, format, &evalError);
2389                            if(evalError != dummyExp)
2390                            {
2391                               exp.type = evalError;
2392                               exp.constant = PrintHexUInt64(address);
2393                            }
2394                            else if(evaluation)
2395                            {
2396                               expNew = ParseExpressionString(evaluation);
2397                               delete evaluation;
2398                               expNew.destType = exp.expType;
2399                               if(exp.expType)
2400                                  exp.expType.refCount++;
2401                               //FreeType(memberExp.destType);
2402                               FreeType(exp.expType);
2403                               FreeType(exp.destType);
2404                               FreeExpContents(exp);
2405                               ProcessExpressionType(expNew);
2406                               DebugComputeExpression(expNew);
2407                               expNew.prev = prev;
2408                               expNew.next = next;
2409                               expNew.isConstant = true;
2410                               expNew.address = address;
2411                               expNew.hasAddress = true;
2412                               *exp = *expNew;
2413                               delete expNew;
2414                            }
2415                            else
2416                            {
2417                               FreeExpContents(exp);
2418                               exp.type = unknownErrorExp;
2419                            }
2420                         }
2421                         else
2422                         {
2423                            FreeExpContents(exp);
2424
2425                            // TESTING THIS HERE...
2426                            exp.type = constantExp;
2427                            exp.constant = PrintHexUInt64(address);
2428
2429                            exp.address = address;
2430                            exp.hasAddress = true;
2431                            exp.isConstant = true;
2432                         }
2433                      }
2434                      else
2435                         exp.type = memberSymbolErrorExp;
2436                   }
2437                   else
2438                      exp.type = memberSymbolErrorExp;
2439                }
2440             }
2441
2442             //if(exp.type != memberExp)
2443             {
2444                //FreeExpression(memberExp);
2445                //FreeIdentifier(memberID);
2446             }
2447          }
2448          else
2449          {
2450             exp.type = memberSymbolErrorExp;
2451          }
2452          break;
2453       }
2454       case typeSizeExp:
2455       {
2456          Type type = ProcessType(exp.typeName.qualifiers, exp.typeName.declarator);
2457          FreeExpContents(exp);
2458          exp.constant = PrintUInt(ComputeTypeSize(type));
2459          exp.type = constantExp;
2460          FreeType(type);
2461          break;
2462       }
2463       case classSizeExp:
2464       {
2465          Symbol classSym = FindClass(exp._class.name);
2466          if(classSym && classSym.registered)
2467          {
2468             //exp.constant = PrintUInt(classSym.registered.size);
2469             //exp.type = constantExp;
2470
2471             char className[1024];
2472             sprintf(className, "__ecereClass_%s", classSym.string);
2473             FreeExpContents(exp);
2474             exp.type = pointerExp;
2475             exp.member.exp = MkExpIdentifier(MkIdentifier(className));
2476             exp.member.member = MkIdentifier("size");
2477          }
2478          break;
2479       }
2480       case castExp:
2481       {
2482          DebugComputeExpression(exp.cast.exp);
2483
2484          if(ExpressionIsError(exp.cast.exp)) //.type == ExpSymbolError
2485             CarryExpressionError(exp, exp.cast.exp);
2486          else
2487          {
2488             exp.hasAddress = exp.cast.exp.hasAddress;
2489             exp.address = exp.cast.exp.address;
2490             if(exp.cast.exp.type == instanceExp && exp.cast.exp.expType && exp.expType && exp.cast.exp.expType.kind == classType && exp.expType.kind == classType &&
2491                exp.cast.exp.expType._class && exp.expType._class && exp.cast.exp.expType._class.registered && exp.expType._class.registered &&
2492                exp.cast.exp.expType._class.registered == exp.expType._class.registered)
2493             {
2494                Instantiation inst = exp.cast.exp.instance;
2495                exp.cast.exp.instance = null;
2496                FreeExpContents(exp);
2497                exp.instance = inst;
2498                exp.type = instanceExp;
2499             }
2500             else if(exp.cast.exp.type == constantExp && exp.expType)
2501             {
2502                Type type = exp.expType;
2503                if(type.kind == classType && type._class && type._class.registered)
2504                {
2505                   Class _class = type._class.registered;
2506                   if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
2507                   {
2508                      if(!_class.dataType)
2509                         _class.dataType = ProcessTypeString(_class.dataTypeString, false);
2510                      type = _class.dataType;
2511                   }
2512                   else if(_class.type == structClass && !type.byReference)
2513                   {
2514                      FreeExpContents(exp);
2515                      exp.type = unknownErrorExp;
2516                      break;
2517                   }
2518                }
2519
2520                switch(type.kind)
2521                {
2522                   case charType:
2523                      if(type.isSigned)
2524                      {
2525                         char value = 0;
2526                         if(GetChar(exp.cast.exp, &value))
2527                         {
2528                            FreeExpContents(exp);
2529                            exp.constant = PrintChar(value);
2530                            exp.type = constantExp;
2531                            exp.isConstant = true;
2532                         }
2533                      }
2534                      else
2535                      {
2536                         unsigned char value = 0;
2537                         if(GetUChar(exp.cast.exp, &value))
2538                         {
2539                            FreeExpContents(exp);
2540                            exp.constant = PrintUChar(value);
2541                            exp.type = constantExp;
2542                            exp.isConstant = true;
2543                         }
2544                      }
2545                      break;
2546                   case shortType:
2547                      if(type.isSigned)
2548                      {
2549                         short value = 0;
2550                         if(GetShort(exp.cast.exp, &value))
2551                         {
2552                            FreeExpContents(exp);
2553                            exp.constant = PrintShort(value);
2554                            exp.type = constantExp;
2555                            exp.isConstant = true;
2556                         }
2557                      }
2558                      else
2559                      {
2560                         unsigned short value = 0;
2561                         if(GetUShort(exp.cast.exp, &value))
2562                         {
2563                            FreeExpContents(exp);
2564                            exp.constant = PrintUShort(value);
2565                            exp.type = constantExp;
2566                            exp.isConstant = true;
2567                         }
2568                      }
2569                      break;
2570                   case intType:
2571                      if(type.isSigned)
2572                      {
2573                         int value = 0;
2574                         if(GetInt(exp.cast.exp, &value))
2575                         {
2576                            FreeExpContents(exp);
2577                            exp.constant = PrintInt(value);
2578                            exp.type = constantExp;
2579                            exp.isConstant = true;
2580                         }
2581                      }
2582                      else
2583                      {
2584                         unsigned int value = 0;
2585                         if(GetUInt(exp.cast.exp, &value))
2586                         {
2587                            FreeExpContents(exp);
2588                            exp.constant = PrintUInt(value);
2589                            exp.type = constantExp;
2590                            exp.isConstant = true;
2591                         }
2592                      }
2593                      break;
2594                   case int64Type:
2595                      if(type.isSigned)
2596                      {
2597                         int64 value = 0;
2598                         if(GetInt64(exp.cast.exp, &value))
2599                         {
2600                            FreeExpContents(exp);
2601                            exp.constant = PrintInt64(value);
2602                            exp.type = constantExp;
2603                            exp.isConstant = true;
2604                         }
2605                      }
2606                      else
2607                      {
2608                         uint64 value = 0;
2609                         if(GetUInt64(exp.cast.exp, &value))
2610                         {
2611                            FreeExpContents(exp);
2612                            exp.constant = PrintUInt64(value);
2613                            exp.type = constantExp;
2614                            exp.isConstant = true;
2615                         }
2616                      }
2617                      break;
2618                   case pointerType:
2619                   case classType:
2620                   {
2621                      uint64 value = 0;
2622                      if(GetUInt64(exp.cast.exp, &value))
2623                      {
2624                         FreeExpContents(exp);
2625                         if(type.kind == pointerType || type.kind == classType)
2626                            exp.constant = PrintHexUInt64(value);
2627                         else
2628                            exp.constant = PrintUInt64(value);
2629                         exp.type = constantExp;
2630                         exp.isConstant = true;
2631                      }
2632                      break;
2633                   }
2634                   case floatType:
2635                   {
2636                      float value = 0;
2637                      if(exp.cast.exp.type == constantExp && exp.cast.exp.constant &&
2638                         (!strcmpi(exp.cast.exp.constant, "nan") ||
2639                         !strcmpi(exp.cast.exp.constant, "-nan") ||
2640                         !strcmpi(exp.cast.exp.constant, "inf") ||
2641                         !strcmpi(exp.cast.exp.constant, "-inf")))
2642                      {
2643                         String constant = exp.cast.exp.constant;
2644                         exp.cast.exp.constant = null;
2645                         FreeExpContents(exp);
2646                         exp.constant = constant;
2647                         exp.type = constantExp;
2648                         exp.isConstant = true;
2649                      }
2650                      else if(GetFloat(exp.cast.exp, &value))
2651                      {
2652                         FreeExpContents(exp);
2653                         exp.constant = DebugPrintFloat(value);
2654                         exp.type = constantExp;
2655                         exp.isConstant = true;
2656                      }
2657                      break;
2658                   }
2659                   case doubleType:
2660                   {
2661                      double value = 0;
2662                      if(exp.cast.exp.type == constantExp && exp.cast.exp.constant &&
2663                         (!strcmpi(exp.cast.exp.constant, "nan") ||
2664                         !strcmpi(exp.cast.exp.constant, "-nan") ||
2665                         !strcmpi(exp.cast.exp.constant, "inf") ||
2666                         !strcmpi(exp.cast.exp.constant, "-inf")))
2667                      {
2668                         String constant = exp.cast.exp.constant;
2669                         exp.cast.exp.constant = null;
2670                         FreeExpContents(exp);
2671                         exp.constant = constant;
2672                         exp.type = constantExp;
2673                         exp.isConstant = true;
2674                      }
2675                      else if(GetDouble(exp.cast.exp, &value))
2676                      {
2677                         FreeExpContents(exp);
2678                         exp.constant = DebugPrintDouble(value);
2679                         exp.type = constantExp;
2680                         exp.isConstant = true;
2681                      }
2682                      break;
2683                   }
2684                }
2685             }
2686          }
2687          break;
2688       }
2689       case conditionExp:
2690       {
2691          if(exp.cond.cond)
2692          {
2693             DebugComputeExpression(exp.cond.cond);
2694
2695             if(ExpressionIsError(exp.cond.cond))
2696                CarryExpressionError(exp, exp.cond.cond);
2697             else if(exp.cond.cond.type == constantExp && exp.cond.cond.constant)
2698             {
2699                Expression e = null;
2700                if(strtol(exp.cond.cond.constant, null, 0))
2701                {
2702                   for(e = exp.cond.exp ? exp.cond.exp->first : null; e; e = e.next)
2703                   {
2704                      DebugComputeExpression(e);
2705                      if(!e.next) break;
2706                   }
2707                   if(e)
2708                   {
2709                      if(ExpressionIsError(e))
2710                      {
2711                         CarryExpressionError(exp, e);
2712                         e = null;
2713                      }
2714                      else
2715                         exp.cond.exp->Remove(e);
2716                   }
2717                }
2718                else
2719                {
2720                   e = exp.cond.elseExp;
2721                   if(e)
2722                   {
2723                      DebugComputeExpression(e);
2724                      if(ExpressionIsError(e))
2725                      {
2726                         CarryExpressionError(exp, e);
2727                         e = null;
2728                      }
2729                      else
2730                         exp.cond.elseExp = null;
2731                   }
2732                }
2733                if(e)
2734                {
2735                   FreeType(exp.expType);
2736                   FreeType(exp.destType);
2737                   e.prev = exp.prev;
2738                   e.next = exp.next;
2739                   FreeExpContents(exp);
2740                   *exp = *e;
2741                   delete e;
2742                }
2743                else if(!ExpressionIsError(exp))
2744                {
2745                   FreeExpContents(exp);
2746                   exp.type = unknownErrorExp;
2747                }
2748             }
2749             else
2750             {
2751                FreeExpContents(exp);
2752                exp.type = unknownErrorExp;
2753             }
2754          }
2755          else
2756          {
2757             FreeExpContents(exp);
2758             exp.type = unknownErrorExp;
2759          }
2760          break;
2761       }
2762    }
2763 }
2764
2765 void ApplyUnitConverters(Expression exp)
2766 {
2767    Property convert = null;
2768    Type type = exp.expType;
2769    bool useGet = false;
2770    if(type.kind == classType && type._class && type._class.registered)
2771    {
2772       Class _class = type._class.registered;
2773       if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
2774       {
2775          if(_class.type == unitClass && _class.base.type == unitClass)
2776          {
2777             Property p;
2778             for(p = _class.conversions.first; p; p = p.next)
2779             {
2780                if(!strcmp(p.name, _class.base.fullName))
2781                {
2782                   convert = p;
2783                   break;
2784                }
2785                else
2786                {
2787                   Class c = eSystem_FindClass(_class.module, p.name);
2788                   if(c)
2789                   {
2790                      Property p2;
2791                      for(p2 = c.conversions.first; p2; p2 = p2.next)
2792                      {
2793                         if(!strcmp(p2.name, _class.base.fullName))
2794                         {
2795                            convert = p;
2796                            break;
2797                         }
2798                      }
2799                   }
2800                   if(convert)
2801                      break;
2802                }
2803             }
2804          }
2805
2806          if(!_class.dataType)
2807             _class.dataType = ProcessTypeString(_class.dataTypeString, false);
2808          type = _class.dataType;
2809       }
2810    }
2811    if(convert)
2812    {
2813       switch(type.kind)
2814       {
2815          case charType:
2816             if(type.isSigned)
2817             {
2818                char value = 0;
2819                if(GetChar(exp, &value))
2820                {
2821                   FreeExpContents(exp);
2822                   exp.constant = PrintChar(value);
2823                   exp.type = constantExp;
2824                   exp.isConstant = true;
2825                }
2826             }
2827             else
2828             {
2829                unsigned char value = 0;
2830                if(GetUChar(exp, &value))
2831                {
2832                   FreeExpContents(exp);
2833                   exp.constant = PrintUChar(value);
2834                   exp.type = constantExp;
2835                   exp.isConstant = true;
2836                }
2837             }
2838             break;
2839          case shortType:
2840             if(type.isSigned)
2841             {
2842                short value = 0;
2843                if(GetShort(exp, &value))
2844                {
2845                   FreeExpContents(exp);
2846                   exp.constant = PrintShort(value);
2847                   exp.type = constantExp;
2848                   exp.isConstant = true;
2849                }
2850             }
2851             else
2852             {
2853                unsigned short value = 0;
2854                if(GetUShort(exp, &value))
2855                {
2856                   FreeExpContents(exp);
2857                   exp.constant = PrintUShort(value);
2858                   exp.type = constantExp;
2859                   exp.isConstant = true;
2860                }
2861             }
2862             break;
2863          case intType:
2864             if(type.isSigned)
2865             {
2866                int value = 0;
2867                if(GetInt(exp, &value))
2868                {
2869                   FreeExpContents(exp);
2870                   exp.constant = PrintInt(value);
2871                   exp.type = constantExp;
2872                   exp.isConstant = true;
2873                }
2874             }
2875             else
2876             {
2877                unsigned int value = 0;
2878                if(GetUInt(exp, &value))
2879                {
2880                   FreeExpContents(exp);
2881                   exp.constant = PrintUInt(value);
2882                   exp.type = constantExp;
2883                   exp.isConstant = true;
2884                }
2885             }
2886             break;
2887          case int64Type:
2888             if(type.isSigned)
2889             {
2890                int64 value = 0;
2891                if(GetInt64(exp, &value))
2892                {
2893                   FreeExpContents(exp);
2894                   exp.constant = PrintInt64(value);
2895                   exp.type = constantExp;
2896                   exp.isConstant = true;
2897                }
2898             }
2899             else
2900             {
2901                uint64 value = 0;
2902                if(GetUInt64(exp, &value))
2903                {
2904                   FreeExpContents(exp);
2905                   exp.constant = PrintUInt64(value);
2906                   exp.type = constantExp;
2907                   exp.isConstant = true;
2908                }
2909             }
2910             break;
2911          case pointerType:
2912          case classType:
2913          {
2914             uint64 value = 0;
2915             if(GetUInt64(exp, &value))
2916             {
2917                FreeExpContents(exp);
2918                if(type.kind == pointerType || type.kind == classType)
2919                   exp.constant = PrintHexUInt64(value);
2920                else
2921                   exp.constant = PrintUInt64(value);
2922                exp.type = constantExp;
2923                exp.isConstant = true;
2924             }
2925             break;
2926          }
2927          case floatType:
2928          {
2929             float value = 0;
2930             if(exp.type == constantExp && exp.constant &&
2931                (!strcmpi(exp.constant, "nan") ||
2932                !strcmpi(exp.constant, "-nan") ||
2933                !strcmpi(exp.constant, "inf") ||
2934                !strcmpi(exp.constant, "-inf")))
2935             {
2936                String constant = exp.constant;
2937                exp.constant = null;
2938                FreeExpContents(exp);
2939                exp.constant = constant;
2940                exp.type = constantExp;
2941                exp.isConstant = true;
2942             }
2943             else if(GetFloat(exp, &value))
2944             {
2945                if(convert)
2946                {
2947                   float (*convertFn)(float) = (useGet ? (void *)convert.Get : (void *)convert.Set);
2948                   if(convertFn)
2949                      value = convertFn(value);
2950                }
2951                FreeExpContents(exp);
2952                exp.constant = DebugPrintFloat(value);
2953                exp.type = constantExp;
2954                exp.isConstant = true;
2955             }
2956             break;
2957          }
2958          case doubleType:
2959          {
2960             double value = 0;
2961             if(exp.type == constantExp && exp.constant &&
2962                (!strcmpi(exp.constant, "nan") ||
2963                !strcmpi(exp.constant, "-nan") ||
2964                !strcmpi(exp.constant, "inf") ||
2965                !strcmpi(exp.constant, "-inf")))
2966             {
2967                String constant = exp.constant;
2968                exp.constant = null;
2969                FreeExpContents(exp);
2970                exp.constant = constant;
2971                exp.type = constantExp;
2972                exp.isConstant = true;
2973             }
2974             else if(GetDouble(exp, &value))
2975             {
2976                if(convert)
2977                {
2978                   double (*convertFn)(double) = (useGet ? (void *)convert.Get : (void *)convert.Set);
2979                   if(convertFn)
2980                      value = convertFn(value);
2981                }
2982                FreeExpContents(exp);
2983                exp.constant = DebugPrintDouble(value);
2984                exp.type = constantExp;
2985                exp.isConstant = true;
2986             }
2987             break;
2988          }
2989       }
2990    }
2991 }