compiler/libec: Fixed more memory leaks
[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                                           FreeIdentifier(nextID);
1750                                        }
1751                                     }
1752                                  }
1753                               }
1754
1755                               member.initializer.exp = MkExpInstance(MkInstantiation(spec, null,
1756                                  MkListOne(MkMembersInitList(partList))));
1757                            }
1758                            found = true;
1759                            break;
1760                         }
1761                      }
1762                      else
1763                      {
1764                         eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
1765                         if(curMember == dataMember)
1766                         {
1767                            found = true;
1768                            break;
1769                         }
1770
1771                         /*
1772                         if(curMember)
1773                            curMember = curMember.next;
1774                         else
1775                            curMember = parentMember.members.first;
1776
1777                         if(curMember == dataMember)
1778                         {
1779                            found = true;
1780                            break;
1781                         }
1782                         */
1783                      }
1784                   }
1785                }
1786                if(found) break;
1787             }
1788          }
1789
1790          if(member && member.initializer && member.initializer.type == expInitializer)
1791          {
1792             Initializer init { loc = yylloc };
1793             if(namedParentMember.type == unionMember && dataMember.name)
1794                init.id = MkIdentifier(dataMember.name);
1795
1796             if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
1797                member.initializer.exp.expType._class.registered.type == structClass)
1798             {
1799                OldList * subList = MkList();
1800                ProcessBracketInst(member.initializer.exp.instance, subList);
1801                FreeExpression(member.initializer.exp);
1802                if(subList->count)
1803                {
1804                   init.type = listInitializer;
1805                   init.list = subList;
1806                }
1807                else
1808                {
1809                   FreeInitializer(init);
1810                   init = null;
1811                }
1812             }
1813             else
1814             {
1815                member.initializer.exp.usage.usageGet = true;
1816                ProcessExpression(member.initializer.exp);
1817                init.type = expInitializer;
1818                init.exp = member.initializer.exp;
1819             }
1820             if(init)
1821                ListAdd(list, init);
1822
1823             member.initializer.exp = null;
1824             FreeInitializer(member.initializer);
1825             member.initializer = null;
1826             someMemberSet = true;
1827          }
1828          else if(member && member.initializer && member.initializer.type == listInitializer)
1829          {
1830             if(namedParentMember.type == unionMember && dataMember.name)
1831                member.initializer.id = MkIdentifier(dataMember.name);
1832
1833             ListAdd(list, member.initializer);
1834             member.initializer = null;
1835             someMemberSet = true;
1836          }
1837          else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/ && parentMember.type != unionMember && namedParentMember.type != unionMember)
1838          {
1839             Symbol classSym;
1840             Initializer init { loc = yylloc };
1841             if(namedParentMember.type == unionMember && dataMember.name)
1842                init.id = MkIdentifier(dataMember.name);
1843
1844             if(!dataMember.dataType)
1845                dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1846             classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1847             if(classSym && classSym.registered && classSym.registered.type == structClass)
1848             {
1849                OldList * subList = MkList();
1850                Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null);
1851                Instantiation inst = MkInstantiation(spec, null, null);
1852                ProcessBracketInst(inst, subList);
1853                FreeInstance(inst);
1854
1855                if(subList->count)
1856                {
1857                   init.type = listInitializer;
1858                   init.list = subList;
1859                }
1860                else
1861                {
1862                   FreeInitializer(init);
1863                   init = null;
1864                }
1865             }
1866             else
1867             {
1868                init.type = expInitializer;
1869                init.exp = MkExpConstant("0");
1870             }
1871             someMemberSet = true;
1872             if(init)
1873                ListAdd(list, init);
1874          }
1875       }
1876       /*
1877       if(parentMember.type == unionMember)
1878          break;
1879       */
1880    }
1881    // TESTING THIS NEW CODE FOR ANCHORS...
1882    if(/*parentMember.type == unionMember && */!someMemberSet && !parentMemberSet)
1883    {
1884       Symbol classSym;
1885       Initializer init { loc = yylloc };
1886
1887       dataMember = parentMember.members.first;
1888       if(namedParentMember.type == unionMember && dataMember.name)
1889          init.id = MkIdentifier(dataMember.name);
1890
1891       if(!dataMember.dataType && dataMember.dataTypeString)
1892          dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1893       classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1894       if(classSym && classSym.registered && classSym.registered.type == structClass)
1895       {
1896          OldList * subList = MkList();
1897          Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null);
1898          Instantiation inst = MkInstantiation(spec, null, null);
1899          ProcessBracketInst(inst, subList);
1900          FreeInstance(inst);
1901
1902          init.type = listInitializer;
1903          init.list = subList;
1904       }
1905       else if(dataMember.dataType && (dataMember.dataType.kind == arrayType || dataMember.dataType.kind == structType))
1906       {
1907          Type t = dataMember.dataType.kind == arrayType ? dataMember.dataType.type : dataMember.dataType.members.first;
1908          Initializer i = MkInitializerAssignment(MkExpConstant("0"));
1909          while(t && (t.kind == arrayType || t.kind == structType))
1910          {
1911             i = MkInitializerList(MkListOne(i));
1912             if(t.kind == arrayType)
1913                t = t.type;
1914             else if(t.kind == structType)
1915                t = t.members.first;
1916          }
1917          init.type = listInitializer;
1918          init.list = MkListOne(i);
1919       }
1920       else
1921       {
1922          init.type = expInitializer;
1923          init.exp = MkExpConstant("0");
1924       }
1925       ListAdd(list, init);
1926    }
1927    return true;
1928 }
1929
1930 static bool ProcessBracketInst(Instantiation inst, OldList list)
1931 {
1932    static int recursionCount = 0;
1933    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1934    Class _class = null;
1935    int anonID = 1;
1936
1937    if(recursionCount > 500) return false;
1938    recursionCount++;
1939
1940    while(_class != classSym.registered)
1941    {
1942       DataMember dataMember;
1943       Class lastClass = _class;
1944
1945       for(_class = classSym.registered; _class.base != lastClass && _class.base.type != systemClass; _class = _class.base);
1946
1947       for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
1948       {
1949          if(!dataMember.isProperty && !dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
1950          {
1951             OldList * subList = MkList(); //(dataMember.type == structMember ? MkList() : null);
1952
1953             if(!ProcessBracketInst_DataMember(dataMember, inst, subList ? subList : list, dataMember, false))
1954             {
1955                if(subList)
1956                   FreeList(subList, FreeInitializer);
1957                recursionCount--;
1958                return false;
1959             }
1960             if(dataMember.type == structMember || (subList && subList->count))
1961             {
1962                Initializer init = MkInitializerList(subList);
1963                char id[100];
1964                sprintf(id, "__anon%d", anonID);
1965                init.id = MkIdentifier(id);
1966                ListAdd(list, init);
1967             }
1968             else
1969                delete subList;
1970             anonID ++;
1971          }
1972          else
1973          {
1974             MembersInit members;
1975             MemberInit member = null;
1976             bool found = false;
1977
1978             if(inst.members && inst.members->first)
1979             {
1980                DataMember curMember = null;
1981                Class curClass = null;
1982                DataMember subMemberStack[256];
1983                int subMemberStackPos = 0;
1984
1985                for(members = inst.members->first; members; members = members.next)
1986                {
1987                   if(members.type == dataMembersInit)
1988                   {
1989                      for(member = members.dataMembers->first; member; member = member.next)
1990                      {
1991                         Identifier firstID = member.identifiers ? member.identifiers->first : null;
1992                         if(firstID)
1993                         {
1994                            DataMember _subMemberStack[256];
1995                            int _subMemberStackPos = 0;
1996                            DataMember thisMember = (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule);
1997                            // FILL MEMBER STACK
1998                            if(!thisMember)
1999                               thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
2000                            if(thisMember)
2001                            {
2002                               curMember = thisMember;
2003                               curClass = curMember._class;
2004                               memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
2005                               subMemberStackPos = _subMemberStackPos;
2006                            }
2007
2008                            if(curMember == dataMember)
2009                            {
2010                               if(dataMember.isProperty)
2011                               {
2012                                  if(!((Property)dataMember).Set)
2013                                  {
2014                                     Compiler_Error($"No set defined for property %s\n", dataMember.name);
2015                                     continue;
2016                                  }
2017                                  recursionCount--;
2018                                  return false;
2019                               }
2020
2021                               // Look for another member of this one and merge them
2022                               // into one instantiation...
2023                               if(member.identifiers->count > 1 && member.initializer && member.initializer.type == expInitializer)
2024                               {
2025                                  OldList * partList = MkList();
2026                                  // TODO: We're assuming this is a simple _class right now...
2027                                  Specifier spec;
2028                                  MembersInit nextMembers;
2029                                  MemberInit next = member.next;
2030                                  Symbol symbol;
2031                                  if(!dataMember.dataType)
2032                                     dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
2033                                  symbol = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null;
2034                                  spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, symbol, null);
2035
2036                                  member.identifiers->Remove(firstID);
2037                                  ListAdd(partList,
2038                                     MkMemberInit(member.identifiers, MkInitializerAssignment(member.initializer.exp)));
2039
2040                                  for(nextMembers = members; nextMembers; nextMembers = nextMembers.next)
2041                                  {
2042                                     if(!nextMembers.dataMembers) continue;
2043
2044                                     if(members != nextMembers) next = nextMembers.dataMembers->first;
2045
2046                                     if(nextMembers.type == dataMembersInit)
2047                                     {
2048                                        MemberInit nextMember;
2049
2050                                        for(nextMember = next; nextMember;
2051                                            nextMember = next, next = nextMember ? nextMember.next : null)
2052                                        {
2053                                           Identifier nextID = nextMember.identifiers->first;
2054                                           if(nextMember.identifiers &&
2055                                              nextMember.identifiers->count > 1 &&
2056                                              !strcmp(firstID.string, nextID.string))
2057                                           {
2058                                              nextMembers.dataMembers->Remove(nextMember);
2059                                              nextMember.identifiers->Remove(nextID);
2060                                              ListAdd(partList, nextMember);
2061                                              FreeIdentifier(nextID);
2062                                           }
2063                                        }
2064                                     }
2065                                  }
2066
2067                                  member.initializer.exp = MkExpInstance(MkInstantiation(spec, null,
2068                                     MkListOne(MkMembersInitList(partList))));
2069
2070                                  FreeIdentifier(firstID);
2071                                  // TESTING THIS
2072                                  member.identifiers = null;
2073                               }
2074                               found = true;
2075                               break;
2076                            }
2077                         }
2078                         else
2079                         {
2080                            eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
2081                            if(curMember == dataMember)
2082                            {
2083                               if(dataMember.isProperty)
2084                               {
2085                                  if(!((Property)dataMember).Set)
2086                                  {
2087                                     Compiler_Error($"No set defined for property %s\n", dataMember.name);
2088                                     continue;
2089                                  }
2090                                  recursionCount--;
2091                                  return false;
2092                               }
2093                               found = true;
2094                               break;
2095                            }
2096                         }
2097                      }
2098                   }
2099                   if(found) break;
2100                }
2101             }
2102
2103             if(dataMember.isProperty) continue;
2104             if(member && member.initializer && member.initializer.type == expInitializer)
2105             {
2106                if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
2107                   member.initializer.exp.expType._class && member.initializer.exp.expType._class.registered && member.initializer.exp.expType._class.registered.type == structClass)
2108                {
2109                   OldList * subList = MkList();
2110                   ProcessBracketInst(member.initializer.exp.instance, subList);
2111                   FreeExpression(member.initializer.exp);
2112                   member.initializer.exp = null;
2113                   ListAdd(list, MkInitializerList(subList));
2114                }
2115                else
2116                {
2117                   member.initializer.exp.usage.usageGet = true;
2118                   ProcessExpression(member.initializer.exp);
2119                   ListAdd(list, MkInitializerAssignment(CopyExpression(member.initializer.exp)));
2120                }
2121
2122                // Take this out
2123                // member.exp = null;
2124                member.takeOutExp = true;
2125             }
2126             else if(member && member.initializer && member.initializer.type == listInitializer)
2127             {
2128                ListAdd(list, member.initializer);
2129                member.initializer = null;
2130             }
2131             else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/)
2132             {
2133                Symbol classSym;
2134
2135                if(!dataMember.dataType)
2136                   dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
2137                classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
2138
2139                if(classSym && classSym.registered && classSym.registered.type == structClass)
2140                {
2141                   OldList * subList = MkList();
2142                   Specifier spec = _MkSpecifierName(dataMember.dataTypeString, classSym, null);
2143                   Instantiation inst = MkInstantiation(spec, null, null);
2144                   ProcessBracketInst(inst, subList);
2145                   FreeInstance(inst);
2146                   ListAdd(list, MkInitializerList(subList));
2147                }
2148                else if(dataMember.dataType.kind == arrayType)
2149                {
2150                   Type t = dataMember.dataType.type;
2151                   Initializer inner = MkInitializerAssignment(null), i = inner;
2152                   while(t && t.kind == arrayType)
2153                   {
2154                      i = MkInitializerList(MkListOne(i));
2155                      t = t.type;
2156                   }
2157                   if(t && t.kind == classType && t._class && t._class.registered && t._class.registered.type == structClass)
2158                   {
2159                      OldList * subList = MkList();
2160                      Specifier spec = _MkSpecifierName(t._class.registered.name, classSym, null);
2161                      Instantiation inst = MkInstantiation(spec, null, null);
2162                      ProcessBracketInst(inst, subList);
2163                      FreeInstance(inst);
2164                      inner.type = listInitializer;
2165                      inner.list = subList;
2166                   }
2167                   else
2168                      inner.exp = MkExpConstant("0");
2169                   ListAdd(list,  MkInitializerList(MkListOne(i)));
2170                }
2171                else
2172                   ListAdd(list, MkInitializerAssignment(MkExpConstant("0")));
2173             }
2174          }
2175       }
2176    }
2177
2178    if(inst.members && inst.members->first)
2179    {
2180       MembersInit members;
2181       MemberInit member = null;
2182
2183       for(members = inst.members->first; members; members = members.next)
2184       {
2185          if(members.type == dataMembersInit)
2186          {
2187             for(member = members.dataMembers->first; member; member = member.next)
2188             {
2189                if(member.takeOutExp)
2190                {
2191                   FreeInitializer(member.initializer);
2192                   member.initializer = null;
2193                }
2194             }
2195          }
2196       }
2197    }
2198    recursionCount--;
2199    return true;
2200 }
2201
2202 static Declaration curDecl;
2203 static int declTempCount;
2204
2205 static void ProcessDeclaration(Declaration decl)
2206 {
2207    yylloc = decl.loc;
2208    switch(decl.type)
2209    {
2210       case initDeclaration:
2211       {
2212          if(!curDecl) { curDecl = decl; declTempCount = 0; }
2213          if(decl.specifiers)
2214          {
2215             Specifier s;
2216             for(s = decl.specifiers->first; s; s = s.next)
2217             {
2218                ProcessSpecifier(s);
2219             }
2220          }
2221          if(decl.declarators)
2222          {
2223             InitDeclarator d;
2224
2225             for(d = decl.declarators->first; d; d = d.next)
2226             {
2227               if(d.initializer)
2228                   ProcessInitializer(d.initializer);
2229             }
2230          }
2231          if(curDecl == decl) { curDecl = null; declTempCount = 0; }
2232          break;
2233       }
2234       case instDeclaration:
2235       {
2236          Instantiation inst = decl.inst;
2237
2238          if(inCompiler)
2239          {
2240             Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
2241             if(!curCompound)
2242             {
2243                Statement stmt;
2244
2245                if(!inst.isConstant || (classSym && classSym.registered && (classSym.registered.type == normalClass || classSym.registered.type == noHeadClass)))
2246                {
2247                   // If this instantiation is outside, turn it into a declaration plus an instantiation expression
2248                   decl.type = initDeclaration;
2249                   decl.specifiers = MkListOne(MkSpecifierName/*MkClassName*/(inst._class.name));
2250                   if(decl.declMode == staticAccess)
2251                   {
2252                      decl.specifiers->Insert(null, MkSpecifier(STATIC));
2253                   }
2254                   decl.declarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(inst.exp.identifier.string)), null));
2255
2256                   ProcessDeclaration(decl);
2257                   CreateInstancesBody();
2258
2259                   {
2260                      Expression exp = MkExpInstance(inst);
2261                      stmt = MkExpressionStmt(MkListOne(exp));       // MkExpOp(inst.exp, '=',
2262                      ListAdd(createInstancesBody.compound.statements, stmt);
2263                      ProcessExpressionType(exp);
2264                   }
2265
2266                   if(classSym && classSym.registered && (classSym.registered.type == normalClass))
2267                   {
2268                      ListAdd(createInstancesBody.compound.statements,
2269                         MkExpressionStmt(MkListOne(MkExpCall(
2270                            MkExpIdentifier(MkIdentifier("ecere::com::eInstance_IncRef")),
2271                            MkListOne(CopyExpression(inst.exp))))));
2272
2273                      // We'd like the = 0 as well...
2274                      {
2275                         Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2276                         ListAddFront(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2277                         ProcessExpressionType(exp);
2278                      }
2279                   }
2280                   else if(classSym && classSym.registered && (classSym.registered.type == noHeadClass))
2281                   {
2282                      Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2283                      ListAddFront(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2284                      ProcessExpressionType(exp);
2285                   }
2286
2287                   createInstancesExternal.CreateEdge(curExternal, false);
2288                   destroyInstancesExternal.CreateEdge(curExternal, false);
2289                   break;
2290                }
2291                else
2292                {
2293                   // Precompiler won't know if this isn't constant
2294                   CreateInstancesBody();
2295                }
2296             }
2297
2298             {
2299                char className[1024];
2300                className[0] = 0;
2301
2302                decl.type = initDeclaration;
2303                decl.specifiers = MkList();
2304                decl.declarators = MkList();
2305
2306                // Replace instantiation here
2307                if(classSym && classSym.registered && classSym.registered.type == bitClass)
2308                {
2309                   OldList list = { 0 };
2310
2311                   // Put the instantiation in an InitDeclarator...
2312                   ProcessInstMembers(inst, inst.exp, &list, false);
2313                   ProcessExpression(inst.exp);
2314
2315                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2316                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2317                      MkInitializerAssignment(list.first)));
2318                   inst.exp.identifier = null;
2319                }
2320                else if(classSym && classSym.registered && classSym.registered.type == unitClass)
2321                {
2322                   OldList list = { 0 };
2323
2324                   // Put the instantiation in an InitDeclarator...
2325                   ProcessInstMembers(inst, inst.exp, &list, false);
2326                   ProcessExpression(inst.exp);
2327
2328                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2329                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2330                      MkInitializerAssignment(list.first)));
2331
2332                   inst.exp.identifier = null;
2333                }
2334                else if(classSym && classSym.registered && classSym.registered.type == structClass)
2335                {
2336                   Expression exp;
2337
2338                   DeclareStruct(curExternal, inst._class.name, false, true);
2339                   /*{
2340                      strcpy(className, "__ecereClass_");
2341                      FullClassNameCat(className, classSym.string, true);
2342                      DeclareClass(classSym, className);
2343                   }*/
2344
2345                   ProcessExpression(inst.exp);
2346
2347                   // Put the instantiation in an InitDeclarator...
2348                   {
2349                      if(inst.fullSet)
2350                      {
2351                         ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2352                         ListAdd(decl.declarators,
2353                            MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier), null));
2354                         inst.exp.identifier = null;
2355                      }
2356                      else
2357                      {
2358                         OldList * list = MkList();
2359                         if(ProcessBracketInst(inst, list))
2360                         {
2361                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2362                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2363                               MkInitializerList(list)));
2364                            inst.exp.identifier = null;
2365                         }
2366                         else
2367                         {
2368                            // If bracket instantiation failed (property: for conversions only?)
2369                            // TODO: (Fix this so it initializes members through brackets,
2370                            //        and then does properties)
2371                            //list->Free(null);
2372                            //delete list;
2373                            // TESTING THIS MEMORY LEAK FIX:
2374                            FreeList(list, FreeInitializer);
2375
2376                            exp = MkExpBrackets(MkList());
2377                            ProcessInstMembers(inst, inst.exp, exp.list, true);
2378                            ListAdd(exp.list, CopyExpression(inst.exp));
2379                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2380                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2381                               MkInitializerAssignment(exp)));
2382                            inst.exp.identifier = null;
2383                         }
2384                      }
2385                   }
2386                }
2387                else
2388                {
2389                   Expression newCall;
2390
2391                   strcpy(className, "__ecereClass_");
2392
2393                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass && classSym.registered.templateClass)
2394                   {
2395                      classSym = FindClass(classSym.registered.templateClass.fullName);
2396                      FullClassNameCat(className, classSym.string, true);
2397                   }
2398                   else
2399                      FullClassNameCat(className, inst._class.name, true);
2400
2401                   if(classSym)
2402                      DeclareClass(curExternal, classSym, className);
2403
2404                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass &&
2405                      (classSym.registered.templateClass ? classSym.registered.templateClass.fixed : classSym.registered.fixed))
2406                   {
2407                      char size[256];
2408                      Class c = classSym.registered.templateClass ? classSym.registered.templateClass : classSym.registered;
2409                      Expression e = MkExpClassSize(MkSpecifierName(c.name));
2410                      ProcessExpressionType(e);
2411                      sprintf(size, "%d", c.structSize);
2412                      newCall = MkExpCall(QMkExpId("ecere::com::eSystem_New0"), MkListOne( e /*MkExpConstant(size)*/));
2413                   }
2414                   else
2415                   {
2416                      newCall = MkExpCall(QMkExpId("ecere::com::eInstance_New"), MkListOne(QMkExpId(className)));
2417                      ProcessExpressionType(newCall);
2418                      newCall.byReference = true;
2419                   }
2420
2421                   if(inst.exp)
2422                   {
2423                      Expression exp, newExp;
2424                      Identifier id = CopyIdentifier(inst.exp.identifier);
2425
2426                      // Put the instantiation in an InitDeclarator...
2427                      if(inst.members && inst.members->first)
2428                      {
2429                         newExp = MkExpOp(CopyExpression(inst.exp), '=', newCall);
2430
2431                         exp = MkExpBrackets(MkList());
2432                         ListAdd(exp.list, newExp);
2433                         ProcessInstMembers(inst, inst.exp, exp.list, false);
2434                         ListAdd(exp.list, inst.exp);
2435
2436                         ProcessExpression(inst.exp);
2437
2438                         // Take it out since we're using it...
2439                         inst.exp = null;
2440                      }
2441                      else
2442                         exp = newCall;
2443
2444                      ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2445                      ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(id),
2446                         MkInitializerAssignment(exp)));
2447                      //inst.exp.identifier = null;
2448                   }
2449                   else
2450                      FreeExpression(newCall);
2451                }
2452             }
2453             FreeInstance(inst);
2454          }
2455          else
2456             ProcessInstantiation(inst);
2457          break;
2458       }
2459       case structDeclaration:
2460       {
2461          if(decl.specifiers)
2462          {
2463             Specifier spec;
2464             for(spec = decl.specifiers->first; spec; spec = spec.next)
2465                ProcessSpecifier(spec);
2466          }
2467          break;
2468       }
2469    }
2470 }
2471
2472 static void ProcessStatement(Statement stmt)
2473 {
2474    yylloc = stmt.loc;
2475    switch(stmt.type)
2476    {
2477       case labeledStmt:
2478          if(stmt.labeled.stmt)
2479             ProcessStatement(stmt.labeled.stmt);
2480          break;
2481       case caseStmt:
2482          if(stmt.caseStmt.exp)
2483             ProcessExpression(stmt.caseStmt.exp);
2484          if(stmt.caseStmt.stmt)
2485             ProcessStatement(stmt.caseStmt.stmt);
2486          break;
2487       case compoundStmt:
2488       {
2489          if(stmt.compound.context)
2490          {
2491             Declaration decl;
2492             Statement s;
2493             Statement prevCompound = curCompound;
2494             Context prevContext = curContext;
2495
2496             if(!stmt.compound.isSwitch)
2497             {
2498                curCompound = stmt;
2499                curContext = stmt.compound.context;
2500             }
2501
2502             if(stmt.compound.declarations)
2503             {
2504                for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
2505                   ProcessDeclaration(decl);
2506             }
2507             if(stmt.compound.statements)
2508             {
2509                for(s = stmt.compound.statements->first; s; s = s.next)
2510                {
2511                   ProcessStatement(s);
2512                }
2513             }
2514
2515             curCompound = prevCompound;
2516             curContext = prevContext;
2517          }
2518          break;
2519       }
2520       case expressionStmt:
2521       {
2522          Expression exp;
2523          if(stmt.expressions)
2524          {
2525             for(exp = stmt.expressions->first; exp; exp = exp.next)
2526             {
2527                ProcessExpression(exp);
2528             }
2529          }
2530          break;
2531       }
2532       case ifStmt:
2533       {
2534          Expression exp;
2535
2536          ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
2537          for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
2538          {
2539             ProcessExpression(exp);
2540          }
2541          if(stmt.ifStmt.stmt)
2542             ProcessStatement(stmt.ifStmt.stmt);
2543          if(stmt.ifStmt.elseStmt)
2544             ProcessStatement(stmt.ifStmt.elseStmt);
2545          break;
2546       }
2547       case switchStmt:
2548       {
2549          Expression exp;
2550          ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
2551          for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
2552             ProcessExpression(exp);
2553          ProcessStatement(stmt.switchStmt.stmt);
2554          break;
2555       }
2556       case whileStmt:
2557       {
2558          if(stmt.whileStmt.exp)
2559          {
2560             Expression exp;
2561
2562             ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
2563             for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
2564             {
2565                ProcessExpression(exp);
2566             }
2567          }
2568          if(stmt.whileStmt.stmt)
2569             ProcessStatement(stmt.whileStmt.stmt);
2570          break;
2571       }
2572       case doWhileStmt:
2573       {
2574          if(stmt.doWhile.exp)
2575          {
2576             Expression exp;
2577             ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
2578             for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
2579             {
2580                ProcessExpression(exp);
2581             }
2582          }
2583          if(stmt.doWhile.stmt)
2584             ProcessStatement(stmt.doWhile.stmt);
2585          break;
2586       }
2587       case forStmt:
2588       {
2589          Expression exp;
2590          if(stmt.forStmt.init)
2591             ProcessStatement(stmt.forStmt.init);
2592
2593          if(stmt.forStmt.check && stmt.forStmt.check.expressions)
2594          {
2595             ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
2596          }
2597
2598          if(stmt.forStmt.check)
2599             ProcessStatement(stmt.forStmt.check);
2600          if(stmt.forStmt.increment)
2601          {
2602             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
2603                ProcessExpression(exp);
2604          }
2605          if(stmt.forStmt.stmt)
2606             ProcessStatement(stmt.forStmt.stmt);
2607          break;
2608       }
2609       case gotoStmt:
2610          break;
2611       case continueStmt:
2612          break;
2613       case breakStmt:
2614          break;
2615       case returnStmt:
2616       {
2617          Expression exp;
2618          if(stmt.expressions && stmt.expressions->last)
2619          {
2620             ((Expression)stmt.expressions->last).usage.usageGet = true;
2621             for(exp = stmt.expressions->first; exp; exp = exp.next)
2622             {
2623                ProcessExpression(exp);
2624             }
2625          }
2626          break;
2627       }
2628       case badDeclarationStmt:
2629       {
2630          ProcessDeclaration(stmt.decl);
2631          break;
2632       }
2633       case asmStmt:
2634       {
2635          AsmField field;
2636          if(stmt.asmStmt.inputFields)
2637          {
2638             for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
2639                if(field.expression)
2640                   ProcessExpression(field.expression);
2641          }
2642          if(stmt.asmStmt.outputFields)
2643          {
2644             for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
2645                if(field.expression)
2646                   ProcessExpression(field.expression);
2647          }
2648          if(stmt.asmStmt.clobberedFields)
2649          {
2650             for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
2651                if(field.expression)
2652                   ProcessExpression(field.expression);
2653          }
2654          break;
2655       }
2656    }
2657 }
2658 static void ProcessFunction(FunctionDefinition function)
2659 {
2660    if(function.body)
2661    {
2662       yylloc = function.loc;
2663       ProcessStatement(function.body);
2664    }
2665 }
2666
2667 /////////// INSTANTIATIONS / DATA TYPES PASS /////////////////////////////////////////////
2668 public void ProcessInstantiations()
2669 {
2670    External external;
2671    // Is this still needed?
2672    //CreateInstancesBody();
2673
2674    for(external = ast->first; external; external = external.next)
2675    {
2676       curExternal = external;
2677       if(external.type == declarationExternal)
2678       {
2679          //currentClass = external.function._class;
2680          if(external.declaration)
2681          {
2682             bool isInstance = external.declaration.type == instDeclaration;
2683             Symbol sym = isInstance ? FindClass(external.declaration.inst._class.name) : null;
2684             ProcessDeclaration(external.declaration);
2685
2686             if(isInstance)
2687             {
2688                // Move edges to the global instances to the create instance body instead
2689                TopoEdge e, next;
2690                for(e = external.incoming.first; e; e = next)
2691                {
2692                   External from = e.from;
2693
2694                   next = e.in.next;
2695
2696                   if(from.incoming.count)
2697                   {
2698                      bool reroute = true;
2699                      if(sym && sym.registered && sym.registered.type == structClass)
2700                         reroute = false;
2701                      else if(from.type == declarationExternal && from.declaration && (!from.declaration.declarators || !from.declaration.declarators->count) && from.declaration.specifiers)
2702                      {
2703                         Specifier spec = null;
2704                         for(spec = from.declaration.specifiers->first; spec; spec = spec.next)
2705                         {
2706                            if(spec.type == structSpecifier || spec.type == unionSpecifier)
2707                               break;
2708                         }
2709                         if(sym.registered && spec && spec.id && spec.id.string)
2710                         {
2711                            char className[1024];
2712                            Class c = sym.registered;
2713                            strcpy(className, "__ecereClass_");
2714                            if(c.type == noHeadClass && c.templateClass)
2715                               FullClassNameCat(className, c.templateClass.name, true);
2716                            else
2717                               FullClassNameCat(className, c.name, true);
2718                            if(!strcmp(c.name, spec.id.string))
2719                               reroute = false;
2720                         }
2721                      }
2722                      if(reroute)
2723                      {
2724                         bool skip = false;
2725                         e.to = createInstancesExternal;
2726                         external.incoming.Remove((IteratorPointer)e);
2727                         for(i : createInstancesExternal.incoming)
2728                         {
2729                            if(i.from == from)
2730                            {
2731                               skip = true;
2732                               if(i.breakable && !e.breakable)
2733                               {
2734                                  i.breakable = true;
2735                                  createInstancesExternal.nonBreakableIncoming++;
2736                               }
2737                               break;
2738                            }
2739                         }
2740                         if(skip)
2741                         {
2742                            external.nonBreakableIncoming--;
2743                            e.from.outgoing.Remove((IteratorPointer)e);
2744                            delete e;
2745                         }
2746                         else
2747                         {
2748                            createInstancesExternal.incoming.Add(e);
2749                            if(!e.breakable)
2750                            {
2751                               external.nonBreakableIncoming--;
2752                               createInstancesExternal.nonBreakableIncoming++;
2753                            }
2754                         }
2755                      }
2756                   }
2757                }
2758             }
2759          }
2760       }
2761       else if(external.type == functionExternal)
2762       {
2763          //currentClass = null;
2764          ProcessFunction(external.function);
2765       }
2766       else if(external.type == classExternal)
2767       {
2768          ClassDefinition _class = external._class;
2769          //currentClass = external.symbol.registered;
2770          if(_class.definitions)
2771          {
2772             ClassDef def;
2773             //Class regClass = _class.symbol.registered;
2774
2775             // Process all functions
2776             for(def = _class.definitions->first; def; def = def.next)
2777             {
2778                if(def.type == functionClassDef)
2779                {
2780                   curExternal = def.function.declarator ? def.function.declarator.symbol.pointerExternal : external;
2781                   ProcessFunction((FunctionDefinition)def.function);
2782                }
2783                else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
2784                {
2785                   ProcessInstantiation(def.decl.inst);
2786                }
2787                else if(def.type == defaultPropertiesClassDef && def.defProperties)
2788                {
2789                   MemberInit defProperty;
2790
2791                   // Add this to the context
2792                   Symbol thisSymbol
2793                   {
2794                      string = CopyString("this");
2795                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2796                   };
2797                   globalContext.symbols.Add((BTNode)thisSymbol);
2798
2799                   for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
2800                   {
2801                      //thisClass = regClass;
2802                      ProcessMemberInitData(defProperty); ///*, regClass, &id
2803                      //thisClass = null;
2804                   }
2805
2806                   globalContext.symbols.Remove((BTNode)thisSymbol);
2807                   FreeSymbol(thisSymbol);
2808                }
2809                else if(def.type == propertyClassDef && def.propertyDef)
2810                {
2811                   PropertyDef prop = def.propertyDef;
2812
2813                   // Add this to the context
2814                   Symbol thisSymbol
2815                   {
2816                      string = CopyString("this");
2817                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2818                   };
2819                   globalContext.symbols.Add((BTNode)thisSymbol);
2820
2821                   //thisClass = regClass;
2822                   if(prop.setStmt)
2823                   {
2824                      curExternal = prop.symbol ? prop.symbol.externalSet : null;
2825                      ProcessStatement(prop.setStmt);
2826                   }
2827                   if(prop.getStmt)
2828                   {
2829                      curExternal = prop.symbol ? prop.symbol.externalGet : null;
2830                      ProcessStatement(prop.getStmt);
2831                   }
2832                   if(prop.issetStmt)
2833                   {
2834                      curExternal = prop.symbol ? prop.symbol.externalIsSet : null;
2835                      ProcessStatement(prop.issetStmt);
2836                   }
2837                   //thisClass = null;
2838
2839                   globalContext.symbols.Remove((BTNode)thisSymbol);
2840                   FreeSymbol(thisSymbol);
2841                }
2842                else if(def.type == propertyWatchClassDef && def.propertyWatch)
2843                {
2844                   PropertyWatch propertyWatch = def.propertyWatch;
2845
2846                   // Add this to the context
2847                   Symbol thisSymbol
2848                   {
2849                      string = CopyString("this");
2850                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2851                   };
2852                   globalContext.symbols.Add((BTNode)thisSymbol);
2853
2854                   //thisClass = regClass;
2855                   if(propertyWatch.compound)
2856                   {
2857                      /* This was already added in pass15:ProcessClass()
2858                      Symbol thisSymbol
2859                      {
2860                         string = CopyString("this");
2861                         type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2862                      };*/
2863                      propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
2864                      curExternal = null;
2865                      ProcessStatement(propertyWatch.compound);
2866                   }
2867                   // thisClass = null;
2868
2869                   //globalContext.symbols.Delete((BTNode)thisSymbol);
2870                   globalContext.symbols.Remove((BTNode)thisSymbol);
2871                   FreeSymbol(thisSymbol);
2872                }
2873              }
2874          }
2875       }
2876    }
2877 }