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