ecere/gui/Window: Prevent uninitialized values if base Window methods not overridden...
[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 && member.identifiers->first)
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                      Type destType = exp.destType;
862                      *exp = *e;
863                      list.Remove(e);
864                      delete e;
865
866                      // Fixes PrintLn(Degrees { 1 })
867                      if(!exp.destType)
868                         exp.destType = destType;
869                      else
870                         FreeType(destType);
871                      exp.expType = expType;
872                      exp.prev = prev;
873                      exp.next = next;
874                      while((e = list.first))
875                      {
876                         list.Remove(e);
877                         FreeExpression(e);
878                      }
879                   }
880                   else
881                   {
882                      exp.type = constantExp;
883                      exp.constant = CopyString("0");
884                   }
885                }
886             }
887             else if(classSym && classSym.registered && classSym.registered.type == structClass)
888             {
889                if(inst.exp)
890                {
891                   // Set members
892                   exp.type = bracketsExp;
893                   exp.list = MkList();
894
895                   ProcessInstMembers(inst, inst.exp, exp.list, false);
896
897                   ProcessExpression(inst.exp);
898
899                   if(!exp.list->count)
900                   {
901                      exp.type = dummyExp; // remove expression
902                      delete exp.list;
903                   }
904
905                   // Take expression out... -- It seems ProcessInstMembers() makes copies of it and it needs to be freed now
906                   // inst.exp = null;
907                }
908                else
909                {
910                   Declaration decl;
911                   Declaration dummyDecl;
912                   // Unnamed instantiation
913
914                   // Make a declaration in the closest compound statement
915                   // (Do not reuse (since using address for function calls)...)
916
917                   /*
918                   ListAdd(decls, MkInitDeclarator(
919                      MkDeclaratorIdentifier(MkIdentifier(className)), null));
920                   decl = MkDeclaration(specs, decls);
921                   */
922                   /*    Never mind this... somebody might modify the values...
923
924                   if(inst.isConstant)
925                   {
926                      sprintf(className, "__simpleStruct%d", curContext.simpleID++);
927                      inst.id = MkIdentifier(className);
928                      decl = MkDeclarationInst(inst);
929                      exp.type = ExpIdentifier;
930                      exp.identifier = inst.id;
931                      if(!curCompound.compound.declarations)
932                         curCompound.compound.declarations = MkList();
933                      curCompound.compound.declarations->Insert(null, decl);
934                      ProcessDeclaration(decl);
935                   }
936                   else
937                   */
938
939                   {
940                      //OldList * specs = MkList(), * decls = MkList();
941                      //sprintf(className, "__ecereClassData_%s", inst._class.name);
942                      //ListAdd(specs, MkStructOrUnion(SpecifierStruct, MkIdentifier(className), null));
943
944
945                      // TRICKY STUFF, UGLY HACK FOR stateSizeAnchor = SizeAnchor { size.w = 10 };
946                      dummyDecl = MkDeclaration(null,null);
947                      if(curCompound)
948                      {
949                         if(!curCompound.compound.declarations)
950                            curCompound.compound.declarations = MkList();
951                         curCompound.compound.declarations->Insert(null, dummyDecl);
952                      }
953
954                      sprintf(className, "__simpleStruct%d", curContext.simpleID++);
955
956                      {
957                         OldList * list = MkList();
958                         if(inst.isConstant && ProcessBracketInst(inst, list))
959                         {
960                            decl = MkDeclaration(MkList(), MkList());
961
962                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
963                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(className)),
964                               MkInitializerList(list)));
965
966                            exp.type = identifierExp;
967                            exp.identifier = MkIdentifier(className);
968                         }
969                         else
970                         {
971                            list->Free(null);
972                            delete list;
973
974                            decl = MkDeclarationInst(MkInstantiation(CopySpecifier(inst._class), MkExpIdentifier(MkIdentifier(className)), null));
975
976
977                            // Set properties & data members in expression
978                            // to handle jump and control statements
979                            // Set unset data members to 0
980                            exp.type = bracketsExp;
981                            exp.list = MkList();
982
983                            instExp = QMkExpId(className);
984                            instExp.loc = exp.loc;
985                            instExp.expType = MkClassType(inst._class.name);
986
987                            // Mark the declarated instance as fullset so it doesn't need to be zeroed out
988                            decl.inst.fullSet = ProcessInstMembers(inst, instExp, exp.list, false);
989
990                            ListAdd(exp.list, instExp);
991                         }
992                      }
993
994                      FreeType(exp.expType);
995                      exp.expType = MkClassType(inst._class.name);
996
997                      // TRICKY STUFF, UGLY HACK FOR stateSizeAnchor = SizeAnchor { size.w = 10 };
998                      {
999                         void * prev = dummyDecl.prev, * next = dummyDecl.next;
1000                         *dummyDecl = *decl;
1001                         dummyDecl.prev = prev;
1002                         dummyDecl.next = next;
1003                         delete decl;
1004                         decl = dummyDecl;
1005                      }
1006                      ProcessDeclaration(decl);
1007
1008                      /*
1009                      if(!curCompound.compound.declarations)
1010                         curCompound.compound.declarations = MkList();
1011                      curCompound.compound.declarations->Insert(null, decl);
1012                      */
1013                   }
1014                }
1015             }
1016             else
1017             {
1018                Expression newCall;
1019
1020                if(classSym && classSym.registered && classSym.registered.type == noHeadClass &&
1021                   (classSym.registered.templateClass ? classSym.registered.templateClass.fixed : classSym.registered.fixed))
1022                {
1023                   char size[256];
1024                   Class c = classSym.registered.templateClass ? classSym.registered.templateClass : classSym.registered;
1025                   Expression e = MkExpClassSize(MkSpecifierName(c.name));
1026                   ProcessExpressionType(e);
1027                   sprintf(size, "%d", c.structSize);
1028                   newCall = MkExpCall(QMkExpId("ecere::com::eSystem_New0"), MkListOne( e /*MkExpConstant(size)*/));
1029                   newCall.byReference = true;
1030                }
1031                else
1032                {
1033                   strcpy(className, "__ecereClass_");
1034                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass && classSym.registered.templateClass)
1035                   {
1036                      classSym = FindClass(classSym.registered.templateClass.fullName);
1037                      FullClassNameCat(className, classSym.string, true);
1038                   }
1039                   else
1040                      FullClassNameCat(className, inst._class.name, true);
1041
1042                   DeclareClass(curExternal, classSym, className);
1043                   newCall = MkExpCall(QMkExpId("ecere::com::eInstance_New"), MkListOne(QMkExpId(className)));
1044                   newCall.usage = exp.usage;
1045
1046                   ProcessExpressionType(newCall);
1047                   if(newCall.expType && exp.expType)
1048                      newCall.expType.passAsTemplate = exp.expType.passAsTemplate;
1049                   newCall.byReference = true;
1050                }
1051
1052                if(inst.exp)
1053                {
1054                   if(inst.members && inst.members->first)
1055                   {
1056                      exp.type = bracketsExp;
1057                      exp.list = MkList();
1058
1059                      if(!inst.built)
1060                      {
1061                         ListAdd(exp.list, MkExpOp(inst.exp, '=', newCall));
1062                      }
1063                      else
1064                         FreeExpression(newCall);
1065
1066                      ProcessInstMembers(inst, inst.exp, exp.list, false);
1067
1068                      if(inst.built)
1069                         FreeExpression(inst.exp);
1070                   }
1071                   else
1072                   {
1073                      exp.type = opExp;
1074                      exp.op.op = '=';
1075                      exp.op.exp1 = inst.exp;
1076                      exp.op.exp2 = newCall;
1077
1078                      ProcessExpression(inst.exp);
1079                   }
1080                   inst.exp = null;
1081                }
1082                else
1083                {
1084                   // Unnamed instantiation
1085                   if(inst.members && inst.members->first)
1086                   {
1087                      char ecereTemp[100];
1088                      MembersInit members;
1089                      int tempCount = exp.tempCount;
1090                      OldList * expList;
1091
1092                      // Check if members use temp count...
1093                      for(members = inst.members->first; members; members = members.next)
1094                      {
1095                         if(members.type == dataMembersInit && members.dataMembers)
1096                         {
1097                            MemberInit member;
1098                            for(member = members.dataMembers->first; member; member = member.next)
1099                            {
1100                               if(member.initializer && member.initializer.type == expInitializer)
1101                               {
1102                                  ProcessMemberInitData(member);   // ADDED THIS TO HAVE PROPER tempCount ALREADY...
1103                                  tempCount = Max(tempCount, member.initializer.exp.tempCount);
1104                               }
1105                            }
1106                         }
1107                      }
1108                      if(curDecl)
1109                         tempCount = Max(tempCount, declTempCount);
1110
1111                      tempCount++;
1112                      curExternal.function.tempCount = Max(curExternal.function.tempCount, tempCount);
1113                      sprintf(ecereTemp, "__ecereInstance%d", tempCount);
1114                      exp.type = extensionCompoundExp;
1115                      exp.compound = MkCompoundStmt(null, null);
1116                      exp.compound.compound.context = PushContext();
1117                      exp.compound.compound.context.simpleID = exp.compound.compound.context.parent.simpleID;
1118                      exp.compound.compound.declarations = MkListOne(QMkDeclaration(inst._class.name, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(ecereTemp)),
1119                         MkInitializerAssignment(newCall))));
1120                      exp.compound.compound.statements = MkListOne(MkExpressionStmt((expList = MkList())));
1121
1122                      instExp = QMkExpId(ecereTemp);
1123                      instExp.tempCount = tempCount;
1124                      instExp.expType = MkClassType(inst._class.name);
1125                      instExp.byReference = true;
1126                      ProcessInstMembers(inst, instExp, expList, false);
1127                      FreeExpression(instExp);
1128
1129                      if(exp.usage)
1130                      {
1131                         Expression tmpExp = QMkExpId(ecereTemp);
1132                         tmpExp.byReference = true;
1133                         ListAdd(expList, tmpExp);
1134                      }
1135                      exp.tempCount = tempCount;
1136                      if(curDecl)
1137                         declTempCount = Max(declTempCount, tempCount);
1138                      PopContext(exp.compound.compound.context);
1139                   }
1140                   else
1141                   {
1142                      Expression prev = exp.prev, next = exp.next;
1143                      FreeType(newCall.destType);
1144                      FreeType(newCall.expType);
1145                      newCall.destType = exp.destType;
1146                      newCall.expType = exp.expType;
1147                      *exp = *newCall;
1148                      exp.prev = prev;
1149                      exp.next = next;
1150                      delete newCall;
1151                   }
1152                }
1153             }
1154             if(exp.type != instanceExp)
1155                FreeInstance(inst);
1156          }
1157          else
1158             ProcessInstantiation(inst);
1159          break;
1160       }
1161       case constantExp:
1162          break;
1163       case stringExp:
1164          break;
1165       case newExp:
1166       case new0Exp:
1167          // if(exp._new.size) exp._new.size.usage.usageGet = true;
1168          ProcessExpression(exp._new.size);
1169          break;
1170       case renewExp:
1171       case renew0Exp:
1172          // if(exp._renew.size) exp._renew.size.usage.usageGet = true;
1173          ProcessExpression(exp._renew.size);
1174          // if(exp._renew.exp) exp._renew.exp.usage.usageGet = true;
1175          ProcessExpression(exp._renew.exp);
1176          break;
1177       case opExp:
1178       {
1179          //bool assign = false;
1180
1181          switch(exp.op.op)
1182          {
1183             // Assignment Operators
1184             case '=':
1185                if(exp.op.exp2)
1186                   exp.op.exp2.usage.usageGet = true;
1187                if(exp.op.exp1)
1188                   exp.op.exp1.usage.usageSet = true;
1189                //assign = true;
1190                break;
1191             case MUL_ASSIGN:
1192             case DIV_ASSIGN:
1193             case MOD_ASSIGN:
1194             case ADD_ASSIGN:
1195             case SUB_ASSIGN:
1196             case LEFT_ASSIGN:
1197             case RIGHT_ASSIGN:
1198             case AND_ASSIGN:
1199             case XOR_ASSIGN:
1200             case OR_ASSIGN:
1201                if(exp.op.exp2)
1202                   exp.op.exp2.usage.usageGet = true;
1203                //assign = true;
1204                if(exp.op.exp1)
1205                   exp.op.exp1.usage.usageSet = true;
1206                break;
1207
1208             case INC_OP:
1209             case DEC_OP:
1210                if(exp.op.exp1)
1211                   exp.op.exp1.usage.usageSet = true;
1212
1213             // Unary operators
1214             case '&':
1215                // Also binary
1216                if(exp.op.exp1 && exp.op.exp2)
1217                {
1218                   exp.op.exp1.usage.usageGet = true;
1219                   exp.op.exp2.usage.usageGet = true;
1220                }
1221                break;
1222             case '*':
1223             case '+':
1224             case '-':
1225                // Also binary
1226                if(exp.op.exp1)
1227                {
1228                   exp.op.exp1.usage.usageGet = true;
1229                }
1230             case '~':
1231             case '!':
1232                if(exp.op.exp2)
1233                   exp.op.exp2.usage.usageGet = true;
1234                break;
1235
1236             // Binary only operators
1237             case '/':
1238             case '%':
1239             case LEFT_OP:
1240             case RIGHT_OP:
1241             case '<':
1242             case '>':
1243             case LE_OP:
1244             case GE_OP:
1245             case EQ_OP:
1246             case NE_OP:
1247             case '|':
1248             case '^':
1249             case AND_OP:
1250             case OR_OP:
1251                if(exp.op.exp1)
1252                   exp.op.exp1.usage.usageGet = true;
1253                if(exp.op.exp2)
1254                   exp.op.exp2.usage.usageGet = true;
1255                break;
1256          }
1257
1258          if(exp.op.exp1)
1259          {
1260             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)
1261             {
1262                Type type { };
1263                CopyTypeInto(type, exp.op.exp1.destType);
1264                type.passAsTemplate = false;
1265                FreeType(exp.op.exp1.destType);
1266                exp.op.exp1.destType = type;
1267             }
1268             // TEST: if(exp.op.exp2) exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1269             ProcessExpression(exp.op.exp1);
1270             // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1271          }
1272
1273          if(exp.op.exp2)
1274          {
1275             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)
1276             {
1277                Type type { };
1278                CopyTypeInto(type, exp.op.exp2.destType);
1279                type.passAsTemplate = false;
1280                FreeType(exp.op.exp2.destType);
1281                exp.op.exp2.destType = type;
1282             }
1283
1284             // Don't use the temporaries used by the left side...
1285             if(exp.op.exp1)
1286                // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1287                exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1288             ProcessExpression(exp.op.exp2);
1289             // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1290          }
1291          break;
1292       }
1293       case extensionExpressionExp:
1294       case bracketsExp:
1295       {
1296          Expression e;
1297          for(e = exp.list->first; e; e = e.next)
1298          {
1299             e.tempCount = Max(e.tempCount, exp.tempCount);
1300             if(!e.next)
1301             {
1302                e.usage |= (exp.usage & (ExpUsage { usageGet = true, usageArg = true }));
1303             }
1304             ProcessExpression(e);
1305             if(!e.next && e.expType && e.expType.passAsTemplate && exp.expType && !exp.expType.passAsTemplate)
1306                modifyPassAsTemplate(&exp.expType, true);
1307             exp.tempCount = Max(exp.tempCount, e.tempCount);
1308          }
1309          break;
1310       }
1311       case indexExp:
1312       {
1313          Expression e;
1314
1315          exp.index.exp.usage.usageGet = true;
1316          ProcessExpression(exp.index.exp);
1317          for(e = exp.index.index->first; e; e = e.next)
1318          {
1319             if(!e.next)
1320                e.usage.usageGet = true;
1321             ProcessExpression(e);
1322          }
1323          // Ignore temps in the index for now...
1324          exp.tempCount = exp.index.exp.tempCount;
1325          /*
1326          if(exp.index.exp.expType)
1327          {
1328             Type source = exp.index.exp.expType;
1329             if(source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1330                eClass_IsDerived(source._class.registered, containerClass))
1331             {
1332                Class _class = source._class.registered;
1333                // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1334
1335                char iteratorType[1024];
1336                OldList * declarations = MkList();
1337                OldList * statements = MkList();
1338                OldList * args = MkList();
1339                OldList * instMembers = MkList();
1340                Expression expExt;
1341                Context context = PushContext();
1342
1343                sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1344
1345                ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1346
1347                ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1348                   MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1349
1350                ListAdd(args, MkExpBrackets(exp.index.index));
1351                ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1352
1353                ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1354                   MkIdentifier("Index")), args))));
1355
1356                ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1357
1358                exp.type = bracketsExp;
1359                exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1360                expExt.compound.compound.context = context;
1361                PopContext(context);
1362                expExt.usage = exp.usage;
1363                ProcessExpressionType(exp.list->first);
1364                ProcessExpression(exp.list->first);
1365             }
1366          }
1367          */
1368          break;
1369       }
1370       case callExp:
1371       {
1372          Expression e;
1373          //Method method = null;
1374
1375          ProcessExpression(exp.call.exp);
1376
1377          if(exp.call.arguments)
1378          {
1379             for(e = exp.call.arguments->first; e; e = e.next)
1380             {
1381                e.usage.usageGet = true;
1382                e.usage.usageArg = true;
1383
1384                // TEST: e.tempCount = Max(e.tempCount, exp.tempCount);
1385                ProcessExpression(e);
1386                // TEST: exp.tempCount = Max(exp.tempCount, e.tempCount);
1387             }
1388          }
1389          break;
1390       }
1391       case memberExp:
1392       {
1393          exp.member.exp.usage.usageGet = true;
1394          // Tweak for LinkList::first to be casted to proper type (e.g. Link) when accessing members
1395          if(exp.member.memberType == dataMember &&
1396             exp.member.exp.expType && exp.member.exp.expType.thisClassFrom && exp.member.exp.expType.kind == classType &&
1397             exp.member.exp.expType._class && exp.member.exp.expType._class.registered &&
1398             !eClass_IsDerived(exp.member.exp.expType.thisClassFrom, exp.member.exp.expType._class.registered))
1399             exp.member.exp.expType.passAsTemplate = true;
1400          ProcessExpression(exp.member.exp);
1401
1402          // Must do this here so we can set the MemberType of deep properties inside instantiations
1403          if(!exp.member.memberType)
1404          {
1405             Type type = exp.member.exp.expType;
1406             if((type && type.kind == classType && exp.member.member))
1407             {
1408                // Check if it's an instance
1409                Class _class = (exp.member.member._class && exp.member.member.classSym) ? exp.member.member.classSym.registered : (type._class ? type._class.registered : null);
1410                Property prop = null;
1411                Method method = null;
1412                DataMember member = null;
1413                Property revConvert = null;
1414
1415                // Prioritize data members over properties for "this"
1416                if(exp.member.thisPtr)
1417                {
1418                   member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
1419                   if(!member)
1420                      prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
1421                }
1422                // Prioritize properties over data members otherwise
1423                else
1424                {
1425                   // Look for publicAccess Members first
1426                   prop = eClass_FindProperty(_class, exp.member.member.string, null);
1427                   if(!prop)
1428                      member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
1429                   if(!prop && !member)
1430                   {
1431                      method = eClass_FindMethod(_class, exp.member.member.string, null);
1432                      if(!method)
1433                      {
1434                         prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
1435                         if(!prop)
1436                            member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
1437                      }
1438                   }
1439                }
1440                if(!prop && !member && !method)     // NOTE: Recently added the !method here, causes private methods to unprioritized
1441                   method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
1442                if(!prop && !member && !method)
1443                {
1444                   Symbol classSym = FindClass(exp.member.member.string);
1445                   if(classSym)
1446                   {
1447                      Class convertClass = classSym.registered;
1448                      if(convertClass)
1449                         revConvert = eClass_FindProperty(convertClass, _class.fullName, privateModule);
1450                   }
1451                }
1452
1453                if(prop)
1454                {
1455                   exp.member.memberType = propertyMember;
1456                   if(!prop.dataType)
1457                      prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1458
1459                   FreeType(exp.expType);
1460                   exp.expType = prop.dataType;
1461                   if(prop.dataType) prop.dataType.refCount++;
1462                }
1463                else if(method)
1464                {
1465                   exp.member.memberType = methodMember;
1466                   if(!method.dataType)
1467                      //method.dataType = ((Symbol)method.symbol).type;
1468                      ProcessMethodType(method);
1469
1470                   FreeType(exp.expType);
1471                   exp.expType = method.dataType;
1472                   if(method.dataType) method.dataType.refCount++;
1473                }
1474                else if(member)
1475                {
1476                   exp.member.memberType = dataMember;
1477                   DeclareStruct(curExternal, _class.fullName, false, true);
1478                   if(!member.dataType)
1479                      member.dataType = ProcessTypeString(member.dataTypeString, false);
1480
1481                   FreeType(exp.expType);
1482                   exp.expType = member.dataType;
1483                   if(member.dataType) member.dataType.refCount++;
1484                }
1485                else if(revConvert)
1486                {
1487                   exp.member.memberType = reverseConversionMember;
1488
1489                   FreeType(exp.expType);
1490                   exp.expType = MkClassType(revConvert._class.fullName);
1491                }/*
1492                else
1493                   printf($"Error: Couldn't find member %s in class %s\n",
1494                      exp.member.member.string, _class.name);*/
1495             }
1496          }
1497          break;
1498       }
1499       case typeSizeExp:
1500          break;
1501       case castExp:
1502       {
1503          //exp.cast.exp.usage.usageGet = true;
1504          exp.cast.exp.usage |= exp.usage;
1505          ProcessExpression(exp.cast.exp);
1506          break;
1507       }
1508       case conditionExp:
1509       {
1510          Expression e;
1511          if(exp.usage.usageGet)
1512             exp.cond.cond.usage.usageGet = true;
1513
1514          ProcessExpression(exp.cond.cond);
1515          for(e = exp.cond.exp->first; e; e = e.next)
1516          {
1517             if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
1518             ProcessExpression(e);
1519          }
1520          if(exp.cond.elseExp)
1521          {
1522             if(exp.usage.usageGet) exp.cond.elseExp.usage.usageGet = true;
1523             ProcessExpression(exp.cond.elseExp);
1524          }
1525          break;
1526       }
1527       case extensionCompoundExp:
1528       {
1529          if(exp.compound.compound.statements &&
1530          ((Statement)exp.compound.compound.statements->last).type == expressionStmt &&
1531          ((Statement)exp.compound.compound.statements->last).expressions &&
1532          ((Statement)exp.compound.compound.statements->last).expressions->last)
1533          {
1534             ((Expression)((Statement)exp.compound.compound.statements->last).expressions->last).usage = exp.usage;
1535          }
1536          ProcessStatement(exp.compound);
1537          break;
1538       }
1539       case vaArgExp:
1540       {
1541          ProcessExpression(exp.vaArg.exp);
1542          break;
1543       }
1544       case extensionInitializerExp:
1545       {
1546          ProcessInitializer(exp.initializer.initializer);
1547          break;
1548       }
1549    }
1550    CheckTemplateTypes(exp);
1551 }
1552
1553 static void ProcessInitializer(Initializer init)
1554 {
1555    switch(init.type)
1556    {
1557       case expInitializer:
1558          init.exp.usage.usageGet = true;
1559          ProcessExpression(init.exp);
1560          break;
1561       case listInitializer:
1562       {
1563          Initializer i;
1564          for(i = init.list->first; i; i = i.next)
1565             ProcessInitializer(i);
1566          break;
1567       }
1568    }
1569 }
1570
1571 static void ProcessSpecifier(Specifier spec)
1572 {
1573    switch(spec.type)
1574    {
1575       case baseSpecifier:
1576          break;
1577       case nameSpecifier:
1578       {
1579          break;
1580       }
1581       case enumSpecifier:
1582       {
1583          Enumerator e;
1584          if(spec.list)
1585          {
1586             for(e = spec.list->first; e; e = e.next)
1587             {
1588                if(e.exp)
1589                   ProcessExpression(e.exp);
1590             }
1591          }
1592          break;
1593       }
1594       case structSpecifier:
1595       case unionSpecifier:
1596       {
1597          //Declaration decl;
1598          if(spec.definitions)
1599          {
1600             ClassDef def;
1601             for(def = spec.definitions->first; def; def = def.next)
1602             {
1603                if(def.type == declarationClassDef && def.decl && def.decl.type == structDeclaration)
1604                   ProcessDeclaration(def.decl);
1605             }
1606          }
1607          break;
1608       }
1609       /*
1610       case SpecifierClass:
1611       {
1612          break;
1613       }*/
1614    }
1615 }
1616
1617 static bool ProcessBracketInst_DataMember(DataMember parentMember, Instantiation inst, OldList list, DataMember namedParentMember, bool parentMemberSet)
1618 {
1619    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1620    DataMember dataMember = null;
1621    bool someMemberSet = false;
1622    int anonID = 1;
1623
1624    // For simple classes, ensure all members are initialized
1625    for(dataMember = parentMember.members.first; dataMember; dataMember = dataMember.next)
1626    {
1627       MembersInit members;
1628       MemberInit member = null;
1629
1630       if(!dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
1631       {
1632          OldList * subList = MkList(); //(dataMember.type == structMember) ? MkList() : null;
1633
1634          if(!ProcessBracketInst_DataMember(dataMember, inst, subList ? subList : list, dataMember.name ? dataMember : namedParentMember, someMemberSet || parentMemberSet || dataMember.prev))
1635          {
1636             if(subList)
1637                FreeList(subList, FreeInitializer);
1638
1639             return false;
1640          }
1641          if(subList && subList->count)
1642          {
1643             Initializer init = MkInitializerList(subList);
1644             char id[100];
1645             sprintf(id, "__anon%d", anonID);
1646             init.id = MkIdentifier(id);
1647             ListAdd(list, init);
1648             someMemberSet = true;
1649          }
1650          else
1651          {
1652             if(list.count)
1653                someMemberSet = true;
1654             delete subList;
1655          }
1656          anonID++;
1657       }
1658       else
1659       {
1660          Class curClass = null;
1661          DataMember curMember = null;
1662          DataMember subMemberStack[256];
1663          int subMemberStackPos = 0;
1664          bool found = false;
1665
1666          if(inst.members && inst.members->first)
1667          {
1668             for(members = inst.members->first; members; members = members.next)
1669             {
1670                if(members.type == dataMembersInit)
1671                {
1672                   for(member = members.dataMembers->first; member; member = member.next)
1673                   {
1674                      if(member.identifiers)
1675                      {
1676                         Identifier firstID = member.identifiers->first;
1677
1678                         DataMember _subMemberStack[256];
1679                         int _subMemberStackPos = 0;
1680                         DataMember thisMember;
1681                         thisMember = firstID ? (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule) : null;
1682                         // FILL MEMBER STACK
1683                         if(!thisMember && firstID)
1684                            thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
1685                         if(thisMember && thisMember.memberAccess == publicAccess)
1686                         {
1687                            curMember = thisMember;
1688                            curClass = curMember._class;
1689                            memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
1690                            subMemberStackPos = _subMemberStackPos;
1691                         }
1692                         /*
1693                         BTNamedLink link = parentMember.membersAlpha.Find((uintptr)firstID.string);
1694                         if(link)
1695                         {
1696                            curMember = link.data;
1697                         }
1698
1699                         // Choose the first specified member of the union...
1700                         if(parentMember.type == unionMember)
1701                         {
1702                            if(link)
1703                               dataMember = curMember;
1704                         }
1705                         */
1706
1707                         if(dataMember == thisMember)
1708                         {
1709                            // Look for another member of this one and merge them
1710                            // into one instantiation...
1711                            if(member.identifiers->count > 1 && member.initializer && member.initializer.type == expInitializer)
1712                            {
1713                               OldList * partList = MkList();
1714                               // TODO: We're assuming this is a simple class right now...
1715                               Symbol symbol;
1716                               Specifier spec;
1717                               MembersInit nextMembers;
1718                               MemberInit next = member.next;
1719
1720                               if(!dataMember.dataType)
1721                                  dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1722                               symbol = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null;
1723                               spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, symbol, null);
1724
1725                               {
1726                                  OldList * identifiers = MkList();
1727                                  Identifier id;
1728                                  for(id = ((Identifier)member.identifiers->first).next; id; id = id.next)
1729                                     identifiers->Add(CopyIdentifier(id));
1730
1731                                  // *** THE IDENTIFIERS WERE BEING REUSED, CAUSING A CRASH WITH EXPRESSION TEMPLATE CODE IN pass1.ec ***
1732                                  // members->Add(MkMemberInit(ids, MkInitializerAssignment(MkExpConstant(ui64String))));
1733                                  /*member.identifiers->Remove(firstID);*/
1734                                  ListAdd(partList,
1735                                     MkMemberInit(/*member.identifiers*/identifiers, MkInitializerAssignment(member.initializer.exp)));
1736                               }
1737
1738                               for(nextMembers = members; nextMembers; nextMembers = nextMembers.next)
1739                               {
1740                                  if(!nextMembers.dataMembers)
1741                                     continue;
1742
1743                                  if(members != nextMembers) next = nextMembers.dataMembers->first;
1744
1745                                  if(nextMembers.type == dataMembersInit)
1746                                  {
1747                                     MemberInit nextMember;
1748
1749                                     for(nextMember = next; nextMember;
1750                                         nextMember = next, next = nextMember ? nextMember.next : null)
1751                                     {
1752                                        Identifier nextID = nextMember.identifiers->first;
1753                                        if(nextMember.identifiers &&
1754                                           nextMember.identifiers->count > 1 &&
1755                                           !strcmp(firstID.string, nextID.string))
1756                                        {
1757                                           nextMembers.dataMembers->Remove(nextMember);
1758                                           nextMember.identifiers->Remove(nextID);
1759                                           ListAdd(partList, nextMember);
1760                                           FreeIdentifier(nextID);
1761                                        }
1762                                     }
1763                                  }
1764                               }
1765
1766                               member.initializer.exp = MkExpInstance(MkInstantiation(spec, null,
1767                                  MkListOne(MkMembersInitList(partList))));
1768                            }
1769                            found = true;
1770                            break;
1771                         }
1772                      }
1773                      else
1774                      {
1775                         eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
1776                         if(curMember == dataMember)
1777                         {
1778                            found = true;
1779                            break;
1780                         }
1781
1782                         /*
1783                         if(curMember)
1784                            curMember = curMember.next;
1785                         else
1786                            curMember = parentMember.members.first;
1787
1788                         if(curMember == dataMember)
1789                         {
1790                            found = true;
1791                            break;
1792                         }
1793                         */
1794                      }
1795                   }
1796                }
1797                if(found) break;
1798             }
1799          }
1800
1801          if(member && member.initializer && member.initializer.type == expInitializer)
1802          {
1803             Initializer init { loc = yylloc };
1804             if(namedParentMember.type == unionMember && dataMember.name)
1805                init.id = MkIdentifier(dataMember.name);
1806
1807             if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
1808                member.initializer.exp.expType._class.registered.type == structClass)
1809             {
1810                OldList * subList = MkList();
1811                ProcessBracketInst(member.initializer.exp.instance, subList);
1812                FreeExpression(member.initializer.exp);
1813                if(subList->count)
1814                {
1815                   init.type = listInitializer;
1816                   init.list = subList;
1817                }
1818                else
1819                {
1820                   FreeInitializer(init);
1821                   init = null;
1822                }
1823             }
1824             else
1825             {
1826                member.initializer.exp.usage.usageGet = true;
1827                ProcessExpression(member.initializer.exp);
1828                init.type = expInitializer;
1829                init.exp = member.initializer.exp;
1830             }
1831             if(init)
1832                ListAdd(list, init);
1833
1834             member.initializer.exp = null;
1835             FreeInitializer(member.initializer);
1836             member.initializer = null;
1837             someMemberSet = true;
1838          }
1839          else if(member && member.initializer && member.initializer.type == listInitializer)
1840          {
1841             if(namedParentMember.type == unionMember && dataMember.name)
1842                member.initializer.id = MkIdentifier(dataMember.name);
1843
1844             ListAdd(list, member.initializer);
1845             member.initializer = null;
1846             someMemberSet = true;
1847          }
1848          else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/ && parentMember.type != unionMember && namedParentMember.type != unionMember)
1849          {
1850             Symbol classSym;
1851             Initializer init { loc = yylloc };
1852             if(namedParentMember.type == unionMember && dataMember.name)
1853                init.id = MkIdentifier(dataMember.name);
1854
1855             if(!dataMember.dataType)
1856                dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1857             classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1858             if(classSym && classSym.registered && classSym.registered.type == structClass)
1859             {
1860                OldList * subList = MkList();
1861                Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null);
1862                Instantiation inst = MkInstantiation(spec, null, null);
1863                ProcessBracketInst(inst, subList);
1864                FreeInstance(inst);
1865
1866                if(subList->count)
1867                {
1868                   init.type = listInitializer;
1869                   init.list = subList;
1870                }
1871                else
1872                {
1873                   FreeInitializer(init);
1874                   init = null;
1875                }
1876             }
1877             else
1878             {
1879                init.type = expInitializer;
1880                init.exp = MkExpConstant("0");
1881             }
1882             someMemberSet = true;
1883             if(init)
1884                ListAdd(list, init);
1885          }
1886       }
1887       /*
1888       if(parentMember.type == unionMember)
1889          break;
1890       */
1891    }
1892    // TESTING THIS NEW CODE FOR ANCHORS...
1893    if(/*parentMember.type == unionMember && */!someMemberSet && !parentMemberSet)
1894    {
1895       Symbol classSym;
1896       Initializer init { loc = yylloc };
1897
1898       dataMember = parentMember.members.first;
1899       if(namedParentMember.type == unionMember && dataMember.name)
1900          init.id = MkIdentifier(dataMember.name);
1901
1902       if(!dataMember.dataType && dataMember.dataTypeString)
1903          dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1904       classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1905       if(classSym && classSym.registered && classSym.registered.type == structClass)
1906       {
1907          OldList * subList = MkList();
1908          Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null);
1909          Instantiation inst = MkInstantiation(spec, null, null);
1910          ProcessBracketInst(inst, subList);
1911          FreeInstance(inst);
1912
1913          init.type = listInitializer;
1914          init.list = subList;
1915       }
1916       else if(dataMember.dataType && (dataMember.dataType.kind == arrayType || dataMember.dataType.kind == structType))
1917       {
1918          Type t = dataMember.dataType.kind == arrayType ? dataMember.dataType.type : dataMember.dataType.members.first;
1919          Initializer i = MkInitializerAssignment(MkExpConstant("0"));
1920          while(t && (t.kind == arrayType || t.kind == structType))
1921          {
1922             i = MkInitializerList(MkListOne(i));
1923             if(t.kind == arrayType)
1924                t = t.type;
1925             else if(t.kind == structType)
1926                t = t.members.first;
1927          }
1928          init.type = listInitializer;
1929          init.list = MkListOne(i);
1930       }
1931       else
1932       {
1933          init.type = expInitializer;
1934          init.exp = MkExpConstant("0");
1935       }
1936       ListAdd(list, init);
1937    }
1938    return true;
1939 }
1940
1941 static bool ProcessBracketInst(Instantiation inst, OldList list)
1942 {
1943    static int recursionCount = 0;
1944    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1945    Class _class = null;
1946    int anonID = 1;
1947
1948    if(recursionCount > 500) return false;
1949    recursionCount++;
1950
1951    while(_class != classSym.registered)
1952    {
1953       DataMember dataMember;
1954       Class lastClass = _class;
1955
1956       for(_class = classSym.registered; _class.base != lastClass && _class.base.type != systemClass; _class = _class.base);
1957
1958       for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
1959       {
1960          if(!dataMember.isProperty && !dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
1961          {
1962             OldList * subList = MkList(); //(dataMember.type == structMember ? MkList() : null);
1963
1964             if(!ProcessBracketInst_DataMember(dataMember, inst, subList ? subList : list, dataMember, false))
1965             {
1966                if(subList)
1967                   FreeList(subList, FreeInitializer);
1968                recursionCount--;
1969                return false;
1970             }
1971             if(dataMember.type == structMember || (subList && subList->count))
1972             {
1973                Initializer init = MkInitializerList(subList);
1974                char id[100];
1975                sprintf(id, "__anon%d", anonID);
1976                init.id = MkIdentifier(id);
1977                ListAdd(list, init);
1978             }
1979             else
1980                delete subList;
1981             anonID ++;
1982          }
1983          else
1984          {
1985             MembersInit members;
1986             MemberInit member = null;
1987             bool found = false;
1988
1989             if(inst.members && inst.members->first)
1990             {
1991                DataMember curMember = null;
1992                Class curClass = null;
1993                DataMember subMemberStack[256];
1994                int subMemberStackPos = 0;
1995
1996                for(members = inst.members->first; members; members = members.next)
1997                {
1998                   if(members.type == dataMembersInit)
1999                   {
2000                      for(member = members.dataMembers->first; member; member = member.next)
2001                      {
2002                         Identifier firstID = member.identifiers ? member.identifiers->first : null;
2003                         if(firstID)
2004                         {
2005                            DataMember _subMemberStack[256];
2006                            int _subMemberStackPos = 0;
2007                            DataMember thisMember = (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule);
2008                            // FILL MEMBER STACK
2009                            if(!thisMember)
2010                               thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
2011                            if(thisMember)
2012                            {
2013                               curMember = thisMember;
2014                               curClass = curMember._class;
2015                               memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
2016                               subMemberStackPos = _subMemberStackPos;
2017                            }
2018
2019                            if(curMember == dataMember)
2020                            {
2021                               if(dataMember.isProperty)
2022                               {
2023                                  if(!((Property)dataMember).Set)
2024                                  {
2025                                     Compiler_Error($"No set defined for property %s\n", dataMember.name);
2026                                     continue;
2027                                  }
2028                                  recursionCount--;
2029                                  return false;
2030                               }
2031
2032                               // Look for another member of this one and merge them
2033                               // into one instantiation...
2034                               if(member.identifiers->count > 1 && member.initializer && member.initializer.type == expInitializer)
2035                               {
2036                                  OldList * partList = MkList();
2037                                  // TODO: We're assuming this is a simple _class right now...
2038                                  Specifier spec;
2039                                  MembersInit nextMembers;
2040                                  MemberInit next = member.next;
2041                                  Symbol symbol;
2042                                  if(!dataMember.dataType)
2043                                     dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
2044                                  symbol = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null;
2045                                  spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, symbol, null);
2046
2047                                  member.identifiers->Remove(firstID);
2048                                  ListAdd(partList,
2049                                     MkMemberInit(member.identifiers, MkInitializerAssignment(member.initializer.exp)));
2050
2051                                  for(nextMembers = members; nextMembers; nextMembers = nextMembers.next)
2052                                  {
2053                                     if(!nextMembers.dataMembers) continue;
2054
2055                                     if(members != nextMembers) next = nextMembers.dataMembers->first;
2056
2057                                     if(nextMembers.type == dataMembersInit)
2058                                     {
2059                                        MemberInit nextMember;
2060
2061                                        for(nextMember = next; nextMember;
2062                                            nextMember = next, next = nextMember ? nextMember.next : null)
2063                                        {
2064                                           Identifier nextID = nextMember.identifiers->first;
2065                                           if(nextMember.identifiers &&
2066                                              nextMember.identifiers->count > 1 &&
2067                                              !strcmp(firstID.string, nextID.string))
2068                                           {
2069                                              nextMembers.dataMembers->Remove(nextMember);
2070                                              nextMember.identifiers->Remove(nextID);
2071                                              ListAdd(partList, nextMember);
2072                                              FreeIdentifier(nextID);
2073                                           }
2074                                        }
2075                                     }
2076                                  }
2077
2078                                  member.initializer.exp = MkExpInstance(MkInstantiation(spec, null,
2079                                     MkListOne(MkMembersInitList(partList))));
2080
2081                                  FreeIdentifier(firstID);
2082                                  // TESTING THIS
2083                                  member.identifiers = null;
2084                               }
2085                               found = true;
2086                               break;
2087                            }
2088                         }
2089                         else
2090                         {
2091                            eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
2092                            if(curMember == dataMember)
2093                            {
2094                               if(dataMember.isProperty)
2095                               {
2096                                  if(!((Property)dataMember).Set)
2097                                  {
2098                                     Compiler_Error($"No set defined for property %s\n", dataMember.name);
2099                                     continue;
2100                                  }
2101                                  recursionCount--;
2102                                  return false;
2103                               }
2104                               found = true;
2105                               break;
2106                            }
2107                         }
2108                      }
2109                   }
2110                   if(found) break;
2111                }
2112             }
2113
2114             if(dataMember.isProperty) continue;
2115             if(member && member.initializer && member.initializer.type == expInitializer)
2116             {
2117                if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
2118                   member.initializer.exp.expType._class && member.initializer.exp.expType._class.registered && member.initializer.exp.expType._class.registered.type == structClass)
2119                {
2120                   OldList * subList = MkList();
2121                   ProcessBracketInst(member.initializer.exp.instance, subList);
2122                   FreeExpression(member.initializer.exp);
2123                   member.initializer.exp = null;
2124                   ListAdd(list, MkInitializerList(subList));
2125                }
2126                else
2127                {
2128                   member.initializer.exp.usage.usageGet = true;
2129                   ProcessExpression(member.initializer.exp);
2130                   ListAdd(list, MkInitializerAssignment(CopyExpression(member.initializer.exp)));
2131                }
2132
2133                // Take this out
2134                // member.exp = null;
2135                member.takeOutExp = true;
2136             }
2137             else if(member && member.initializer && member.initializer.type == listInitializer)
2138             {
2139                ListAdd(list, member.initializer);
2140                member.initializer = null;
2141             }
2142             else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/)
2143             {
2144                Symbol classSym;
2145
2146                if(!dataMember.dataType)
2147                   dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
2148                classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
2149
2150                if(classSym && classSym.registered && classSym.registered.type == structClass)
2151                {
2152                   OldList * subList = MkList();
2153                   Specifier spec = _MkSpecifierName(dataMember.dataTypeString, classSym, null);
2154                   Instantiation inst = MkInstantiation(spec, null, null);
2155                   ProcessBracketInst(inst, subList);
2156                   FreeInstance(inst);
2157                   ListAdd(list, MkInitializerList(subList));
2158                }
2159                else if(dataMember.dataType.kind == arrayType)
2160                {
2161                   Type t = dataMember.dataType.type;
2162                   Initializer inner = MkInitializerAssignment(null), i = inner;
2163                   while(t && t.kind == arrayType)
2164                   {
2165                      i = MkInitializerList(MkListOne(i));
2166                      t = t.type;
2167                   }
2168                   if(t && t.kind == classType && t._class && t._class.registered && t._class.registered.type == structClass)
2169                   {
2170                      OldList * subList = MkList();
2171                      Specifier spec = _MkSpecifierName(t._class.registered.name, classSym, null);
2172                      Instantiation inst = MkInstantiation(spec, null, null);
2173                      ProcessBracketInst(inst, subList);
2174                      FreeInstance(inst);
2175                      inner.type = listInitializer;
2176                      inner.list = subList;
2177                   }
2178                   else
2179                      inner.exp = MkExpConstant("0");
2180                   ListAdd(list,  MkInitializerList(MkListOne(i)));
2181                }
2182                else
2183                   ListAdd(list, MkInitializerAssignment(MkExpConstant("0")));
2184             }
2185          }
2186       }
2187    }
2188
2189    if(inst.members && inst.members->first)
2190    {
2191       MembersInit members;
2192       MemberInit member = null;
2193
2194       for(members = inst.members->first; members; members = members.next)
2195       {
2196          if(members.type == dataMembersInit)
2197          {
2198             for(member = members.dataMembers->first; member; member = member.next)
2199             {
2200                if(member.takeOutExp)
2201                {
2202                   FreeInitializer(member.initializer);
2203                   member.initializer = null;
2204                }
2205             }
2206          }
2207       }
2208    }
2209    recursionCount--;
2210    return true;
2211 }
2212
2213 static Declaration curDecl;
2214 static int declTempCount;
2215
2216 static void ProcessDeclaration(Declaration decl)
2217 {
2218    yylloc = decl.loc;
2219    switch(decl.type)
2220    {
2221       case initDeclaration:
2222       {
2223          if(!curDecl) { curDecl = decl; declTempCount = 0; }
2224          if(decl.specifiers)
2225          {
2226             Specifier s;
2227             for(s = decl.specifiers->first; s; s = s.next)
2228             {
2229                ProcessSpecifier(s);
2230             }
2231          }
2232          if(decl.declarators)
2233          {
2234             InitDeclarator d;
2235
2236             for(d = decl.declarators->first; d; d = d.next)
2237             {
2238               if(d.initializer)
2239                   ProcessInitializer(d.initializer);
2240             }
2241          }
2242          if(curDecl == decl) { curDecl = null; declTempCount = 0; }
2243          break;
2244       }
2245       case instDeclaration:
2246       {
2247          Instantiation inst = decl.inst;
2248
2249          if(inCompiler)
2250          {
2251             Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
2252             if(!curCompound)
2253             {
2254                Statement stmt;
2255
2256                if(!inst.isConstant || (classSym && classSym.registered && (classSym.registered.type == normalClass || classSym.registered.type == noHeadClass)))
2257                {
2258                   // If this instantiation is outside, turn it into a declaration plus an instantiation expression
2259                   decl.type = initDeclaration;
2260                   decl.specifiers = MkListOne(MkSpecifierName/*MkClassName*/(inst._class.name));
2261                   if(decl.declMode == staticAccess)
2262                   {
2263                      decl.specifiers->Insert(null, MkSpecifier(STATIC));
2264                   }
2265                   decl.declarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(inst.exp.identifier.string)), null));
2266
2267                   ProcessDeclaration(decl);
2268                   CreateInstancesBody();
2269
2270                   {
2271                      Expression exp = MkExpInstance(inst);
2272                      stmt = MkExpressionStmt(MkListOne(exp));       // MkExpOp(inst.exp, '=',
2273                      ListAdd(createInstancesBody.compound.statements, stmt);
2274                      ProcessExpressionType(exp);
2275                   }
2276
2277                   if(classSym && classSym.registered && (classSym.registered.type == normalClass))
2278                   {
2279                      ListAdd(createInstancesBody.compound.statements,
2280                         MkExpressionStmt(MkListOne(MkExpCall(
2281                            MkExpIdentifier(MkIdentifier("ecere::com::eInstance_IncRef")),
2282                            MkListOne(CopyExpression(inst.exp))))));
2283
2284                      // We'd like the = 0 as well...
2285                      {
2286                         Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2287                         ListAddFront(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2288                         ProcessExpressionType(exp);
2289                      }
2290                   }
2291                   else if(classSym && classSym.registered && (classSym.registered.type == noHeadClass))
2292                   {
2293                      Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2294                      ListAddFront(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2295                      ProcessExpressionType(exp);
2296                   }
2297
2298                   createInstancesExternal.CreateEdge(curExternal, false);
2299                   destroyInstancesExternal.CreateEdge(curExternal, false);
2300                   break;
2301                }
2302                else
2303                {
2304                   // Precompiler won't know if this isn't constant
2305                   CreateInstancesBody();
2306                }
2307             }
2308
2309             {
2310                char className[1024];
2311                className[0] = 0;
2312
2313                decl.type = initDeclaration;
2314                decl.specifiers = MkList();
2315                decl.declarators = MkList();
2316
2317                // Replace instantiation here
2318                if(classSym && classSym.registered && classSym.registered.type == bitClass)
2319                {
2320                   OldList list = { 0 };
2321
2322                   // Put the instantiation in an InitDeclarator...
2323                   ProcessInstMembers(inst, inst.exp, &list, false);
2324                   ProcessExpression(inst.exp);
2325
2326                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2327                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2328                      MkInitializerAssignment(list.first)));
2329                   inst.exp.identifier = null;
2330                }
2331                else if(classSym && classSym.registered && classSym.registered.type == unitClass)
2332                {
2333                   OldList list = { 0 };
2334
2335                   // Put the instantiation in an InitDeclarator...
2336                   ProcessInstMembers(inst, inst.exp, &list, false);
2337                   ProcessExpression(inst.exp);
2338
2339                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2340                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2341                      MkInitializerAssignment(list.first)));
2342
2343                   inst.exp.identifier = null;
2344                }
2345                else if(classSym && classSym.registered && classSym.registered.type == structClass)
2346                {
2347                   Expression exp;
2348
2349                   DeclareStruct(curExternal, inst._class.name, false, true);
2350                   /*{
2351                      strcpy(className, "__ecereClass_");
2352                      FullClassNameCat(className, classSym.string, true);
2353                      DeclareClass(classSym, className);
2354                   }*/
2355
2356                   ProcessExpression(inst.exp);
2357
2358                   // Put the instantiation in an InitDeclarator...
2359                   {
2360                      if(inst.fullSet)
2361                      {
2362                         ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2363                         ListAdd(decl.declarators,
2364                            MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier), null));
2365                         inst.exp.identifier = null;
2366                      }
2367                      else
2368                      {
2369                         OldList * list = MkList();
2370                         if(ProcessBracketInst(inst, list))
2371                         {
2372                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2373                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2374                               MkInitializerList(list)));
2375                            inst.exp.identifier = null;
2376                         }
2377                         else
2378                         {
2379                            // If bracket instantiation failed (property: for conversions only?)
2380                            // TODO: (Fix this so it initializes members through brackets,
2381                            //        and then does properties)
2382                            //list->Free(null);
2383                            //delete list;
2384                            // TESTING THIS MEMORY LEAK FIX:
2385                            FreeList(list, FreeInitializer);
2386
2387                            exp = MkExpBrackets(MkList());
2388                            ProcessInstMembers(inst, inst.exp, exp.list, true);
2389                            ListAdd(exp.list, CopyExpression(inst.exp));
2390                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2391                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2392                               MkInitializerAssignment(exp)));
2393                            inst.exp.identifier = null;
2394                         }
2395                      }
2396                   }
2397                }
2398                else
2399                {
2400                   Expression newCall;
2401
2402                   strcpy(className, "__ecereClass_");
2403
2404                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass && classSym.registered.templateClass)
2405                   {
2406                      classSym = FindClass(classSym.registered.templateClass.fullName);
2407                      FullClassNameCat(className, classSym.string, true);
2408                   }
2409                   else
2410                      FullClassNameCat(className, inst._class.name, true);
2411
2412                   if(classSym)
2413                      DeclareClass(curExternal, classSym, className);
2414
2415                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass &&
2416                      (classSym.registered.templateClass ? classSym.registered.templateClass.fixed : classSym.registered.fixed))
2417                   {
2418                      char size[256];
2419                      Class c = classSym.registered.templateClass ? classSym.registered.templateClass : classSym.registered;
2420                      Expression e = MkExpClassSize(MkSpecifierName(c.name));
2421                      ProcessExpressionType(e);
2422                      sprintf(size, "%d", c.structSize);
2423                      newCall = MkExpCall(QMkExpId("ecere::com::eSystem_New0"), MkListOne( e /*MkExpConstant(size)*/));
2424                   }
2425                   else
2426                   {
2427                      newCall = MkExpCall(QMkExpId("ecere::com::eInstance_New"), MkListOne(QMkExpId(className)));
2428                      ProcessExpressionType(newCall);
2429                      newCall.byReference = true;
2430                   }
2431
2432                   if(inst.exp)
2433                   {
2434                      Expression exp, newExp;
2435                      Identifier id = CopyIdentifier(inst.exp.identifier);
2436
2437                      // Put the instantiation in an InitDeclarator...
2438                      if(inst.members && inst.members->first)
2439                      {
2440                         newExp = MkExpOp(CopyExpression(inst.exp), '=', newCall);
2441
2442                         exp = MkExpBrackets(MkList());
2443                         ListAdd(exp.list, newExp);
2444                         ProcessInstMembers(inst, inst.exp, exp.list, false);
2445                         ListAdd(exp.list, inst.exp);
2446
2447                         ProcessExpression(inst.exp);
2448
2449                         // Take it out since we're using it...
2450                         inst.exp = null;
2451                      }
2452                      else
2453                         exp = newCall;
2454
2455                      ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2456                      ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(id),
2457                         MkInitializerAssignment(exp)));
2458                      //inst.exp.identifier = null;
2459                   }
2460                   else
2461                      FreeExpression(newCall);
2462                }
2463             }
2464             FreeInstance(inst);
2465          }
2466          else
2467             ProcessInstantiation(inst);
2468          break;
2469       }
2470       case structDeclaration:
2471       {
2472          if(decl.specifiers)
2473          {
2474             Specifier spec;
2475             for(spec = decl.specifiers->first; spec; spec = spec.next)
2476                ProcessSpecifier(spec);
2477          }
2478          break;
2479       }
2480    }
2481 }
2482
2483 static void ProcessStatement(Statement stmt)
2484 {
2485    yylloc = stmt.loc;
2486    switch(stmt.type)
2487    {
2488       case labeledStmt:
2489          if(stmt.labeled.stmt)
2490             ProcessStatement(stmt.labeled.stmt);
2491          break;
2492       case caseStmt:
2493          if(stmt.caseStmt.exp)
2494             ProcessExpression(stmt.caseStmt.exp);
2495          if(stmt.caseStmt.stmt)
2496             ProcessStatement(stmt.caseStmt.stmt);
2497          break;
2498       case compoundStmt:
2499       {
2500          if(stmt.compound.context)
2501          {
2502             Declaration decl;
2503             Statement s;
2504             Statement prevCompound = curCompound;
2505             Context prevContext = curContext;
2506
2507             if(!stmt.compound.isSwitch)
2508             {
2509                curCompound = stmt;
2510                curContext = stmt.compound.context;
2511             }
2512
2513             if(stmt.compound.declarations)
2514             {
2515                for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
2516                   ProcessDeclaration(decl);
2517             }
2518             if(stmt.compound.statements)
2519             {
2520                for(s = stmt.compound.statements->first; s; s = s.next)
2521                {
2522                   ProcessStatement(s);
2523                }
2524             }
2525
2526             curCompound = prevCompound;
2527             curContext = prevContext;
2528          }
2529          break;
2530       }
2531       case expressionStmt:
2532       {
2533          Expression exp;
2534          if(stmt.expressions)
2535          {
2536             for(exp = stmt.expressions->first; exp; exp = exp.next)
2537             {
2538                ProcessExpression(exp);
2539             }
2540          }
2541          break;
2542       }
2543       case ifStmt:
2544       {
2545          Expression exp;
2546
2547          ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
2548          for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
2549          {
2550             ProcessExpression(exp);
2551          }
2552          if(stmt.ifStmt.stmt)
2553             ProcessStatement(stmt.ifStmt.stmt);
2554          if(stmt.ifStmt.elseStmt)
2555             ProcessStatement(stmt.ifStmt.elseStmt);
2556          break;
2557       }
2558       case switchStmt:
2559       {
2560          Expression exp;
2561          ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
2562          for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
2563             ProcessExpression(exp);
2564          ProcessStatement(stmt.switchStmt.stmt);
2565          break;
2566       }
2567       case whileStmt:
2568       {
2569          if(stmt.whileStmt.exp)
2570          {
2571             Expression exp;
2572
2573             ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
2574             for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
2575             {
2576                ProcessExpression(exp);
2577             }
2578          }
2579          if(stmt.whileStmt.stmt)
2580             ProcessStatement(stmt.whileStmt.stmt);
2581          break;
2582       }
2583       case doWhileStmt:
2584       {
2585          if(stmt.doWhile.exp)
2586          {
2587             Expression exp;
2588             ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
2589             for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
2590             {
2591                ProcessExpression(exp);
2592             }
2593          }
2594          if(stmt.doWhile.stmt)
2595             ProcessStatement(stmt.doWhile.stmt);
2596          break;
2597       }
2598       case forStmt:
2599       {
2600          Expression exp;
2601          if(stmt.forStmt.init)
2602             ProcessStatement(stmt.forStmt.init);
2603
2604          if(stmt.forStmt.check && stmt.forStmt.check.expressions)
2605          {
2606             ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
2607          }
2608
2609          if(stmt.forStmt.check)
2610             ProcessStatement(stmt.forStmt.check);
2611          if(stmt.forStmt.increment)
2612          {
2613             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
2614                ProcessExpression(exp);
2615          }
2616          if(stmt.forStmt.stmt)
2617             ProcessStatement(stmt.forStmt.stmt);
2618          break;
2619       }
2620       case gotoStmt:
2621          break;
2622       case continueStmt:
2623          break;
2624       case breakStmt:
2625          break;
2626       case returnStmt:
2627       {
2628          Expression exp;
2629          if(stmt.expressions && stmt.expressions->last)
2630          {
2631             ((Expression)stmt.expressions->last).usage.usageGet = true;
2632             for(exp = stmt.expressions->first; exp; exp = exp.next)
2633             {
2634                ProcessExpression(exp);
2635             }
2636          }
2637          break;
2638       }
2639       case badDeclarationStmt:
2640       {
2641          ProcessDeclaration(stmt.decl);
2642          break;
2643       }
2644       case asmStmt:
2645       {
2646          AsmField field;
2647          if(stmt.asmStmt.inputFields)
2648          {
2649             for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
2650                if(field.expression)
2651                   ProcessExpression(field.expression);
2652          }
2653          if(stmt.asmStmt.outputFields)
2654          {
2655             for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
2656                if(field.expression)
2657                   ProcessExpression(field.expression);
2658          }
2659          if(stmt.asmStmt.clobberedFields)
2660          {
2661             for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
2662                if(field.expression)
2663                   ProcessExpression(field.expression);
2664          }
2665          break;
2666       }
2667    }
2668 }
2669 static void ProcessFunction(FunctionDefinition function)
2670 {
2671    if(function.body)
2672    {
2673       yylloc = function.loc;
2674       ProcessStatement(function.body);
2675    }
2676 }
2677
2678 /////////// INSTANTIATIONS / DATA TYPES PASS /////////////////////////////////////////////
2679 public void ProcessInstantiations()
2680 {
2681    External external;
2682    // Is this still needed?
2683    //CreateInstancesBody();
2684
2685    for(external = ast->first; external; external = external.next)
2686    {
2687       curExternal = external;
2688       if(external.type == declarationExternal)
2689       {
2690          //currentClass = external.function._class;
2691          if(external.declaration)
2692          {
2693             bool isInstance = external.declaration.type == instDeclaration;
2694             Symbol sym = isInstance ? FindClass(external.declaration.inst._class.name) : null;
2695             ProcessDeclaration(external.declaration);
2696
2697             if(isInstance)
2698             {
2699                // Move edges to the global instances to the create instance body instead
2700                TopoEdge e, next;
2701                for(e = external.incoming.first; e; e = next)
2702                {
2703                   External from = e.from;
2704
2705                   next = e.in.next;
2706
2707                   if(from.incoming.count)
2708                   {
2709                      bool reroute = true;
2710                      if(sym && sym.registered && sym.registered.type == structClass)
2711                         reroute = false;
2712                      else if(from.type == declarationExternal && from.declaration && (!from.declaration.declarators || !from.declaration.declarators->count) && from.declaration.specifiers)
2713                      {
2714                         Specifier spec = null;
2715                         for(spec = from.declaration.specifiers->first; spec; spec = spec.next)
2716                         {
2717                            if(spec.type == structSpecifier || spec.type == unionSpecifier)
2718                               break;
2719                         }
2720                         if(sym.registered && spec && spec.id && spec.id.string)
2721                         {
2722                            char className[1024];
2723                            Class c = sym.registered;
2724                            strcpy(className, "__ecereClass_");
2725                            if(c.type == noHeadClass && c.templateClass)
2726                               FullClassNameCat(className, c.templateClass.name, true);
2727                            else
2728                               FullClassNameCat(className, c.name, true);
2729                            if(!strcmp(c.name, spec.id.string))
2730                               reroute = false;
2731                         }
2732                      }
2733                      if(reroute)
2734                      {
2735                         bool skip = false;
2736                         e.to = createInstancesExternal;
2737                         external.incoming.Remove((IteratorPointer)e);
2738                         for(i : createInstancesExternal.incoming)
2739                         {
2740                            if(i.from == from)
2741                            {
2742                               skip = true;
2743                               if(i.breakable && !e.breakable)
2744                               {
2745                                  i.breakable = true;
2746                                  createInstancesExternal.nonBreakableIncoming++;
2747                               }
2748                               break;
2749                            }
2750                         }
2751                         if(skip)
2752                         {
2753                            external.nonBreakableIncoming--;
2754                            e.from.outgoing.Remove((IteratorPointer)e);
2755                            delete e;
2756                         }
2757                         else
2758                         {
2759                            createInstancesExternal.incoming.Add(e);
2760                            if(!e.breakable)
2761                            {
2762                               external.nonBreakableIncoming--;
2763                               createInstancesExternal.nonBreakableIncoming++;
2764                            }
2765                         }
2766                      }
2767                   }
2768                }
2769             }
2770          }
2771       }
2772       else if(external.type == functionExternal)
2773       {
2774          //currentClass = null;
2775          ProcessFunction(external.function);
2776       }
2777       else if(external.type == classExternal)
2778       {
2779          ClassDefinition _class = external._class;
2780          //currentClass = external.symbol.registered;
2781          if(_class.definitions)
2782          {
2783             ClassDef def;
2784             //Class regClass = _class.symbol.registered;
2785
2786             // Process all functions
2787             for(def = _class.definitions->first; def; def = def.next)
2788             {
2789                if(def.type == functionClassDef)
2790                {
2791                   curExternal = def.function.declarator ? def.function.declarator.symbol.pointerExternal : external;
2792                   ProcessFunction((FunctionDefinition)def.function);
2793                }
2794                else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
2795                {
2796                   ProcessInstantiation(def.decl.inst);
2797                }
2798                else if(def.type == defaultPropertiesClassDef && def.defProperties)
2799                {
2800                   MemberInit defProperty;
2801
2802                   // Add this to the context
2803                   Symbol thisSymbol
2804                   {
2805                      string = CopyString("this");
2806                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2807                   };
2808                   globalContext.symbols.Add((BTNode)thisSymbol);
2809
2810                   for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
2811                   {
2812                      //thisClass = regClass;
2813                      ProcessMemberInitData(defProperty); ///*, regClass, &id
2814                      //thisClass = null;
2815                   }
2816
2817                   globalContext.symbols.Remove((BTNode)thisSymbol);
2818                   FreeSymbol(thisSymbol);
2819                }
2820                else if(def.type == propertyClassDef && def.propertyDef)
2821                {
2822                   PropertyDef prop = def.propertyDef;
2823
2824                   // Add this to the context
2825                   Symbol thisSymbol
2826                   {
2827                      string = CopyString("this");
2828                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2829                   };
2830                   globalContext.symbols.Add((BTNode)thisSymbol);
2831
2832                   //thisClass = regClass;
2833                   if(prop.setStmt)
2834                   {
2835                      curExternal = prop.symbol ? prop.symbol.externalSet : null;
2836                      ProcessStatement(prop.setStmt);
2837                   }
2838                   if(prop.getStmt)
2839                   {
2840                      curExternal = prop.symbol ? prop.symbol.externalGet : null;
2841                      ProcessStatement(prop.getStmt);
2842                   }
2843                   if(prop.issetStmt)
2844                   {
2845                      curExternal = prop.symbol ? prop.symbol.externalIsSet : null;
2846                      ProcessStatement(prop.issetStmt);
2847                   }
2848                   //thisClass = null;
2849
2850                   globalContext.symbols.Remove((BTNode)thisSymbol);
2851                   FreeSymbol(thisSymbol);
2852                }
2853                else if(def.type == propertyWatchClassDef && def.propertyWatch)
2854                {
2855                   PropertyWatch propertyWatch = def.propertyWatch;
2856
2857                   // Add this to the context
2858                   Symbol thisSymbol
2859                   {
2860                      string = CopyString("this");
2861                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2862                   };
2863                   globalContext.symbols.Add((BTNode)thisSymbol);
2864
2865                   //thisClass = regClass;
2866                   if(propertyWatch.compound)
2867                   {
2868                      /* This was already added in pass15:ProcessClass()
2869                      Symbol thisSymbol
2870                      {
2871                         string = CopyString("this");
2872                         type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2873                      };*/
2874                      propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
2875                      curExternal = null;
2876                      ProcessStatement(propertyWatch.compound);
2877                   }
2878                   // thisClass = null;
2879
2880                   //globalContext.symbols.Delete((BTNode)thisSymbol);
2881                   globalContext.symbols.Remove((BTNode)thisSymbol);
2882                   FreeSymbol(thisSymbol);
2883                }
2884              }
2885          }
2886       }
2887    }
2888 }