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