ide/debugger: Fixed mistakes and omissions for conversion properties
[sdk] / ide / src / debugger / debugTools.ec
1 import "ide"
2
3 #include <math.h>
4
5 static Map<String, uintptr> oneArgFns
6 { [
7    { "sqrt", (uintptr)sqrt },
8    { "log", (uintptr)log },
9    { "log10", (uintptr)log10 },
10    { "sin", (uintptr)sin },
11    { "cos", (uintptr)cos },
12    { "tan", (uintptr)tan },
13    { "asin", (uintptr)asin },
14    { "acos", (uintptr)acos },
15    { "atan", (uintptr)atan },
16    { "sinh", (uintptr)sinh },
17    { "cosh", (uintptr)cosh },
18    { "tanh", (uintptr)tanh },
19    { "asinh", (uintptr)asinh },
20    { "acosh", (uintptr)acosh },
21    { "atanh", (uintptr)atanh },
22    { "exp", (uintptr)exp },
23    { "floor", (uintptr)floor },
24    { "ceil", (uintptr)ceil },
25    { "fabs", (uintptr)sqrt }
26
27 ] };
28
29 static Map<String, uintptr> twoArgFns
30 { [
31    { "pow", (uintptr)pow },
32    { "atan2", (uintptr)atan2 },
33    { "fmod", (uintptr)fmod }
34 ] };
35
36 static void CarryExpressionError(Expression exp, Expression expError)
37 {
38    Expression temp { };
39
40    // This function assumes that expError is contained within exp,
41    // and therefore these types will be freed when freeing the old contents
42    // of the expression we're carying into.
43
44    if(expError.destType) expError.destType.refCount++;
45    if(expError.expType) expError.expType.refCount++;
46
47    *temp = *expError;
48
49    // -- Careful: this could be problematic as FreeExpContents will free the contents of expError
50    // Nulling things that may be freed now, but this is all overly messy/complex
51    switch(expError.type)
52    {
53       case functionCallErrorExp:
54          expError.call.exp = null;
55          expError.call.arguments = null;
56          break;
57       case symbolErrorExp:
58          expError.identifier = null;
59          break;
60       case memoryErrorExp:
61          expError.constant = null;
62          break;
63       case memberPropertyErrorExp:
64       case memberSymbolErrorExp:
65          expError.member.exp = null;
66          expError.member.member = null;
67          break;
68    }
69
70    /*
71    Identifier identifier = expError.identifier;
72    expError.identifier = null;
73    FreeExpContents(exp);
74    exp.identifier = identifier;
75    exp.type = expError.type;
76    */
77    if(exp.expType) FreeType(exp.expType);
78    if(exp.destType) FreeType(exp.destType);
79    FreeExpContents(exp);
80    *exp = *temp; //*expError;
81    delete temp;
82    // memset(expError, 0, sizeof(class Expression));
83 }
84
85 static char GetGdbFormatChar(Type type)
86 {
87 //          x : Regard the bits of the value as an integer, and print the integer in hexadecimal.
88 //          d : Print as integer in signed decimal.
89 //          u : Print as integer in unsigned decimal.
90 //          o : Print as integer in octal.
91 //          t : Print as integer in binary. The letter `t' stands for "two". (4)
92 //          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:
93 //          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.
94 //          f : Regard the bits of the value as a floating point number and print using typical floating point syntax.
95    if(!type)
96       return 'x';
97
98    switch(type.kind)
99    {
100       case charType:
101          //return 'c';
102       case shortType:
103       case intType:
104       case longType:
105       case int64Type:
106          if(type.isSigned)
107             return 'd';
108          else
109             return 'u';
110       case floatType:
111          return 'f';
112       case doubleType:
113          return 'f';
114       case structType:
115       case unionType:
116       case functionType:
117       case arrayType:
118          // return 'u';
119          return 0;
120       case ellipsisType:
121       case enumType:
122       case methodType:
123       case vaListType:
124       // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
125       case dummyType:
126          break;
127       case classType:
128       case pointerType:
129          return 'x';
130    }
131    return 'x';
132 }
133
134 /*static */bool ExpressionIsError(Expression exp)
135 {
136    return (exp.type == dereferenceErrorExp || exp.type == symbolErrorExp ||
137          exp.type == memberSymbolErrorExp || exp.type == memoryErrorExp || exp.type == unknownErrorExp ||
138          exp.type == noDebuggerErrorExp || exp.type == memberPropertyErrorExp || exp.type == functionCallErrorExp || exp.type == divideBy0ErrorExp);
139 }
140
141 void DebugComputeExpression(Expression exp)
142 {
143 #ifdef _DEBUG
144    char expString[1024] = "";
145    //char temp[1024];
146    //if(inCompiler)
147       PrintExpression(exp, expString);
148    // printf("%s (exp.type = %s)\n", expString, exp.type.OnGetString(temp, null, null));
149 #endif
150    switch(exp.type)
151    {
152       case identifierExp:
153       {
154          Expression prev = exp.prev, next = exp.next;
155          char * evaluation = null;
156          ExpressionType evalError = dummyExp;
157          Expression expNew;
158          TypeKind kind = dummyType;
159          Type dataType = exp.expType;
160
161          char temp[1024];
162          uint64 address;
163          bool hasAddress;
164          bool isPointer = false;
165
166          if(dataType && dataType.kind == classType && dataType._class.registered)
167          {
168             Class _class = dataType._class.registered;
169             if(_class.type == bitClass || _class.type == unitClass || _class.type == enumClass)
170             {
171                if(!_class.dataType)
172                   _class.dataType = ProcessTypeString(_class.dataTypeString, false);
173                dataType = _class.dataType;
174             }
175             else if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass) // Added systemClass here for Instance
176             {
177                isPointer = true;
178             }
179          }
180          else if(dataType && dataType.kind == classType && !dataType._class.registered)
181             isPointer = true;
182          if(dataType)
183             kind = dataType.kind;
184          else
185             exp.type = symbolErrorExp;
186          temp[0] = '\0';
187          switch(kind)
188          {
189             case intPtrType: case intSizeType: case _BoolType:
190             case charType: case shortType: case intType: case int64Type: case longType: case floatType: case doubleType:
191             case enumType:
192             case arrayType:
193             case structType:
194             case pointerType:
195             case unionType:
196                sprintf(temp, "&%s", exp.identifier.string);
197                break;
198             case classType:
199                if(exp.byReference && dataType._class && dataType._class.registered && dataType._class.registered.type == structClass)
200                // if(!dataType._class || !dataType._class.registered || dataType._class.registered.type != structClass || exp.byReference)
201                   strcpy(temp, exp.identifier.string);
202                else
203                   sprintf(temp, "&%s", exp.identifier.string);
204                break;
205             case functionType:
206             case ellipsisType:
207             case methodType:
208             case vaListType:
209             // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
210             case dummyType:
211                break;
212          }
213          if(temp[0])
214          {
215             evaluation = Debugger::EvaluateExpression(temp, &evalError);
216             if(evaluation)
217             {
218                address = _strtoui64(evaluation, null, 0);
219                //delete evaluation;
220                //evaluation = null;
221             }
222             else
223                address = 0;
224             hasAddress = true;
225          }
226          else
227             hasAddress = false;
228
229          if(evalError == dummyExp)
230          {
231             switch(kind)
232             {
233                case charType:
234                   delete evaluation;
235                   evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
236                   if(evaluation)
237                   {
238                      //int c, len;
239                      char * temp;
240                      temp = strstr(evaluation, " '");
241                      //len = strlen(temp);
242                      if(temp)
243                         temp[0] = '\0';
244                      {/*
245                         for(c = 0; c < len; c++)
246                            temp[c] = ' ';
247                         eString_TrimRSpaces(evaluation, evaluation);
248                      */}
249                   }
250                   break;
251                case shortType:
252                case intType:
253                case longType:
254                case intPtrType:
255                case intSizeType:
256                case _BoolType:
257                case int64Type:
258                case floatType:
259                case doubleType:
260                case enumType:
261                case pointerType:
262                   delete evaluation;
263                   evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
264                   if(evaluation)
265                   {
266                      if(kind == pointerType)
267                      {
268                         uint64 value;
269                         value = _strtoui64(evaluation, null, 0);
270                         delete evaluation;
271                         evaluation = PrintHexUInt64(value);
272                      }
273                   }
274                   break;
275                case classType:
276                   if(isPointer)
277                   {
278                      int size;
279                      char format;
280                      delete evaluation;
281                      //evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
282                      size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
283                      format = GetGdbFormatChar(exp.expType);
284                      evaluation = Debugger::ReadMemory(address, size, format, &evalError);
285                      if(evaluation)
286                         StripQuotes(evaluation, evaluation);
287                   }
288                   break;
289                case structType:
290                case unionType:
291                case functionType:
292                   //evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
293                   delete evaluation;
294                   break;
295                case arrayType:
296                {
297                   // for classType  --> if(_class.type == structClass) ?
298                   //char temp[1024];
299                   //sprintf(temp, "&%s", exp.identifier.string);
300                   //evaluation = Debugger::EvaluateExpression(temp, &evalError);
301                   break;
302                }
303                case ellipsisType:
304                case methodType:
305                case vaListType:
306                // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
307                case dummyType:
308                   delete evaluation;
309                   evaluation = Debugger::EvaluateExpression(exp.identifier.string, &evalError);
310                   break;
311             }
312          }
313          switch(evalError)
314          {
315             case dummyExp:
316                if(evaluation)
317                {
318                   // Going back to parsing the expression string so as to catch inf/-inf/nan/-nan etc.
319                   expNew = ParseExpressionString(evaluation);
320                   //expNew = MkExpConstant(evaluation);
321                   //printf("Evaluation = %s\n", evaluation);
322                   delete evaluation;
323                   expNew.destType = exp.expType;
324
325                   // WHY EXACTLY MUST WE PROCESS THIS EXPRESSION TYPE AGAIN ? ADDED THIS FOR 0x00000000
326                   if(exp.expType && (exp.expType.kind == pointerType || exp.expType.kind == classType) && expNew.destType)
327                   {
328                      expNew.expType = expNew.destType;
329                      expNew.destType.refCount++;
330                   }
331                   else
332                      ProcessExpressionType(expNew);
333                   FreeType(exp.destType);
334                   FreeExpContents(exp);
335
336                   DebugComputeExpression(expNew);
337                   expNew.prev = prev;
338                   expNew.next = next;
339                   expNew.isConstant = true;
340                   expNew.address = address;
341                   expNew.hasAddress = hasAddress;
342                   *exp = *expNew;
343                   delete expNew;
344                }
345                else
346                {
347                   // Unhandled code path, evaluation is null
348                   FreeExpContents(exp);
349                   exp.type = unknownErrorExp;
350                }
351                break;
352             case symbolErrorExp:
353                // Keep the identifier
354                exp.type = evalError;
355                break;
356             default:
357                FreeExpContents(exp);
358                exp.type = evalError;
359                break;
360          }
361          break;
362       }
363       case instanceExp:
364       {
365          ComputeInstantiation(exp);
366          break;
367       }
368       /*
369       case constantExp:
370          break;
371       */
372       case opExp:
373       {
374          Expression expError = null;
375          Expression exp1, exp2 = null;
376          Operand op1 = { 0 }, op2 = { 0 };
377
378          /*
379          if(exp.op.op == '&' || exp.op.op == '*')
380          {
381             if(!exp.op.exp1 && exp.op.exp2)
382             {
383                if(exp.op.exp2.type == identifierExp)
384                {
385                   Expression prev = exp.prev, next = exp.next;
386                   char * evaluation = null;
387                   ExpressionType evalError = dummyExp;
388                   Expression expNew;
389                   char temp[1024];
390                   sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.identifier.string);
391                   evaluation = Debugger::EvaluateExpression(temp, &evalError);
392                   if(evalError != dummyExp)
393                   {
394                      exp.type = evalError;
395                      exp.constant = CopyString("");
396                   }
397                   else if(evaluation)
398                   {
399                      expNew = ParseExpressionString(evaluation);
400                      delete evaluation;
401                      expNew.destType = exp.expType;
402                      FreeType(exp.destType);
403                      FreeExpContents(exp);
404                      ProcessExpressionType(expNew);
405                      DebugComputeExpression(expNew);
406                      expNew.prev = prev;
407                      expNew.next = next;
408                      expNew.isConstant = true;
409                      *exp = *expNew;
410                      delete expNew;
411                   }
412                   else
413                      exp.type = ExpUnknownError;
414                   break;
415                }
416                //else
417                {
418                   uint64 address;
419                   int size;
420                   char format;
421                   if(exp.op.op == '*')
422                   {
423                   DebugComputeExpression(exp.op.exp2);
424                   size = ComputeTypeSize(exp.op.exp2.expType);
425                   format = GetGdbFormatChar(exp.op.exp2.expType);
426                   GetInt(exp.op.exp2, &address);
427                   //sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.constant);
428                   evaluation = Debug_ReadMemory(address, size, format, &evalError);
429                   }
430                   else
431                      evalError = ExpUnknownError;
432                }
433             }
434          }
435          */
436
437          // We don't care about operations with only exp2 (INC_OP, DEC_OP...)
438          if(exp.op.exp2)
439          {
440             Expression e = exp.op.exp2;
441
442             while((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list)
443             {
444                if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
445                {
446                   if(e.type == extensionCompoundExp)
447                      e = ((Statement)e.compound.compound.statements->last).expressions->last;
448                   else
449                      e = e.list->last;
450                }
451             }
452             if(exp.op.op == TokenType::sizeOf && e && e.expType)
453             {
454                if(e.type == stringExp && e.string)
455                {
456                   char * string = e.string;
457                   int len = strlen(string);
458                   char * tmp = new char[len-2+1];
459                   len = UnescapeString(tmp, string + 1, len - 2);
460                   delete tmp;
461                   FreeExpContents(exp);
462                   exp.type = constantExp;
463                   exp.constant = PrintUInt(len + 1);
464                }
465                else
466                {
467                   Type type = e.expType;
468                   type.refCount++;
469                   FreeExpContents(exp);
470                   exp.type = constantExp;
471                   exp.constant = PrintUInt(ComputeTypeSize(type));
472                   FreeType(type);
473                }
474                break;
475             }
476             else
477             {
478                DebugComputeExpression(exp.op.exp2);
479                if(ExpressionIsError(exp.op.exp2))
480                   expError = exp.op.exp2;
481             }
482          }
483          if(!expError)
484          {
485             if(exp.op.exp1)
486             {
487                DebugComputeExpression(exp.op.exp1);
488                if(ExpressionIsError(exp.op.exp1))
489                   expError = exp.op.exp1;
490                else
491                {
492                   if(exp.op.exp2)
493                   {
494                      if(ExpressionIsError(exp.op.exp2))
495                         expError = exp.op.exp2;
496                      else
497                      {
498                         exp1 = exp.op.exp1;
499                         exp2 = exp.op.exp2;
500                         op1 = GetOperand(exp1);
501                         if(op1.type) op1.type.refCount++;
502                         op2 = GetOperand(exp2);
503                         if(op2.type) op2.type.refCount++;
504                      }
505                   }
506                }
507             }
508             else if(exp.op.exp2)
509             {
510                if(ExpressionIsError(exp.op.exp2))
511                   expError = exp.op.exp2;
512                else
513                {
514                   exp1 = exp.op.exp2;
515                   if(exp.op.op == '&' || exp.op.op == '*')
516                   {
517                      Expression prev = exp1.prev, next = exp1.next;
518                      Expression expNew;
519                      ExpressionType evalError = dummyExp;
520                      char * evaluation = null;
521                      if(exp.op.op == '&')
522                      {
523                         if(exp1.hasAddress)
524                         {
525                            char * temp;
526                            //sprintf(temp, "%u", exp1.address);
527                            temp = PrintHexUInt64(exp1.address);
528                            expNew = ParseExpressionString(temp);
529                            delete temp;
530                            //expNew.address = exp1.address;
531                            expNew.expType = exp.expType;
532                            /*
533                            expNew.destType = exp.expType;
534                            expNew.destType.refCount++;
535                            */
536                            FreeType(exp.destType);
537                            FreeExpContents(exp);
538                            ProcessExpressionType(expNew);
539                            DebugComputeExpression(expNew);
540                            expNew.prev = prev;
541                            expNew.next = next;
542                            expNew.isConstant = true;
543                            *exp = *expNew;
544                            delete expNew;
545                         }
546                         else
547                            exp1.address = 0;
548                      }
549                      else if(exp.op.op == '*')
550                      {
551                         // TODO: Common pathway for * and [ ]
552                         if(!exp.expType)
553                         {
554                            delete evaluation;
555                            FreeExpContents(exp1);
556                            exp1.type = dereferenceErrorExp;
557                            expError = exp1;
558                         }
559                         else
560                         {
561                            uint64 address = 0;
562                            int size;
563                            char format;
564                            Expression e = exp1;
565                            uint offset = 0;
566                            bool gotAddress = false;
567
568                            while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
569                            {
570                               if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
571                               {
572                                  if(e.type == extensionCompoundExp)
573                                     e = ((Statement)e.compound.compound.statements->last).expressions->last;
574                                  else
575                                     e = e.list->last;
576                               }
577                               else if(e.type == castExp)
578                                  e = e.cast.exp;
579                            }
580
581                            if(e.expType.kind == structType)
582                            {
583                               address = exp1.address;
584                               gotAddress = true;
585                            }
586                            else
587                               gotAddress = GetUInt64(e, &address);
588                            size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
589                            if(exp.expType && exp.expType.type && exp.expType.kind == arrayType)
590                               // For multilevels arrays
591                               format = 'x';
592                            else
593                               format = GetGdbFormatChar(exp.expType);
594                            while(e.type == opExp && e.op.op == '+' && e.op.exp1 && e.op.exp2)
595                            {
596                               Expression e1 = e.op.exp1, e2 = e.op.exp2;
597                               while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
598                               {
599                                  if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
600                                  {
601                                     if(e1.type == extensionCompoundExp)
602                                        e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
603                                     else
604                                        e1 = e1.list->last;
605                                  }
606                                  else if(e1.type == castExp)
607                                     e1 = e1.cast.exp;
608                               }
609                               while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
610                               {
611                                  if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
612                                  {
613                                     if(e2.type == extensionCompoundExp)
614                                        e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
615                                     else
616                                        e2 = e2.list->last;
617                                  }
618                                  else if(e2.type == castExp)
619                                     e2 = e2.cast.exp;
620                               }
621
622                               if((e1.type == stringExp || e1.type == opExp) && e.op.exp2.isConstant && e.op.exp2.expType && e.op.exp2.expType.kind == intType)
623                               {
624                                  offset += strtol(e.op.exp2.constant, null, 0);
625                                  e = e1;
626                               }
627                               else if((e2.type == stringExp || e2.type == opExp) && e.op.exp1.isConstant && e.op.exp1.expType && e.op.exp1.expType.kind == intType)
628                               {
629                                  offset += strtol(e.op.exp1.constant, null, 0);
630                                  e = e2;
631                               }
632                               else
633                                   break;
634                            }
635
636                            if(e.type == stringExp)
637                            {
638                               char * tmp = null;
639                               String string = e.string;
640                               bool valid = false;
641                               Type expType = exp1.expType.type;
642                               if(expType) expType.refCount++;
643
644                               if(string)
645                               {
646                                  int len = string ? strlen(string) : 0;
647                                  tmp = new char[len-2+1];
648                                  len = UnescapeString(tmp, string + 1, len - 2);
649                                  if(len >= 0 && offset * size + size-1 <= len)
650                                     valid = true;
651                               }
652
653                               FreeExpContents(exp);
654                               if(!valid)
655                                  exp.type = dereferenceErrorExp;
656                               else if(expType)
657                               {
658                                  exp.type = constantExp;
659                                  exp.isConstant = true;
660                                  switch(expType.kind)
661                                  {
662                                     case charType:   exp.constant = expType.isSigned ? PrintChar(((char *)tmp)[offset]) : PrintUChar(((byte *)tmp)[offset]); break;
663                                     case shortType:  exp.constant = expType.isSigned ? PrintShort(((short *)tmp)[offset]) : PrintUShort(((uint16 *)tmp)[offset]); break;
664                                     case intType:    exp.constant = expType.isSigned ? PrintInt(((int *)tmp)[offset]) : PrintUInt(((uint *)tmp)[offset]); break;
665                                     case int64Type:  exp.constant = expType.isSigned ? PrintInt64(((int64 *)tmp)[offset]) : PrintUInt64(((uint64 *)tmp)[offset]); break;
666                                     case floatType:  exp.constant = PrintFloat(((float *)tmp)[offset]); break;
667                                     case doubleType: exp.constant = PrintDouble(((double *)tmp)[offset]); break;
668                                     default:
669                                        exp.type = unknownErrorExp;
670                                  }
671                               }
672                               else
673                                  exp.type = unknownErrorExp;
674                               FreeType(expType);
675                               delete tmp;
676                            }
677                            else if(gotAddress && exp.expType.kind == arrayType)
678                            {
679                               FreeExpContents(exp);
680                               exp.type = constantExp;
681                               exp.isConstant = true;
682                               exp.constant = PrintHexUInt64(address);
683                               exp.address = address;
684                               exp.hasAddress = true;
685                            }
686                            else if(gotAddress && format)
687                            {
688                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
689                               switch(evalError)
690                               {
691                                  case dummyExp:
692                                     if(evaluation)
693                                     {
694                                        expNew = ParseExpressionString(evaluation);
695                                        expNew.address = address;
696                                        expNew.hasAddress = true;
697                                        delete evaluation;
698                                        expNew.destType = exp.expType;
699                                        FreeType(exp.destType);
700                                        FreeExpContents(exp);
701                                        ProcessExpressionType(expNew);
702                                        DebugComputeExpression(expNew);
703                                        expNew.prev = prev;
704                                        expNew.next = next;
705                                        expNew.isConstant = true;
706                                        *exp = *expNew;
707                                        delete expNew;
708                                     }
709                                     else
710                                     {
711                                        // Unhandled code path, evaluation is null
712                                        FreeExpContents(exp);
713                                        exp.type = unknownErrorExp;
714                                     }
715                                     break;
716                                  case memoryErrorExp:
717                                     delete evaluation;
718                                     FreeExpContents(exp1);
719                                     exp1.type = evalError;
720                                     exp1.constant = PrintHexUInt64(address);
721                                     expError = exp1;
722                                     break;
723                                  default:
724                                     delete evaluation;
725                                     FreeExpContents(exp1);
726                                     exp1.type = evalError;
727                                     expError = exp1;
728                                     break;
729                               }
730                            }
731                            else
732                            {
733                               FreeExpContents(exp1);
734                               exp1.type = unknownErrorExp;  // Not supported yet, generate error to fallback to GDB printout
735                               expError = exp1;
736                            }
737                         }
738                      }
739                   }
740                   else
741                      op1 = GetOperand(exp1);
742                   if(op1.type) op1.type.refCount++;
743                }
744             }
745          }
746          if(expError)
747             CarryExpressionError(exp, expError);
748          else if(exp.type == opExp)
749          {
750             if(exp1 && exp2 && exp1.expType && exp2.expType &&
751                ((exp1.expType.kind == pointerType || exp1.expType.kind == arrayType) ||
752                 (exp2.expType.kind == pointerType || exp2.expType.kind == arrayType)))
753             {
754                bool valid = false;
755                // TODO: Support 1 + pointer
756                if((exp.op.op == '+' || exp.op.op == '-') && exp2.expType && op2.type && op2.type.kind == intType)
757                {
758                   Expression e = exp1;
759                   while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
760                   {
761                      if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
762                      {
763                         if(e.type == extensionCompoundExp)
764                            e = ((Statement)e.compound.compound.statements->last).expressions->last;
765                         else
766                            e = e.list->last;
767                      }
768                      else if(e.type == castExp)
769                         e = e.cast.exp;
770                   }
771
772                   if(e.type == stringExp)
773                   {
774                      uint64 offset = (exp.op.op == '+') ? op2.i64 : -op2.i64;
775                      String newString = null;
776                      if(e.string)
777                      {
778                         int len = strlen(e.string) - 2;
779                         char * tmp = OffsetEscapedString(e.string + 1, len, (int)offset);
780                         if(tmp)
781                         {
782                            len -= tmp - (e.string + 1);
783                            newString = new char[2 + len];
784                            newString[0] = '\"';
785                            memcpy(newString + 1, tmp, len);
786                            newString[1 + len] = '\"';
787                            newString[1 + len + 1] = 0;
788                         }
789                      }
790                      valid = true;
791                      FreeExpContents(exp);
792                      if(newString)
793                      {
794                         exp.type = stringExp;
795                         exp.string = newString;
796                      }
797                      else
798                         exp.type = dereferenceErrorExp;
799                   }
800                   else if(op1.type)
801                   {
802                      // TODO: Do pointer operations
803                      if(exp1.expType && exp1.expType.type)
804                      {
805                         uint size = ComputeTypeSize(exp1.expType.type);
806                         if(size)
807                         {
808                            valid = true;
809                            op1.ui64 /= exp1.expType.type.size;
810                            CallOperator(exp, exp1, exp2, op1, op2);
811                            if(exp.type == constantExp)
812                            {
813                               exp.address = _strtoui64(exp.constant, null, 0);
814                               exp.address *= size;
815                               if(op1.type.kind == arrayType)
816                                  exp.hasAddress = true;
817                            }
818                         }
819                      }
820                   }
821                }
822                if(!valid)
823                {
824                   FreeExpContents(exp);
825                   exp.type = unknownErrorExp;   // We should have an invalid operands error
826                }
827             }
828             else
829             {
830                if(!exp2 && exp1 && exp1.type == constantExp && exp1.constant && !strcmp(exp1.constant, "nan") && exp.op.op == '-')
831                {
832                   FreeExpContents(exp);
833                   exp.constant = CopyString("-nan");
834                   exp.type = constantExp;
835                }
836                else
837                {
838                   if((exp.op.op == '/' || exp.op.op == '%') && op2.kind != doubleType && op1.kind != doubleType && op2.kind != floatType && op1.kind != floatType &&
839                      (((op2.kind == int64Type || op2.kind == intPtrType || op2.kind == intSizeType) && !op2.i64) ||
840                      (op2.kind == intType && !op2.i) || (op2.kind == shortType && !op2.s) || (op2.kind == charType && !op2.c)))
841                   {
842                      FreeExpContents(exp);
843                      exp.type = divideBy0ErrorExp;
844                   }
845                   else
846                      CallOperator(exp, exp1, exp2, op1, op2);
847                }
848             }
849             FreeType(op1.type);
850             FreeType(op2.type);
851             if(exp.type == constantExp)
852                exp.isConstant = true;
853          }
854          break;
855       }
856       case bracketsExp:
857       {
858          Expression e, n;
859          //for(
860          //   e = (*exp.list).first, n = e ? e.next : null;
861          //   e;
862          //   e = n, n = n?(n.next) : null)
863
864          for(e = exp.list->first; e; e = n)
865          {
866             n = e.next;
867             if(!n)
868             {
869                OldList * list = exp.list;
870                DebugComputeExpression(e);
871                //if(ExpressionIsError(e)) //.type == ExpSymbolError
872                //   CarryExpressionError(exp, e);
873                //FreeExpContents(exp);
874                FreeType(exp.expType);
875                FreeType(exp.destType);
876                *exp = *e;
877                delete e;
878                delete list;
879             }
880             else
881             {
882                FreeExpression(e);
883             }
884          }
885          break;
886       }
887       case indexExp:
888       {
889          int size;
890          char format;
891          Expression e;
892          exp.isConstant = true;
893
894          DebugComputeExpression(exp.index.exp);
895          if(ExpressionIsError(exp.index.exp)) //.type == ExpSymbolError
896             CarryExpressionError(exp, exp.index.exp);
897          else
898          {
899             Expression prev = exp.prev, next = exp.next;
900             char * evaluation = null;
901             ExpressionType evalError = dummyExp;
902
903             if(!exp.index.exp.isConstant)
904                exp.isConstant = false;
905
906             // int r[0]
907             // 4 == size = ComputeTypeSize(exp.expType);
908             // 0 == size = ComputeTypeSize(exp.expType.arrayType);
909             // 4 == size = ComputeTypeSize(exp.index.exp.expType);
910             // 0 == size = ComputeTypeSize(exp.index.exp.expType.arrayType);
911
912             size = ComputeTypeSize(exp.expType);
913             if(exp.expType && exp.expType.type && exp.expType.kind == arrayType)
914                // For multilevels arrays
915                format = 'x';
916             else
917                format = GetGdbFormatChar(exp.expType);
918
919             for(e = exp.index.index->first; e; e = e.next)
920             {
921                DebugComputeExpression(e);
922                if(ExpressionIsError(e)) //.type == ExpSymbolError
923                {
924                   CarryExpressionError(exp, e);
925                   break;
926                }
927                if(!e.next)
928                {
929                   // Check if this type is int
930                }
931                if(!e.isConstant)
932                   exp.isConstant = false;
933             }
934             if(!ExpressionIsError(exp))
935             {
936                // Is this necessary here? pass15 had done this already...
937                if(exp.expType) FreeType(exp.expType);
938                exp.expType = Dereference(exp.index.exp.expType);
939
940                if(!exp.expType)
941                {
942                   delete evaluation;
943                   FreeExpContents(exp);
944                   exp.type = dereferenceErrorExp;
945                }
946                else if(exp.index.index && exp.index.index->last && ((Expression)exp.index.index->last) && ((Expression)exp.index.index->last).expType)
947                {
948                   Type type = ((Expression)exp.index.index->last).expType;
949                   if(type.kind == intType || type.kind == charType || type.kind == shortType || type.kind == int64Type || type.kind == intPtrType ||
950                      type.kind == intSizeType || type.kind == longType || type.kind == _BoolType || type.kind == enumType ||
951                         (type.kind == classType && type._class && type._class.registered &&
952                            type._class.registered.type == enumClass))
953                   {
954                      bool gotAddress = false;
955                      uint64 address = 0, offset = 0;
956                      Expression expNew, last = (Expression)exp.index.index->last;
957                      Expression e = exp.index.exp;
958
959                      while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
960                      {
961                         if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
962                         {
963                            if(e.type == extensionCompoundExp)
964                               e = ((Statement)e.compound.compound.statements->last).expressions->last;
965                            else
966                               e = e.list->last;
967                         }
968                         else if(e.type == castExp)
969                            e = e.cast.exp;
970                      }
971
972                      //GetUInt(exp.index.exp, &address);
973
974                      GetUInt64(last, &offset);
975
976                      // TOFIX: Check if it has address: TESTING
977                      if(exp.index.exp.hasAddress && exp.index.exp.expType.kind == arrayType)
978                      {
979                         address = exp.index.exp.address;
980                         gotAddress = true;
981                      }
982                      else if(exp.index.exp.type == constantExp)
983                         gotAddress = GetUInt64(exp.index.exp, &address);
984
985                      while(e.type == opExp && e.op.op == '+' && e.op.exp1 && e.op.exp2)
986                      {
987                         Expression e1 = e.op.exp1, e2 = e.op.exp2;
988                         while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
989                         {
990                            if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
991                            {
992                               if(e1.type == extensionCompoundExp)
993                                  e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
994                               else
995                                  e1 = e1.list->last;
996                            }
997                            else if(e1.type == castExp)
998                               e1 = e1.cast.exp;
999                         }
1000                         while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
1001                         {
1002                            if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
1003                            {
1004                               if(e2.type == extensionCompoundExp)
1005                                  e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
1006                               else
1007                                  e2 = e2.list->last;
1008                            }
1009                            else if(e2.type == castExp)
1010                               e2 = e2.cast.exp;
1011                         }
1012
1013                         if((e1.type == stringExp || e1.type == opExp) && e.op.exp2.isConstant && e.op.exp2.expType && e.op.exp2.expType.kind == intType)
1014                         {
1015                            offset += strtol(e.op.exp2.constant, null, 0);
1016                            e = e1;
1017                         }
1018                         else if((e2.type == stringExp || e2.type == opExp) && e.op.exp1.isConstant && e.op.exp1.expType && e.op.exp1.expType.kind == intType)
1019                         {
1020                            offset += strtol(e.op.exp1.constant, null, 0);
1021                            e = e2;
1022                         }
1023                         else
1024                             break;
1025                      }
1026
1027                      //size = ComputeTypeSize(exp.expType.arrayType); //exp.expType.arrayType.size;
1028                      address += offset * size;
1029
1030                      if(e.type == stringExp)
1031                      {
1032                         char * tmp = null;
1033                         String string = e.string;
1034                         bool valid = false;
1035                         Type expType = exp.index.exp.expType.type;
1036                         if(expType) expType.refCount++;
1037
1038                         if(string)
1039                         {
1040                            int len = string ? strlen(string) : 0;
1041                            tmp = new char[len-2+1];
1042                            len = UnescapeString(tmp, string + 1, len - 2);
1043                            if(len >= 0 && offset * size + size-1 <= len)
1044                               valid = true;
1045                         }
1046
1047                         FreeExpContents(exp);
1048                         if(!valid)
1049                            exp.type = dereferenceErrorExp;
1050                         else if(expType)
1051                         {
1052                            exp.type = constantExp;
1053                            exp.isConstant = true;
1054                            switch(expType.kind)
1055                            {
1056                               case charType:   exp.constant = expType.isSigned ? PrintChar(((char *)tmp)[offset]) : PrintUChar(((byte *)tmp)[offset]); break;
1057                               case shortType:  exp.constant = expType.isSigned ? PrintShort(((short *)tmp)[offset]) : PrintUShort(((uint16 *)tmp)[offset]); break;
1058                               case intType:    exp.constant = expType.isSigned ? PrintInt(((int *)tmp)[offset]) : PrintUInt(((uint *)tmp)[offset]); break;
1059                               case int64Type:  exp.constant = expType.isSigned ? PrintInt64(((int64 *)tmp)[offset]) : PrintUInt64(((uint64 *)tmp)[offset]); break;
1060                               case floatType:  exp.constant = PrintFloat(((float *)tmp)[offset]); break;
1061                               case doubleType: exp.constant = PrintDouble(((double *)tmp)[offset]); break;
1062                               default:
1063                                  exp.type = unknownErrorExp;
1064                            }
1065                         }
1066                         else
1067                            exp.type = unknownErrorExp;
1068                         FreeType(expType);
1069                         delete tmp;
1070                      }
1071                      else if(gotAddress && exp.expType.kind == arrayType)
1072                      {
1073                         FreeExpContents(exp);
1074                         exp.type = constantExp;
1075                         exp.isConstant = true;
1076                         exp.constant = PrintHexUInt64(address);
1077                         exp.address = address;
1078                         exp.hasAddress = true;
1079                      }
1080                      else if(gotAddress)
1081                      {
1082                         evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1083                         switch(evalError)
1084                         {
1085                            case dummyExp:
1086                               if(evaluation)
1087                               {
1088                                  expNew = ParseExpressionString(evaluation);
1089                                  delete evaluation;
1090                                  expNew.destType = exp.expType;
1091                                  FreeType(exp.destType);
1092                                  FreeExpContents(exp);
1093                                  ProcessExpressionType(expNew);
1094                                  DebugComputeExpression(expNew);
1095
1096                                  // TOFIX: Only for Array Types
1097                                  expNew.address = address;
1098
1099                                  expNew.hasAddress = true;
1100                                  expNew.prev = prev;
1101                                  expNew.next = next;
1102                                  expNew.isConstant = true;
1103                                  *exp = *expNew;
1104                                  delete expNew;
1105                               }
1106                               else
1107                               {
1108                                  // Unhandled code path, evaluation is null
1109                                  FreeExpContents(exp);
1110                                  exp.type = unknownErrorExp;
1111                               }
1112                               break;
1113                            case memoryErrorExp:
1114                               delete evaluation;
1115                               FreeExpContents(exp);
1116                               exp.type = evalError;
1117                               exp.constant = PrintHexUInt64(address);
1118                               break;
1119                            default:
1120                               delete evaluation;
1121                               FreeExpContents(exp);
1122                               exp.type = evalError;
1123                               break;
1124                         }
1125                      }
1126                      else
1127                      {
1128                         FreeExpContents(exp);
1129                         exp.type = unknownErrorExp;
1130                      }
1131                   }
1132                }
1133             }
1134          }
1135          break;
1136       }
1137       case callExp:
1138       {
1139          Expression callExp = exp.call.exp;
1140          Identifier id = (callExp && callExp.type == identifierExp) ? callExp.identifier : null;
1141          bool resolved = false;
1142          if(id && id.string)
1143          {
1144             if(!strcmp(id.string, "nan") || !strcmp(id.string, "inf"))
1145             {
1146                String s = id.string;
1147                id.string = null;
1148                FreeExpContents(exp);
1149                exp.type = constantExp;
1150                exp.constant = s;
1151                resolved = true;
1152             }
1153             else if(exp.call.arguments)
1154             {
1155                if(exp.call.arguments->count == 1)
1156                {
1157                   double (* fn1)(double) = (void *)oneArgFns[id.string];
1158                   if(fn1)
1159                   {
1160                      Expression arg = exp.call.arguments->first;
1161                      DebugComputeExpression(arg);
1162                      if(ExpressionIsError(arg))
1163                         CarryExpressionError(exp, arg);
1164                      else if(arg.isConstant && arg.type == constantExp)
1165                      {
1166                         double v;
1167                         if(GetDouble(arg, &v))
1168                         {
1169                            FreeExpContents(exp);
1170                            exp.type = constantExp;
1171                            v = fn1(v);
1172                            exp.constant = PrintDouble(v);
1173                            exp.isConstant = true;
1174                            resolved = true;
1175                         }
1176                      }
1177                   }
1178                }
1179                else if(exp.call.arguments->count == 2)
1180                {
1181                   double (* fn2)(double, double) = (void *)twoArgFns[id.string];
1182                   if(fn2)
1183                   {
1184                      Expression arg1 = exp.call.arguments->first;
1185                      Expression arg2 = exp.call.arguments->last;
1186                      DebugComputeExpression(arg1);
1187                      DebugComputeExpression(arg2);
1188                      if(ExpressionIsError(arg1))
1189                         CarryExpressionError(exp, arg1);
1190                      else if(ExpressionIsError(arg2))
1191                         CarryExpressionError(exp, arg2);
1192                      else if(arg1.isConstant && arg1.type == constantExp && arg2.isConstant && arg2.type == constantExp)
1193                      {
1194                         double v1, v2;
1195                         if(GetDouble(arg1, &v1) && GetDouble(arg2, &v2))
1196                         {
1197                            FreeExpContents(exp);
1198                            exp.type = constantExp;
1199                            v1 = fn2(v1, v2);
1200                            exp.constant = PrintDouble(v1);
1201                            exp.isConstant = true;
1202                            resolved = true;
1203                         }
1204                      }
1205                   }
1206                }
1207             }
1208          }
1209          if(!resolved)
1210             exp.type = functionCallErrorExp;
1211          break;
1212       }
1213       case memberExp:
1214       {
1215          Expression memberExp = exp.member.exp;
1216          Identifier memberID = exp.member.member;
1217          //Class _class;
1218          Property prop = null;
1219          DataMember member = null;
1220          Class convertTo = null;
1221          uint offset = 0;  // THIS WASN'T INITIALIZED... IS IT ALWAYS SET?
1222
1223          Type type; // = memberExp.expType;
1224          DebugComputeExpression(memberExp);
1225          type = memberExp.expType;
1226          if(ExpressionIsError(memberExp))
1227             CarryExpressionError(exp, memberExp);
1228          else if(type)
1229          {
1230             // _class = (memberID && memberID.classSym) ? memberID.classSym.registered : ((type.kind == classType && type._class) ? type._class.registered : null);
1231             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);
1232             if(!_class)
1233             {
1234                char string[256] = "";
1235                Symbol classSym;
1236                PrintTypeNoConst(type, string, false, true);
1237                classSym = FindClass(string);
1238                _class = classSym ? classSym.registered : null;
1239             }
1240
1241             if(memberID && _class)
1242             {
1243                /*
1244                prop = eClass_FindProperty(_class, memberID.string);
1245                if(!prop)
1246                   member = eClass_FindDataMember(_class, memberID.string);
1247                */
1248                // member = eClass_FindDataMember(_class, memberID.string);
1249                member = eClass_FindDataMemberAndOffset(_class, memberID.string, &offset, _class.module.application, null, null);
1250                if(!member)
1251                   prop = eClass_FindProperty(_class, memberID.string, _class.module.application);
1252             }
1253             if(!prop && !member && _class && memberID)
1254             {
1255                Symbol classSym = FindClass(memberID.string);
1256                convertTo = _class;
1257                _class = classSym ? classSym.registered : null;
1258                if(_class)
1259                   prop = eClass_FindProperty(_class, convertTo.fullName, _class.module.application);
1260             }
1261
1262             //DebugComputeExpression(memberExp);
1263             if(ExpressionIsError(memberExp))
1264                CarryExpressionError(exp, memberExp);
1265             else
1266             {
1267                if(exp.member.memberType == methodMember)
1268                {
1269                   FreeExpContents(exp);
1270                   exp.type = unknownErrorExp;
1271                }
1272                else if(prop)
1273                {
1274                   bool supported = false;
1275                   if(prop.compiled)
1276                   {
1277                      Type type = prop.dataType;
1278                      // TODO: Assuming same base type for units...
1279                      if(_class.type == unitClass)
1280                      {
1281                         if(type.kind == classType)
1282                         {
1283                            Class _class = type._class.registered;
1284                            if(_class.type == unitClass)
1285                            {
1286                               if(!_class.dataType)
1287                                  _class.dataType = ProcessTypeString(_class.dataTypeString, false);
1288                               type = _class.dataType;
1289                            }
1290                         }
1291                         switch(type.kind)
1292                         {
1293                            case floatType:
1294                            {
1295                               float value;
1296                               float (*Get)(float) = (void *) (convertTo ? prop.Set : prop.Get);
1297                               GetFloat(memberExp, &value);
1298                               exp.constant = PrintFloat(Get ? Get(value) : value);
1299                               exp.type = constantExp;
1300                               exp.isConstant = true;
1301                               supported = true;
1302                               break;
1303                            }
1304                            case doubleType:
1305                            {
1306                               double value;
1307                               double (*Get)(double) = (void *) (convertTo ? prop.Set : prop.Get);
1308                               GetDouble(memberExp, &value);
1309                               exp.constant = PrintDouble(Get ? Get(value) : value);
1310                               exp.isConstant = true;
1311                               exp.type = constantExp;
1312                               supported = true;
1313                               break;
1314                            }
1315                         }
1316                      }
1317                      else
1318                      {
1319                         if(convertTo)
1320                         {
1321                            Expression value = memberExp;
1322                            Type type = prop.dataType;
1323                            if(_class.type == structClass)
1324                            {
1325                               switch(type.kind)
1326                               {
1327                                  case classType:
1328                                  {
1329                                     Class propertyClass = type._class.registered;
1330                                     if(propertyClass.type == structClass && value.type == instanceExp)
1331                                     {
1332                                        void (*Set)(void *, void *) = (void *)prop.Set;
1333                                        exp.instance = Instantiation
1334                                        {
1335                                           data = new0 byte[_class.structSize];
1336                                           _class = MkSpecifierName(_class.name);
1337                                           loc = exp.loc;
1338                                        };
1339                                        exp.type = instanceExp;
1340
1341                                        Set(exp.instance.data, value.instance.data);
1342                                        PopulateInstance(exp.instance);
1343                                        supported = true;
1344                                     }
1345                                     break;
1346                                  }
1347                                  case intType:
1348                                  {
1349                                     int intValue;
1350                                     void (*Set)(void *, int) = (void *)prop.Set;
1351
1352                                     exp.instance = Instantiation
1353                                     {
1354                                        data = new0 byte[_class.structSize];
1355                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1356                                        loc = exp.loc;
1357                                     };
1358                                     exp.type = instanceExp;
1359
1360                                     GetInt(value, &intValue);
1361
1362                                     Set(exp.instance.data, intValue);
1363                                     PopulateInstance(exp.instance);
1364                                     supported = true;
1365                                     break;
1366                                  }
1367                                  case int64Type:
1368                                  {
1369                                     int64 intValue;
1370                                     void (*Set)(void *, int64) = (void *)prop.Set;
1371
1372                                     exp.instance = Instantiation
1373                                     {
1374                                        data = new0 byte[_class.structSize];
1375                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1376                                        loc = exp.loc;
1377                                     };
1378                                     exp.type = instanceExp;
1379
1380                                     GetInt64(value, &intValue);
1381
1382                                     Set(exp.instance.data, intValue);
1383                                     PopulateInstance(exp.instance);
1384                                     supported = true;
1385                                     break;
1386                                  }
1387                                  case doubleType:
1388                                  {
1389                                     double doubleValue;
1390                                     void (*Set)(void *, double) = (void *)prop.Set;
1391
1392                                     exp.instance = Instantiation
1393                                     {
1394                                        data = new0 byte[_class.structSize];
1395                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1396                                        loc = exp.loc;
1397                                     };
1398                                     exp.type = instanceExp;
1399
1400                                     GetDouble(value, &doubleValue);
1401
1402                                     Set(exp.instance.data, doubleValue);
1403                                     PopulateInstance(exp.instance);
1404                                     supported = true;
1405                                     break;
1406                                  }
1407                               }
1408                            }
1409                            else if(_class.type == bitClass)
1410                            {
1411                               switch(type.kind)
1412                               {
1413                                  case classType:
1414                                  {
1415                                     Class propertyClass = type._class.registered;
1416                                     if(propertyClass.type == structClass && value.instance.data)
1417                                     {
1418                                        unsigned int (*Set)(void *) = (void *)prop.Set;
1419                                        unsigned int bits = Set(value.instance.data);
1420                                        exp.constant = PrintHexUInt(bits);
1421                                        exp.type = constantExp;
1422                                        supported = true;
1423                                        break;
1424                                     }
1425                                     else if(_class.type == bitClass)
1426                                     {
1427                                        unsigned int value;
1428                                        unsigned int (*Set)(unsigned int) = (void *)prop.Set;
1429                                        unsigned int bits;
1430
1431                                        GetUInt(memberExp, &value);
1432                                        bits = Set(value);
1433                                        exp.constant = PrintHexUInt(bits);
1434                                        exp.type = constantExp;
1435                                        supported = true;
1436                                     }
1437                                  }
1438                               }
1439                            }
1440                         }
1441                         else
1442                         {
1443                            if(_class.type == bitClass)
1444                            {
1445                               uint value;
1446                               GetUInt(memberExp, &value);
1447
1448                               switch(type.kind)
1449                               {
1450                                  case classType:
1451                                  {
1452                                     Class _class = type._class.registered;
1453                                     if(_class.type == structClass)
1454                                     {
1455                                        void (*Get)(unsigned int, void *) = (void *)prop.Get;
1456
1457                                        exp.instance = Instantiation
1458                                        {
1459                                           data = new0 byte[_class.structSize];
1460                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
1461                                           loc = exp.loc;
1462                                        };
1463                                        //exp.instance.fullSet = true;
1464                                        exp.type = instanceExp;
1465                                        Get(value, exp.instance.data);
1466                                        PopulateInstance(exp.instance);
1467                                        supported = true;
1468                                     }
1469                                     else if(_class.type == bitClass)
1470                                     {
1471                                        unsigned int (*Get)(unsigned int) = (void *)prop.Get;
1472                                        uint64 bits = Get(value);
1473                                        exp.constant = PrintHexUInt64(bits);
1474                                        exp.type = constantExp;
1475                                        supported = true;
1476                                     }
1477                                     break;
1478                                  }
1479                               }
1480                            }
1481                            else if(_class.type == structClass)
1482                            {
1483                               char * value = (memberExp.type == instanceExp ) ? memberExp.instance.data : null;
1484                               switch(type.kind)
1485                               {
1486                                  case classType:
1487                                  {
1488                                     Class _class = type._class.registered;
1489                                     if(_class.type == structClass && value)
1490                                     {
1491                                        void (*Get)(void *, void *) = (void *)prop.Get;
1492
1493                                        exp.instance = Instantiation
1494                                        {
1495                                           data = new0 byte[_class.structSize];
1496                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
1497                                           loc = exp.loc;
1498                                        };
1499                                        //exp.instance.fullSet = true;
1500                                        exp.type = instanceExp;
1501                                        Get(value, exp.instance.data);
1502                                        PopulateInstance(exp.instance);
1503                                        supported = true;
1504                                     }
1505                                     break;
1506                                  }
1507                               }
1508                            }
1509                            /*else
1510                            {
1511                               char * value = memberExp.instance.data;
1512                               switch(type.kind)
1513                               {
1514                                  case classType:
1515                                  {
1516                                     Class _class = type._class.registered;
1517                                     if(_class.type == normalClass)
1518                                     {
1519                                        void *(*Get)(void *) = (void *)prop.Get;
1520
1521                                        exp.instance = Instantiation
1522                                        {
1523                                           data = Get(value, exp.instance.data);     ?????
1524                                           _class = MkSpecifierName(_class.name); //MkClassName(_class.name);
1525                                           loc = exp.loc;
1526                                        };
1527                                        exp.type = instanceExp;
1528                                     }
1529                                     break;
1530                                  }
1531                               }
1532                            }
1533                            */
1534                         }
1535                      }
1536                   }
1537                   if(!supported)
1538                   {
1539                      exp.type = memberPropertyErrorExp;
1540                      exp.isConstant = false;
1541                   }
1542                }
1543                else if(member)
1544                {
1545                   if(memberExp.hasAddress || memberExp.type == constantExp)
1546                   //if(memberExp.expType && memberExp.expType.kind == intType)  // && !exp.index.exp.expType.isSigned
1547                   {
1548                      if(_class.type == bitClass)
1549                      {
1550                         if(memberExp.type == constantExp)
1551                         {
1552                            // Unfinished business...
1553                            BitMember bitMember = (BitMember)member;
1554                            uint64 bits = 0;
1555                            GetUInt64(memberExp, &bits);
1556                            bits &= bitMember.mask;
1557                            bits >>= bitMember.pos;
1558
1559                            FreeExpression(exp.member.exp);
1560                            FreeIdentifier(exp.member.member);
1561
1562                            exp.constant = PrintUInt64(bits);
1563
1564                            exp.isConstant = true;
1565                            exp.type = constantExp;
1566                            exp.hasAddress = false;
1567                         }
1568                      }
1569                      else
1570                      {
1571                         char * evaluation = null;
1572                         ExpressionType evalError = dummyExp;
1573                         bool gotAddress = false;
1574                         uint64 address = 0;
1575                         Expression prev = exp.prev, next = exp.next;
1576                         char format;
1577                         int size;
1578                         Expression expNew;
1579                         TypeKind kind = dummyType;
1580                         Type dataType = member.dataType;
1581
1582                         if(!dataType)
1583                            dataType = member.dataType = ProcessTypeString(member.dataTypeString, false);
1584
1585                         if(dataType.kind == classType && dataType._class.registered &&
1586                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1587                         {
1588                            if(dataType._class.registered.dataTypeString)
1589                               dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
1590                            dataType = dataType._class.registered.dataType;
1591                            if(!dataType)
1592                               dataType = ProcessTypeString("int", false);
1593                         }
1594
1595                         size = ComputeTypeSize(member.dataType);
1596
1597                         format = GetGdbFormatChar(dataType);
1598                         //if(memberExp.address)
1599                         {
1600                            //GetInt(memberExp, &address);
1601                            //offset = member.offset;
1602
1603                            // TESTING NOHEAD HERE?
1604                            if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass)
1605                               offset += member._class.offset;
1606
1607                            // VERIFY THIS: (trying to fix primitive.type)
1608                            // if(memberExp.type == constantExp)
1609                            if(memberExp.hasAddress && (_class.type != normalClass && _class.type != noHeadClass && _class.type != systemClass))
1610                            {
1611                               address = memberExp.address;
1612                               gotAddress = true;
1613                            }
1614                            else if(memberExp.type == constantExp)
1615                               gotAddress = GetUInt64(memberExp, &address);
1616                            else
1617                            {
1618                               gotAddress = GetUInt64(memberExp, &address);
1619                               //printf("Unhandled !!\n");
1620
1621                               //printf("memberExp.hasAddress = %d\n", memberExp.hasAddress);
1622                               //printf("memberExp.type = %d\n", memberExp.type);
1623                               //printf("_class.name = %s, _class.type = %d\n", _class.name, _class.type);
1624                            }
1625
1626                            address += offset;
1627
1628                            if(!gotAddress)
1629                               exp.type = unknownErrorExp;
1630                            else if((dataType.kind == classType && dataType._class &&
1631                                  (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
1632                               (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
1633                            {
1634                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1635                               if(evalError != dummyExp)
1636                               {
1637                                  exp.type = evalError;
1638                                  exp.constant = PrintHexUInt64(address);
1639                               }
1640                               else if(evaluation)
1641                               {
1642                                  //printf("evaluation = %s\n", evaluation);
1643                                  expNew = ParseExpressionString(evaluation);
1644                                  delete evaluation;
1645                                  expNew.destType = exp.expType;
1646                                  if(exp.expType)
1647                                     exp.expType.refCount++;
1648                                  //FreeType(memberExp.destType);
1649                                  FreeType(exp.expType);
1650                                  FreeType(exp.destType);
1651                                  FreeExpContents(exp);
1652                                  ProcessExpressionType(expNew);
1653                                  DebugComputeExpression(expNew);
1654                                  expNew.prev = prev;
1655                                  expNew.next = next;
1656                                  expNew.isConstant = true;
1657                                  expNew.address = address;
1658                                  expNew.hasAddress = true;
1659                                  *exp = *expNew;
1660                                  delete expNew;
1661                               }
1662                               else
1663                               {
1664                                  FreeExpContents(exp);
1665                                  exp.type = unknownErrorExp;
1666                               }
1667                            }
1668                            else
1669                            {
1670                               // TESTING THIS HERE...
1671                               exp.type = constantExp;
1672                               exp.constant = PrintHexUInt64(address);
1673
1674                               exp.address = address;
1675                               exp.hasAddress = true;
1676                               exp.isConstant = true;
1677                            }
1678                         }
1679                      }
1680                      //else
1681                      //   exp.type = ExpUnknownError;
1682
1683                      //FreeExpContents(exp);
1684                      //exp.constant = PrintUInt64(value);
1685                      //exp.type = constantExp;
1686                   }
1687                }
1688                else
1689                {
1690                   if(type && (type.kind == structType || type.kind == unionType))
1691                   {
1692                      uint offset = 0;
1693                      Type memberType = exp.member.member ? FindMemberAndOffset(type, exp.member.member.string, &offset) : null;
1694                      if(memberType)
1695                      {
1696                         char * evaluation = null;
1697                         ExpressionType evalError = dummyExp;
1698                         uint64 address = 0;
1699                         bool gotAddress = false;
1700                         Expression prev = exp.prev, next = exp.next;
1701                         char format;
1702                         int size = memberType.size;
1703                         Expression expNew;
1704                         Type dataType = memberType;
1705                         TypeKind kind = dummyType;
1706
1707                         if(dataType.kind == classType && dataType._class.registered &&
1708                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
1709                            dataType = dataType._class.registered.dataType;
1710
1711                         format = GetGdbFormatChar(dataType);
1712
1713                         if(memberExp.hasAddress)
1714                         {
1715                            address = memberExp.address;
1716                            gotAddress = true;
1717                         }
1718                         else if(memberExp.type == constantExp)
1719                            gotAddress = GetUInt64(memberExp, &address);
1720
1721                         address += offset;
1722
1723                         if(!gotAddress)
1724                         {
1725                            FreeExpContents(exp);
1726                            exp.type = unknownErrorExp;
1727                         }
1728                         else if((dataType.kind == classType && dataType._class &&
1729                               (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
1730                            (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
1731                         {
1732                            evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1733                            if(evalError != dummyExp)
1734                            {
1735                               exp.type = evalError;
1736                               exp.constant = PrintHexUInt64(address);
1737                            }
1738                            else if(evaluation)
1739                            {
1740                               expNew = ParseExpressionString(evaluation);
1741                               delete evaluation;
1742                               expNew.destType = exp.expType;
1743                               if(exp.expType)
1744                                  exp.expType.refCount++;
1745                               //FreeType(memberExp.destType);
1746                               FreeType(exp.expType);
1747                               FreeType(exp.destType);
1748                               FreeExpContents(exp);
1749                               ProcessExpressionType(expNew);
1750                               DebugComputeExpression(expNew);
1751                               expNew.prev = prev;
1752                               expNew.next = next;
1753                               expNew.isConstant = true;
1754                               expNew.address = address;
1755                               expNew.hasAddress = true;
1756                               *exp = *expNew;
1757                               delete expNew;
1758                            }
1759                            else
1760                            {
1761                               FreeExpContents(exp);
1762                               exp.type = unknownErrorExp;
1763                            }
1764                         }
1765                         else
1766                         {
1767                            FreeExpContents(exp);
1768
1769                            // TESTING THIS HERE...
1770                            exp.type = constantExp;
1771                            exp.constant = PrintHexUInt64(address);
1772
1773                            exp.address = address;
1774                            exp.hasAddress = true;
1775                            exp.isConstant = true;
1776                         }
1777                      }
1778                      else
1779                         exp.type = memberSymbolErrorExp;
1780                   }
1781                   else
1782                      exp.type = memberSymbolErrorExp;
1783                }
1784             }
1785
1786             //if(exp.type != memberExp)
1787             {
1788                //FreeExpression(memberExp);
1789                //FreeIdentifier(memberID);
1790             }
1791          }
1792          else
1793          {
1794             exp.type = memberSymbolErrorExp;
1795          }
1796          break;
1797       }
1798       case typeSizeExp:
1799       {
1800          Type type = ProcessType(exp.typeName.qualifiers, exp.typeName.declarator);
1801          FreeExpContents(exp);
1802          exp.constant = PrintUInt(ComputeTypeSize(type));
1803          exp.type = constantExp;
1804          FreeType(type);
1805          break;
1806       }
1807       case classSizeExp:
1808       {
1809          Symbol classSym = FindClass(exp._class.name);
1810          if(classSym && classSym.registered)
1811          {
1812             //exp.constant = PrintUInt(classSym.registered.size);
1813             //exp.type = constantExp;
1814
1815             char className[1024];
1816             sprintf(className, "__ecereClass_%s", classSym.string);
1817             FreeExpContents(exp);
1818             exp.type = pointerExp;
1819             exp.member.exp = MkExpIdentifier(MkIdentifier(className));
1820             exp.member.member = MkIdentifier("size");
1821          }
1822          break;
1823       }
1824       case castExp:
1825       {
1826          DebugComputeExpression(exp.cast.exp);
1827
1828          if(ExpressionIsError(exp.cast.exp)) //.type == ExpSymbolError
1829             CarryExpressionError(exp, exp.cast.exp);
1830          else
1831          {
1832             exp.hasAddress = exp.cast.exp.hasAddress;
1833             exp.address = exp.cast.exp.address;
1834             if(exp.cast.exp.type == constantExp && exp.expType)
1835             {
1836                Type type = exp.expType;
1837                if(type.kind == classType && type._class && type._class.registered)
1838                {
1839                   Class _class = type._class.registered;
1840                   if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
1841                   {
1842                      if(!_class.dataType)
1843                         _class.dataType = ProcessTypeString(_class.dataTypeString, false);
1844                      type = _class.dataType;
1845                   }
1846                   else if(_class.type == structClass && !type.byReference)
1847                   {
1848                      FreeExpContents(exp);
1849                      exp.type = unknownErrorExp;
1850                      break;
1851                   }
1852                }
1853
1854                switch(type.kind)
1855                {
1856                   case charType:
1857                      if(type.isSigned)
1858                      {
1859                         char value = 0;
1860                         if(GetChar(exp.cast.exp, &value))
1861                         {
1862                            FreeExpContents(exp);
1863                            exp.constant = PrintChar(value);
1864                            exp.type = constantExp;
1865                            exp.isConstant = true;
1866                         }
1867                      }
1868                      else
1869                      {
1870                         unsigned char value = 0;
1871                         if(GetUChar(exp.cast.exp, &value))
1872                         {
1873                            FreeExpContents(exp);
1874                            exp.constant = PrintUChar(value);
1875                            exp.type = constantExp;
1876                            exp.isConstant = true;
1877                         }
1878                      }
1879                      break;
1880                   case shortType:
1881                      if(type.isSigned)
1882                      {
1883                         short value = 0;
1884                         if(GetShort(exp.cast.exp, &value))
1885                         {
1886                            FreeExpContents(exp);
1887                            exp.constant = PrintShort(value);
1888                            exp.type = constantExp;
1889                            exp.isConstant = true;
1890                         }
1891                      }
1892                      else
1893                      {
1894                         unsigned short value = 0;
1895                         if(GetUShort(exp.cast.exp, &value))
1896                         {
1897                            FreeExpContents(exp);
1898                            exp.constant = PrintUShort(value);
1899                            exp.type = constantExp;
1900                            exp.isConstant = true;
1901                         }
1902                      }
1903                      break;
1904                   case intType:
1905                      if(type.isSigned)
1906                      {
1907                         int value = 0;
1908                         if(GetInt(exp.cast.exp, &value))
1909                         {
1910                            FreeExpContents(exp);
1911                            exp.constant = PrintInt(value);
1912                            exp.type = constantExp;
1913                            exp.isConstant = true;
1914                         }
1915                      }
1916                      else
1917                      {
1918                         unsigned int value = 0;
1919                         if(GetUInt(exp.cast.exp, &value))
1920                         {
1921                            FreeExpContents(exp);
1922                            exp.constant = PrintUInt(value);
1923                            exp.type = constantExp;
1924                            exp.isConstant = true;
1925                         }
1926                      }
1927                      break;
1928                   case int64Type:
1929                      if(type.isSigned)
1930                      {
1931                         int64 value = 0;
1932                         if(GetInt64(exp.cast.exp, &value))
1933                         {
1934                            FreeExpContents(exp);
1935                            exp.constant = PrintInt64(value);
1936                            exp.type = constantExp;
1937                            exp.isConstant = true;
1938                         }
1939                      }
1940                      else
1941                      {
1942                         uint64 value = 0;
1943                         if(GetUInt64(exp.cast.exp, &value))
1944                         {
1945                            FreeExpContents(exp);
1946                            exp.constant = PrintUInt64(value);
1947                            exp.type = constantExp;
1948                            exp.isConstant = true;
1949                         }
1950                      }
1951                      break;
1952                   case pointerType:
1953                   case classType:
1954                   {
1955                      uint64 value = 0;
1956                      if(GetUInt64(exp.cast.exp, &value))
1957                      {
1958                         FreeExpContents(exp);
1959                         if(type.kind == pointerType || type.kind == classType)
1960                            exp.constant = PrintHexUInt64(value);
1961                         else
1962                            exp.constant = PrintUInt64(value);
1963                         exp.type = constantExp;
1964                         exp.isConstant = true;
1965                      }
1966                      break;
1967                   }
1968                   case floatType:
1969                   {
1970                      float value = 0;
1971                      if(exp.cast.exp.type == constantExp && exp.cast.exp.constant &&
1972                         (!strcmpi(exp.cast.exp.constant, "nan") ||
1973                         !strcmpi(exp.cast.exp.constant, "-nan") ||
1974                         !strcmpi(exp.cast.exp.constant, "inf") ||
1975                         !strcmpi(exp.cast.exp.constant, "-inf")))
1976                      {
1977                         String constant = exp.cast.exp.constant;
1978                         exp.cast.exp.constant = null;
1979                         FreeExpContents(exp);
1980                         exp.constant = constant;
1981                         exp.type = constantExp;
1982                         exp.isConstant = true;
1983                      }
1984                      else if(GetFloat(exp.cast.exp, &value))
1985                      {
1986                         FreeExpContents(exp);
1987                         exp.constant = PrintFloat(value);
1988                         exp.type = constantExp;
1989                         exp.isConstant = true;
1990                      }
1991                      break;
1992                   }
1993                   case doubleType:
1994                   {
1995                      double value = 0;
1996                      if(exp.cast.exp.type == constantExp && exp.cast.exp.constant &&
1997                         (!strcmpi(exp.cast.exp.constant, "nan") ||
1998                         !strcmpi(exp.cast.exp.constant, "-nan") ||
1999                         !strcmpi(exp.cast.exp.constant, "inf") ||
2000                         !strcmpi(exp.cast.exp.constant, "-inf")))
2001                      {
2002                         String constant = exp.cast.exp.constant;
2003                         exp.cast.exp.constant = null;
2004                         FreeExpContents(exp);
2005                         exp.constant = constant;
2006                         exp.type = constantExp;
2007                         exp.isConstant = true;
2008                      }
2009                      else if(GetDouble(exp.cast.exp, &value))
2010                      {
2011                         FreeExpContents(exp);
2012                         exp.constant = PrintDouble(value);
2013                         exp.type = constantExp;
2014                         exp.isConstant = true;
2015                      }
2016                      break;
2017                   }
2018                }
2019             }
2020          }
2021          break;
2022       }
2023       case conditionExp:
2024       {
2025          if(exp.cond.cond)
2026          {
2027             DebugComputeExpression(exp.cond.cond);
2028
2029             if(ExpressionIsError(exp.cond.cond))
2030                CarryExpressionError(exp, exp.cond.cond);
2031             else if(exp.cond.cond.type == constantExp && exp.cond.cond.constant)
2032             {
2033                Expression e = null;
2034                if(strtol(exp.cond.cond.constant, null, 0))
2035                {
2036                   for(e = exp.cond.exp ? exp.cond.exp->first : null; e; e = e.next)
2037                   {
2038                      DebugComputeExpression(e);
2039                      if(!e.next) break;
2040                   }
2041                   if(e)
2042                   {
2043                      if(ExpressionIsError(e))
2044                      {
2045                         CarryExpressionError(exp, e);
2046                         e = null;
2047                      }
2048                      else
2049                         exp.cond.exp->Remove(e);
2050                   }
2051                }
2052                else
2053                {
2054                   e = exp.cond.elseExp;
2055                   if(e)
2056                   {
2057                      DebugComputeExpression(e);
2058                      if(ExpressionIsError(e))
2059                      {
2060                         CarryExpressionError(exp, e);
2061                         e = null;
2062                      }
2063                      else
2064                         exp.cond.elseExp = null;
2065                   }
2066                }
2067                if(e)
2068                {
2069                   FreeType(exp.expType);
2070                   FreeType(exp.destType);
2071                   e.prev = exp.prev;
2072                   e.next = exp.next;
2073                   FreeExpContents(exp);
2074                   *exp = *e;
2075                   delete e;
2076                }
2077                else if(!ExpressionIsError(exp))
2078                {
2079                   FreeExpContents(exp);
2080                   exp.type = unknownErrorExp;
2081                }
2082             }
2083             else
2084             {
2085                FreeExpContents(exp);
2086                exp.type = unknownErrorExp;
2087             }
2088          }
2089          else
2090          {
2091             FreeExpContents(exp);
2092             exp.type = unknownErrorExp;
2093          }
2094          break;
2095       }
2096    }
2097 }