ide/debugger/watches: Fixed evaluating casted indexed arrays
[sdk] / ide / src / debugger / debugTools.ec
index 45e1c94..e7a0815 100644 (file)
@@ -1,7 +1,5 @@
 import "ide"
 
-#include <math.h>
-
 static Map<String, uintptr> oneArgFns
 { [
    { "sqrt", (uintptr)sqrt },
@@ -23,7 +21,6 @@ static Map<String, uintptr> oneArgFns
    { "floor", (uintptr)floor },
    { "ceil", (uintptr)ceil },
    { "fabs", (uintptr)sqrt }
-
 ] };
 
 static Map<String, uintptr> twoArgFns
@@ -157,11 +154,27 @@ void DebugComputeExpression(Expression exp)
          Expression expNew;
          TypeKind kind = dummyType;
          Type dataType = exp.expType;
-
-         char temp[1024];
-         uint64 address;
+         uint64 address = 0;
          bool hasAddress;
          bool isPointer = false;
+         bool evaluate = false;
+         bool evaluateAddress = false;
+         String idString = null;
+         if(exp.identifier.string)
+         {
+            const String start = (exp.identifier.string[0] == ':' && exp.identifier.string[1] == ':') ? exp.identifier.string + 2 : exp.identifier.string;
+            if(strstr(start, "::"))
+            {
+               char prefix[] = "__ecereNameSpace__";
+               int len = strlen(start);
+               idString = new char[len + sizeof(prefix)];
+               memcpy(idString, prefix, sizeof(prefix) - 1);
+               memcpy(idString + sizeof(prefix) - 1, start, len + 1);
+               ChangeCh(idString + sizeof(prefix) - 1, ':', '_');
+            }
+            else
+               idString = CopyString(exp.identifier.string);
+         }
 
          if(dataType && dataType.kind == classType && dataType._class.registered)
          {
@@ -183,7 +196,6 @@ void DebugComputeExpression(Expression exp)
             kind = dataType.kind;
          else
             exp.type = symbolErrorExp;
-         temp[0] = '\0';
          switch(kind)
          {
             case intPtrType: case intSizeType: case _BoolType:
@@ -193,14 +205,16 @@ void DebugComputeExpression(Expression exp)
             case structType:
             case pointerType:
             case unionType:
-               sprintf(temp, "&%s", exp.identifier.string);
+               evaluate = true;
+               evaluateAddress = true;
                break;
             case classType:
                if(exp.byReference && dataType._class && dataType._class.registered && dataType._class.registered.type == structClass)
                // if(!dataType._class || !dataType._class.registered || dataType._class.registered.type != structClass || exp.byReference)
-                  strcpy(temp, exp.identifier.string);
+                  evaluateAddress = false;
                else
-                  sprintf(temp, "&%s", exp.identifier.string);
+                  evaluateAddress = true;
+               evaluate = true;
                break;
             case functionType:
             case ellipsisType:
@@ -210,8 +224,17 @@ void DebugComputeExpression(Expression exp)
             case dummyType:
                break;
          }
-         if(temp[0])
+         if(evaluate)
          {
+            char temp[1024];
+            if(evaluateAddress)
+            {
+               temp[0] = '&';
+               strcpy(temp + 1, idString);
+            }
+            else
+               strcpy(temp, idString);
+
             evaluation = Debugger::EvaluateExpression(temp, &evalError);
             if(evaluation)
             {
@@ -232,7 +255,7 @@ void DebugComputeExpression(Expression exp)
             {
                case charType:
                   delete evaluation;
-                  evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
+                  evaluation = Debugger::EvaluateExpression(idString, &evalError);
                   if(evaluation)
                   {
                      //int c, len;
@@ -260,7 +283,7 @@ void DebugComputeExpression(Expression exp)
                case enumType:
                case pointerType:
                   delete evaluation;
-                  evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
+                  evaluation = Debugger::EvaluateExpression(idString, &evalError);
                   if(evaluation)
                   {
                      if(kind == pointerType)
@@ -278,7 +301,7 @@ void DebugComputeExpression(Expression exp)
                      int size;
                      char format;
                      delete evaluation;
-                     //evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
+                     //evaluation = Debugger::EvaluateExpression(idString, &evalError);
                      size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
                      format = GetGdbFormatChar(exp.expType);
                      evaluation = Debugger::ReadMemory(address, size, format, &evalError);
@@ -289,14 +312,14 @@ void DebugComputeExpression(Expression exp)
                case structType:
                case unionType:
                case functionType:
-                  //evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
+                  //evaluation = Debugger::EvaluateExpression(idString, &evalError);
                   delete evaluation;
                   break;
                case arrayType:
                {
                   // for classType  --> if(_class.type == structClass) ?
                   //char temp[1024];
-                  //sprintf(temp, "&%s", exp.identifier.string);
+                  //sprintf(temp, "&%s", idString);
                   //evaluation = Debugger::EvaluateExpression(temp, &evalError);
                   break;
                }
@@ -306,15 +329,18 @@ void DebugComputeExpression(Expression exp)
                // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
                case dummyType:
                   delete evaluation;
-                  evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
+                  evaluation = Debugger::EvaluateExpression(idString, &evalError);
                   break;
             }
          }
          switch(evalError)
          {
             case dummyExp:
-               if(evaluation)
+               if(evaluation && (exp.type != symbolErrorExp || !exp.identifier || !idString || strcmp(evaluation, idString)))
                {
+                  char * lt = strchr(evaluation, '<');
+                  if(lt) *lt = 0;
+
                   // Going back to parsing the expression string so as to catch inf/-inf/nan/-nan etc.
                   expNew = ParseExpressionString(evaluation);
                   //expNew = MkExpConstant(evaluation);
@@ -327,6 +353,13 @@ void DebugComputeExpression(Expression exp)
                   {
                      expNew.expType = expNew.destType;
                      expNew.destType.refCount++;
+                     // For negative values parsed as opExp
+                     if(expNew.type == opExp && expNew.op.op == '-' && !expNew.op.exp1 && expNew.op.exp2)
+                     {
+                        expNew.op.exp2.expType = expNew.destType;
+                        expNew.destType.refCount++;
+                        expNew.op.exp2.isConstant = true;
+                     }
                   }
                   else
                      ProcessExpressionType(expNew);
@@ -407,7 +440,6 @@ void DebugComputeExpression(Expression exp)
 
                            Property prop = null;
                            DataMember dataMember = null;
-                           Method method = null;
                            uint dataMemberOffset;
 
                            if(!ident)
@@ -813,8 +845,6 @@ void DebugComputeExpression(Expression exp)
          {
             FreeInstance(inst);
          }
-
-         //ComputeInstantiation(exp);
          break;
       }
       /*
@@ -824,7 +854,7 @@ void DebugComputeExpression(Expression exp)
       case opExp:
       {
          Expression expError = null;
-         Expression exp1, exp2 = null;
+         Expression exp1 = null, exp2 = null;
          Operand op1 = { 0 }, op2 = { 0 };
 
          /*
@@ -955,6 +985,12 @@ void DebugComputeExpression(Expression exp)
                         if(op2.type) op2.type.refCount++;
                      }
                   }
+                  else
+                  {
+                     exp1 = exp.op.exp1;
+                     op1 = GetOperand(exp1);
+                     if(op1.type) op1.type.refCount++;
+                  }
                }
             }
             else if(exp.op.exp2)
@@ -1204,27 +1240,39 @@ void DebugComputeExpression(Expression exp)
                 (exp2.expType.kind == pointerType || exp2.expType.kind == arrayType)))
             {
                bool valid = false;
-               // TODO: Support 1 + pointer
-               if((exp.op.op == '+' || exp.op.op == '-') && exp2.expType && op2.type && op2.type.kind == intType)
+               if((exp.op.op == '+' || exp.op.op == '-') && (op2.type || op1.type))
                {
-                  Expression e = exp1;
-                  while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
+                  Expression e1 = exp1, e2 = exp2;
+                  while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
+                  {
+                     if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
+                     {
+                        if(e1.type == extensionCompoundExp)
+                           e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
+                        else
+                           e1 = e1.list->last;
+                     }
+                     else if(e1.type == castExp)
+                        e1 = e1.cast.exp;
+                  }
+                  while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
                   {
-                     if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
+                     if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
                      {
-                        if(e.type == extensionCompoundExp)
-                           e = ((Statement)e.compound.compound.statements->last).expressions->last;
+                        if(e2.type == extensionCompoundExp)
+                           e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
                         else
-                           e = e.list->last;
+                           e2 = e2.list->last;
                      }
-                     else if(e.type == castExp)
-                        e = e.cast.exp;
+                     else if(e2.type == castExp)
+                        e2 = e2.cast.exp;
                   }
 
-                  if(e.type == stringExp)
+                  if((e1.type == stringExp && op2.type && op2.type.kind == intType) || (e2.type == stringExp && op1.type && op1.type.kind == intType))
                   {
-                     uint64 offset = (exp.op.op == '+') ? op2.i64 : -op2.i64;
+                     uint64 offset = ((exp.op.op == '+') ? 1 : -1) * (e1.type == stringExp ? op2.i64 : op1.i64);
                      String newString = null;
+                     Expression e = e1.type == stringExp ? e1 : e2;
                      if(e.string)
                      {
                         int len = strlen(e.string) - 2;
@@ -1232,7 +1280,7 @@ void DebugComputeExpression(Expression exp)
                         if(tmp)
                         {
                            len -= tmp - (e.string + 1);
-                           newString = new char[2 + len];
+                           newString = new char[2 + len + 1];
                            newString[0] = '\"';
                            memcpy(newString + 1, tmp, len);
                            newString[1 + len] = '\"';
@@ -1249,24 +1297,44 @@ void DebugComputeExpression(Expression exp)
                      else
                         exp.type = dereferenceErrorExp;
                   }
-                  else if(op1.type)
+                  // Can't add 2 pointers...
+                  else if(exp.op.op != '+' ||
+                     !((exp1.expType.kind == pointerType || exp1.expType.kind == arrayType) &&
+                       (exp2.expType.kind == pointerType || exp2.expType.kind == arrayType)))
                   {
-                     // TODO: Do pointer operations
-                     if(exp1.expType && exp1.expType.type)
+                     bool op1IsPointer = exp1.expType.kind == pointerType || exp1.expType.kind == arrayType;
+                     bool op2IsPointer = exp2.expType.kind == pointerType || exp2.expType.kind == arrayType;
+                     bool addressResult = !op1IsPointer || !op2IsPointer;
+                     uint size = 0;
+                     valid = true;
+                     if(op1IsPointer)
+                        size = ComputeTypeSize(exp1.expType.type);
+                     else if(op2IsPointer)
+                        size = ComputeTypeSize(exp2.expType.type);
+
+                     if(addressResult && size)
+                     {
+                       if(op1IsPointer) op2.ui64 *= size;
+                       else if(op1IsPointer) op1.ui64 *= size;
+                     }
+
+                     CallOperator(exp, exp1, exp2, op1, op2);
+                     if(exp.type == constantExp)
                      {
-                        uint size = ComputeTypeSize(exp1.expType.type);
-                        if(size)
+                        if(addressResult)
                         {
-                           valid = true;
-                           op1.ui64 /= exp1.expType.type.size;
-                           CallOperator(exp, exp1, exp2, op1, op2);
-                           if(exp.type == constantExp)
-                           {
-                              exp.address = _strtoui64(exp.constant, null, 0);
-                              exp.address *= size;
-                              if(op1.type.kind == arrayType)
-                                 exp.hasAddress = true;
-                           }
+                           exp.address = _strtoui64(exp.constant, null, 0);
+                           delete exp.constant;
+                           exp.constant = PrintHexUInt64(exp.address);
+                           if(op1.type.kind == arrayType || op2.type.kind == arrayType)
+                              exp.hasAddress = true;
+                        }
+                        else
+                        {
+                           int64 v = _strtoi64(exp.constant, null, 0);
+                           if(size) v /= size;
+                           delete exp.constant;
+                           exp.constant = PrintInt(v);
                         }
                      }
                   }
@@ -1351,6 +1419,7 @@ void DebugComputeExpression(Expression exp)
             Expression prev = exp.prev, next = exp.next;
             char * evaluation = null;
             ExpressionType evalError = dummyExp;
+            Type dataType = exp.index.exp.expType ? exp.index.exp.expType.type : null;
 
             if(!exp.index.exp.isConstant)
                exp.isConstant = false;
@@ -1361,12 +1430,12 @@ void DebugComputeExpression(Expression exp)
             // 4 == size = ComputeTypeSize(exp.index.exp.expType);
             // 0 == size = ComputeTypeSize(exp.index.exp.expType.arrayType);
 
-            size = ComputeTypeSize(exp.expType);
-            if(exp.expType && exp.expType.type && exp.expType.kind == arrayType)
+            size = ComputeTypeSize(dataType);
+            if(dataType && dataType.type && dataType.kind == arrayType)
                // For multilevels arrays
                format = 'x';
             else
-               format = GetGdbFormatChar(exp.expType);
+               format = GetGdbFormatChar(dataType);
 
             for(e = exp.index.index->first; e; e = e.next)
             {
@@ -1745,8 +1814,10 @@ void DebugComputeExpression(Expression exp)
                            case floatType:
                            {
                               float value;
-                              float (*Get)(float) = (void *) (convertTo ? prop.Set : prop.Get);
+                              float (*Get)(float) = (convertTo ? (void *)prop.Set : (void *)prop.Get);
                               GetFloat(memberExp, &value);
+
+                              FreeExpContents(exp);
                               exp.constant = PrintFloat(Get ? Get(value) : value);
                               exp.type = constantExp;
                               exp.isConstant = true;
@@ -1756,8 +1827,10 @@ void DebugComputeExpression(Expression exp)
                            case doubleType:
                            {
                               double value;
-                              double (*Get)(double) = (void *) (convertTo ? prop.Set : prop.Get);
+                              double (*Get)(double) = (convertTo ? (void *)prop.Set : (void *)prop.Get);
                               GetDouble(memberExp, &value);
+
+                              FreeExpContents(exp);
                               exp.constant = PrintDouble(Get ? Get(value) : value);
                               exp.isConstant = true;
                               exp.type = constantExp;
@@ -1772,6 +1845,8 @@ void DebugComputeExpression(Expression exp)
                         {
                            Expression value = memberExp;
                            Type type = prop.dataType;
+                           exp.member.exp = null;
+
                            if(_class.type == structClass)
                            {
                               switch(type.kind)
@@ -1782,6 +1857,7 @@ void DebugComputeExpression(Expression exp)
                                     if(propertyClass.type == structClass && value.type == instanceExp)
                                     {
                                        void (*Set)(void *, void *) = (void *)prop.Set;
+                                       FreeExpContents(exp);
                                        exp.instance = Instantiation
                                        {
                                           data = new0 byte[_class.structSize];
@@ -1801,6 +1877,8 @@ void DebugComputeExpression(Expression exp)
                                     int intValue;
                                     void (*Set)(void *, int) = (void *)prop.Set;
 
+                                    GetInt(value, &intValue);
+                                    FreeExpContents(exp);
                                     exp.instance = Instantiation
                                     {
                                        data = new0 byte[_class.structSize];
@@ -1809,8 +1887,6 @@ void DebugComputeExpression(Expression exp)
                                     };
                                     exp.type = instanceExp;
 
-                                    GetInt(value, &intValue);
-
                                     Set(exp.instance.data, intValue);
                                     PopulateInstance(exp.instance);
                                     supported = true;
@@ -1821,6 +1897,8 @@ void DebugComputeExpression(Expression exp)
                                     int64 intValue;
                                     void (*Set)(void *, int64) = (void *)prop.Set;
 
+                                    GetInt64(value, &intValue);
+                                    FreeExpContents(exp);
                                     exp.instance = Instantiation
                                     {
                                        data = new0 byte[_class.structSize];
@@ -1829,18 +1907,38 @@ void DebugComputeExpression(Expression exp)
                                     };
                                     exp.type = instanceExp;
 
-                                    GetInt64(value, &intValue);
-
                                     Set(exp.instance.data, intValue);
                                     PopulateInstance(exp.instance);
                                     supported = true;
                                     break;
                                  }
+                                 case floatType:
+                                 {
+                                    float floatValue;
+                                    void (*Set)(void *, float) = (void *)prop.Set;
+
+                                    GetFloat(value, &floatValue);
+                                    FreeExpContents(exp);
+                                    exp.instance = Instantiation
+                                    {
+                                       data = new0 byte[_class.structSize];
+                                       _class = MkSpecifierName/*MkClassName*/(_class.name);
+                                       loc = exp.loc;
+                                    };
+                                    exp.type = instanceExp;
+
+                                    Set(exp.instance.data, floatValue);
+                                    PopulateInstance(exp.instance);
+                                    supported = true;
+                                    break;
+                                 }
                                  case doubleType:
                                  {
                                     double doubleValue;
                                     void (*Set)(void *, double) = (void *)prop.Set;
 
+                                    GetDouble(value, &doubleValue);
+                                    FreeExpContents(exp);
                                     exp.instance = Instantiation
                                     {
                                        data = new0 byte[_class.structSize];
@@ -1849,8 +1947,6 @@ void DebugComputeExpression(Expression exp)
                                     };
                                     exp.type = instanceExp;
 
-                                    GetDouble(value, &doubleValue);
-
                                     Set(exp.instance.data, doubleValue);
                                     PopulateInstance(exp.instance);
                                     supported = true;
@@ -1869,6 +1965,7 @@ void DebugComputeExpression(Expression exp)
                                     {
                                        unsigned int (*Set)(void *) = (void *)prop.Set;
                                        unsigned int bits = Set(value.instance.data);
+                                       FreeExpContents(exp);
                                        exp.constant = PrintHexUInt(bits);
                                        exp.type = constantExp;
                                        supported = true;
@@ -1882,6 +1979,7 @@ void DebugComputeExpression(Expression exp)
 
                                        GetUInt(memberExp, &value);
                                        bits = Set(value);
+                                       FreeExpContents(exp);
                                        exp.constant = PrintHexUInt(bits);
                                        exp.type = constantExp;
                                        supported = true;
@@ -1889,6 +1987,7 @@ void DebugComputeExpression(Expression exp)
                                  }
                               }
                            }
+                           FreeExpression(value);
                         }
                         else
                         {
@@ -1906,6 +2005,7 @@ void DebugComputeExpression(Expression exp)
                                     {
                                        void (*Get)(unsigned int, void *) = (void *)prop.Get;
 
+                                       FreeExpContents(exp);
                                        exp.instance = Instantiation
                                        {
                                           data = new0 byte[_class.structSize];
@@ -1932,7 +2032,10 @@ void DebugComputeExpression(Expression exp)
                            }
                            else if(_class.type == structClass)
                            {
-                              char * value = (memberExp.type == instanceExp ) ? memberExp.instance.data : null;
+                              byte * value = (memberExp.type == instanceExp ) ? memberExp.instance.data : null;
+                              if(value)
+                                 memberExp.instance.data = null;
+
                               switch(type.kind)
                               {
                                  case classType:
@@ -1942,6 +2045,7 @@ void DebugComputeExpression(Expression exp)
                                     {
                                        void (*Get)(void *, void *) = (void *)prop.Get;
 
+                                       FreeExpContents(exp);
                                        exp.instance = Instantiation
                                        {
                                           data = new0 byte[_class.structSize];
@@ -1957,6 +2061,8 @@ void DebugComputeExpression(Expression exp)
                                     break;
                                  }
                               }
+
+                              delete value;
                            }
                            /*else
                            {
@@ -1970,6 +2076,7 @@ void DebugComputeExpression(Expression exp)
                                     {
                                        void *(*Get)(void *) = (void *)prop.Get;
 
+                                       FreeExpContents(exp);
                                        exp.instance = Instantiation
                                        {
                                           data = Get(value, exp.instance.data);     ?????
@@ -2028,7 +2135,6 @@ void DebugComputeExpression(Expression exp)
                         char format;
                         int size;
                         Expression expNew;
-                        TypeKind kind = dummyType;
                         Type dataType = member.dataType;
 
                         if(!dataType)
@@ -2201,7 +2307,6 @@ void DebugComputeExpression(Expression exp)
                         int size = memberType.size;
                         Expression expNew;
                         Type dataType = memberType;
-                        TypeKind kind = dummyType;
 
                         if(dataType.kind == classType && dataType._class.registered &&
                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
@@ -2604,3 +2709,231 @@ void DebugComputeExpression(Expression exp)
       }
    }
 }
+
+void ApplyUnitConverters(Expression exp)
+{
+   Property convert = null;
+   Type type = exp.expType;
+   bool useGet = false;
+   if(type.kind == classType && type._class && type._class.registered)
+   {
+      Class _class = type._class.registered;
+      if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
+      {
+         if(_class.type == unitClass && _class.base.type == unitClass)
+         {
+            Property p;
+            for(p = _class.conversions.first; p; p = p.next)
+            {
+               if(!strcmp(p.name, _class.base.fullName))
+               {
+                  convert = p;
+                  break;
+               }
+               else
+               {
+                  Class c = eSystem_FindClass(_class.module, p.name);
+                  if(c)
+                  {
+                     Property p2;
+                     for(p2 = c.conversions.first; p2; p2 = p2.next)
+                     {
+                        if(!strcmp(p2.name, _class.base.fullName))
+                        {
+                           convert = p;
+                           break;
+                        }
+                     }
+                  }
+                  if(convert)
+                     break;
+               }
+            }
+         }
+
+         if(!_class.dataType)
+            _class.dataType = ProcessTypeString(_class.dataTypeString, false);
+         type = _class.dataType;
+      }
+   }
+   if(convert)
+   {
+      switch(type.kind)
+      {
+         case charType:
+            if(type.isSigned)
+            {
+               char value = 0;
+               if(GetChar(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintChar(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            else
+            {
+               unsigned char value = 0;
+               if(GetUChar(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintUChar(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            break;
+         case shortType:
+            if(type.isSigned)
+            {
+               short value = 0;
+               if(GetShort(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintShort(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            else
+            {
+               unsigned short value = 0;
+               if(GetUShort(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintUShort(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            break;
+         case intType:
+            if(type.isSigned)
+            {
+               int value = 0;
+               if(GetInt(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintInt(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            else
+            {
+               unsigned int value = 0;
+               if(GetUInt(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintUInt(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            break;
+         case int64Type:
+            if(type.isSigned)
+            {
+               int64 value = 0;
+               if(GetInt64(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintInt64(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            else
+            {
+               uint64 value = 0;
+               if(GetUInt64(exp, &value))
+               {
+                  FreeExpContents(exp);
+                  exp.constant = PrintUInt64(value);
+                  exp.type = constantExp;
+                  exp.isConstant = true;
+               }
+            }
+            break;
+         case pointerType:
+         case classType:
+         {
+            uint64 value = 0;
+            if(GetUInt64(exp, &value))
+            {
+               FreeExpContents(exp);
+               if(type.kind == pointerType || type.kind == classType)
+                  exp.constant = PrintHexUInt64(value);
+               else
+                  exp.constant = PrintUInt64(value);
+               exp.type = constantExp;
+               exp.isConstant = true;
+            }
+            break;
+         }
+         case floatType:
+         {
+            float value = 0;
+            if(exp.type == constantExp && exp.constant &&
+               (!strcmpi(exp.constant, "nan") ||
+               !strcmpi(exp.constant, "-nan") ||
+               !strcmpi(exp.constant, "inf") ||
+               !strcmpi(exp.constant, "-inf")))
+            {
+               String constant = exp.constant;
+               exp.constant = null;
+               FreeExpContents(exp);
+               exp.constant = constant;
+               exp.type = constantExp;
+               exp.isConstant = true;
+            }
+            else if(GetFloat(exp, &value))
+            {
+               if(convert)
+               {
+                  float (*convertFn)(float) = (useGet ? (void *)convert.Get : (void *)convert.Set);
+                  if(convertFn)
+                     value = convertFn(value);
+               }
+               FreeExpContents(exp);
+               exp.constant = PrintFloat(value);
+               exp.type = constantExp;
+               exp.isConstant = true;
+            }
+            break;
+         }
+         case doubleType:
+         {
+            double value = 0;
+            if(exp.type == constantExp && exp.constant &&
+               (!strcmpi(exp.constant, "nan") ||
+               !strcmpi(exp.constant, "-nan") ||
+               !strcmpi(exp.constant, "inf") ||
+               !strcmpi(exp.constant, "-inf")))
+            {
+               String constant = exp.constant;
+               exp.constant = null;
+               FreeExpContents(exp);
+               exp.constant = constant;
+               exp.type = constantExp;
+               exp.isConstant = true;
+            }
+            else if(GetDouble(exp, &value))
+            {
+               if(convert)
+               {
+                  double (*convertFn)(double) = (useGet ? (void *)convert.Get : (void *)convert.Set);
+                  if(convertFn)
+                     value = convertFn(value);
+               }
+               FreeExpContents(exp);
+               exp.constant = PrintDouble(value);
+               exp.type = constantExp;
+               exp.isConstant = true;
+            }
+            break;
+         }
+      }
+   }
+}