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