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