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