Initial git commit -- Transition from CodeGuard repository
[sdk] / compiler / libec / src / pass16.ec
1 import "ecdefs"
2
3 #define YYLTYPE Location
4 #include "grammar.eh"
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((uint)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    }
1534    CheckTemplateTypes(exp);
1535 }
1536
1537 static void ProcessInitializer(Initializer init)
1538 {
1539    switch(init.type)
1540    {
1541       case expInitializer:
1542          init.exp.usage.usageGet = true;
1543          ProcessExpression(init.exp);
1544          break;
1545       case listInitializer:
1546       {
1547          Initializer i;
1548          for(i = init.list->first; i; i = i.next)
1549             ProcessInitializer(i);
1550          break;
1551       }
1552    }
1553 }
1554
1555 static void ProcessSpecifier(Specifier spec)
1556 {
1557    switch(spec.type)
1558    {
1559       case baseSpecifier:
1560          break;
1561       case nameSpecifier:
1562       {
1563          break;
1564       }
1565       case enumSpecifier:
1566       {
1567          Enumerator e;
1568          if(spec.list)
1569          {
1570             for(e = spec.list->first; e; e = e.next)
1571             {
1572                if(e.exp)
1573                   ProcessExpression(e.exp);
1574             }
1575          }
1576          break;
1577       }
1578       case structSpecifier:
1579       case unionSpecifier:
1580       {
1581          //Declaration decl;
1582          if(spec.definitions)
1583          {
1584             ClassDef def;
1585             for(def = spec.definitions->first; def; def = def.next)
1586             {
1587                if(def.type == declarationClassDef && def.decl && def.decl.type == structDeclaration)
1588                   ProcessDeclaration(def.decl);
1589             }
1590          }
1591          break;
1592       }
1593       /*
1594       case SpecifierClass:
1595       {
1596          break;
1597       }*/
1598    }
1599 }
1600
1601 static bool ProcessBracketInst_DataMember(DataMember parentMember, Instantiation inst, OldList list)
1602 {
1603    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1604    DataMember dataMember = null;
1605    bool someMemberSet = false;
1606
1607    // For simple classes, ensure all members are initialized
1608    for(dataMember = parentMember.members.first; dataMember; dataMember = dataMember.next)
1609    {
1610       MembersInit members;
1611       MemberInit member = null;
1612
1613       if(!dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
1614       {
1615          if(!ProcessBracketInst_DataMember(dataMember, inst, list))
1616             return false;
1617       }
1618       else 
1619       {
1620          Class curClass = null;
1621          DataMember curMember = null;
1622          DataMember subMemberStack[256];
1623          int subMemberStackPos = 0;
1624          bool found = false;
1625
1626          if(inst.members && inst.members->first)
1627          {
1628             for(members = inst.members->first; members; members = members.next)
1629             {
1630                if(members.type == dataMembersInit)
1631                {
1632                   for(member = members.dataMembers->first; member; member = member.next)
1633                   {
1634                      if(member.identifiers)
1635                      {
1636                         Identifier firstID = member.identifiers->first;
1637
1638                         DataMember _subMemberStack[256];
1639                         int _subMemberStackPos = 0;
1640                         DataMember thisMember;
1641                         thisMember = firstID ? (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule) : null;
1642                         // FILL MEMBER STACK
1643                         if(!thisMember && firstID)
1644                            thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
1645                         if(thisMember && thisMember.memberAccess == publicAccess)
1646                         {
1647                            curMember = thisMember;
1648                            curClass = curMember._class;
1649                            memcpy(subMemberStack, _subMemberStack, sizeof(int) * _subMemberStackPos);
1650                            subMemberStackPos = _subMemberStackPos;
1651                         }
1652                         /*
1653                         BTNamedLink link = parentMember.membersAlpha.Find((uint)firstID.string);
1654                         if(link)
1655                         {
1656                            curMember = link.data;
1657                         }
1658
1659                         // Choose the first specified member of the union...
1660                         if(parentMember.type == unionMember)
1661                         {
1662                            if(link)
1663                               dataMember = curMember;
1664                         }
1665                         */
1666
1667                         if(dataMember == thisMember)
1668                         {
1669                            // Look for another member of this one and merge them
1670                            // into one instantiation...
1671                            if(member.identifiers->count > 1 && member.initializer && member.initializer.type == expInitializer)
1672                            {
1673                               OldList * partList = MkList();
1674                               // TODO: We're assuming this is a simple class right now...
1675                               Symbol symbol;
1676                               Specifier spec;
1677                               MembersInit nextMembers;
1678                               MemberInit next = member.next;
1679
1680                               if(!dataMember.dataType)
1681                                  dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1682                               symbol = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null;
1683                               spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, symbol, null);
1684
1685                               {
1686                                  OldList * identifiers = MkList();
1687                                  Identifier id;
1688                                  for(id = ((Identifier)member.identifiers->first).next; id; id = id.next)
1689                                     identifiers->Add(CopyIdentifier(id));
1690
1691                                  // *** THE IDENTIFIERS WERE BEING REUSED, CAUSING A CRASH WITH EXPRESSION TEMPLATE CODE IN pass1.ec ***
1692                                  // members->Add(MkMemberInit(ids, MkInitializerAssignment(MkExpConstant(ui64String))));
1693                                  /*member.identifiers->Remove(firstID);*/
1694                                  ListAdd(partList, 
1695                                     MkMemberInit(/*member.identifiers*/identifiers, MkInitializerAssignment(member.initializer.exp)));
1696                               }
1697                           
1698                               for(nextMembers = members; nextMembers; nextMembers = nextMembers.next)
1699                               {
1700                                  if(!nextMembers.dataMembers)
1701                                     continue;
1702
1703                                  if(members != nextMembers) next = nextMembers.dataMembers->first;
1704
1705                                  if(nextMembers.type == dataMembersInit)
1706                                  {
1707                                     MemberInit nextMember;
1708
1709                                     for(nextMember = next; nextMember;
1710                                         nextMember = next, next = nextMember ? nextMember.next : null)
1711                                     {
1712                                        Identifier nextID = nextMember.identifiers->first;
1713                                        if(nextMember.identifiers && 
1714                                           nextMember.identifiers->count > 1 &&
1715                                           !strcmp(firstID.string, nextID.string))
1716                                        {
1717                                           nextMembers.dataMembers->Remove(nextMember);
1718                                           nextMember.identifiers->Remove(nextID);
1719                                           ListAdd(partList, nextMember);
1720                                        }
1721                                     }
1722                                  }
1723                               }
1724
1725                               member.initializer.exp = MkExpInstance(MkInstantiation(spec, null, 
1726                                  MkListOne(MkMembersInitList(partList))));
1727                            }
1728                            found = true;
1729                            break;
1730                         }
1731                      }
1732                      else
1733                      {
1734                         eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
1735                         if(curMember == dataMember)
1736                         {
1737                            found = true;
1738                            break;
1739                         }
1740
1741                         /*
1742                         if(curMember)
1743                            curMember = curMember.next;
1744                         else
1745                            curMember = parentMember.members.first;
1746
1747                         if(curMember == dataMember)
1748                         {
1749                            found = true;
1750                            break;
1751                         }
1752                         */
1753                      }
1754                   }
1755                }
1756                if(found) break;
1757             }
1758          }
1759
1760          if(member && member.initializer && member.initializer.type == expInitializer)
1761          {
1762             Expression memberExp = null;
1763             if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
1764                member.initializer.exp.expType._class.registered.type == structClass)
1765             {
1766                OldList * subList = MkList();
1767                ProcessBracketInst(member.initializer.exp.instance, subList);
1768                FreeExpression(member.initializer.exp);
1769                ListAdd(list, MkInitializerList(subList));
1770             }
1771             else
1772             {
1773                member.initializer.exp.usage.usageGet = true;
1774                ProcessExpression(member.initializer.exp);
1775                ListAdd(list, MkInitializerAssignment(member.initializer.exp));
1776             }
1777             member.initializer.exp = null;
1778             FreeInitializer(member.initializer);
1779             member.initializer = null;
1780             someMemberSet = true;
1781          }
1782          else if(member && member.initializer && member.initializer.type == listInitializer)
1783          {
1784             ListAdd(list, member.initializer);
1785             member.initializer = null;
1786             someMemberSet = true;
1787          }
1788          else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/ && parentMember.type != unionMember)
1789          {
1790             Symbol classSym;
1791             if(!dataMember.dataType)
1792                dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1793             classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1794             if(classSym && classSym.registered && classSym.registered.type == structClass)
1795             {
1796                OldList * subList = MkList();
1797                Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null); 
1798                Instantiation inst = MkInstantiation(spec, null, null);
1799                ProcessBracketInst(inst, subList);
1800                FreeInstance(inst);
1801
1802                ListAdd(list, MkInitializerList(subList));
1803             }
1804             else
1805                ListAdd(list, MkInitializerAssignment(MkExpConstant("0")));
1806          }
1807       }
1808       /*
1809       if(parentMember.type == unionMember)
1810          break;
1811       */
1812    }
1813    // TESTING THIS NEW CODE FOR ANCHORS...
1814    if(parentMember.type == unionMember && !someMemberSet)
1815    {
1816       Symbol classSym;
1817       dataMember = parentMember.members.first;
1818       if(!dataMember.dataType && dataMember.dataTypeString)
1819          dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1820       classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
1821       if(classSym && classSym.registered && classSym.registered.type == structClass)
1822       {
1823          OldList * subList = MkList();
1824          Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null); 
1825          Instantiation inst = MkInstantiation(spec, null, null);
1826          ProcessBracketInst(inst, subList);
1827          FreeInstance(inst);
1828
1829          ListAdd(list, MkInitializerList(subList));
1830       }
1831       else
1832          ListAdd(list, MkInitializerAssignment(MkExpConstant("0")));
1833    }
1834    return true;
1835 }
1836
1837 static bool ProcessBracketInst(Instantiation inst, OldList list)
1838 {
1839    static int recursionCount = 0;
1840    Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1841    Class _class = null;
1842
1843    if(recursionCount > 500) return false;
1844    recursionCount++;
1845
1846    while(_class != classSym.registered)
1847    {
1848       DataMember dataMember;
1849       Class lastClass = _class;
1850
1851       for(_class = classSym.registered; _class.base != lastClass && _class.base.type != systemClass; _class = _class.base);
1852
1853       for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
1854       {
1855          if(!dataMember.isProperty && !dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
1856          {
1857             if(!ProcessBracketInst_DataMember(dataMember, inst, list))
1858             {
1859                recursionCount--;
1860                return false;
1861             }
1862          }
1863          else 
1864          {
1865             MembersInit members;
1866             MemberInit member = null;
1867             bool found = false;
1868
1869             if(inst.members && inst.members->first)
1870             {
1871                DataMember curMember = null;
1872                Class curClass = null;
1873                DataMember subMemberStack[256];
1874                int subMemberStackPos = 0;
1875
1876                for(members = inst.members->first; members; members = members.next)
1877                {
1878                   if(members.type == dataMembersInit)
1879                   {
1880                      for(member = members.dataMembers->first; member; member = member.next)
1881                      {
1882                         Identifier firstID = member.identifiers ? member.identifiers->first : null;
1883                         if(firstID)
1884                         {
1885                            DataMember _subMemberStack[256];
1886                            int _subMemberStackPos = 0;
1887                            DataMember thisMember = (DataMember)eClass_FindProperty(classSym.registered, firstID.string, privateModule);
1888                            // FILL MEMBER STACK
1889                            if(!thisMember)
1890                               thisMember = (DataMember)eClass_FindDataMember(classSym.registered, firstID.string, privateModule, _subMemberStack, &_subMemberStackPos);
1891                            if(thisMember)
1892                            {
1893                               curMember = thisMember;
1894                               curClass = curMember._class;
1895                               memcpy(subMemberStack, _subMemberStack, sizeof(int) * _subMemberStackPos);
1896                               subMemberStackPos = _subMemberStackPos;
1897                            }
1898
1899                            if(curMember == dataMember)
1900                            {
1901                               if(dataMember.isProperty)
1902                               {
1903                                  if(!((Property)dataMember).Set) 
1904                                  {
1905                                     Compiler_Error("No set defined for property %s\n", dataMember.name);
1906                                     continue;
1907                                  }
1908                                  recursionCount--;
1909                                  return false;
1910                               }
1911
1912                               // Look for another member of this one and merge them
1913                               // into one instantiation...
1914                               if(member.identifiers->count > 1 && member.initializer && member.initializer.type == expInitializer)
1915                               {
1916                                  OldList * partList = MkList();
1917                                  // TODO: We're assuming this is a simple _class right now...
1918                                  Specifier spec;
1919                                  MembersInit nextMembers;
1920                                  MemberInit next = member.next;
1921                                  Symbol symbol;
1922                                  if(!dataMember.dataType)
1923                                     dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
1924                                  symbol = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null;
1925                                  spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, symbol, null); 
1926
1927                                  member.identifiers->Remove(firstID);
1928                                  ListAdd(partList, 
1929                                     MkMemberInit(member.identifiers, MkInitializerAssignment(member.initializer.exp)));
1930
1931                                  for(nextMembers = members; nextMembers; nextMembers = nextMembers.next)
1932                                  {
1933                                     if(!nextMembers.dataMembers) continue;
1934
1935                                     if(members != nextMembers) next = nextMembers.dataMembers->first;
1936
1937                                     if(nextMembers.type == dataMembersInit)
1938                                     {
1939                                        MemberInit nextMember;
1940
1941                                        for(nextMember = next; nextMember;
1942                                            nextMember = next, next = nextMember ? nextMember.next : null)
1943                                        {
1944                                           Identifier nextID = nextMember.identifiers->first;
1945                                           if(nextMember.identifiers && 
1946                                              nextMember.identifiers->count > 1 &&
1947                                              !strcmp(firstID.string, nextID.string))
1948                                           {
1949                                              nextMembers.dataMembers->Remove(nextMember);
1950                                              nextMember.identifiers->Remove(nextID);
1951                                              ListAdd(partList, nextMember);
1952                                           }
1953                                        }
1954                                     }
1955                                  }
1956
1957                                  member.initializer.exp = MkExpInstance(MkInstantiation(spec, null, 
1958                                     MkListOne(MkMembersInitList(partList))));
1959
1960                                  // TESTING THIS
1961                                  member.identifiers = null;
1962                               }
1963                               found = true;
1964                               break;
1965                            }
1966                         }
1967                         else
1968                         {
1969                            eClass_FindNextMember(classSym.registered, &curClass, &curMember, subMemberStack, &subMemberStackPos);
1970                            if(curMember == dataMember)
1971                            {
1972                               if(dataMember.isProperty)
1973                               {
1974                                  if(!((Property)dataMember).Set) 
1975                                  {
1976                                     Compiler_Error("No set defined for property %s\n", dataMember.name);
1977                                     continue;
1978                                  }
1979                                  recursionCount--;
1980                                  return false;
1981                               }
1982                               found = true;
1983                               break;
1984                            }
1985                         }
1986                      }
1987                   }
1988                   if(found) break;
1989                }
1990             }
1991
1992             if(dataMember.isProperty) continue;
1993             if(member && member.initializer && member.initializer.type == expInitializer)
1994             {
1995                Expression memberExp = null;
1996                if(member.initializer.exp.type == instanceExp && member.initializer.exp.expType &&
1997                   member.initializer.exp.expType._class && member.initializer.exp.expType._class.registered && member.initializer.exp.expType._class.registered.type == structClass)
1998                {
1999                   OldList * subList = MkList();
2000                   ProcessBracketInst(member.initializer.exp.instance, subList);
2001                   FreeExpression(member.initializer.exp);
2002                   ListAdd(list, MkInitializerList(subList));
2003                }
2004                else
2005                {
2006                   member.initializer.exp.usage.usageGet = true;
2007                   ProcessExpression(member.initializer.exp);
2008                   ListAdd(list, MkInitializerAssignment(member.initializer.exp));
2009                }
2010
2011                // Take this out
2012                // member.exp = null;
2013                member.takeOutExp = true;
2014             }
2015             else if(member && member.initializer && member.initializer.type == listInitializer)
2016             {
2017                ListAdd(list, member.initializer);
2018                member.initializer = null;
2019             }
2020             else if(dataMember && dataMember.dataTypeString/* && !inst.fullSet*/)
2021             {
2022                Symbol classSym;
2023
2024                if(!dataMember.dataType)
2025                   dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
2026                classSym = (dataMember.dataType && dataMember.dataType.kind == classType) ? dataMember.dataType._class : null; // FindClass(dataMember.dataTypeString);
2027
2028                if(classSym && classSym.registered && classSym.registered.type == structClass)
2029                {
2030                   OldList * subList = MkList();
2031                   Specifier spec = _MkSpecifierName/*MkClassName*/(dataMember.dataTypeString, classSym, null); 
2032                   Instantiation inst = MkInstantiation(spec, null, null);
2033                   ProcessBracketInst(inst, subList);
2034                   FreeInstance(inst);
2035                   ListAdd(list, MkInitializerList(subList));
2036                }
2037                else if(dataMember.dataType.kind == arrayType)
2038                   ListAdd(list, MkInitializerList(MkListOne(MkInitializerAssignment(MkExpConstant("0")))));
2039                else
2040                   ListAdd(list, MkInitializerAssignment(MkExpConstant("0")));
2041             }
2042          }
2043       }
2044    }
2045
2046    if(inst.members && inst.members->first)
2047    {
2048       MembersInit members;
2049       MemberInit member = null;
2050
2051       for(members = inst.members->first; members; members = members.next)
2052       {
2053          if(members.type == dataMembersInit)
2054          {
2055             for(member = members.dataMembers->first; member; member = member.next)
2056             {
2057                if(member.takeOutExp)
2058                {
2059                   member.initializer.exp = null;
2060                   FreeInitializer(member.initializer);
2061                   member.initializer = null;
2062                }
2063             }
2064          }
2065       }
2066    }
2067    recursionCount--;
2068    return true;
2069 }
2070
2071 static Declaration curDecl;
2072 static int declTempCount;
2073
2074 static void ProcessDeclaration(Declaration decl)
2075 {
2076    yylloc = decl.loc;
2077    switch(decl.type)
2078    {
2079       case initDeclaration:
2080       {
2081          if(!curDecl) { curDecl = decl; declTempCount = 0; }
2082          if(decl.specifiers)
2083          {
2084             Specifier s;
2085             for(s = decl.specifiers->first; s; s = s.next)
2086             {
2087                ProcessSpecifier(s);
2088             }
2089          }
2090          if(decl.declarators)
2091          {
2092             InitDeclarator d;
2093
2094             for(d = decl.declarators->first; d; d = d.next)
2095             {
2096               if(d.initializer)
2097                   ProcessInitializer(d.initializer);
2098             }
2099          }
2100          if(curDecl == decl) { curDecl = null; declTempCount = 0; }
2101          break;
2102       }
2103       case instDeclaration:
2104       {
2105          Instantiation inst = decl.inst;
2106          
2107          if(inCompiler)
2108          {
2109             Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
2110             if(!curCompound)
2111             {
2112                Statement stmt;
2113
2114                if(!inst.isConstant || (classSym && classSym.registered && (classSym.registered.type == normalClass || classSym.registered.type == noHeadClass)))
2115                {
2116                   // If this instantiation is outside, turn it into a declaration plus an instantiation expression
2117                   decl.type = initDeclaration;
2118                   decl.specifiers = MkListOne(MkSpecifierName/*MkClassName*/(inst._class.name));
2119                   if(decl.declMode == staticAccess)
2120                   {
2121                      decl.specifiers->Insert(null, MkSpecifier(STATIC));
2122                   }
2123                   decl.declarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(inst.exp.identifier.string)), null));
2124
2125                   ProcessDeclaration(decl);
2126                   CreateInstancesBody();
2127
2128                   {
2129                      Expression exp = MkExpInstance(inst);
2130                      stmt = MkExpressionStmt(MkListOne(exp));       // MkExpOp(inst.exp, '=',
2131                      ListAdd(createInstancesBody.compound.statements, stmt);
2132                      ProcessExpressionType(exp);
2133                   }
2134
2135                   if(classSym && classSym.registered && (classSym.registered.type == normalClass))
2136                   {
2137                      ListAdd(createInstancesBody.compound.statements, 
2138                         MkExpressionStmt(MkListOne(MkExpCall(
2139                            MkExpIdentifier(MkIdentifier("ecere::com::eInstance_IncRef")),
2140                            MkListOne(CopyExpression(inst.exp))))));
2141
2142                      // We'd like the = 0 as well...
2143                      {
2144                         Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2145                         ListAdd(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2146                         ProcessExpressionType(exp);
2147                      }
2148                   }
2149                   else if(classSym && classSym.registered && (classSym.registered.type == noHeadClass))
2150                   {
2151                      Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
2152                      ListAdd(destroyInstancesBody.compound.statements, MkExpressionStmt(MkListOne(exp)));
2153                      ProcessExpressionType(exp);
2154                   }
2155                   break;
2156                }
2157                else
2158                {
2159                   // Precompiler won't know if this isn't constant
2160                   CreateInstancesBody();
2161                }
2162             }
2163          
2164             {
2165                char className[1024];
2166                
2167                decl.type = initDeclaration;
2168                decl.specifiers = MkList();
2169                decl.declarators = MkList();
2170       
2171                // Replace instantiation here
2172                if(classSym && classSym.registered && classSym.registered.type == bitClass)
2173                {
2174                   OldList list = { 0 };
2175
2176                   // Put the instantiation in an InitDeclarator...
2177                   ProcessInstMembers(inst, inst.exp, &list, false);
2178                   ProcessExpression(inst.exp);
2179
2180                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2181                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2182                      MkInitializerAssignment(list.first)));
2183                   inst.exp.identifier = null;
2184                }
2185                else if(classSym && classSym.registered && classSym.registered.type == unitClass)
2186                {
2187                   OldList list = { 0 };
2188
2189                   // Put the instantiation in an InitDeclarator...
2190                   ProcessInstMembers(inst, inst.exp, &list, false);
2191                   ProcessExpression(inst.exp);
2192
2193                   ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2194                   ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2195                      MkInitializerAssignment(list.first)));
2196
2197                   inst.exp.identifier = null;
2198                }
2199                else if(classSym && classSym.registered && classSym.registered.type == structClass)
2200                {
2201                   Expression exp;
2202
2203                   DeclareStruct(inst._class.name, false);
2204                   /*{
2205                      strcpy(className, "__ecereClass_");
2206                      FullClassNameCat(className, classSym.string, true);
2207                      MangleClassName(className);
2208                      DeclareClass(classSym, className);
2209                   }*/
2210
2211                   ProcessExpression(inst.exp);
2212
2213                   // Put the instantiation in an InitDeclarator...
2214                   {
2215                      if(inst.fullSet)
2216                      {
2217                         ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2218                         ListAdd(decl.declarators, 
2219                            MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier), null));
2220                         inst.exp.identifier = null;
2221                      }
2222                      else 
2223                      {
2224                         OldList * list = MkList();
2225                         if(ProcessBracketInst(inst, list))
2226                         {
2227                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2228                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2229                               MkInitializerList(list)));
2230                            inst.exp.identifier = null;
2231                         }
2232                         else
2233                         {
2234                            // If bracket instantiation failed (property: for conversions only?)
2235                            // TODO: (Fix this so it initializes members through brackets,
2236                            //        and then does properties)
2237                            //list->Free(null);
2238                            //delete list;
2239                            // TESTING THIS MEMORY LEAK FIX:
2240                            FreeList(list, FreeInitializer);
2241
2242                            exp = MkExpBrackets(MkList());
2243                            ProcessInstMembers(inst, inst.exp, exp.list, true);
2244                            ListAdd(exp.list, CopyExpression(inst.exp));
2245                            ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2246                            ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(inst.exp.identifier),
2247                               MkInitializerAssignment(exp)));
2248                            inst.exp.identifier = null;
2249                         }
2250                      }
2251                   }
2252                }
2253                else
2254                {
2255                   Expression newCall;
2256
2257                   if(classSym && classSym.registered && classSym.registered.type == noHeadClass && 
2258                      (classSym.registered.templateClass ? classSym.registered.templateClass.fixed : classSym.registered.fixed))
2259                   {
2260                      char size[256];
2261                      sprintf(size, "%d", classSym.registered.templateClass ? classSym.registered.templateClass.structSize : classSym.registered.structSize);
2262                      newCall = MkExpCall(QMkExpId("ecere::com::eSystem_New0"), MkListOne(MkExpConstant(size)));
2263                   }
2264                   else
2265                   {
2266                      strcpy(className, "__ecereClass_");
2267
2268                      if(classSym && classSym.registered && classSym.registered.type == noHeadClass && classSym.registered.templateClass)
2269                      {
2270                         classSym = FindClass(classSym.registered.templateClass.fullName);
2271                         FullClassNameCat(className, classSym.string, true);
2272                      }
2273                      else
2274                         FullClassNameCat(className, inst._class.name, true);
2275                      MangleClassName(className);
2276
2277                      DeclareClass(classSym, className);   // THIS WAS IN C VERSION BUT NOT IN eC VERSION?
2278                      newCall = MkExpCall(QMkExpId("ecere::com::eInstance_New"), MkListOne(QMkExpId(className)));
2279                      ProcessExpressionType(newCall);
2280                      newCall.byReference = true;
2281                   }
2282
2283                   if(classSym)
2284                      DeclareClass(classSym, className);
2285
2286                   if(inst.exp)
2287                   {
2288                      Expression exp, newExp;
2289                      Identifier id = CopyIdentifier(inst.exp.identifier);
2290
2291                      // Put the instantiation in an InitDeclarator...
2292                      if(inst.members && inst.members->first)
2293                      {
2294                         newExp = MkExpOp(CopyExpression(inst.exp), '=', newCall);
2295
2296                         exp = MkExpBrackets(MkList());
2297                         ListAdd(exp.list, newExp);
2298                         ProcessInstMembers(inst, inst.exp, exp.list, false);
2299                         ListAdd(exp.list, inst.exp);
2300
2301                         ProcessExpression(inst.exp);
2302
2303                         // Take it out since we're using it...
2304                         inst.exp = null;
2305                      }
2306                      else
2307                         exp = newCall;
2308
2309                      ListAdd(decl.specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
2310                      ListAdd(decl.declarators, MkInitDeclarator(MkDeclaratorIdentifier(id),
2311                         MkInitializerAssignment(exp)));
2312                      //inst.exp.identifier = null;
2313                   }
2314                   else
2315                      FreeExpression(newCall);
2316                }
2317             }
2318             FreeInstance(inst);
2319          }
2320          else
2321             ProcessInstantiation(inst);
2322          break;
2323       }
2324       case structDeclaration:
2325       {
2326          if(decl.specifiers)
2327          {
2328             Specifier spec;
2329             for(spec = decl.specifiers->first; spec; spec = spec.next)
2330                ProcessSpecifier(spec);
2331          }
2332          break;
2333       }
2334    }
2335 }
2336
2337 static void ProcessStatement(Statement stmt)
2338 {
2339    yylloc = stmt.loc;
2340    switch(stmt.type)
2341    {
2342       case labeledStmt:
2343          if(stmt.labeled.stmt)
2344             ProcessStatement(stmt.labeled.stmt);
2345          break;
2346       case caseStmt:
2347          if(stmt.caseStmt.exp)
2348             ProcessExpression(stmt.caseStmt.exp);
2349          if(stmt.caseStmt.stmt)
2350             ProcessStatement(stmt.caseStmt.stmt);
2351          break;
2352       case compoundStmt:
2353       {
2354          if(stmt.compound.context)
2355          {
2356             Declaration decl;
2357             Statement s;
2358             Statement prevCompound = curCompound;
2359             Context prevContext = curContext;
2360
2361             if(!stmt.compound.isSwitch)
2362             {
2363                curCompound = stmt;
2364                curContext = stmt.compound.context;
2365             }
2366
2367             if(stmt.compound.declarations)
2368             {
2369                for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
2370                   ProcessDeclaration(decl);
2371             }
2372             if(stmt.compound.statements)
2373             {
2374                for(s = stmt.compound.statements->first; s; s = s.next)
2375                {
2376                   ProcessStatement(s);
2377                }
2378             }
2379
2380             curCompound = prevCompound;
2381             curContext = prevContext;
2382          }
2383          break;
2384       }
2385       case expressionStmt:
2386       {
2387          Expression exp;
2388          if(stmt.expressions)
2389          {
2390             for(exp = stmt.expressions->first; exp; exp = exp.next)
2391             {
2392                ProcessExpression(exp);
2393             }
2394          }
2395          break;
2396       }
2397       case ifStmt:
2398       {
2399          Expression exp;
2400
2401          ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
2402          for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
2403          {
2404             ProcessExpression(exp);
2405          }
2406          if(stmt.ifStmt.stmt)
2407             ProcessStatement(stmt.ifStmt.stmt);
2408          if(stmt.ifStmt.elseStmt)
2409             ProcessStatement(stmt.ifStmt.elseStmt);
2410          break;
2411       }
2412       case switchStmt:
2413       {
2414          Expression exp;
2415          ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
2416          for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
2417             ProcessExpression(exp);
2418          ProcessStatement(stmt.switchStmt.stmt);
2419          break;
2420       }
2421       case whileStmt:
2422       {
2423          if(stmt.whileStmt.exp)
2424          {
2425             Expression exp;
2426
2427             ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
2428             for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
2429             {
2430                ProcessExpression(exp);
2431             }
2432          }
2433          if(stmt.whileStmt.stmt)
2434             ProcessStatement(stmt.whileStmt.stmt);
2435          break;
2436       }
2437       case doWhileStmt:
2438       {
2439          if(stmt.doWhile.exp)
2440          {
2441             Expression exp;
2442             ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
2443             for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
2444             {
2445                ProcessExpression(exp);
2446             }
2447          }
2448          if(stmt.doWhile.stmt)
2449             ProcessStatement(stmt.doWhile.stmt);
2450          break;
2451       }
2452       case forStmt:
2453       {
2454          Expression exp;
2455          if(stmt.forStmt.init)
2456             ProcessStatement(stmt.forStmt.init);
2457
2458          if(stmt.forStmt.check && stmt.forStmt.check.expressions)
2459          {
2460             ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
2461          }
2462
2463          if(stmt.forStmt.check)
2464             ProcessStatement(stmt.forStmt.check);
2465          if(stmt.forStmt.increment)
2466          {
2467             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
2468                ProcessExpression(exp);
2469          }
2470          if(stmt.forStmt.stmt)
2471             ProcessStatement(stmt.forStmt.stmt);
2472          break;
2473       }
2474       case gotoStmt:
2475          break;
2476       case continueStmt:
2477          break;
2478       case breakStmt:
2479          break;
2480       case returnStmt:
2481       {
2482          Expression exp;
2483          if(stmt.expressions && stmt.expressions->last)
2484          {
2485             ((Expression)stmt.expressions->last).usage.usageGet = true;
2486             for(exp = stmt.expressions->first; exp; exp = exp.next)
2487             {
2488                ProcessExpression(exp);
2489             }
2490          }
2491          break;
2492       }
2493       case badDeclarationStmt:
2494       {
2495          ProcessDeclaration(stmt.decl);
2496          break;
2497       }
2498       case asmStmt:
2499       {
2500          AsmField field;
2501          if(stmt.asmStmt.inputFields)
2502          {
2503             for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
2504                if(field.expression)
2505                   ProcessExpression(field.expression);
2506          }
2507          if(stmt.asmStmt.outputFields)
2508          {
2509             for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
2510                if(field.expression)
2511                   ProcessExpression(field.expression);
2512          }
2513          if(stmt.asmStmt.clobberedFields)
2514          {
2515             for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
2516                if(field.expression)
2517                   ProcessExpression(field.expression);
2518          }
2519          break;
2520       }
2521    }
2522 }
2523 static void ProcessFunction(FunctionDefinition function)
2524 {
2525    if(function.body)
2526    {
2527       yylloc = function.loc;
2528       ProcessStatement(function.body);
2529    }
2530 }
2531
2532 /////////// INSTANTIATIONS / DATA TYPES PASS /////////////////////////////////////////////
2533 public void ProcessInstantiations()
2534 {
2535    External external;
2536    // Is this still needed?
2537    //CreateInstancesBody();
2538    
2539    for(external = ast->first; external; external = external.next)
2540    {
2541       curExternal = external;
2542       if(external.type == declarationExternal)
2543       {
2544          //currentClass = external.function._class;
2545          if(external.declaration)
2546             ProcessDeclaration(external.declaration);
2547       }
2548       else if(external.type == functionExternal)
2549       {
2550          //currentClass = null;
2551          ProcessFunction(external.function);
2552       }
2553       else if(external.type == classExternal)
2554       {
2555          ClassDefinition _class = external._class;
2556          //currentClass = external.symbol.registered;
2557          if(_class.definitions)
2558          {
2559             ClassDef def;
2560             //Class regClass = _class.symbol.registered;
2561
2562             // Process all functions
2563             for(def = _class.definitions->first; def; def = def.next)
2564             {
2565                if(def.type == functionClassDef)
2566                {
2567                   curExternal = def.function.declarator ? def.function.declarator.symbol.pointerExternal : external;
2568                   ProcessFunction((FunctionDefinition)def.function);
2569                }
2570                else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
2571                {
2572                   ProcessInstantiation(def.decl.inst);
2573                }
2574                else if(def.type == defaultPropertiesClassDef && def.defProperties)
2575                {
2576                   MemberInit defProperty;
2577
2578                   // Add this to the context
2579                   Symbol thisSymbol
2580                   {
2581                      string = CopyString("this");
2582                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2583                   };
2584                   globalContext.symbols.Add((BTNode)thisSymbol);
2585                   
2586                   for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
2587                   {
2588                      //thisClass = regClass;
2589                      ProcessMemberInitData(defProperty); ///*, regClass, &id
2590                      //thisClass = null;
2591                   }
2592
2593                   globalContext.symbols.Remove((BTNode)thisSymbol);
2594                   FreeSymbol(thisSymbol);
2595                }
2596                else if(def.type == propertyClassDef && def.propertyDef)
2597                {
2598                   PropertyDef prop = def.propertyDef;
2599
2600                   // Add this to the context
2601                   Symbol thisSymbol
2602                   {
2603                      string = CopyString("this");
2604                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2605                   };
2606                   globalContext.symbols.Add((BTNode)thisSymbol);
2607                   
2608                   //thisClass = regClass;
2609                   if(prop.setStmt)
2610                   {
2611                      curExternal = prop.symbol ? prop.symbol.externalSet : null;
2612                      ProcessStatement(prop.setStmt);
2613                   }
2614                   if(prop.getStmt)
2615                   {
2616                      curExternal = prop.symbol ? prop.symbol.externalGet : null;
2617                      ProcessStatement(prop.getStmt);
2618                   }
2619                   if(prop.issetStmt)
2620                   {
2621                      curExternal = prop.symbol ? prop.symbol.externalIsSet : null;
2622                      ProcessStatement(prop.issetStmt);
2623                   }
2624                   //thisClass = null;
2625
2626                   globalContext.symbols.Remove((BTNode)thisSymbol);
2627                   FreeSymbol(thisSymbol);
2628                }
2629                else if(def.type == propertyWatchClassDef && def.propertyWatch)
2630                {
2631                   PropertyWatch propertyWatch = def.propertyWatch;
2632         
2633                   // Add this to the context
2634                   Symbol thisSymbol
2635                   {
2636                      string = CopyString("this");
2637                      type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2638                   };
2639                   globalContext.symbols.Add((BTNode)thisSymbol);
2640                   
2641                   //thisClass = regClass;
2642                   if(propertyWatch.compound)
2643                   {
2644                      Symbol thisSymbol
2645                      {
2646                         string = CopyString("this");
2647                         type = MkClassTypeSymbol(_class.symbol); //regClass.fullName);
2648                      };
2649                      propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
2650                      curExternal = null;
2651                      ProcessStatement(propertyWatch.compound);
2652                   }
2653                   // thisClass = null;
2654
2655                   //globalContext.symbols.Delete((BTNode)thisSymbol);
2656                   globalContext.symbols.Remove((BTNode)thisSymbol);
2657                   FreeSymbol(thisSymbol);
2658                }
2659              }
2660          }
2661       }
2662    }
2663 }