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