compiler/libec: Fixed referencing member of List::first ( Broken by 47a3b8193f238ab7c...
[sdk] / compiler / libec / src / pass16.ec
1 import "ecdefs"
2
3 #define YYLTYPE Location
4 #include "grammar.h"
5
6 extern External curExternal;
7 static Statement curCompound;
8 static Statement createInstancesBody;
9 static Statement destroyInstancesBody;
10 static External createInstancesExternal;
11 static External destroyInstancesExternal;
12
13 static void CreateInstancesBody()
14 {
15    if(inCompiler && !createInstancesBody)
16    {
17       char registerName[1024], moduleName[MAX_FILENAME];
18       OldList * specifiers;
19       Declarator declarator;
20
21       createInstancesBody = MkCompoundStmt(null, MkList());
22       createInstancesBody.compound.context = Context { parent = globalContext };
23
24       specifiers = MkList();
25       ListAdd(specifiers, MkSpecifier(VOID));
26
27       //strcpy(moduleName, outputFile);
28       GetLastDirectory(outputFile, moduleName);
29       StripExtension(moduleName);
30       FixModuleName(moduleName);
31       sprintf(registerName, "__ecereCreateModuleInstances_%s", moduleName);
32
33       declarator = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(registerName)), null);
34
35       {
36          FunctionDefinition function = _MkFunction(specifiers, declarator, null, false);
37          ProcessFunctionBody(function, createInstancesBody);
38          ListAdd(ast, createInstancesExternal = MkExternalFunction(function));
39       }
40
41       // Destroy Instances Body
42       destroyInstancesBody = MkCompoundStmt(null, MkList());
43       destroyInstancesBody.compound.context = Context { parent = globalContext };
44
45       specifiers = MkList();
46       ListAdd(specifiers, MkSpecifier(VOID));
47
48       sprintf(registerName, "__ecereDestroyModuleInstances_%s", moduleName);
49
50       declarator = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(registerName)), null);
51
52       {
53          FunctionDefinition function = _MkFunction(specifiers, declarator, null, false);
54          ProcessFunctionBody(function, destroyInstancesBody);
55          ListAdd(ast, destroyInstancesExternal = MkExternalFunction(function));
56       }
57    }
58 }
59
60 // ***************** EXPRESSION PROCESSING ***************************
61 static void ProcessMemberInitData(MemberInit member)
62 {
63    if(member.initializer)
64       ProcessInitializer(member.initializer);
65 }
66
67 static void ProcessInstantiation(Instantiation inst)
68 {
69    if(inst.members && inst.members->first)
70    {
71       MembersInit members;
72       for(members = inst.members->first; members; members = members.next)
73       {
74          if(members.type == dataMembersInit)
75          {
76             if(members.dataMembers)
77             {
78                MemberInit member;
79                for(member = members.dataMembers->first; member; member = member.next)
80                   ProcessMemberInitData(member);
81             }
82          }
83          else if(members.type == methodMembersInit)
84          {
85             ProcessFunction((FunctionDefinition)members.function);
86          }
87       }
88    }
89 }
90
91 // ADDED TO SUPPORT NESTED UNNAMED STRUCTURES
92 static bool ProcessInstMembers_SimpleMemberEnsure(DataMember parentMember, Instantiation inst, Expression instExp, OldList list, bool zeroOut)
93 {
94    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
95
96    // For simple classes, ensure all members are initialized
97    bool fullSet = true;
98    DataMember dataMember;
99    for(dataMember = parentMember.members.first; dataMember; dataMember = dataMember.next)
100    {
101       if(!dataMember.isProperty)
102       {
103          if(!dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
104          {
105             if(!ProcessInstMembers_SimpleMemberEnsure(dataMember, inst, instExp, list, zeroOut))
106                fullSet = false;
107          }
108          else
109          {
110             bool memberFilled = false;
111             if(inst.members && inst.members->first)
112             {
113                Class curClass = null;
114                DataMember curMember = null;
115                DataMember subMemberStack[256];
116                int subMemberStackPos = 0;
117                MembersInit members;
118
119                for(members = inst.members->first; members; members = members.next)
120                {
121                   if(members.type == dataMembersInit)
122                   {
123                      MemberInit member = null;
124                      for(member = members.dataMembers->first; member; member = member.next)
125                      {
126                         if(member.identifiers)
127                         {
128                            Identifier firstID = member.identifiers->first;
129                            DataMember _subMemberStack[256];
130                            int _subMemberStackPos = 0;
131                            DataMember thisMember = (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule);
132                            // FILL MEMBER STACK
133                            if(!thisMember)
134                               thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
135                            if(thisMember)
136                            {
137                               if(thisMember && thisMember.memberAccess == publicAccess)
138                               {
139                                  curMember = thisMember;
140                                  curClass = curMember._class;
141                                  memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
142                                  subMemberStackPos = _subMemberStackPos;
143                               }
144                               if(!firstID.next && thisMember == dataMember)
145                               {
146                                  memberFilled = true;
147                                  break;
148                               }
149                            }
150
151                            /*
152                            BTNamedLink link = parentMember.membersAlpha.Find((uintptr)firstID.string);
153                            if(link)
154                            {
155                               curMember = link.data;
156                               if(!firstID.next && curMember == dataMember)
157                               {
158                                  memberFilled = true;
159                                  break;
160                               }
161                            }
162                            */
163                         }
164                         else
165                         {
166                            eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
167                            if(curMember == dataMember)
168                            {
169                               memberFilled = true;
170                               break;
171                            }
172                            /*
173                            if(curMember)
174                               curMember = curMember.next;
175                            else
176                               curMember = parentMember.members.first;
177                            */
178
179                            //while(curMember)
180                            //   curMember = curMember.next;
181                         }
182                      }
183                      if(memberFilled) break;
184                   }
185                   if(memberFilled) break;
186                }
187             }
188             if(!memberFilled)
189             {
190                if(zeroOut)
191                {
192                   Expression instExpCopy = CopyExpression(instExp);
193                   Expression memberExp;
194                   Expression setExp;
195                   Expression value = MkExpConstant("0");
196
197                   memberExp = MkExpMember(instExpCopy, MkIdentifier(dataMember.name));
198                   memberExp.member.memberType = MemberType::dataMember;
199
200                   value.usage.usageGet = true;
201                   setExp = MkExpOp(memberExp, '=', value);
202
203                   value.loc = inst.loc;
204
205                   // Testing this
206                   setExp.loc = inst.loc;
207
208                   FreeType(instExpCopy.expType);
209                   instExpCopy.expType = instExp.expType;
210                   if(instExp.expType) instExp.expType.refCount++;
211
212                   ProcessExpressionType(setExp);
213                   ProcessExpression(setExp);
214
215                   ListAdd(list, setExp);
216                }
217                fullSet = false;
218             }
219          }
220       }
221       /*
222       if(parentMember.type == unionMember)
223          break;
224       */
225    }
226    return fullSet;
227 }
228
229 // Returns if all members are set
230 static bool ProcessInstMembers(Instantiation inst, Expression instExp, OldList list, bool zeroOut)
231 {
232    MembersInit members;
233    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
234    bool fullSet = true, convert = false;
235    if(classSym && classSym.registered && classSym.registered.type == bitClass)
236    {
237       Expression exp = null;
238       if(inst.members && inst.members->first)
239       {
240          // Ensure all members are initialized only once
241          Class _class = null;
242          while(_class != classSym.registered)
243          {
244             BitMember bitMember = null;
245             Class lastClass = _class;
246
247             for(_class = classSym.registered; _class.base != lastClass && _class.base.type != systemClass; _class = _class.base);
248
249             for(bitMember = _class.membersAndProperties.first; bitMember; bitMember = bitMember.next)
250             {
251                BitMember curMember = null;
252                Class curClass = null;
253                DataMember subMemberStack[256];
254                int subMemberStackPos = 0;
255                MemberInit member = null;
256                bool found = false;
257                for(members = inst.members->first; members; members = members.next)
258                {
259                   if(members.type == dataMembersInit)
260                   {
261                      for(member = members.dataMembers->first; member; member = member.next)
262                      {
263                         if(member.identifiers)
264                         {
265                            Identifier firstID = member.identifiers->first;
266                            DataMember _subMemberStack[256];
267                            int _subMemberStackPos = 0;
268
269                            // FILL MEMBER STACK
270                            BitMember thisMember = (BitMember)eClass_FindDataMember(_class, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
271                            if(!thisMember)
272                            {
273                               // WARNING: Brackets needed here, awaiting precomp fix
274                               thisMember = (BitMember)eClass_FindProperty(_class, firstID.string, privateModule);
275                            }
276                            if(thisMember && thisMember.memberAccess == publicAccess)
277                            {
278                               curMember = thisMember;
279                               curClass = curMember._class;
280                               memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
281                               subMemberStackPos = _subMemberStackPos;
282                            }
283                            if(thisMember == bitMember)
284                            {
285                               found = true;
286                               break;
287                            }
288                         }
289                         else
290                         {
291                            eClass_FindNextMember(classSym.registered, &curClass, (DataMember *)&curMember, subMemberStack, &subMemberStackPos);
292                            if(curMember == bitMember)
293                            {
294                               found = true;
295                               break;
296                            }
297                         }
298                      }
299                   }
300                   if(found) break;
301                }
302
303                if(member)
304                {
305                   if(!bitMember.isProperty)
306                   {
307                      Expression part = null;
308                      OldList * specs = MkList();
309                      Declarator decl;
310                      //decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
311                      decl = SpecDeclFromString(_class.dataTypeString, specs, null);
312
313                      ProcessInitializer(member.initializer);
314
315                      if(member.initializer && member.initializer.type == expInitializer)
316                      {
317                         if(bitMember.pos)
318                         {
319                            char pos[10];
320                            sprintf(pos, "%d", bitMember.pos);
321                            // (((type) value) << bitPos)
322                            part = MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(MkExpCast(
323                               MkTypeName(specs, decl), MkExpBrackets(MkListOne(member.initializer.exp))))), LEFT_OP, MkExpConstant(pos))));
324                         }
325                         else
326                            part = MkExpBrackets(MkListOne(MkExpCast(MkTypeName(specs, decl),
327                               MkExpBrackets(MkListOne(member.initializer.exp)))));
328                         // Take it out
329                         member.initializer.exp = null;
330                         FreeInitializer(member.initializer);
331                         member.initializer = null;
332                      }
333
334                      if(exp)
335                         exp = MkExpOp(exp,'|', part);
336                      else
337                         exp = part;
338                   }
339                   // Clean this up... should only be used for Conversion properties...
340                   else
341                   {
342                      char setName[1024], getName[1024];
343                      DeclareProperty(curExternal, (Property)bitMember, setName, getName);
344                      if(member.initializer && member.initializer.type == expInitializer)
345                      {
346                         exp = MkExpCall(MkExpIdentifier(MkIdentifier(setName)),
347                            MkListOne(member.initializer.exp));
348
349                         // Take it out
350                         member.initializer.exp = null;
351                         FreeInitializer(member.initializer);
352                         member.initializer = null;
353                      }
354                   }
355                }
356             }
357          }
358       }
359       if(exp)
360          exp = MkExpBrackets(MkListOne(exp));
361       else
362          exp = MkExpConstant("0");
363
364       // Just added this one...
365       exp.expType = MkClassType(classSym.string);
366
367       ProcessExpression(exp);
368
369       ListAdd(list, exp);
370    }
371    else if(classSym && classSym.registered && classSym.registered.type == unitClass)
372    {
373       Class _class = classSym.registered;
374       Expression exp = null;
375       if(inst.members && inst.members->first)
376       {
377          MemberInit member = null;
378          Property prop = null;
379          bool found = false;
380          for(members = inst.members->first; members; members = members.next)
381          {
382             if(members.type == dataMembersInit)
383             {
384                for(member = members.dataMembers->first; member; member = member.next)
385                {
386                   if(member.identifiers)
387                   {
388                      Identifier firstID = member.identifiers->first;
389                      prop = eClass_FindProperty(_class, firstID.string, privateModule);
390                      if(prop)
391                      {
392                         found = true;
393                         break;
394                      }
395                      prop = null;
396                   }
397                   else
398                   {
399                      found = true;
400                      break;
401                   }
402                }
403             }
404             if(found) break;
405          }
406
407          if(member)
408          {
409             if(prop)
410             {
411                char setName[1024], getName[1024];
412                DeclareProperty(curExternal, prop, setName, getName);
413                if(member.initializer && member.initializer.type == expInitializer)
414                {
415                   exp = MkExpCall(MkExpIdentifier(MkIdentifier(setName)), MkListOne(member.initializer.exp));
416
417                   // Take it out
418                   member.initializer.exp = null;
419                   FreeInitializer(member.initializer);
420                   member.initializer = null;
421                }
422             }
423             else
424             {
425                ProcessInitializer(member.initializer);
426                if(member.initializer && member.initializer.type == expInitializer)
427                {
428                   //exp = MkExpBrackets(MkListOne(MkExpCast(QMkClass(_class.fullName, null), member.exp)));
429                   exp = MkExpCast(QMkClass(_class.fullName, null), MkExpBrackets(MkListOne(member.initializer.exp)));
430
431                   // Take it out
432                   member.initializer.exp = null;
433                   FreeInitializer(member.initializer);
434                   member.initializer = null;
435                }
436             }
437          }
438       }
439       if(exp)
440          exp = MkExpBrackets(MkListOne(exp));
441       else
442          exp = MkExpConstant("0");
443
444       ProcessExpression(exp);
445
446       ListAdd(list, exp);
447    }
448    else if(classSym && classSym.registered)
449    {
450       if(classSym.registered.type == structClass)
451       {
452          // For simple classes, ensure all members are initialized
453          Class _class = null;
454          while(_class != classSym.registered)
455          {
456             DataMember dataMember;
457             Class lastClass = _class;
458
459             for(_class = classSym.registered; _class.base != lastClass && _class.base.type != systemClass; _class = _class.base);
460
461             if(_class.structSize != _class.memberOffset)
462                fullSet = false;
463
464             for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
465             {
466                if(!dataMember.isProperty)
467                {
468                   if(!dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
469                   {
470                      if(!ProcessInstMembers_SimpleMemberEnsure(dataMember, inst, instExp, list, zeroOut))
471                         fullSet = false;
472                   }
473                   else
474                   {
475                      bool memberFilled = false;
476                      if(inst.members && inst.members->first)
477                      {
478                         Class curClass = null;
479                         DataMember curMember = null;
480                         DataMember subMemberStack[256];
481                         int subMemberStackPos = 0;
482
483                         for(members = inst.members->first; members; members = members.next)
484                         {
485                            if(members.type == dataMembersInit && members.dataMembers)
486                            {
487                               MemberInit member = null;
488                               for(member = members.dataMembers->first; member; member = member.next)
489                               {
490                                  if(member.identifiers)
491                                  {
492                                     DataMember _subMemberStack[256];
493                                     int _subMemberStackPos = 0;
494                                     Identifier firstID = member.identifiers->first;
495                                     DataMember thisMember = (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule);
496                                     // FILL MEMBER STACK
497                                     if(!thisMember)
498                                        thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
499                                     if(thisMember)
500                                     {
501                                        if(thisMember.memberAccess == publicAccess)
502                                        {
503                                           curMember = thisMember;
504                                           curClass = curMember._class;
505                                           memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
506                                           subMemberStackPos = _subMemberStackPos;
507                                        }
508                                        if(!firstID.next && curMember == dataMember)
509                                        {
510                                           memberFilled = true;
511                                           break;
512                                        }
513                                     }
514                                  }
515                                  else
516                                  {
517                                     eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
518                                     if(curMember == dataMember)
519                                     {
520                                        memberFilled = true;
521                                        break;
522                                     }
523                                  }
524                               }
525                               if(memberFilled) break;
526                            }
527                            if(memberFilled) break;
528                         }
529                      }
530                      if(!memberFilled)
531                      {
532                         if(zeroOut)
533                         {
534                            Expression instExpCopy = CopyExpression(instExp);
535                            Expression memberExp;
536                            Expression setExp;
537                            Expression value = MkExpConstant("0");
538
539                            memberExp = MkExpMember(instExpCopy, MkIdentifier(dataMember.name));
540                            memberExp.member.memberType = MemberType::dataMember;
541
542                            value.usage.usageGet = true;
543                            setExp = MkExpOp(memberExp, '=', value);
544
545                            value.loc = inst.loc;
546
547                            // Testing this
548                            setExp.loc = inst.loc;
549
550                            FreeType(instExpCopy.expType);
551                            instExpCopy.expType = instExp.expType;
552                            if(instExp.expType) instExp.expType.refCount++;
553
554                            ProcessExpressionType(setExp);
555                            ProcessExpression(setExp);
556
557                            ListAdd(list, setExp);
558                         }
559                         fullSet = false;
560                      }
561                   }
562                }
563             }
564          }
565       }
566
567       // THEN SET EVERYTHING IN THE ORDER IT IS SET
568       if(inst.members && inst.members->first)
569       {
570          Class curClass = null;
571          DataMember curMember = null;
572          DataMember subMemberStack[256];
573          int subMemberStackPos = 0;
574
575          for(members = inst.members->first; members; members = members.next)
576          {
577             if(members.type == dataMembersInit && members.dataMembers)
578             {
579                MemberInit member = null;
580                Method method = null;
581
582                for(member = members.dataMembers->first; member; member = member.next)
583                {
584                   Identifier ident = null;
585                   DataMember thisMember = null;
586                   if(member.identifiers)
587                   {
588                      DataMember _subMemberStack[256];
589                      int _subMemberStackPos = 0;
590                      Identifier firstID = member.identifiers->first;
591                      thisMember = (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule);
592                      // FILL MEMBER STACK
593                      if(!thisMember)
594                         thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
595                      ident = firstID;
596                      if(thisMember)
597                      {
598                         if(thisMember.memberAccess == publicAccess)
599                         {
600                            curMember = thisMember;
601                            curClass = curMember._class;
602                            memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
603                            subMemberStackPos = _subMemberStackPos;
604                         }
605                      }
606                      else if(classSym.registered.type != structClass)
607                      {
608                         method = eClass_FindMethod(classSym.registered, ident.string, privateModule);
609                         if(!method || method.type != virtualMethod)
610                            method = null;
611                      }
612                   }
613                   else
614                   {
615                      eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
616                      thisMember = curMember;
617                   }
618
619                   if(instExp && (thisMember || method))
620                   {
621                      Expression instExpCopy = CopyExpression(instExp);
622                      Expression setExp = null;
623
624                      instExpCopy.tempCount = instExp.tempCount;
625
626                      if(!ident)
627                         ident = MkIdentifier(thisMember.name);
628                      if(ident)
629                      {
630                         Expression memberExp;
631                         bool freeMemberExp = false;
632
633                         if(thisMember && thisMember.isProperty && ((Property)thisMember).conversion)
634                            convert = true;
635                         if(member.identifiers && member.identifiers->count > 1)
636                         {
637                            Identifier id = member.identifiers->first;
638                            // TODO: Set the member types for those
639                            memberExp = MkExpMember(instExpCopy, id);
640                            for(id = id.next; id; id = id.next)
641                               memberExp = MkExpMember(memberExp, id);
642                         }
643                         else
644                            memberExp = MkExpMember(instExpCopy, ident);
645
646                         if(member.initializer && member.initializer.type == expInitializer && member.initializer.exp)
647                         {
648                            member.initializer.exp.usage.usageGet = true;
649                            setExp = MkExpOp(memberExp, '=', member.initializer.exp);
650
651                            // Take this out
652                            member.initializer.exp = null;
653                            FreeInitializer(member.initializer);
654                            member.initializer = null;
655                         }
656                         else
657                         {
658                            freeMemberExp = true;
659                            // TOCHECK: WHat happens in here?
660                         }
661                         // TODO: list initializer not working...
662                         memberExp.loc = inst.loc;
663
664                         if(member.identifiers)
665                            member.identifiers->Clear();
666
667                         // Testing this
668                         if(setExp)
669                            setExp.loc = inst.loc;
670
671                         FreeType(instExpCopy.expType);
672                         instExpCopy.expType = instExp.expType;
673                         if(instExp.expType) instExp.expType.refCount++;
674
675                         if(setExp)
676                         {
677                            ProcessExpressionType(setExp);
678                            ProcessExpression(setExp);
679
680                            ListAdd(list, setExp);
681                         }
682                         if(freeMemberExp)
683                            FreeExpression(memberExp);
684                      }
685                   }
686                }
687             }
688          }
689       }
690    }
691    return fullSet || convert;
692 }
693
694 // We may want to have 2 functions here for dependency on struct or class pointer
695 public void DeclareClass(External neededFor, Symbol classSym, const char * className)
696 {
697    /*if(classSym.registered.templateClass)
698    {
699       Symbol templateSym;
700       char className[1024];
701       strcpy(className, "__ecereClass_");
702       templateSym = FindClass(classSym.registered.templateClass.fullName);
703       FullClassNameCat(className, templateSym.string, true);
704
705       DeclareClass(templateSym, className);
706    }*/
707    if(classSym && classSym.notYetDeclared)
708    {
709       if(!classSym.mustRegister)
710       {
711          if(!classSym._import)
712          {
713             if(!classSym.module) classSym.module = mainModule;
714             if(!classSym.module) return;
715             classSym._import = ClassImport
716             {
717                isRemote = classSym.registered ? classSym.registered.isRemote : 0;
718                name = CopyString(classSym.string);
719             };
720             classSym.module.classes.Add(classSym._import);
721          }
722          classSym._import.itself = true;
723       }
724       classSym.notYetDeclared = false;
725
726       if(!classSym.pointerExternal && inCompiler)
727       {
728          Declaration decl;
729          OldList * specifiers, * declarators;
730          Declarator d;
731
732          specifiers = MkList();
733          declarators = MkList();
734
735          ListAdd(specifiers, MkSpecifier(EXTERN));
736          ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
737
738          d = MkDeclaratorPointer(MkPointer(null, null),
739             MkDeclaratorIdentifier(MkIdentifier(className)));
740
741          ListAdd(declarators, MkInitDeclarator(d, null));
742
743          decl = MkDeclaration(specifiers, declarators);
744
745          classSym.pointerExternal = MkExternalDeclaration(decl);
746          ast->Add(classSym.pointerExternal);
747
748          DeclareStruct(classSym.pointerExternal, "ecere::com::Class", false, true);
749       }
750    }
751    if(inCompiler && classSym && classSym.pointerExternal && neededFor)
752       neededFor.CreateUniqueEdge(classSym.pointerExternal, false);
753 }
754
755 void ProcessExpressionInstPass(Expression exp)
756 {
757    ProcessExpression(exp);
758 }
759
760 static void ProcessExpression(Expression exp)
761 {
762 #ifdef _DEBUG
763    char debugExpString[1024] = "";
764    PrintExpression(exp, debugExpString);
765 #endif
766    switch(exp.type)
767    {
768       case identifierExp:
769          break;
770       case instanceExp:
771       {
772          Instantiation inst = exp.instance;
773          if(inCompiler && inst._class)
774          {
775             char className[1024];
776             Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
777             Expression instExp;
778
779             if(classSym && classSym.registered && classSym.registered.type == bitClass)
780             {
781                if(inst.exp)
782                {
783                   OldList list = { 0 };
784
785                   ProcessInstMembers(inst, null, &list, false);
786
787                   ProcessExpression(inst.exp);
788
789                   //Why was this here twice? ProcessInstMembers(inst, null, &list);
790                   exp.type = opExp;
791                   exp.op.op = '=';
792                   exp.op.exp1 = inst.exp;
793                   exp.op.exp2 = list.first;
794
795                   // Take expression out... (Why was the comment alone?)
796                   inst.exp = null;
797                }
798                else
799                {
800                   Type expType = exp.expType;
801                   Expression prev = exp.prev, next = exp.next;
802                   OldList list { };
803                   ProcessInstMembers(inst, null, &list, false);
804
805                   // TODO : To Check
806                   FreeType(exp.destType);
807
808                   *exp = *(Expression)list.first;
809
810                   {
811                      Expression firstExp = list.first;
812                      delete firstExp;
813                   }
814
815                   FreeType(exp.destType);
816                   exp.destType = expType;
817                   //if(expType) expType.refCount++;
818
819                   exp.prev = prev;
820                   exp.next = next;
821                }
822             }
823             else if(classSym && classSym.registered && (classSym.registered.type == unitClass || classSym.registered.type == enumClass))
824             {
825                if(inst.exp)
826                {
827                   OldList list = { 0 };
828                   Expression e;
829
830                   ProcessInstMembers(inst, null, &list, false);
831
832                   ProcessExpression(inst.exp);
833
834                   //Why was this here twice? ProcessInstMembers(inst, null, &list);
835                   exp.type = opExp;
836                   exp.op.op = '=';
837                   exp.op.exp1 = inst.exp;
838                   exp.op.exp2 = list.first;
839
840                   // Take expression out... (Why was the comment alone?)
841                   inst.exp = null;
842
843                   list.Remove(list.first);
844                   while((e = list.first))
845                   {
846                      list.Remove(e);
847                      FreeExpression(e);
848                   }
849                }
850                else
851                {
852                   Expression prev = exp.prev, next = exp.next;
853                   Type expType = exp.expType;
854                   OldList list = { 0 };
855                   ProcessInstMembers(inst, null, &list, false);
856
857                   // TODO : To Check
858                   if(list.first)
859                   {
860                      Expression e = list.first;
861                      FreeType(exp.destType);
862                      *exp = *e;
863                      list.Remove(e);
864                      delete e;
865                      exp.expType = expType;
866                      exp.prev = prev;
867                      exp.next = next;
868                      while((e = list.first))
869                      {
870                         list.Remove(e);
871                         FreeExpression(e);
872                      }
873                   }
874                   else
875                   {
876                      exp.type = constantExp;
877                      exp.constant = CopyString("0");
878                   }
879                }
880             }
881             else if(classSym && classSym.registered && classSym.registered.type == structClass)
882             {
883                if(inst.exp)
884                {
885                   // Set members
886                   exp.type = bracketsExp;
887                   exp.list = MkList();
888
889                   ProcessInstMembers(inst, inst.exp, exp.list, false);
890
891                   ProcessExpression(inst.exp);
892
893                   if(!exp.list->count)
894                   {
895                      exp.type = dummyExp; // remove expression
896                      delete exp.list;
897                   }
898
899                   // Take expression out... -- It seems ProcessInstMembers() makes copies of it and it needs to be freed now
900                   // inst.exp = null;
901                }
902                else
903                {
904                   Declaration decl;
905                   Declaration dummyDecl;
906                   // Unnamed instantiation
907
908                   // Make a declaration in the closest compound statement
909                   // (Do not reuse (since using address for function calls)...)
910
911                   /*
912                   ListAdd(decls, MkInitDeclarator(
913                      MkDeclaratorIdentifier(MkIdentifier(className)), null));
914                   decl = MkDeclaration(specs, decls);
915                   */
916                   /*    Never mind this... somebody might modify the values...
917
918                   if(inst.isConstant)
919                   {
920                      sprintf(className, "__simpleStruct%d", curContext.simpleID++);
921                      inst.id = MkIdentifier(className);
922                      decl = MkDeclarationInst(inst);
923                      exp.type = ExpIdentifier;
924                      exp.identifier = inst.id;
925                      if(!curCompound.compound.declarations)
926                         curCompound.compound.declarations = MkList();
927                      curCompound.compound.declarations->Insert(null, decl);
928                      ProcessDeclaration(decl);
929                   }
930                   else
931                   */
932
933                   {
934                      //OldList * specs = MkList(), * decls = MkList();
935                      //sprintf(className, "__ecereClassData_%s", inst._class.name);
936                      //ListAdd(specs, MkStructOrUnion(SpecifierStruct, MkIdentifier(className), null));
937
938
939                      // TRICKY STUFF, UGLY HACK FOR stateSizeAnchor = SizeAnchor { size.w = 10 };
940                      dummyDecl = MkDeclaration(null,null);
941                      if(!curCompound.compound.declarations)
942                         curCompound.compound.declarations = MkList();
943                      curCompound.compound.declarations->Insert(null, dummyDecl);
944
945                      sprintf(className, "__simpleStruct%d", curContext.simpleID++);
946
947                      {
948                         OldList * list = MkList();
949                         if(inst.isConstant && ProcessBracketInst(inst, list))
950                         {
951                            decl = MkDeclaration(MkList(), MkList());
952
953                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
954                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(className)),
955                               MkInitializerList(list)));
956
957                            exp.type = identifierExp;
958                            exp.identifier = MkIdentifier(className);
959                         }
960                         else
961                         {
962                            list->Free(null);
963                            delete list;
964
965                            decl = MkDeclarationInst(MkInstantiation(CopySpecifier(inst._class), MkExpIdentifier(MkIdentifier(className)), null));
966
967
968                            // Set properties & data members in expression
969                            // to handle jump and control statements
970                            // Set unset data members to 0
971                            exp.type = bracketsExp;
972                            exp.list = MkList();
973
974                            instExp = QMkExpId(className);
975                            instExp.loc = exp.loc;
976                            instExp.expType = MkClassType(inst._class.name);
977
978                            // Mark the declarated instance as fullset so it doesn't need to be zeroed out
979                            decl.inst.fullSet = ProcessInstMembers(inst, instExp, exp.list, false);
980
981                            ListAdd(exp.list, instExp);
982                         }
983                      }
984
985                      FreeType(exp.expType);
986                      exp.expType = MkClassType(inst._class.name);
987
988                      // TRICKY STUFF, UGLY HACK FOR stateSizeAnchor = SizeAnchor { size.w = 10 };
989                      {
990                         void * prev = dummyDecl.prev, * next = dummyDecl.next;
991                         *dummyDecl = *decl;
992                         dummyDecl.prev = prev;
993                         dummyDecl.next = next;
994                         delete decl;
995                         decl = dummyDecl;
996                      }
997                      ProcessDeclaration(decl);
998
999                      /*
1000                      if(!curCompound.compound.declarations)
1001                         curCompound.compound.declarations = MkList();
1002                      curCompound.compound.declarations->Insert(null, decl);
1003                      */
1004                   }
1005                }
1006             }
1007             else
1008             {
1009                Expression newCall;
1010
1011                if(classSym && classSym.registered && classSym.registered.type == noHeadClass &&
1012                   (classSym.registered.templateClass ? classSym.registered.templateClass.fixed : classSym.registered.fixed))
1013                {
1014                   char size[256];
1015                   Class c = classSym.registered.templateClass ? classSym.registered.templateClass : classSym.registered;
1016                   Expression e = MkExpClassSize(MkSpecifierName(c.name));
1017                   ProcessExpressionType(e);
1018                   sprintf(size, "%d", c.structSize);
1019                   newCall = MkExpCall(QMkExpId("ecere::com::eSystem_New0"), MkListOne( e /*MkExpConstant(size)*/));
1020                   newCall.byReference = true;
1021                }
1022                else
1023                {
1024                   strcpy(className, "__ecereClass_");
1025                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass && classSym.registered.templateClass)
1026                   {
1027                      classSym = FindClass(classSym.registered.templateClass.fullName);
1028                      FullClassNameCat(className, classSym.string, true);
1029                   }
1030                   else
1031                      FullClassNameCat(className, inst._class.name, true);
1032
1033                   DeclareClass(curExternal, classSym, className);
1034                   newCall = MkExpCall(QMkExpId("ecere::com::eInstance_New"), MkListOne(QMkExpId(className)));
1035                   newCall.usage = exp.usage;
1036
1037                   ProcessExpressionType(newCall);
1038                   if(newCall.expType && exp.expType)
1039                      newCall.expType.passAsTemplate = exp.expType.passAsTemplate;
1040                   newCall.byReference = true;
1041                }
1042
1043                if(inst.exp)
1044                {
1045                   if(inst.members && inst.members->first)
1046                   {
1047                      exp.type = bracketsExp;
1048                      exp.list = MkList();
1049
1050                      if(!inst.built)
1051                      {
1052                         ListAdd(exp.list, MkExpOp(inst.exp, '=', newCall));
1053                      }
1054                      else
1055                         FreeExpression(newCall);
1056
1057                      ProcessInstMembers(inst, inst.exp, exp.list, false);
1058
1059                      if(inst.built)
1060                         FreeExpression(inst.exp);
1061                   }
1062                   else
1063                   {
1064                      exp.type = opExp;
1065                      exp.op.op = '=';
1066                      exp.op.exp1 = inst.exp;
1067                      exp.op.exp2 = newCall;
1068
1069                      ProcessExpression(inst.exp);
1070                   }
1071                   inst.exp = null;
1072                }
1073                else
1074                {
1075                   // Unnamed instantiation
1076                   if(inst.members && inst.members->first)
1077                   {
1078                      char ecereTemp[100];
1079                      MembersInit members;
1080                      int tempCount = exp.tempCount;
1081                      OldList * expList;
1082
1083                      // Check if members use temp count...
1084                      for(members = inst.members->first; members; members = members.next)
1085                      {
1086                         if(members.type == dataMembersInit && members.dataMembers)
1087                         {
1088                            MemberInit member;
1089                            for(member = members.dataMembers->first; member; member = member.next)
1090                            {
1091                               if(member.initializer && member.initializer.type == expInitializer)
1092                               {
1093                                  ProcessMemberInitData(member);   // ADDED THIS TO HAVE PROPER tempCount ALREADY...
1094                                  tempCount = Max(tempCount, member.initializer.exp.tempCount);
1095                               }
1096                            }
1097                         }
1098                      }
1099                      if(curDecl)
1100                         tempCount = Max(tempCount, declTempCount);
1101
1102                      tempCount++;
1103                      curExternal.function.tempCount = Max(curExternal.function.tempCount, tempCount);
1104                      sprintf(ecereTemp, "__ecereInstance%d", tempCount);
1105                      exp.type = extensionCompoundExp;
1106                      exp.compound = MkCompoundStmt(null, null);
1107                      exp.compound.compound.context = PushContext();
1108                      exp.compound.compound.context.simpleID = exp.compound.compound.context.parent.simpleID;
1109                      exp.compound.compound.declarations = MkListOne(QMkDeclaration(inst._class.name, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(ecereTemp)),
1110                         MkInitializerAssignment(newCall))));
1111                      exp.compound.compound.statements = MkListOne(MkExpressionStmt((expList = MkList())));
1112
1113                      instExp = QMkExpId(ecereTemp);
1114                      instExp.tempCount = tempCount;
1115                      instExp.expType = MkClassType(inst._class.name);
1116                      instExp.byReference = true;
1117                      ProcessInstMembers(inst, instExp, expList, false);
1118                      FreeExpression(instExp);
1119
1120                      if(exp.usage)
1121                      {
1122                         Expression tmpExp = QMkExpId(ecereTemp);
1123                         tmpExp.byReference = true;
1124                         ListAdd(expList, tmpExp);
1125                      }
1126                      exp.tempCount = tempCount;
1127                      if(curDecl)
1128                         declTempCount = Max(declTempCount, tempCount);
1129                      PopContext(exp.compound.compound.context);
1130                   }
1131                   else
1132                   {
1133                      Expression prev = exp.prev, next = exp.next;
1134                      FreeType(newCall.destType);
1135                      FreeType(newCall.expType);
1136                      newCall.destType = exp.destType;
1137                      newCall.expType = exp.expType;
1138                      *exp = *newCall;
1139                      exp.prev = prev;
1140                      exp.next = next;
1141                      delete newCall;
1142                   }
1143                }
1144             }
1145             if(exp.type != instanceExp)
1146                FreeInstance(inst);
1147          }
1148          else
1149             ProcessInstantiation(inst);
1150          break;
1151       }
1152       case constantExp:
1153          break;
1154       case stringExp:
1155          break;
1156       case newExp:
1157       case new0Exp:
1158          // if(exp._new.size) exp._new.size.usage.usageGet = true;
1159          ProcessExpression(exp._new.size);
1160          break;
1161       case renewExp:
1162       case renew0Exp:
1163          // if(exp._renew.size) exp._renew.size.usage.usageGet = true;
1164          ProcessExpression(exp._renew.size);
1165          // if(exp._renew.exp) exp._renew.exp.usage.usageGet = true;
1166          ProcessExpression(exp._renew.exp);
1167          break;
1168       case opExp:
1169       {
1170          //bool assign = false;
1171
1172          switch(exp.op.op)
1173          {
1174             // Assignment Operators
1175             case '=':
1176                if(exp.op.exp2)
1177                   exp.op.exp2.usage.usageGet = true;
1178                if(exp.op.exp1)
1179                   exp.op.exp1.usage.usageSet = true;
1180                //assign = true;
1181                break;
1182             case MUL_ASSIGN:
1183             case DIV_ASSIGN:
1184             case MOD_ASSIGN:
1185             case ADD_ASSIGN:
1186             case SUB_ASSIGN:
1187             case LEFT_ASSIGN:
1188             case RIGHT_ASSIGN:
1189             case AND_ASSIGN:
1190             case XOR_ASSIGN:
1191             case OR_ASSIGN:
1192                if(exp.op.exp2)
1193                   exp.op.exp2.usage.usageGet = true;
1194                //assign = true;
1195                if(exp.op.exp1)
1196                   exp.op.exp1.usage.usageSet = true;
1197                break;
1198
1199             case INC_OP:
1200             case DEC_OP:
1201                if(exp.op.exp1)
1202                   exp.op.exp1.usage.usageSet = true;
1203
1204             // Unary operators
1205             case '&':
1206                // Also binary
1207                if(exp.op.exp1 && exp.op.exp2)
1208                {
1209                   exp.op.exp1.usage.usageGet = true;
1210                   exp.op.exp2.usage.usageGet = true;
1211                }
1212                break;
1213             case '*':
1214             case '+':
1215             case '-':
1216                // Also binary
1217                if(exp.op.exp1)
1218                {
1219                   exp.op.exp1.usage.usageGet = true;
1220                }
1221             case '~':
1222             case '!':
1223                if(exp.op.exp2)
1224                   exp.op.exp2.usage.usageGet = true;
1225                break;
1226
1227             // Binary only operators
1228             case '/':
1229             case '%':
1230             case LEFT_OP:
1231             case RIGHT_OP:
1232             case '<':
1233             case '>':
1234             case LE_OP:
1235             case GE_OP:
1236             case EQ_OP:
1237             case NE_OP:
1238             case '|':
1239             case '^':
1240             case AND_OP:
1241             case OR_OP:
1242                if(exp.op.exp1)
1243                   exp.op.exp1.usage.usageGet = true;
1244                if(exp.op.exp2)
1245                   exp.op.exp2.usage.usageGet = true;
1246                break;
1247          }
1248
1249          if(exp.op.exp1)
1250          {
1251             if(exp.op.exp1 && exp.op.exp2 && exp.op.exp1.destType && exp.op.exp1.destType.passAsTemplate && exp.op.exp1.expType && !exp.op.exp1.expType.passAsTemplate && !exp.op.exp1.usage.usageSet)
1252             {
1253                Type type { };
1254                CopyTypeInto(type, exp.op.exp1.destType);
1255                type.passAsTemplate = false;
1256                FreeType(exp.op.exp1.destType);
1257                exp.op.exp1.destType = type;
1258             }
1259             // TEST: if(exp.op.exp2) exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1260             ProcessExpression(exp.op.exp1);
1261             // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1262          }
1263
1264          if(exp.op.exp2)
1265          {
1266             if(exp.op.exp1 && exp.op.exp2 && exp.op.exp2.destType && exp.op.exp2.destType.passAsTemplate && exp.op.exp2.expType && !exp.op.exp2.expType.passAsTemplate && !exp.op.exp1.usage.usageSet)
1267             {
1268                Type type { };
1269                CopyTypeInto(type, exp.op.exp2.destType);
1270                type.passAsTemplate = false;
1271                FreeType(exp.op.exp2.destType);
1272                exp.op.exp2.destType = type;
1273             }
1274
1275             // Don't use the temporaries used by the left side...
1276             if(exp.op.exp1)
1277                // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1278                exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1279             ProcessExpression(exp.op.exp2);
1280             // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1281          }
1282          break;
1283       }
1284       case extensionExpressionExp:
1285       case bracketsExp:
1286       {
1287          Expression e;
1288          for(e = exp.list->first; e; e = e.next)
1289          {
1290             e.tempCount = Max(e.tempCount, exp.tempCount);
1291             if(!e.next)
1292             {
1293                e.usage |= (exp.usage & (ExpUsage { usageGet = true, usageArg = true }));
1294             }
1295             ProcessExpression(e);
1296             exp.tempCount = Max(exp.tempCount, e.tempCount);
1297          }
1298          break;
1299       }
1300       case indexExp:
1301       {
1302          Expression e;
1303
1304          exp.index.exp.usage.usageGet = true;
1305          ProcessExpression(exp.index.exp);
1306          for(e = exp.index.index->first; e; e = e.next)
1307          {
1308             if(!e.next)
1309                e.usage.usageGet = true;
1310             ProcessExpression(e);
1311          }
1312          // Ignore temps in the index for now...
1313          exp.tempCount = exp.index.exp.tempCount;
1314          /*
1315          if(exp.index.exp.expType)
1316          {
1317             Type source = exp.index.exp.expType;
1318             if(source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1319                eClass_IsDerived(source._class.registered, containerClass))
1320             {
1321                Class _class = source._class.registered;
1322                // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1323
1324                char iteratorType[1024];
1325                OldList * declarations = MkList();
1326                OldList * statements = MkList();
1327                OldList * args = MkList();
1328                OldList * instMembers = MkList();
1329                Expression expExt;
1330                Context context = PushContext();
1331
1332                sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1333
1334                ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1335
1336                ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1337                   MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1338
1339                ListAdd(args, MkExpBrackets(exp.index.index));
1340                ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1341
1342                ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1343                   MkIdentifier("Index")), args))));
1344
1345                ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1346
1347                exp.type = bracketsExp;
1348                exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1349                expExt.compound.compound.context = context;
1350                PopContext(context);
1351                expExt.usage = exp.usage;
1352                ProcessExpressionType(exp.list->first);
1353                ProcessExpression(exp.list->first);
1354             }
1355          }
1356          */
1357          break;
1358       }
1359       case callExp:
1360       {
1361          Expression e;
1362          //Method method = null;
1363
1364          ProcessExpression(exp.call.exp);
1365
1366          if(exp.call.arguments)
1367          {
1368             for(e = exp.call.arguments->first; e; e = e.next)
1369             {
1370                e.usage.usageGet = true;
1371                e.usage.usageArg = true;
1372
1373                // TEST: e.tempCount = Max(e.tempCount, exp.tempCount);
1374                ProcessExpression(e);
1375                // TEST: exp.tempCount = Max(exp.tempCount, e.tempCount);
1376             }
1377          }
1378          break;
1379       }
1380       case memberExp:
1381       {
1382          exp.member.exp.usage.usageGet = true;
1383          // Tweak for LinkList::first to be casted to proper type (e.g. Link) when accessing members
1384          if(exp.member.memberType == dataMember &&
1385             exp.member.exp.expType && exp.member.exp.expType.thisClassFrom && exp.member.exp.expType.kind == classType &&
1386             exp.member.exp.expType._class && exp.member.exp.expType._class.registered &&
1387             !eClass_IsDerived(exp.member.exp.expType.thisClassFrom, exp.member.exp.expType._class.registered))
1388             exp.member.exp.expType.passAsTemplate = true;
1389          ProcessExpression(exp.member.exp);
1390
1391          // Must do this here so we can set the MemberType of deep properties inside instantiations
1392          if(!exp.member.memberType)
1393          {
1394             Type type = exp.member.exp.expType;
1395             if((type && type.kind == classType && exp.member.member))
1396             {
1397                // Check if it's an instance
1398                Class _class = (exp.member.member._class && exp.member.member.classSym) ? exp.member.member.classSym.registered : (type._class ? type._class.registered : null);
1399                Property prop = null;
1400                Method method = null;
1401                DataMember member = null;
1402                Property revConvert = null;
1403
1404                // Prioritize data members over properties for "this"
1405                if(exp.member.thisPtr)
1406                {
1407                   member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
1408                   if(!member)
1409                      prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
1410                }
1411                // Prioritize properties over data members otherwise
1412                else
1413                {
1414                   // Look for publicAccess Members first
1415                   prop = eClass_FindProperty(_class, exp.member.member.string, null);
1416                   if(!prop)
1417                      member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
1418                   if(!prop && !member)
1419                   {
1420                      method = eClass_FindMethod(_class, exp.member.member.string, null);
1421                      if(!method)
1422                      {
1423                         prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
1424                         if(!prop)
1425                            member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
1426                      }
1427                   }
1428                }
1429                if(!prop && !member && !method)     // NOTE: Recently added the !method here, causes private methods to unprioritized
1430                   method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
1431                if(!prop && !member && !method)
1432                {
1433                   Symbol classSym = FindClass(exp.member.member.string);
1434                   if(classSym)
1435                   {
1436                      Class convertClass = classSym.registered;
1437                      if(convertClass)
1438                         revConvert = eClass_FindProperty(convertClass, _class.fullName, privateModule);
1439                   }
1440                }
1441
1442                if(prop)
1443                {
1444                   exp.member.memberType = propertyMember;
1445                   if(!prop.dataType)
1446                      prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1447
1448                   FreeType(exp.expType);
1449                   exp.expType = prop.dataType;
1450                   if(prop.dataType) prop.dataType.refCount++;
1451                }
1452                else if(method)
1453                {
1454                   exp.member.memberType = methodMember;
1455                   if(!method.dataType)
1456                      //method.dataType = ((Symbol)method.symbol).type;
1457                      ProcessMethodType(method);
1458
1459                   FreeType(exp.expType);
1460                   exp.expType = method.dataType;
1461                   if(method.dataType) method.dataType.refCount++;
1462                }
1463                else if(member)
1464                {
1465                   exp.member.memberType = dataMember;
1466                   DeclareStruct(curExternal, _class.fullName, false, true);
1467                   if(!member.dataType)
1468                      member.dataType = ProcessTypeString(member.dataTypeString, false);
1469
1470                   FreeType(exp.expType);
1471                   exp.expType = member.dataType;
1472                   if(member.dataType) member.dataType.refCount++;
1473                }
1474                else if(revConvert)
1475                {
1476                   exp.member.memberType = reverseConversionMember;
1477
1478                   FreeType(exp.expType);
1479                   exp.expType = MkClassType(revConvert._class.fullName);
1480                }/*
1481                else
1482                   printf($"Error: Couldn't find member %s in class %s\n",
1483                      exp.member.member.string, _class.name);*/
1484             }
1485          }
1486          break;
1487       }
1488       case typeSizeExp:
1489          break;
1490       case castExp:
1491       {
1492          //exp.cast.exp.usage.usageGet = true;
1493          exp.cast.exp.usage |= exp.usage;
1494          ProcessExpression(exp.cast.exp);
1495          break;
1496       }
1497       case conditionExp:
1498       {
1499          Expression e;
1500          if(exp.usage.usageGet)
1501             exp.cond.cond.usage.usageGet = true;
1502
1503          ProcessExpression(exp.cond.cond);
1504          for(e = exp.cond.exp->first; e; e = e.next)
1505          {
1506             if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
1507             ProcessExpression(e);
1508          }
1509          if(exp.cond.elseExp)
1510          {
1511             if(exp.usage.usageGet) exp.cond.elseExp.usage.usageGet = true;
1512             ProcessExpression(exp.cond.elseExp);
1513          }
1514          break;
1515       }
1516       case extensionCompoundExp:
1517       {
1518          if(exp.compound.compound.statements &&
1519          ((Statement)exp.compound.compound.statements->last).type == expressionStmt &&
1520          ((Statement)exp.compound.compound.statements->last).expressions &&
1521          ((Statement)exp.compound.compound.statements->last).expressions->last)
1522          {
1523             ((Expression)((Statement)exp.compound.compound.statements->last).expressions->last).usage = exp.usage;
1524          }
1525          ProcessStatement(exp.compound);
1526          break;
1527       }
1528       case vaArgExp:
1529       {
1530          ProcessExpression(exp.vaArg.exp);
1531          break;
1532       }
1533       case extensionInitializerExp:
1534       {
1535          ProcessInitializer(exp.initializer.initializer);
1536          break;
1537       }
1538    }
1539    CheckTemplateTypes(exp);
1540 }
1541
1542 static void ProcessInitializer(Initializer init)
1543 {
1544    switch(init.type)
1545    {
1546       case expInitializer:
1547          init.exp.usage.usageGet = true;
1548          ProcessExpression(init.exp);
1549          break;
1550       case listInitializer:
1551       {
1552          Initializer i;
1553          for(i = init.list->first; i; i = i.next)
1554             ProcessInitializer(i);
1555          break;
1556       }
1557    }
1558 }
1559
1560 static void ProcessSpecifier(Specifier spec)
1561 {
1562    switch(spec.type)
1563    {
1564       case baseSpecifier:
1565          break;
1566       case nameSpecifier:
1567       {
1568          break;
1569       }
1570       case enumSpecifier:
1571       {
1572          Enumerator e;
1573          if(spec.list)
1574          {
1575             for(e = spec.list->first; e; e = e.next)
1576             {
1577                if(e.exp)
1578                   ProcessExpression(e.exp);
1579             }
1580          }
1581          break;
1582       }
1583       case structSpecifier:
1584       case unionSpecifier:
1585       {
1586          //Declaration decl;
1587          if(spec.definitions)
1588          {
1589             ClassDef def;
1590             for(def = spec.definitions->first; def; def = def.next)
1591             {
1592                if(def.type == declarationClassDef && def.decl && def.decl.type == structDeclaration)
1593                   ProcessDeclaration(def.decl);
1594             }
1595          }
1596          break;
1597       }
1598       /*
1599       case SpecifierClass:
1600       {
1601          break;
1602       }*/
1603    }
1604 }
1605
1606 static bool ProcessBracketInst_DataMember(DataMember parentMember, Instantiation inst, OldList list, DataMember namedParentMember, bool parentMemberSet)
1607 {
1608    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1609    DataMember dataMember = null;
1610    bool someMemberSet = false;
1611    int anonID = 1;
1612
1613    // For simple classes, ensure all members are initialized
1614    for(dataMember = parentMember.members.first; dataMember; dataMember = dataMember.next)
1615    {
1616       MembersInit members;
1617       MemberInit member = null;
1618
1619       if(!dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
1620       {
1621          OldList * subList = MkList(); //(dataMember.type == structMember) ? MkList() : null;
1622
1623          if(!ProcessBracketInst_DataMember(dataMember, inst, subList ? subList : list, dataMember.name ? dataMember : namedParentMember, someMemberSet || parentMemberSet || dataMember.prev))
1624          {
1625             if(subList)
1626                FreeList(subList, FreeInitializer);
1627
1628             return false;
1629          }
1630          if(subList && subList->count)
1631          {
1632             Initializer init = MkInitializerList(subList);
1633             char id[100];
1634             sprintf(id, "__anon%d", anonID);
1635             init.id = MkIdentifier(id);
1636             ListAdd(list, init);
1637             someMemberSet = true;
1638          }
1639          else
1640          {
1641             if(list.count)
1642                someMemberSet = true;
1643             delete subList;
1644          }
1645          anonID++;
1646       }
1647       else
1648       {
1649          Class curClass = null;
1650          DataMember curMember = null;
1651          DataMember subMemberStack[256];
1652          int subMemberStackPos = 0;
1653          bool found = false;
1654
1655          if(inst.members && inst.members->first)
1656          {
1657             for(members = inst.members->first; members; members = members.next)
1658             {
1659                if(members.type == dataMembersInit)
1660                {
1661                   for(member = members.dataMembers->first; member; member = member.next)
1662                   {
1663                      if(member.identifiers)
1664                      {
1665                         Identifier firstID = member.identifiers->first;
1666
1667                         DataMember _subMemberStack[256];
1668                         int _subMemberStackPos = 0;
1669                         DataMember thisMember;
1670                         thisMember = firstID ? (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule) : null;
1671                         // FILL MEMBER STACK
1672                         if(!thisMember && firstID)
1673                            thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
1674                         if(thisMember && thisMember.memberAccess == publicAccess)
1675                         {
1676                            curMember = thisMember;
1677                            curClass = curMember._class;
1678                            memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
1679                            subMemberStackPos = _subMemberStackPos;
1680                         }
1681                         /*
1682                         BTNamedLink link = parentMember.membersAlpha.Find((uintptr)firstID.string);
1683                         if(link)
1684                         {
1685                            curMember = link.data;
1686                         }
1687
1688                         // Choose the first specified member of the union...
1689                         if(parentMember.type == unionMember)
1690                         {
1691                            if(link)
1692                               dataMember = curMember;
1693                         }
1694                         */
1695
1696                         if(dataMember == thisMember)
1697                         {
1698                            // Look for another member of this one and merge them
1699                            // into one instantiation...
1700                            if(member.identifiers->count > 1 && member.initializer && member.initializer.type == expInitializer)
1701                            {
1702                               OldList * partList = MkList();
1703                               // TODO: We're assuming this is a simple class right now...
1704                               Symbol symbol;
1705                               Specifier spec;
1706                               MembersInit nextMembers;
1707                               MemberInit next = member.next;
1708
1709                               if(!dataMember.dataType)
1710                                  dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1711                               symbol = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null;
1712                               spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, symbol, null);
1713
1714                               {
1715                                  OldList * identifiers = MkList();
1716                                  Identifier id;
1717                                  for(id = ((Identifier)member.identifiers->first).next; id; id = id.next)
1718                                     identifiers->Add(CopyIdentifier(id));
1719
1720                                  // *** THE IDENTIFIERS WERE BEING REUSED, CAUSING A CRASH WITH EXPRESSION TEMPLATE CODE IN pass1.ec ***
1721                                  // members->Add(MkMemberInit(ids, MkInitializerAssignment(MkExpConstant(ui64String))));
1722                                  /*member.identifiers->Remove(firstID);*/
1723                                  ListAdd(partList,
1724                                     MkMemberInit(/*member.identifiers*/identifiers, MkInitializerAssignment(member.initializer.exp)));
1725                               }
1726
1727                               for(nextMembers = members; nextMembers; nextMembers = nextMembers.next)
1728                               {
1729                                  if(!nextMembers.dataMembers)
1730                                     continue;
1731
1732                                  if(members != nextMembers) next = nextMembers.dataMembers->first;
1733
1734                                  if(nextMembers.type == dataMembersInit)
1735                                  {
1736                                     MemberInit nextMember;
1737
1738                                     for(nextMember = next; nextMember;
1739                                         nextMember = next, next = nextMember ? nextMember.next : null)
1740                                     {
1741                                        Identifier nextID = nextMember.identifiers->first;
1742                                        if(nextMember.identifiers &&
1743                                           nextMember.identifiers->count > 1 &&
1744                                           !strcmp(firstID.string, nextID.string))
1745                                        {
1746                                           nextMembers.dataMembers->Remove(nextMember);
1747                                           nextMember.identifiers->Remove(nextID);
1748                                           ListAdd(partList, nextMember);
1749                                        }
1750                                     }
1751                                  }
1752                               }
1753
1754                               member.initializer.exp = MkExpInstance(MkInstantiation(spec, null,
1755                                  MkListOne(MkMembersInitList(partList))));
1756                            }
1757                            found = true;
1758                            break;
1759                         }
1760                      }
1761                      else
1762                      {
1763                         eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
1764                         if(curMember == dataMember)
1765                         {
1766                            found = true;
1767                            break;
1768                         }
1769
1770                         /*
1771                         if(curMember)
1772                            curMember = curMember.next;
1773                         else
1774                            curMember = parentMember.members.first;
1775
1776                         if(curMember == dataMember)
1777                         {
1778                            found = true;
1779                            break;
1780                         }
1781                         */
1782                      }
1783                   }
1784                }
1785                if(found) break;
1786             }
1787          }
1788
1789          if(member && member.initializer && member.initializer.type == expInitializer)
1790          {
1791             Initializer init { loc = yylloc };
1792             if(namedParentMember.type == unionMember && dataMember.name)
1793                init.id = MkIdentifier(dataMember.name);
1794
1795             if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
1796                member.initializer.exp.expType._class.registered.type == structClass)
1797             {
1798                OldList * subList = MkList();
1799                ProcessBracketInst(member.initializer.exp.instance, subList);
1800                FreeExpression(member.initializer.exp);
1801                if(subList->count)
1802                {
1803                   init.type = listInitializer;
1804                   init.list = subList;
1805                }
1806                else
1807                {
1808                   FreeInitializer(init);
1809                   init = null;
1810                }
1811             }
1812             else
1813             {
1814                member.initializer.exp.usage.usageGet = true;
1815                ProcessExpression(member.initializer.exp);
1816                init.type = expInitializer;
1817                init.exp = member.initializer.exp;
1818             }
1819             if(init)
1820                ListAdd(list, init);
1821
1822             member.initializer.exp = null;
1823             FreeInitializer(member.initializer);
1824             member.initializer = null;
1825             someMemberSet = true;
1826          }
1827          else if(member && member.initializer && member.initializer.type == listInitializer)
1828          {
1829             if(namedParentMember.type == unionMember && dataMember.name)
1830                member.initializer.id = MkIdentifier(dataMember.name);
1831
1832             ListAdd(list, member.initializer);
1833             member.initializer = null;
1834             someMemberSet = true;
1835          }
1836          else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/ && parentMember.type != unionMember && namedParentMember.type != unionMember)
1837          {
1838             Symbol classSym;
1839             Initializer init { loc = yylloc };
1840             if(namedParentMember.type == unionMember && dataMember.name)
1841                init.id = MkIdentifier(dataMember.name);
1842
1843             if(!dataMember.dataType)
1844                dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1845             classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1846             if(classSym && classSym.registered && classSym.registered.type == structClass)
1847             {
1848                OldList * subList = MkList();
1849                Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null);
1850                Instantiation inst = MkInstantiation(spec, null, null);
1851                ProcessBracketInst(inst, subList);
1852                FreeInstance(inst);
1853
1854                if(subList->count)
1855                {
1856                   init.type = listInitializer;
1857                   init.list = subList;
1858                }
1859                else
1860                {
1861                   FreeInitializer(init);
1862                   init = null;
1863                }
1864             }
1865             else
1866             {
1867                init.type = expInitializer;
1868                init.exp = MkExpConstant("0");
1869             }
1870             someMemberSet = true;
1871             if(init)
1872                ListAdd(list, init);
1873          }
1874       }
1875       /*
1876       if(parentMember.type == unionMember)
1877          break;
1878       */
1879    }
1880    // TESTING THIS NEW CODE FOR ANCHORS...
1881    if(/*parentMember.type == unionMember && */!someMemberSet && !parentMemberSet)
1882    {
1883       Symbol classSym;
1884       Initializer init { loc = yylloc };
1885
1886       dataMember = parentMember.members.first;
1887       if(namedParentMember.type == unionMember && dataMember.name)
1888          init.id = MkIdentifier(dataMember.name);
1889
1890       if(!dataMember.dataType && dataMember.dataTypeString)
1891          dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1892       classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1893       if(classSym && classSym.registered && classSym.registered.type == structClass)
1894       {
1895          OldList * subList = MkList();
1896          Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null);
1897          Instantiation inst = MkInstantiation(spec, null, null);
1898          ProcessBracketInst(inst, subList);
1899          FreeInstance(inst);
1900
1901          init.type = listInitializer;
1902          init.list = subList;
1903       }
1904       else if(dataMember.dataType && (dataMember.dataType.kind == arrayType || dataMember.dataType.kind == structType))
1905       {
1906          Type t = dataMember.dataType.kind == arrayType ? dataMember.dataType.type : dataMember.dataType.members.first;
1907          Initializer i = MkInitializerAssignment(MkExpConstant("0"));
1908          while(t && (t.kind == arrayType || t.kind == structType))
1909          {
1910             i = MkInitializerList(MkListOne(i));
1911             if(t.kind == arrayType)
1912                t = t.type;
1913             else if(t.kind == structType)
1914                t = t.members.first;
1915          }
1916          init.type = listInitializer;
1917          init.list = MkListOne(i);
1918       }
1919       else
1920       {
1921          init.type = expInitializer;
1922          init.exp = MkExpConstant("0");
1923       }
1924       ListAdd(list, init);
1925    }
1926    return true;
1927 }
1928
1929 static bool ProcessBracketInst(Instantiation inst, OldList list)
1930 {
1931    static int recursionCount = 0;
1932    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1933    Class _class = null;
1934    int anonID = 1;
1935
1936    if(recursionCount > 500) return false;
1937    recursionCount++;
1938
1939    while(_class != classSym.registered)
1940    {
1941       DataMember dataMember;
1942       Class lastClass = _class;
1943
1944       for(_class = classSym.registered; _class.base != lastClass && _class.base.type != systemClass; _class = _class.base);
1945
1946       for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
1947       {
1948          if(!dataMember.isProperty && !dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
1949          {
1950             OldList * subList = MkList(); //(dataMember.type == structMember ? MkList() : null);
1951
1952             if(!ProcessBracketInst_DataMember(dataMember, inst, subList ? subList : list, dataMember, false))
1953             {
1954                if(subList)
1955                   FreeList(subList, FreeInitializer);
1956                recursionCount--;
1957                return false;
1958             }
1959             if(dataMember.type == structMember || (subList && subList->count))
1960             {
1961                Initializer init = MkInitializerList(subList);
1962                char id[100];
1963                sprintf(id, "__anon%d", anonID);
1964                init.id = MkIdentifier(id);
1965                ListAdd(list, init);
1966             }
1967             else
1968                delete subList;
1969             anonID ++;
1970          }
1971          else
1972          {
1973             MembersInit members;
1974             MemberInit member = null;
1975             bool found = false;
1976
1977             if(inst.members && inst.members->first)
1978             {
1979                DataMember curMember = null;
1980                Class curClass = null;
1981                DataMember subMemberStack[256];
1982                int subMemberStackPos = 0;
1983
1984                for(members = inst.members->first; members; members = members.next)
1985                {
1986                   if(members.type == dataMembersInit)
1987                   {
1988                      for(member = members.dataMembers->first; member; member = member.next)
1989                      {
1990                         Identifier firstID = member.identifiers ? member.identifiers->first : null;
1991                         if(firstID)
1992                         {
1993                            DataMember _subMemberStack[256];
1994                            int _subMemberStackPos = 0;
1995                            DataMember thisMember = (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule);
1996                            // FILL MEMBER STACK
1997                            if(!thisMember)
1998                               thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
1999                            if(thisMember)
2000                            {
2001                               curMember = thisMember;
2002                               curClass = curMember._class;
2003                               memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
2004                               subMemberStackPos = _subMemberStackPos;
2005                            }
2006
2007                            if(curMember == dataMember)
2008                            {
2009                               if(dataMember.isProperty)
2010                               {
2011                                  if(!((Property)dataMember).Set)
2012                                  {
2013                                     Compiler_Error($"No set defined for property %s\n", dataMember.name);
2014                                     continue;
2015                                  }
2016                                  recursionCount--;
2017                                  return false;
2018                               }
2019
2020                               // Look for another member of this one and merge them
2021                               // into one instantiation...
2022                               if(member.identifiers->count > 1 && member.initializer && member.initializer.type == expInitializer)
2023                               {
2024                                  OldList * partList = MkList();
2025                                  // TODO: We're assuming this is a simple _class right now...
2026                                  Specifier spec;
2027                                  MembersInit nextMembers;
2028                                  MemberInit next = member.next;
2029                                  Symbol symbol;
2030                                  if(!dataMember.dataType)
2031                                     dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
2032                                  symbol = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null;
2033                                  spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, symbol, null);
2034
2035                                  member.identifiers->Remove(firstID);
2036                                  ListAdd(partList,
2037                                     MkMemberInit(member.identifiers, MkInitializerAssignment(member.initializer.exp)));
2038
2039                                  for(nextMembers = members; nextMembers; nextMembers = nextMembers.next)
2040                                  {
2041                                     if(!nextMembers.dataMembers) continue;
2042
2043                                     if(members != nextMembers) next = nextMembers.dataMembers->first;
2044
2045                                     if(nextMembers.type == dataMembersInit)
2046                                     {
2047                                        MemberInit nextMember;
2048
2049                                        for(nextMember = next; nextMember;
2050                                            nextMember = next, next = nextMember ? nextMember.next : null)
2051                                        {
2052                                           Identifier nextID = nextMember.identifiers->first;
2053                                           if(nextMember.identifiers &&
2054                                              nextMember.identifiers->count > 1 &&
2055                                              !strcmp(firstID.string, nextID.string))
2056                                           {
2057                                              nextMembers.dataMembers->Remove(nextMember);
2058                                              nextMember.identifiers->Remove(nextID);
2059                                              ListAdd(partList, nextMember);
2060                                           }
2061                                        }
2062                                     }
2063                                  }
2064
2065                                  member.initializer.exp = MkExpInstance(MkInstantiation(spec, null,
2066                                     MkListOne(MkMembersInitList(partList))));
2067
2068                                  // TESTING THIS
2069                                  member.identifiers = null;
2070                               }
2071                               found = true;
2072                               break;
2073                            }
2074                         }
2075                         else
2076                         {
2077                            eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
2078                            if(curMember == dataMember)
2079                            {
2080                               if(dataMember.isProperty)
2081                               {
2082                                  if(!((Property)dataMember).Set)
2083                                  {
2084                                     Compiler_Error($"No set defined for property %s\n", dataMember.name);
2085                                     continue;
2086                                  }
2087                                  recursionCount--;
2088                                  return false;
2089                               }
2090                               found = true;
2091                               break;
2092                            }
2093                         }
2094                      }
2095                   }
2096                   if(found) break;
2097                }
2098             }
2099
2100             if(dataMember.isProperty) continue;
2101             if(member && member.initializer && member.initializer.type == expInitializer)
2102             {
2103                if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
2104                   member.initializer.exp.expType._class && member.initializer.exp.expType._class.registered && member.initializer.exp.expType._class.registered.type == structClass)
2105                {
2106                   OldList * subList = MkList();
2107                   ProcessBracketInst(member.initializer.exp.instance, subList);
2108                   FreeExpression(member.initializer.exp);
2109                   member.initializer.exp = null;
2110                   ListAdd(list, MkInitializerList(subList));
2111                }
2112                else
2113                {
2114                   member.initializer.exp.usage.usageGet = true;
2115                   ProcessExpression(member.initializer.exp);
2116                   ListAdd(list, MkInitializerAssignment(CopyExpression(member.initializer.exp)));
2117                }
2118
2119                // Take this out
2120                // member.exp = null;
2121                member.takeOutExp = true;
2122             }
2123             else if(member && member.initializer && member.initializer.type == listInitializer)
2124             {
2125                ListAdd(list, member.initializer);
2126                member.initializer = null;
2127             }
2128             else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/)
2129             {
2130                Symbol classSym;
2131
2132                if(!dataMember.dataType)
2133                   dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
2134                classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
2135
2136                if(classSym && classSym.registered && classSym.registered.type == structClass)
2137                {
2138                   OldList * subList = MkList();
2139                   Specifier spec = _MkSpecifierName(dataMember.dataTypeString, classSym, null);
2140                   Instantiation inst = MkInstantiation(spec, null, null);
2141                   ProcessBracketInst(inst, subList);
2142                   FreeInstance(inst);
2143                   ListAdd(list, MkInitializerList(subList));
2144                }
2145                else if(dataMember.dataType.kind == arrayType)
2146                {
2147                   Type t = dataMember.dataType.type;
2148                   Initializer inner = MkInitializerAssignment(null), i = inner;
2149                   while(t && t.kind == arrayType)
2150                   {
2151                      i = MkInitializerList(MkListOne(i));
2152                      t = t.type;
2153                   }
2154                   if(t && t.kind == classType && t._class && t._class.registered && t._class.registered.type == structClass)
2155                   {
2156                      OldList * subList = MkList();
2157                      Specifier spec = _MkSpecifierName(t._class.registered.name, classSym, null);
2158                      Instantiation inst = MkInstantiation(spec, null, null);
2159                      ProcessBracketInst(inst, subList);
2160                      FreeInstance(inst);
2161                      inner.type = listInitializer;
2162                      inner.list = subList;
2163                   }
2164                   else
2165                      inner.exp = MkExpConstant("0");
2166                   ListAdd(list,  MkInitializerList(MkListOne(i)));
2167                }
2168                else
2169                   ListAdd(list, MkInitializerAssignment(MkExpConstant("0")));
2170             }
2171          }
2172       }
2173    }
2174
2175    if(inst.members && inst.members->first)
2176    {
2177       MembersInit members;
2178       MemberInit member = null;
2179
2180       for(members = inst.members->first; members; members = members.next)
2181       {
2182          if(members.type == dataMembersInit)
2183          {
2184             for(member = members.dataMembers->first; member; member = member.next)
2185             {
2186                if(member.takeOutExp)
2187                {
2188                   FreeInitializer(member.initializer);
2189                   member.initializer = null;
2190                }
2191             }
2192          }
2193       }
2194    }
2195    recursionCount--;
2196    return true;
2197 }
2198
2199 static Declaration curDecl;
2200 static int declTempCount;
2201
2202 static void ProcessDeclaration(Declaration decl)
2203 {
2204    yylloc = decl.loc;
2205    switch(decl.type)
2206    {
2207       case initDeclaration:
2208       {
2209          if(!curDecl) { curDecl = decl; declTempCount = 0; }
2210          if(decl.specifiers)
2211          {
2212             Specifier s;
2213             for(s = decl.specifiers->first; s; s = s.next)
2214             {
2215                ProcessSpecifier(s);
2216             }
2217          }
2218          if(decl.declarators)
2219          {
2220             InitDeclarator d;
2221
2222             for(d = decl.declarators->first; d; d = d.next)
2223             {
2224               if(d.initializer)
2225                   ProcessInitializer(d.initializer);
2226             }
2227          }
2228          if(curDecl == decl) { curDecl = null; declTempCount = 0; }
2229          break;
2230       }
2231       case instDeclaration:
2232       {
2233          Instantiation inst = decl.inst;
2234
2235          if(inCompiler)
2236          {
2237             Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
2238             if(!curCompound)
2239             {
2240                Statement stmt;
2241
2242                if(!inst.isConstant || (classSym && classSym.registered && (classSym.registered.type == normalClass || classSym.registered.type == noHeadClass)))
2243                {
2244                   // If this instantiation is outside, turn it into a declaration plus an instantiation expression
2245                   decl.type = initDeclaration;
2246                   decl.specifiers = MkListOne(MkSpecifierName/*MkClassName*/(inst._class.name));
2247                   if(decl.declMode == staticAccess)
2248                   {
2249                      decl.specifiers->Insert(null, MkSpecifier(STATIC));
2250                   }
2251                   decl.declarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(inst.exp.identifier.string)), null));
2252
2253                   ProcessDeclaration(decl);
2254                   CreateInstancesBody();
2255
2256                   {
2257                      Expression exp = MkExpInstance(inst);
2258                      stmt = MkExpressionStmt(MkListOne(exp));       // MkExpOp(inst.exp, '=',
2259                      ListAdd(createInstancesBody.compound.statements, stmt);
2260                      ProcessExpressionType(exp);
2261                   }
2262
2263                   if(classSym && classSym.registered && (classSym.registered.type == normalClass))
2264                   {
2265                      ListAdd(createInstancesBody.compound.statements,
2266                         MkExpressionStmt(MkListOne(MkExpCall(
2267                            MkExpIdentifier(MkIdentifier("ecere::com::eInstance_IncRef")),
2268                            MkListOne(CopyExpression(inst.exp))))));
2269
2270                      // We'd like the = 0 as well...
2271                      {
2272                         Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2273                         ListAddFront(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2274                         ProcessExpressionType(exp);
2275                      }
2276                   }
2277                   else if(classSym && classSym.registered && (classSym.registered.type == noHeadClass))
2278                   {
2279                      Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2280                      ListAddFront(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2281                      ProcessExpressionType(exp);
2282                   }
2283
2284                   createInstancesExternal.CreateEdge(curExternal, false);
2285                   destroyInstancesExternal.CreateEdge(curExternal, false);
2286                   break;
2287                }
2288                else
2289                {
2290                   // Precompiler won't know if this isn't constant
2291                   CreateInstancesBody();
2292                }
2293             }
2294
2295             {
2296                char className[1024];
2297                className[0] = 0;
2298
2299                decl.type = initDeclaration;
2300                decl.specifiers = MkList();
2301                decl.declarators = MkList();
2302
2303                // Replace instantiation here
2304                if(classSym && classSym.registered && classSym.registered.type == bitClass)
2305                {
2306                   OldList list = { 0 };
2307
2308                   // Put the instantiation in an InitDeclarator...
2309                   ProcessInstMembers(inst, inst.exp, &list, false);
2310                   ProcessExpression(inst.exp);
2311
2312                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2313                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2314                      MkInitializerAssignment(list.first)));
2315                   inst.exp.identifier = null;
2316                }
2317                else if(classSym && classSym.registered && classSym.registered.type == unitClass)
2318                {
2319                   OldList list = { 0 };
2320
2321                   // Put the instantiation in an InitDeclarator...
2322                   ProcessInstMembers(inst, inst.exp, &list, false);
2323                   ProcessExpression(inst.exp);
2324
2325                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2326                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2327                      MkInitializerAssignment(list.first)));
2328
2329                   inst.exp.identifier = null;
2330                }
2331                else if(classSym && classSym.registered && classSym.registered.type == structClass)
2332                {
2333                   Expression exp;
2334
2335                   DeclareStruct(curExternal, inst._class.name, false, true);
2336                   /*{
2337                      strcpy(className, "__ecereClass_");
2338                      FullClassNameCat(className, classSym.string, true);
2339                      DeclareClass(classSym, className);
2340                   }*/
2341
2342                   ProcessExpression(inst.exp);
2343
2344                   // Put the instantiation in an InitDeclarator...
2345                   {
2346                      if(inst.fullSet)
2347                      {
2348                         ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2349                         ListAdd(decl.declarators,
2350                            MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier), null));
2351                         inst.exp.identifier = null;
2352                      }
2353                      else
2354                      {
2355                         OldList * list = MkList();
2356                         if(ProcessBracketInst(inst, list))
2357                         {
2358                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2359                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2360                               MkInitializerList(list)));
2361                            inst.exp.identifier = null;
2362                         }
2363                         else
2364                         {
2365                            // If bracket instantiation failed (property: for conversions only?)
2366                            // TODO: (Fix this so it initializes members through brackets,
2367                            //        and then does properties)
2368                            //list->Free(null);
2369                            //delete list;
2370                            // TESTING THIS MEMORY LEAK FIX:
2371                            FreeList(list, FreeInitializer);
2372
2373                            exp = MkExpBrackets(MkList());
2374                            ProcessInstMembers(inst, inst.exp, exp.list, true);
2375                            ListAdd(exp.list, CopyExpression(inst.exp));
2376                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2377                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2378                               MkInitializerAssignment(exp)));
2379                            inst.exp.identifier = null;
2380                         }
2381                      }
2382                   }
2383                }
2384                else
2385                {
2386                   Expression newCall;
2387
2388                   strcpy(className, "__ecereClass_");
2389
2390                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass && classSym.registered.templateClass)
2391                   {
2392                      classSym = FindClass(classSym.registered.templateClass.fullName);
2393                      FullClassNameCat(className, classSym.string, true);
2394                   }
2395                   else
2396                      FullClassNameCat(className, inst._class.name, true);
2397
2398                   if(classSym)
2399                      DeclareClass(curExternal, classSym, className);
2400
2401                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass &&
2402                      (classSym.registered.templateClass ? classSym.registered.templateClass.fixed : classSym.registered.fixed))
2403                   {
2404                      char size[256];
2405                      Class c = classSym.registered.templateClass ? classSym.registered.templateClass : classSym.registered;
2406                      Expression e = MkExpClassSize(MkSpecifierName(c.name));
2407                      ProcessExpressionType(e);
2408                      sprintf(size, "%d", c.structSize);
2409                      newCall = MkExpCall(QMkExpId("ecere::com::eSystem_New0"), MkListOne( e /*MkExpConstant(size)*/));
2410                   }
2411                   else
2412                   {
2413                      newCall = MkExpCall(QMkExpId("ecere::com::eInstance_New"), MkListOne(QMkExpId(className)));
2414                      ProcessExpressionType(newCall);
2415                      newCall.byReference = true;
2416                   }
2417
2418                   if(inst.exp)
2419                   {
2420                      Expression exp, newExp;
2421                      Identifier id = CopyIdentifier(inst.exp.identifier);
2422
2423                      // Put the instantiation in an InitDeclarator...
2424                      if(inst.members && inst.members->first)
2425                      {
2426                         newExp = MkExpOp(CopyExpression(inst.exp), '=', newCall);
2427
2428                         exp = MkExpBrackets(MkList());
2429                         ListAdd(exp.list, newExp);
2430                         ProcessInstMembers(inst, inst.exp, exp.list, false);
2431                         ListAdd(exp.list, inst.exp);
2432
2433                         ProcessExpression(inst.exp);
2434
2435                         // Take it out since we're using it...
2436                         inst.exp = null;
2437                      }
2438                      else
2439                         exp = newCall;
2440
2441                      ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2442                      ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(id),
2443                         MkInitializerAssignment(exp)));
2444                      //inst.exp.identifier = null;
2445                   }
2446                   else
2447                      FreeExpression(newCall);
2448                }
2449             }
2450             FreeInstance(inst);
2451          }
2452          else
2453             ProcessInstantiation(inst);
2454          break;
2455       }
2456       case structDeclaration:
2457       {
2458          if(decl.specifiers)
2459          {
2460             Specifier spec;
2461             for(spec = decl.specifiers->first; spec; spec = spec.next)
2462                ProcessSpecifier(spec);
2463          }
2464          break;
2465       }
2466    }
2467 }
2468
2469 static void ProcessStatement(Statement stmt)
2470 {
2471    yylloc = stmt.loc;
2472    switch(stmt.type)
2473    {
2474       case labeledStmt:
2475          if(stmt.labeled.stmt)
2476             ProcessStatement(stmt.labeled.stmt);
2477          break;
2478       case caseStmt:
2479          if(stmt.caseStmt.exp)
2480             ProcessExpression(stmt.caseStmt.exp);
2481          if(stmt.caseStmt.stmt)
2482             ProcessStatement(stmt.caseStmt.stmt);
2483          break;
2484       case compoundStmt:
2485       {
2486          if(stmt.compound.context)
2487          {
2488             Declaration decl;
2489             Statement s;
2490             Statement prevCompound = curCompound;
2491             Context prevContext = curContext;
2492
2493             if(!stmt.compound.isSwitch)
2494             {
2495                curCompound = stmt;
2496                curContext = stmt.compound.context;
2497             }
2498
2499             if(stmt.compound.declarations)
2500             {
2501                for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
2502                   ProcessDeclaration(decl);
2503             }
2504             if(stmt.compound.statements)
2505             {
2506                for(s = stmt.compound.statements->first; s; s = s.next)
2507                {
2508                   ProcessStatement(s);
2509                }
2510             }
2511
2512             curCompound = prevCompound;
2513             curContext = prevContext;
2514          }
2515          break;
2516       }
2517       case expressionStmt:
2518       {
2519          Expression exp;
2520          if(stmt.expressions)
2521          {
2522             for(exp = stmt.expressions->first; exp; exp = exp.next)
2523             {
2524                ProcessExpression(exp);
2525             }
2526          }
2527          break;
2528       }
2529       case ifStmt:
2530       {
2531          Expression exp;
2532
2533          ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
2534          for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
2535          {
2536             ProcessExpression(exp);
2537          }
2538          if(stmt.ifStmt.stmt)
2539             ProcessStatement(stmt.ifStmt.stmt);
2540          if(stmt.ifStmt.elseStmt)
2541             ProcessStatement(stmt.ifStmt.elseStmt);
2542          break;
2543       }
2544       case switchStmt:
2545       {
2546          Expression exp;
2547          ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
2548          for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
2549             ProcessExpression(exp);
2550          ProcessStatement(stmt.switchStmt.stmt);
2551          break;
2552       }
2553       case whileStmt:
2554       {
2555          if(stmt.whileStmt.exp)
2556          {
2557             Expression exp;
2558
2559             ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
2560             for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
2561             {
2562                ProcessExpression(exp);
2563             }
2564          }
2565          if(stmt.whileStmt.stmt)
2566             ProcessStatement(stmt.whileStmt.stmt);
2567          break;
2568       }
2569       case doWhileStmt:
2570       {
2571          if(stmt.doWhile.exp)
2572          {
2573             Expression exp;
2574             ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
2575             for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
2576             {
2577                ProcessExpression(exp);
2578             }
2579          }
2580          if(stmt.doWhile.stmt)
2581             ProcessStatement(stmt.doWhile.stmt);
2582          break;
2583       }
2584       case forStmt:
2585       {
2586          Expression exp;
2587          if(stmt.forStmt.init)
2588             ProcessStatement(stmt.forStmt.init);
2589
2590          if(stmt.forStmt.check && stmt.forStmt.check.expressions)
2591          {
2592             ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
2593          }
2594
2595          if(stmt.forStmt.check)
2596             ProcessStatement(stmt.forStmt.check);
2597          if(stmt.forStmt.increment)
2598          {
2599             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
2600                ProcessExpression(exp);
2601          }
2602          if(stmt.forStmt.stmt)
2603             ProcessStatement(stmt.forStmt.stmt);
2604          break;
2605       }
2606       case gotoStmt:
2607          break;
2608       case continueStmt:
2609          break;
2610       case breakStmt:
2611          break;
2612       case returnStmt:
2613       {
2614          Expression exp;
2615          if(stmt.expressions && stmt.expressions->last)
2616          {
2617             ((Expression)stmt.expressions->last).usage.usageGet = true;
2618             for(exp = stmt.expressions->first; exp; exp = exp.next)
2619             {
2620                ProcessExpression(exp);
2621             }
2622          }
2623          break;
2624       }
2625       case badDeclarationStmt:
2626       {
2627          ProcessDeclaration(stmt.decl);
2628          break;
2629       }
2630       case asmStmt:
2631       {
2632          AsmField field;
2633          if(stmt.asmStmt.inputFields)
2634          {
2635             for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
2636                if(field.expression)
2637                   ProcessExpression(field.expression);
2638          }
2639          if(stmt.asmStmt.outputFields)
2640          {
2641             for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
2642                if(field.expression)
2643                   ProcessExpression(field.expression);
2644          }
2645          if(stmt.asmStmt.clobberedFields)
2646          {
2647             for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
2648                if(field.expression)
2649                   ProcessExpression(field.expression);
2650          }
2651          break;
2652       }
2653    }
2654 }
2655 static void ProcessFunction(FunctionDefinition function)
2656 {
2657    if(function.body)
2658    {
2659       yylloc = function.loc;
2660       ProcessStatement(function.body);
2661    }
2662 }
2663
2664 /////////// INSTANTIATIONS / DATA TYPES PASS /////////////////////////////////////////////
2665 public void ProcessInstantiations()
2666 {
2667    External external;
2668    // Is this still needed?
2669    //CreateInstancesBody();
2670
2671    for(external = ast->first; external; external = external.next)
2672    {
2673       curExternal = external;
2674       if(external.type == declarationExternal)
2675       {
2676          //currentClass = external.function._class;
2677          if(external.declaration)
2678          {
2679             bool isInstance = external.declaration.type == instDeclaration;
2680             Symbol sym = isInstance ? FindClass(external.declaration.inst._class.name) : null;
2681             ProcessDeclaration(external.declaration);
2682
2683             if(isInstance)
2684             {
2685                // Move edges to the global instances to the create instance body instead
2686                TopoEdge e, next;
2687                for(e = external.incoming.first; e; e = next)
2688                {
2689                   External from = e.from;
2690
2691                   next = e.in.next;
2692
2693                   if(from.incoming.count)
2694                   {
2695                      bool reroute = true;
2696                      if(sym && sym.registered && sym.registered.type == structClass)
2697                         reroute = false;
2698                      else if(from.type == declarationExternal && from.declaration && (!from.declaration.declarators || !from.declaration.declarators->count) && from.declaration.specifiers)
2699                      {
2700                         Specifier spec = null;
2701                         for(spec = from.declaration.specifiers->first; spec; spec = spec.next)
2702                         {
2703                            if(spec.type == structSpecifier || spec.type == unionSpecifier)
2704                               break;
2705                         }
2706                         if(sym.registered && spec && spec.id && spec.id.string)
2707                         {
2708                            char className[1024];
2709                            Class c = sym.registered;
2710                            strcpy(className, "__ecereClass_");
2711                            if(c.type == noHeadClass && c.templateClass)
2712                               FullClassNameCat(className, c.templateClass.name, true);
2713                            else
2714                               FullClassNameCat(className, c.name, true);
2715                            if(!strcmp(c.name, spec.id.string))
2716                               reroute = false;
2717                         }
2718                      }
2719                      if(reroute)
2720                      {
2721                         bool skip = false;
2722                         e.to = createInstancesExternal;
2723                         external.incoming.Remove((IteratorPointer)e);
2724                         for(i : createInstancesExternal.incoming)
2725                         {
2726                            if(i.from == from)
2727                            {
2728                               skip = true;
2729                               if(i.breakable && !e.breakable)
2730                               {
2731                                  i.breakable = true;
2732                                  createInstancesExternal.nonBreakableIncoming++;
2733                               }
2734                               break;
2735                            }
2736                         }
2737                         if(skip)
2738                         {
2739                            external.nonBreakableIncoming--;
2740                            e.from.outgoing.Remove((IteratorPointer)e);
2741                            delete e;
2742                         }
2743                         else
2744                         {
2745                            createInstancesExternal.incoming.Add(e);
2746                            if(!e.breakable)
2747                            {
2748                               external.nonBreakableIncoming--;
2749                               createInstancesExternal.nonBreakableIncoming++;
2750                            }
2751                         }
2752                      }
2753                   }
2754                }
2755             }
2756          }
2757       }
2758       else if(external.type == functionExternal)
2759       {
2760          //currentClass = null;
2761          ProcessFunction(external.function);
2762       }
2763       else if(external.type == classExternal)
2764       {
2765          ClassDefinition _class = external._class;
2766          //currentClass = external.symbol.registered;
2767          if(_class.definitions)
2768          {
2769             ClassDef def;
2770             //Class regClass = _class.symbol.registered;
2771
2772             // Process all functions
2773             for(def = _class.definitions->first; def; def = def.next)
2774             {
2775                if(def.type == functionClassDef)
2776                {
2777                   curExternal = def.function.declarator ? def.function.declarator.symbol.pointerExternal : external;
2778                   ProcessFunction((FunctionDefinition)def.function);
2779                }
2780                else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
2781                {
2782                   ProcessInstantiation(def.decl.inst);
2783                }
2784                else if(def.type == defaultPropertiesClassDef && def.defProperties)
2785                {
2786                   MemberInit defProperty;
2787
2788                   // Add this to the context
2789                   Symbol thisSymbol
2790                   {
2791                      string = CopyString("this");
2792                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2793                   };
2794                   globalContext.symbols.Add((BTNode)thisSymbol);
2795
2796                   for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
2797                   {
2798                      //thisClass = regClass;
2799                      ProcessMemberInitData(defProperty); ///*, regClass, &id
2800                      //thisClass = null;
2801                   }
2802
2803                   globalContext.symbols.Remove((BTNode)thisSymbol);
2804                   FreeSymbol(thisSymbol);
2805                }
2806                else if(def.type == propertyClassDef && def.propertyDef)
2807                {
2808                   PropertyDef prop = def.propertyDef;
2809
2810                   // Add this to the context
2811                   Symbol thisSymbol
2812                   {
2813                      string = CopyString("this");
2814                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2815                   };
2816                   globalContext.symbols.Add((BTNode)thisSymbol);
2817
2818                   //thisClass = regClass;
2819                   if(prop.setStmt)
2820                   {
2821                      curExternal = prop.symbol ? prop.symbol.externalSet : null;
2822                      ProcessStatement(prop.setStmt);
2823                   }
2824                   if(prop.getStmt)
2825                   {
2826                      curExternal = prop.symbol ? prop.symbol.externalGet : null;
2827                      ProcessStatement(prop.getStmt);
2828                   }
2829                   if(prop.issetStmt)
2830                   {
2831                      curExternal = prop.symbol ? prop.symbol.externalIsSet : null;
2832                      ProcessStatement(prop.issetStmt);
2833                   }
2834                   //thisClass = null;
2835
2836                   globalContext.symbols.Remove((BTNode)thisSymbol);
2837                   FreeSymbol(thisSymbol);
2838                }
2839                else if(def.type == propertyWatchClassDef && def.propertyWatch)
2840                {
2841                   PropertyWatch propertyWatch = def.propertyWatch;
2842
2843                   // Add this to the context
2844                   Symbol thisSymbol
2845                   {
2846                      string = CopyString("this");
2847                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2848                   };
2849                   globalContext.symbols.Add((BTNode)thisSymbol);
2850
2851                   //thisClass = regClass;
2852                   if(propertyWatch.compound)
2853                   {
2854                      /* This was already added in pass15:ProcessClass()
2855                      Symbol thisSymbol
2856                      {
2857                         string = CopyString("this");
2858                         type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2859                      };*/
2860                      propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
2861                      curExternal = null;
2862                      ProcessStatement(propertyWatch.compound);
2863                   }
2864                   // thisClass = null;
2865
2866                   //globalContext.symbols.Delete((BTNode)thisSymbol);
2867                   globalContext.symbols.Remove((BTNode)thisSymbol);
2868                   FreeSymbol(thisSymbol);
2869                }
2870              }
2871          }
2872       }
2873    }
2874 }