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