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