sdk: Fixed many warnings and related problems
[sdk] / compiler / libec / src / pass0.ec
1 import "ecdefs"
2
3 #define YYLTYPE Location
4 #include "grammar.h"
5
6 extern External curExternal;
7
8 /*public void MangleClassName(char * className)
9 {
10    char output[1024];
11    int c, d = 0;
12    char ch;
13    c = 0;
14    if(!strncmp(className, "const ", 6)) c += 6;
15
16    for(; (ch = className[c]); c++)
17    {
18       if(ch == ' ')
19          output[d++] = '_';
20       else if(ch == '*')
21       {
22          output[d++] = '_';
23          output[d++] = 'P';
24          output[d++] = 'T';
25          output[d++] = 'R';
26          output[d++] = '_';
27       }
28       else if(ch == '<')
29       {
30          if(!strncmp(className + c + 1, "const ", 6)) c += 6;
31          output[d++] = '_';
32          output[d++] = 'T';
33          output[d++] = 'P';
34          output[d++] = 'L';
35          output[d++] = '_';
36       }
37       else if(ch == '=')
38       {
39          output[d++] = '_';
40          output[d++] = 'E';
41          output[d++] = 'Q';
42          output[d++] = 'U';
43          output[d++] = '_';
44       }
45       else if(ch == '>')
46       {
47          output[d++] = '_';
48       }
49       else if(ch == ',')
50       {
51          if(!strncmp(className + c + 1, "const ", 6)) c += 6;
52          output[d++] = '_';
53       }
54       else
55          output[d++] = ch;
56    }
57    output[d] = 0;
58    // ChangeCh(className, ' ', '_');
59    // ChangeCh(className, '*', '_');
60 }
61 */
62 public void FullClassNameCat(char * output, const char * className, bool includeTemplateParams)
63 {
64    int c;
65    char ch;
66    int len;
67    /*
68    if(!strchr(className, ':'))
69    {
70       output[len++] = '_';
71       output[len++] = '_';
72    }
73    */
74    //if(strchr(className, ':'))
75    for(c = 0; (ch = className[c]) && ch != '<'; c++)
76    {
77       if(ch == ':')
78       {
79          strcat(output, "__ecereNameSpace__");
80          break;
81       }
82    }
83
84    len = strlen(output);
85
86    c = 0;
87    if(!strncmp(className, "const ", 6)) c += 6;
88
89    for(; (ch = className[c]); c++)
90    {
91       if(ch == ':')
92          output[len++] = '_';
93       else if(ch == ' ')
94          output[len++] = '_';
95       else if(ch == '*')
96       {
97          output[len++] = '_';
98          output[len++] = 'P';
99          output[len++] = 'T';
100          output[len++] = 'R';
101          output[len++] = '_';
102       }
103       else if(ch == '=')
104       {
105          output[len++] = '_';
106          output[len++] = 'E';
107          output[len++] = 'Q';
108          output[len++] = 'U';
109          output[len++] = '_';
110       }
111       else if(ch == '<')
112       {
113          if(!includeTemplateParams) break;
114          if(!strncmp(className + c + 1, "const ", 6)) c += 6;
115          output[len++] = '_';
116          output[len++] = 'T';
117          output[len++] = 'P';
118          output[len++] = 'L';
119          output[len++] = '_';
120       }
121       else if(ch == '>')
122       {
123          output[len++] = '_';
124       }
125       else if(ch == ',')
126       {
127          if(!strncmp(className + c + 1, "const ", 6)) c += 6;
128          output[len++] = '_';
129       }
130       else
131          output[len++] = ch;
132    }
133    output[len++] = 0;
134 }
135
136 static void AddSimpleBaseMembers(OldList list, Class _class, Class topClass)
137 {
138    /*if(_class.base && _class.type != CLASS_SYSTEM)
139       AddSimpleBaseMembers(list, _class.base, topClass);*/
140    if(_class.type != systemClass)
141       AddMembers(list, _class, false, null, topClass, null);
142 }
143
144 static bool NameSpaceContained(NameSpace * ns, NameSpace * parent)
145 {
146    if(ns == parent)
147       return true;
148    else if(ns->parent)
149       return NameSpaceContained(ns->parent, parent);
150    else
151       return false;
152 }
153
154 static void CheckPublicClass(Symbol classSym, AccessMode access, const char * word)
155 {
156    Class regClass = classSym ? classSym.registered : null;
157    if(regClass)
158    {
159       if(regClass.templateClass)
160          regClass = regClass.templateClass;
161       // TODO: Will need to add checks for template parameter classes
162       if(classSym.isStatic && access != staticAccess)
163       {
164          Compiler_Error($"Non-static %s making use of a static class\n", word);
165       }
166       else if(access == publicAccess)
167       {
168          if(!NameSpaceContained(regClass.nameSpace, regClass.module.application.systemNameSpace))
169          {
170             if(NameSpaceContained(regClass.nameSpace, regClass.module.privateNameSpace) || !ModuleAccess(privateModule, regClass.module))
171                Compiler_Error($"Public %s making use of a private class\n", word);
172          }
173       }
174    }
175 }
176
177 static void CheckPublicTypeName(TypeName type, AccessMode access)
178 {
179    if(type.qualifiers)
180    {
181       Specifier spec;
182       for(spec = type.qualifiers->first; spec; spec = spec.next)
183       {
184          // Only check for classes here...
185          // Skip structs etc. for now
186          if(spec.type == nameSpecifier)
187          {
188             Symbol classSym = spec.symbol; // FindClass(spec.name);
189             CheckPublicClass(classSym, access, "define");
190          }
191       }
192    }
193 }
194
195 static void CheckPublicInitializer(Initializer init, AccessMode access)
196 {
197    switch(init.type)
198    {
199       case expInitializer:
200          CheckPublicExpression(init.exp, access);
201          break;
202       case listInitializer:
203       {
204          Initializer i;
205          for(i = init.list->first; i; i = i.next)
206             CheckPublicInitializer(i, access);
207          break;
208       }
209    }
210 }
211
212 static void CheckPublicExpression(Expression exp, AccessMode access)
213 {
214    if(exp)
215    {
216       switch(exp.type)
217       {
218          case identifierExp:
219             break;
220          case constantExp:
221             break;
222          case stringExp:
223             break;
224          case opExp:
225             if(exp.op.exp1)
226                CheckPublicExpression(exp.op.exp1, access);
227             if(exp.op.exp2)
228                CheckPublicExpression(exp.op.exp2, access);
229             break;
230          case bracketsExp:
231          {
232             Expression e;
233             for(e = exp.list->first; e; e = e.next)
234                CheckPublicExpression(e, access);
235             break;
236          }
237          case indexExp:
238          {
239             Expression e;
240             CheckPublicExpression(exp.index.exp, access);
241             for(e = exp.index.index->first; e; e = e.next)
242                CheckPublicExpression(e, access);
243             break;
244          }
245          case callExp:
246          {
247             Expression e;
248             CheckPublicExpression(exp.call.exp, access);
249             if(exp.call.arguments)
250             {
251                for(e = exp.call.arguments->first; e; e = e.next)
252                   CheckPublicExpression(e, access);
253             }
254             break;
255          }
256          case memberExp:
257          {
258             CheckPublicExpression(exp.member.exp, access);
259             break;
260          }
261          case pointerExp:
262          {
263             CheckPublicExpression(exp.member.exp, access);
264             break;
265          }
266          case typeSizeExp:
267             CheckPublicTypeName(exp.typeName, access);
268             break;
269          case castExp:
270          {
271             CheckPublicTypeName(exp.cast.typeName, access);
272             if(exp.cast.exp)
273                CheckPublicExpression(exp.cast.exp, access);
274             break;
275          }
276          case conditionExp:
277          {
278             Expression e;
279             CheckPublicExpression(exp.cond.cond, access);
280             for(e = exp.cond.exp->first; e; e = e.next)
281                CheckPublicExpression(e, access);
282             CheckPublicExpression(exp.cond.elseExp, access);
283             break;
284          }
285          case newExp:
286          case new0Exp:
287             CheckPublicExpression(exp._new.size, access);
288             break;
289          case renewExp:
290          case renew0Exp:
291             CheckPublicExpression(exp._renew.size, access);
292             CheckPublicExpression(exp._renew.exp, access);
293             break;
294          case instanceExp:
295          {
296             MembersInit members;
297             CheckPublicClass(exp.instance._class.symbol /*FindClass(exp.instance._class.name)*/, access, "define");
298             for(members = exp.instance.members->first; members; members = members.next)
299             {
300                if(members.type == dataMembersInit)
301                {
302                   MemberInit member;
303                   for(member = members.dataMembers->first; member; member = member.next)
304                   {
305                      CheckPublicInitializer(member.initializer, access);
306                   }
307                }
308             }
309             break;
310          }
311       }
312    }
313 }
314
315 static void CheckPublicDataType(Type type, AccessMode access, const char * word)
316 {
317    if(type)
318    {
319       switch(type.kind)
320       {
321          case classType:
322          {
323             CheckPublicClass(type._class, access, word);
324             break;
325          }
326          case structType:
327          case unionType:
328          {
329             // Do we want to overlook these C constructs when doing checks? Most likely... Recursion nightmare.
330             /*
331             Type member;
332             Symbol typeSym;
333             if(type.enumName)
334             {
335                typeSym = FindSymbol(type.enumName, globalContext, globalContext, true, false);
336                if(typeSym) type = typeSym.type;
337             }
338             for(member = type.members.first; member; member = member.next)
339                CheckPublicDataType(member, access, word);
340             */
341             break;
342          }
343          case functionType:
344          {
345             Type param;
346             CheckPublicDataType(type.returnType, access, word);
347             for(param = type.params.first; param; param = param.next)
348                CheckPublicDataType(param, access, word);
349             CheckPublicClass(type.thisClass, access, word);
350             break;
351          }
352          case arrayType:
353             CheckPublicDataType(type.arrayType, access, word);
354             if(type.enumClass)
355                CheckPublicClass(type.enumClass, access, word);
356             break;
357          case pointerType:
358          {
359             CheckPublicDataType(type.type, access, word);
360             break;
361          }
362          case methodType:
363          {
364             // Where is this used? Needed?
365             break;
366          }
367          case subClassType:
368          {
369             CheckPublicClass(type._class, access, word);
370             break;
371          }
372       }
373    }
374 }
375
376 static void CheckMembersDefinitions(Class regClass, DataMember member, OldList definitions, AccessMode access)
377 {
378    if(definitions != null)
379    {
380       ClassDef def;
381       for(def = definitions.first; def; def = def.next)
382       {
383          if(def.type == declarationClassDef)
384          {
385             Declaration decl = def.decl;
386             DataMember dataMember;
387
388             yylloc = def.loc;
389             if(decl.type == structDeclaration)
390             {
391                Declarator d;
392                if(decl.declarators)
393                {
394                   for(d = decl.declarators->first; d; d = d.next)
395                   {
396                      Identifier declId = GetDeclId(d);
397                      if(declId)
398                      {
399                         if(member)
400                         {
401                            BTNamedLink link = (BTNamedLink)member.membersAlpha.FindString(declId.string);
402                            dataMember = link ? link.data : null;
403                         }
404                         else
405                            dataMember = eClass_FindDataMember(regClass, declId.string, privateModule, null, null);
406                         if(dataMember)
407                            CheckPublicDataType(dataMember.dataType,  (def.memberAccess == privateAccess) ? privateAccess : access, $"class data member");
408                      }
409                   }
410                }
411                else if(decl.specifiers)
412                {
413                   Specifier spec;
414                   // Unnamed struct/union
415                   for(spec = decl.specifiers->first; spec; spec = spec.next)
416                   {
417                      if(spec.type == structSpecifier || spec.type == unionSpecifier)
418                      {
419                         if(spec.definitions && !spec.id)
420                         {
421                            CheckMembersDefinitions(regClass, member, spec.definitions, (def.memberAccess == privateAccess) ? privateAccess : access);
422                         }
423                         else if(spec.definitions && spec.id)
424                         {
425                            if(member)
426                            {
427                               BTNamedLink link = (BTNamedLink)member.membersAlpha.FindString(spec.id.string);
428                               dataMember = link ? link.data : null;
429                            }
430                            else
431                               dataMember = eClass_FindDataMember(regClass, spec.id.string, privateModule, null, null);
432                            if(dataMember)
433                               CheckPublicDataType(dataMember.dataType,  (def.memberAccess == privateAccess) ? privateAccess : access, $"class data member");
434                         }
435                      }
436                   }
437                }
438             }
439             else if(decl.type == instDeclaration)
440             {
441                CheckPublicClass(decl.inst._class.symbol /*FindClass(decl.inst._class.name)*/, (def.memberAccess == privateAccess) ? privateAccess : access, $"class member instance");
442             }
443          }
444       }
445    }
446 }
447
448 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, Location loc, OldList defs, void * after, OldList initDeclarators, ExtDecl extDecl)
449 {
450    char structName[1024];
451    char className[1024];
452    char constructorName[1024];
453    char destructorName[1024];
454    Class regClass;
455    ClassFunction destructor = null, constructor = null;
456    //bool redefinition = false;
457    bool isUnion = classType == unionClass;
458
459    External external = null;
460
461    ClassDef def;
462    OldList * list;
463    OldList * classDataList;
464
465    if(inCompiler)
466    {
467       list = MkList();
468       classDataList = MkList();
469    }
470
471    /*
472       TODO: Analyze This
473    if(symbol.exclude)
474    {
475       if(inCompiler)
476          return;
477       else
478          redefinition = true;
479    }
480    */
481    regClass = eSystem_FindClass(privateModule, symbol.string);
482    if(!regClass)
483       return;  // TODO: Notify of an error?
484    classType = regClass.type;
485
486    // PUBLISHING CHECK ON BASE CLASS
487    if(inCompiler)
488    {
489       yylloc = loc;
490
491       if(!NameSpaceContained(regClass.nameSpace, &regClass.module.privateNameSpace) && regClass.inheritanceAccess == publicAccess)
492       {
493          if(!regClass.base.symbol)
494             regClass.base.symbol = FindClass(regClass.base.fullName);
495          CheckPublicClass(regClass.base.symbol, publicAccess, $"class");
496       }
497       else if(!symbol.isStatic && regClass.base)
498       {
499          if(!regClass.base.symbol)
500             regClass.base.symbol = FindClass(regClass.base.fullName);
501          CheckPublicClass(regClass.base.symbol, privateAccess, $"class");
502       }
503    }
504
505    /*
506    if(NameSpaceContained(regClass.nameSpace, &regClass.module.privateNameSpace))
507    {
508       if(regClass.inheritanceAccess == publicAccess &&
509          (regClass.base.nameSpace == &regClass.base.module.privateNameSpace || !ModuleAccess(privateModule, regClass.base.module)))
510          Compiler_Error($"Public class publicly inheriting off private base class\n");
511    }
512    else if(!symbol.isStatic)
513    {
514       Symbol baseSym = FindClass(regClass.base.fullName);
515       if(baseSym && baseSym.isStatic)
516          Compiler_Error($"Non-static class inheriting off static base class\n");
517    }
518    */
519
520    /*
521    MOVED ENUM VALUES TO PASS1
522
523    if(classType == enumClass && enumValues)
524    {
525       Enumerator e;
526       for(e = enumValues.first; e; e = e.next)
527       {
528          if(e.exp)
529          {
530             Type destType
531             {
532                kind = TypeInt;
533                refCount = 1;
534             };
535             e.exp.destType = destType;
536
537             ProcessExpressionType(e.exp);
538             ComputeExpression(e.exp);
539             if(e.exp.isConstant && e.exp.type == ExpConstant)
540             {
541                int value;
542                value = strtol(e.exp.string, null, 0);
543                eEnum_AddFixedValue(regClass, e.id.string, value);
544             }
545             else
546                // Sort of an error
547                eEnum_AddValue(regClass, e.id.string);
548          }
549          else
550             eEnum_AddValue(regClass, e.id.string);
551       }
552    }
553    */
554
555    // ACCESS OVERRIDING CODE
556    if(definitions != null)
557    {
558       for(def = definitions.first; def; def = def.next)
559       {
560          if(def.type == accessOverrideClassDef)
561          {
562             DataMember member;
563             Property prop;
564             Method method;
565             if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
566             {
567                eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
568             }
569             else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
570             {
571                eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
572             }
573             else if((method = eClass_FindMethod(regClass, def.id.string, privateModule)))
574             {
575                eClass_AddMethod(regClass, def.id.string, null, null, def.memberAccess);
576             }
577             else
578             {
579                yylloc = def.loc;
580                Compiler_Error($"Couldn't find member %s to override\n", def.id.string);
581             }
582          }
583       }
584    }
585
586    if(inCompiler)
587    {
588       external = MkExternalDeclaration(null);
589       defs.Insert(after, external);
590       curExternal = external;
591       curExternal.symbol = symbol;
592    }
593
594    if((classType == structClass || classType == noHeadClass) && inCompiler)
595    {
596       AddSimpleBaseMembers(list, regClass.base, regClass);
597    }
598
599    // First check if there's any declaration or instantiations, we'll need a struct
600    if(definitions != null)
601    {
602       if(inCompiler)
603       {
604          if(!NameSpaceContained(regClass.nameSpace, &regClass.module.privateNameSpace))
605             CheckMembersDefinitions(regClass, null, definitions, publicAccess);
606          else if(!symbol.isStatic)
607             CheckMembersDefinitions(regClass, null, definitions, privateAccess);
608       }
609       for(def = definitions.first; def; def = def.next)
610       {
611          yylloc = def.loc;
612          if(def.type == declarationClassDef)
613          {
614             Declaration decl = def.decl;
615             yylloc = decl.loc;
616
617             if(decl.type == structDeclaration)
618             {
619                if(inCompiler && classType != bitClass)
620                {
621                   ListAdd(list, MkClassDefDeclaration(decl));
622
623                   // Take it out from here...
624                   def.decl = null;
625                }
626             }
627             else if(decl.type == instDeclaration)
628             {
629                Instantiation inst = decl.inst;
630                Expression exp = inst.exp;
631                Symbol classSym;
632                if(exp)
633                {
634                   // Eventually support multiple instance creations in the same ';'
635                   OldList * specifiers = MkList();
636                   Declarator d;
637
638                   ListAdd(specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
639                   d = MkDeclaratorIdentifier(MkIdentifier(exp.identifier.string));
640
641                   if(inCompiler)
642                   {
643                      OldList * declarators = MkList();
644                      ListAdd(declarators, d);
645
646                      decl = MkStructDeclaration(specifiers, declarators, null);
647                      ListAdd(list, MkClassDefDeclaration(decl));
648
649                      // Add the this pointer to the instance expression
650                      exp.type = memberExp;
651                      exp.member.member = exp.identifier;
652                      exp.member.exp = QMkExpId("this");
653                      exp.member.memberType = dataMember;
654                      exp.member.thisPtr = true;
655                   }
656                   else
657                   {
658                      FreeDeclarator(d);
659                      FreeList(specifiers, FreeSpecifier);
660                   }
661                }
662
663                // Check if it is a simple class
664                // If it is, we only need a constructor if there is data set,
665                // and we don't need a destructor
666                classSym = inst._class.symbol; // FindClass(inst._class.name);
667                if(classSym && classSym.registered &&
668                   (classSym.registered.type == structClass ||
669                    classSym.registered.type == bitClass ||
670                    classSym.registered.type == unitClass))
671                {
672                   if(inst.members && inst.members->count)
673                      symbol.needConstructor = true;
674                }
675                else
676                {
677                   symbol.needConstructor = true;
678                   symbol.needDestructor = true;
679                }
680             }
681          }
682          else if(def.type == classDataClassDef)
683          {
684             Declaration decl = def.decl;
685
686             if(decl.type == structDeclaration)
687             {
688                if(inCompiler && classType != bitClass)
689                {
690                   ListAdd(classDataList, MkClassDefDeclaration(decl));
691
692                   // Take it out from here...
693                   def.decl = null;
694                }
695             }
696          }
697          else if(def.type == defaultPropertiesClassDef)
698             symbol.needConstructor = true;
699          else if(def.type == propertyWatchClassDef)
700             symbol.needConstructor = true;
701          else if(def.type == functionClassDef)
702          {
703             ClassFunction func = def.function;
704             if(func.isDestructor)
705             {
706                if(destructor)
707                {
708                   yylloc = loc;
709                   Compiler_Error($"redefinition of destructor for class %s\n", symbol.string);
710                }
711                else
712                {
713                   symbol.needDestructor = true;
714                   destructor = func;
715                   if(!inCompiler && func.body)
716                   {
717                      // Add this to the context
718                      Symbol thisSymbol
719                      {
720                         string = CopyString("this");
721                         type = MkClassType(regClass.fullName);
722                      };
723                      func.body.compound.context.symbols.Add((BTNode)thisSymbol);
724                   }
725                }
726             }
727             if(func.isConstructor)
728             {
729                if(constructor)
730                {
731                   yylloc = loc;
732                   Compiler_Error($"redefinition of constructor for class %s\n", symbol.string);
733                }
734                else
735                {
736                   symbol.needConstructor = true;
737                   constructor = func;
738
739                   if(!inCompiler && func.body)
740                   {
741                      // Add this to the context
742                      Symbol thisSymbol
743                      {
744                         string = CopyString("this");
745                         type = MkClassType(regClass.fullName);
746                      };
747                      func.body.compound.context.symbols.Add((BTNode)thisSymbol);
748                   }
749                }
750             }
751          }
752       }
753    }
754
755    if(inCompiler)
756    {
757       external.symbol = null;      // curExternal.symbol = null;
758
759       if(list->count)
760       {
761          // We need a struct
762          OldList * specs = MkList(), * declarators = (initDeclarators != null) ? initDeclarators : MkList();
763          initDeclarators = null;
764
765          /*
766          structName[0] = 0;
767          FullClassNameCat(structName, symbol.string, false);
768          */
769          // TESTING THIS HERE INSTEAD:
770          strcpy(structName, symbol.string);
771          symbol.structName = CopyString(structName);
772
773          {
774             Specifier spec = MkStructOrUnion(structSpecifier, MkIdentifier(structName),
775                isUnion ? MkListOne(MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkStructOrUnion(unionSpecifier, null, list)), null, null))) : list);
776             spec.extDeclStruct = extDecl;
777             ListAdd(specs, spec);
778          }
779
780          external.symbol = symbol;
781          // TOFIX : Fix this...
782          symbol.structExternal = external;
783
784          external.declaration = MkDeclaration(specs, declarators);
785          after = external;
786
787          symbol.declaredStruct = true;
788       }
789       else
790       {
791          curExternal = external.prev;
792          defs.Remove(external);
793          FreeExternal(external);
794          delete list;
795       }
796
797       // TODO: Deal with declaration id issues...
798       if(classDataList->count)
799       {
800          // We need a struct
801          char classDataStructName[1024];
802          OldList * specs = MkList();
803          External external;
804
805          strcpy(classDataStructName, "__ecereClassData_");
806          FullClassNameCat(classDataStructName, symbol.string, false);
807
808          declMode = structDeclMode = defaultAccess;
809          ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(classDataStructName), classDataList));
810          external = MkExternalDeclaration(MkDeclaration(specs, null));
811          defs.Insert(after, external);
812          after = external;
813          symbol.classData = true;
814       }
815       else
816          delete classDataList;
817    }
818
819    if(inCompiler)
820    {
821       // Class
822       {
823          OldList * specs = MkList(), * declarators = MkList();
824          strcpy(className, "__ecereClass_");
825          FullClassNameCat(className, symbol.string, true);
826
827          //MangleClassName(className);
828
829          symbol.className = CopyString(className);
830
831          if(!strstr(sourceFile, ".main.ec"))
832             ListAdd(specs, MkSpecifier(STATIC));
833          ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
834          ListAdd(declarators, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null),
835             MkDeclaratorIdentifier(MkIdentifier(className))), null));
836
837          symbol.methodExternal = MkExternalDeclaration(MkDeclaration(specs, declarators));
838          defs.Insert(after, symbol.methodExternal);
839          after = symbol.methodExternal;
840       }
841
842       // Build the destructor
843       if(symbol.needDestructor)
844       {
845          ClassFunction function;
846          OldList * specs = MkList();
847          Declarator decl;
848          Statement body;
849          Context context;
850          OldList * declarations = null, * statements;
851
852          strcpy(destructorName, "__ecereDestructor_");
853          FullClassNameCat(destructorName, symbol.string, false);
854
855          symbol.destructorName = CopyString(destructorName);
856
857          ListAdd(specs, MkSpecifier(VOID));
858
859          context = PushContext();
860
861          statements = MkList();
862
863          if(definitions != null)
864          {
865             for(def = definitions.first; def; def = def.next)
866             {
867                // Get rid of stuff
868                if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
869                {
870                   Instantiation inst = def.decl.inst;
871                   Symbol classSym = inst._class.symbol;
872                   /*if(!classSym)
873                      classSym = inst._class.symbol = FindClass(inst._class.name);*/
874                   if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass))
875                   {
876                      /*  FIX a DecRef declaration problem...
877                      // Decrement counter if it isn't a simple class
878                      ListAdd(statements,
879                         MkExpressionStmt(MkListOne(MkExpCall(
880                            MkExpIdentifier(MkIdentifier("ecere::com::eInstance_DecRef")),
881                            MkListOne(CopyExpression(inst.exp))))));
882                      */
883                      Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
884                      ListAdd(statements, MkExpressionStmt(MkListOne(exp)));
885                   }
886                   if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == noHeadClass))
887                   {
888                      Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
889                      ListAdd(statements, MkExpressionStmt(MkListOne(exp)));
890                   }
891                }
892             }
893          }
894
895          if(destructor && destructor.body)
896          {
897             /*
898             declarations = destructor.body.compound.declarations;
899             if(destructor.body.compound.statements)
900             {
901                Statement stmt;
902                while(stmt = destructor.body.compound.statements.first)
903                {
904                   destructor.body.compound.statements->Remove(stmt);
905                   statements->Add(stmt);
906                }
907             }
908             */
909             // statements->Add(destructor.body);
910             statements->Insert(null, destructor.body);
911             destructor.body.compound.context.parent = context;
912             destructor.body = null;
913          }
914
915          body = MkCompoundStmt(declarations, statements);
916          PopContext(context);
917          body.compound.context = context;
918
919          decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(destructorName)), null);
920
921          // Destructor will have same Symbol ID as class
922          decl.symbol = Symbol
923          {
924             id = symbol.id;
925             idCode = symbol.idCode;
926             //id = symbol.endid;
927          };
928          excludedSymbols->Add(decl.symbol);
929
930          function = MkClassFunction(specs, null, decl, null);
931          ProcessClassFunctionBody(function, body);
932          function.id = symbol.id;
933          function.idCode = symbol.idCode;
934          //function.id = symbol.endid;
935          function.dontMangle = true;
936          definitions.Insert(null, MkClassDefFunction(function));
937       }
938
939       // Build the constructor
940
941       if(symbol.needConstructor && inCompiler)
942       {
943          ClassFunction function;
944          OldList * specs = MkList();
945          Declarator decl;
946          Statement body;
947          Context context;
948          OldList * declarations = null, * statements;
949
950          strcpy(constructorName, "__ecereConstructor_");
951          FullClassNameCat(constructorName, symbol.string, false);
952
953          symbol.constructorName = CopyString(constructorName);
954
955          ListAdd(specs, MkSpecifierName/*MkClassName*/("bool"));
956
957          context = PushContext();
958
959          statements = MkList();
960
961          if(definitions != null)
962          {
963             for(def = definitions.first; def; def = def.next)
964             {
965                if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
966                {
967                   Instantiation inst = def.decl.inst;
968                   Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
969                   /*if(!classSym)
970                      classSym = inst._class.symbol = FindClass(inst._class.name);*/
971
972                   if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass))
973                   {
974                      Instantiation newInst { };
975                      *newInst = *inst;
976                      newInst.members = null;
977                      newInst.exp = CopyExpression(inst.exp);
978                      newInst._class = CopySpecifier(inst._class);
979
980                      ListAdd(statements,
981                         MkExpressionStmt(MkListOne(MkExpInstance(newInst))));
982                      inst.built = true;
983                   }
984
985                   // Increment counter if it isn't a simple class
986                   if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass))
987                   {
988                      ListAdd(statements,
989                         MkExpressionStmt(MkListOne(MkExpCall(
990                            MkExpIdentifier(MkIdentifier("ecere::com::eInstance_IncRef")),
991                            MkListOne(CopyExpression(inst.exp))))));
992                   }
993                }
994             }
995
996             for(def = definitions.first; def; def = def.next)
997             {
998                // Add the default data properties/members
999                if(def.type == defaultPropertiesClassDef && def.defProperties)
1000                {
1001                   MemberInit propertyDef;
1002                   for(propertyDef = def.defProperties->first; propertyDef; propertyDef = propertyDef.next)
1003                   {
1004                      Expression memberExp;
1005                      Identifier id = propertyDef.identifiers->first;
1006                      if(id)
1007                      {
1008                         memberExp = MkExpMember(MkExpIdentifier(MkIdentifier("this")), id);
1009                         for(id = id.next; id; id = id.next)
1010                            memberExp = MkExpMember(memberExp, id);
1011
1012                         // ASSUME: No list initializers here
1013                         ListAdd(statements,
1014                            MkExpressionStmt(MkListOne(MkExpOp(memberExp, '=',
1015                               (propertyDef.initializer && propertyDef.initializer.type == expInitializer ? propertyDef.initializer.exp : null)))));
1016
1017                      }
1018                      // Take it out of there...
1019                      if(propertyDef.initializer)
1020                      {
1021                         if(propertyDef.initializer.type == expInitializer)
1022                            propertyDef.initializer.exp = null;
1023                         FreeInitializer(propertyDef.initializer);
1024                      }
1025                      propertyDef.initializer = null;
1026                      propertyDef.identifiers->Clear();
1027                   }
1028                }
1029             }
1030             for(def = definitions.first; def; def = def.next)
1031             {
1032                // Instanciate stuff
1033                if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
1034                {
1035                   Instantiation inst = def.decl.inst;
1036                   Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1037                   /*if(!classSym)
1038                      classSym = inst._class.symbol = FindClass(inst._class.name);*/
1039
1040                   if(inst.exp || (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass))
1041                   {
1042                      // Only needed here if members are set...
1043                      if(!(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass)) || (inst.members && inst.members->count))
1044                      {
1045                         // Is it safe to take it out here?
1046                         def.decl.inst = null;
1047
1048                         ListAdd(statements,
1049                            MkExpressionStmt(MkListOne(MkExpInstance(inst))));
1050                      }
1051                   }
1052                }
1053             }
1054          }
1055
1056          if(constructor && constructor.body)
1057          {
1058             /*
1059             declarations = constructor.body.compound.declarations;
1060
1061             if(constructor.body.compound.declarations)
1062             {
1063                Declaration decl;
1064                while(decl = constructor.body.compound.declarations.first)
1065                {
1066                   constructor.body.compound.declarations->Remove(decl);
1067                   declarations->Add(decl);
1068                }
1069             }
1070
1071             // We want to keep the context here...
1072             if(constructor.body.compound.statements)
1073             {
1074                Statement stmt;
1075                while(stmt = constructor.body.compound.statements.first)
1076                {
1077                   constructor.body.compound.statements->Remove(stmt);
1078                   statements->Add(stmt);
1079                }
1080             }
1081             */
1082             statements->Add(constructor.body);
1083             constructor.body.compound.context.parent = context;
1084             constructor.body = null;
1085          }
1086
1087          ListAdd(statements, MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("true")))));
1088          body = MkCompoundStmt(declarations, statements);
1089          PopContext(context);
1090          body.compound.context = context;
1091
1092          decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(constructorName)), null);
1093
1094          // Constructor will have same Symbol ID as class
1095          decl.symbol = Symbol { };
1096          excludedSymbols->Add(decl.symbol);
1097
1098          //*decl.symbol = *symbol;
1099          decl.symbol.id = symbol.id;
1100          decl.symbol.idCode = symbol.idCode;
1101          //decl.symbol.id = symbol.endid;
1102
1103          function = MkClassFunction(specs, null, decl, null);
1104          ProcessClassFunctionBody(function, body);
1105          function.id = symbol.id;
1106          function.idCode = symbol.idCode;
1107          //function.id = symbol.endid;
1108          function.dontMangle = true;
1109          if(definitions != null)
1110             definitions.Insert(null, MkClassDefFunction(function));
1111       }
1112    }
1113
1114    // list = null;   // Why was this here?
1115
1116    // Do the functions
1117    if(definitions != null)
1118    {
1119       for(def = definitions.first; def; def = def.next)
1120       {
1121          if(def.type == propertyClassDef && def.propertyDef)
1122          {
1123             PropertyDef propertyDef = def.propertyDef;
1124             ClassDef after = def;
1125             ClassDef newDef;
1126
1127             if(inCompiler)
1128             {
1129                yylloc = propertyDef.loc;
1130                if(!NameSpaceContained(regClass.nameSpace, &regClass.module.privateNameSpace) && def.memberAccess == publicAccess)
1131                   CheckPublicDataType(propertyDef.symbol.type, publicAccess, "class property");
1132                else if(!symbol.isStatic)
1133                   CheckPublicDataType(propertyDef.symbol.type, privateAccess, "class property");
1134             }
1135
1136             {
1137                // Commented this out...  Why exactly?
1138                //if(inCompiler)
1139                {
1140                   ClassFunction func;
1141                   Declarator decl;
1142                   char name[1024];
1143                   OldList * params;
1144                   if(propertyDef.getStmt && propertyDef.id)
1145                   {
1146                      strcpy(name, "__ecereProp_");
1147                      FullClassNameCat(name, symbol.string, false);
1148                      strcat(name, "_Get_");
1149                      // strcat(name, propertyDef.id.string);
1150                      FullClassNameCat(name, propertyDef.id.string, true);
1151                      //MangleClassName(name);
1152
1153                      params = MkList();
1154
1155                      // decl = MkDeclaratorFunction(PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier(name))), params);
1156
1157                      if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1158                         propertyDef.symbol.type._class.registered.type == structClass)
1159                      {
1160                         ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), MkDeclaratorIdentifier(MkIdentifier("value"))));
1161                         decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params));
1162
1163                         func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, decl, null);
1164
1165                         // Take it out here...
1166                         //propertyDef.specifiers = null;
1167                      }
1168                      else
1169                      {
1170                         decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params));
1171
1172                         func = MkClassFunction(CopyList(propertyDef.specifiers, CopySpecifier),
1173                            null, decl, null);
1174                      }
1175
1176                      ProcessClassFunctionBody(func, propertyDef.getStmt);
1177                      func.declarator.symbol = propertyDef.symbol;
1178                      //func.declarator.propSymbol = propertyDef.symbol;
1179                      propertyDef.symbol.externalGet = (External)func;
1180
1181                      func.dontMangle = true;
1182                      newDef = MkClassDefFunction(func);
1183                      definitions.Insert(after, newDef);
1184                      after = newDef;
1185
1186                      if(inCompiler)
1187                         propertyDef.getStmt = null;
1188                      else
1189                         func.body = null;
1190                   }
1191                   if(propertyDef.setStmt && propertyDef.id)
1192                   {
1193                      OldList * specifiers = MkList();
1194
1195                      strcpy(name, "__ecereProp_");
1196                      FullClassNameCat(name, symbol.string, false);
1197                      strcat(name, "_Set_");
1198                      //strcat(name, propertyDef.id.string);
1199                      FullClassNameCat(name, propertyDef.id.string, true);
1200                      //MangleClassName(name);
1201
1202                      params = MkList();
1203
1204                      ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier),
1205                         PlugDeclarator(propertyDef.declarator,
1206                            MkDeclaratorIdentifier(MkIdentifier("value")))));
1207
1208                      // Add const to DB table rows properties Set
1209                      if(propertyDef.isDBProp)
1210                      {
1211                         Specifier spec;
1212                         OldList * specs = ((TypeName)params->last).qualifiers;
1213
1214                         for(spec = specs->first; spec; spec = spec.next)
1215                            if(spec.type == baseSpecifier && spec.specifier == CONST)
1216                               break;
1217                         if(!spec)
1218                            specs->Insert(null, MkSpecifier(CONST));
1219                      }
1220
1221                      // Take it out here...
1222                      //propertyDef.specifiers = null;
1223
1224                      decl = MkDeclaratorFunction(
1225                         MkDeclaratorIdentifier(MkIdentifier(name)), params);
1226
1227                      {
1228                         bool isConversion = propertyDef.symbol._property && propertyDef.symbol._property.conversion;
1229                         bool useVoid = false;
1230                         switch(regClass.type)
1231                         {
1232                            case structClass: case unionClass:  useVoid = true; break;
1233                            case noHeadClass: case normalClass: useVoid = !isConversion; break;
1234                            default:
1235                               useVoid = !isConversion;
1236                               if(useVoid && !propertyDef.isDBProp)
1237                                  Compiler_Warning($"set defined on type without storage for non-conversion property\n");
1238                         }
1239                         ListAdd(specifiers, useVoid ? MkSpecifier(VOID) : MkSpecifierName(regClass.fullName));
1240                      }
1241
1242                      func = MkClassFunction(specifiers, null, decl, null);
1243                      ProcessClassFunctionBody(func, propertyDef.setStmt);
1244                      func.dontMangle = true;
1245                      func.declarator.symbol = propertyDef.symbol;
1246                      //func.declarator.propSymbol = propertyDef.symbol;
1247                      propertyDef.symbol.externalSet = (External)func;
1248                      if(!propertyDef.conversion && regClass.type == normalClass)
1249                         func.propSet = propertyDef.symbol;
1250
1251                      /*
1252
1253                      func.declarator.symbol = Symbol { id = propertyDef.symbol.id + 1 };
1254                      //func.declarator.symbol.methodExternal = (External)func;
1255                      */
1256
1257                      newDef = MkClassDefFunction(func);
1258                      definitions.Insert(after, newDef);
1259                      after = newDef;
1260
1261                      if(inCompiler)
1262                         propertyDef.setStmt = null;
1263                      else
1264                         func.body = null;
1265                   }
1266                   if(propertyDef.issetStmt && propertyDef.id)
1267                   {
1268                      OldList * specifiers = MkList();
1269
1270                      strcpy(name, "__ecereProp_");
1271                      FullClassNameCat(name, symbol.string, false);
1272                      strcat(name, "_IsSet_");
1273                      //strcat(name, propertyDef.id.string);
1274                      FullClassNameCat(name, propertyDef.id.string, true);
1275                      //MangleClassName(name);
1276
1277                      params = MkList();
1278
1279                      decl = MkDeclaratorFunction(
1280                         MkDeclaratorIdentifier(MkIdentifier(name)), params);
1281
1282                      ListAdd(specifiers, MkSpecifierName("bool"));
1283
1284                      func = MkClassFunction(specifiers, null, decl, null);
1285                      ProcessClassFunctionBody(func, propertyDef.issetStmt);
1286                      func.dontMangle = true;
1287                      func.declarator.symbol = propertyDef.symbol;
1288                      //func.declarator.propSymbol = propertyDef.symbol;
1289                      propertyDef.symbol.externalIsSet = (External)func;
1290
1291                      /*
1292
1293                      func.declarator.symbol = Symbol { id = propertyDef.symbol,id + 1, external = (External)func };
1294                      */
1295
1296                      newDef = MkClassDefFunction(func);
1297                      definitions.Insert(after, newDef);
1298                      after = newDef;
1299
1300                      if(inCompiler)
1301                         propertyDef.issetStmt = null;
1302                      else
1303                         func.body = null;
1304                   }
1305                   if(propertyDef.id && inCompiler)
1306                   {
1307                      // Had to put this here because not all properties go through DeclareProperty
1308                      Property prop = eClass_FindProperty(symbol.registered, propertyDef.id.string, privateModule);
1309
1310                      Declaration decl;
1311                      External external;
1312                      OldList * specifiers = MkList();
1313                      specifiers->Insert(null, MkSpecifier(STATIC));
1314                      ListAdd(specifiers, MkSpecifierName("Property"));
1315                      strcpy(name, "__ecereProp_");
1316                      FullClassNameCat(name, symbol.string, false);
1317                      strcat(name, "_");
1318                      //strcat(name, propertyDef.id.string);
1319                      FullClassNameCat(name, propertyDef.id.string, true);
1320                      //MangleClassName(name);
1321
1322                      {
1323                         OldList * list = MkList();
1324                         ListAdd(list, MkInitDeclarator(/*MkDeclaratorPointer(MkPointer(null, null), */
1325                               MkDeclaratorIdentifier(MkIdentifier(name))/*)*/, null));
1326
1327                         strcpy(name, "__ecerePropM_");
1328                         FullClassNameCat(name, symbol.string, false);
1329                         strcat(name, "_");
1330                         //strcat(name, propertyDef.id.string);
1331                         FullClassNameCat(name, propertyDef.id.string, true);
1332                         //MangleClassName(name);
1333
1334                         ListAdd(list, MkInitDeclarator(/*MkDeclaratorPointer(MkPointer(null, null), */
1335                               MkDeclaratorIdentifier(MkIdentifier(name))/*)*/, null));
1336                         decl = MkDeclaration(specifiers, list);
1337                      }
1338                      external = MkExternalDeclaration(decl);
1339                      ast->Insert(curExternal ? curExternal.prev : null, external);
1340                      external.symbol = propertyDef.symbol;
1341
1342                      // Setting it in the Property as well here to prevent DeclareProperty to declare it a second time...
1343                      propertyDef.symbol.externalPtr = external;
1344
1345                      if(inCompiler && prop && prop.symbol)
1346                         ((Symbol)prop.symbol).externalPtr = external;
1347                   }
1348                }
1349             }
1350          }
1351          else if(def.type == classPropertyClassDef && def.propertyDef)
1352          {
1353             PropertyDef propertyDef = def.propertyDef;
1354             ClassDef after = def;
1355             ClassDef newDef;
1356             {
1357                if(inCompiler)
1358                {
1359                   yylloc = propertyDef.loc;
1360
1361                   if(!NameSpaceContained(regClass.nameSpace, &regClass.module.privateNameSpace))
1362                      CheckPublicDataType(propertyDef.symbol.type, publicAccess, "classwide property");
1363                   else if(!symbol.isStatic)
1364                      CheckPublicDataType(propertyDef.symbol.type, privateAccess, "classwide property");
1365                }
1366
1367                // Commented this out...  Why exactly?
1368                //if(inCompiler)
1369                {
1370                   ClassFunction func;
1371                   Declarator decl;
1372                   char name[1024];
1373                   OldList * params;
1374                   if(propertyDef.getStmt && propertyDef.id)
1375                   {
1376                      Declarator declId;
1377
1378                      sprintf(name, "class::__ecereClassProp_");
1379                      FullClassNameCat(name, symbol.string, false);
1380                      strcat(name, "_Get_");
1381                      strcat(name, propertyDef.id.string);
1382                      //MangleClassName(name);
1383
1384                      params = MkList();
1385
1386                      declId = MkDeclaratorIdentifier(MkIdentifier(name));
1387
1388                      // Class properties returns a uint64 even for struct types
1389                      /*if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1390                         propertyDef.symbol.type._class.registered.type == structClass)
1391                      {
1392                         // ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), MkDeclaratorIdentifier(MkIdentifier("value"))));
1393                         //decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1394                         decl = MkDeclaratorFunction(declId, params);
1395                         ListAdd(params, MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorIdentifier(MkIdentifier("_value"))));
1396
1397                         func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, decl, null);
1398                         {
1399                            Declarator ptrDecl;
1400                            Statement body = propertyDef.getStmt;
1401                            decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1402                            if(!body.compound.declarations)
1403                               body.compound.declarations = MkList();
1404                            ListAdd(body.compound.declarations,
1405                               MkDeclaration(CopyList(propertyDef.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(
1406                                  ptrDecl = MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("value"))), MkInitializerAssignment(MkExpCast(MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), CopyDeclarator(propertyDef.declarator)),
1407                                     MkExpIdentifier(MkIdentifier("_value"))))))));
1408                            {
1409                               Symbol sym = ptrDecl.symbol;
1410                               sym.isParam = true;
1411                               FreeType(sym.type);
1412                               sym.type = ProcessType(propertyDef.specifiers, propertyDef.declarator);
1413                            }
1414                         }
1415                      }
1416                      else
1417                      */
1418                      {
1419                         //decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1420                         decl = MkDeclaratorFunction(declId, params);
1421                         //func = MkClassFunction(CopyList(propertyDef.specifiers, CopySpecifier), null, decl, null);
1422                         func = MkClassFunction(MkListOne(MkSpecifierName("uint64")), null, decl, null);
1423                      }
1424
1425                      ProcessClassFunctionBody(func, propertyDef.getStmt);
1426                      func.declarator.symbol = propertyDef.symbol;
1427                      propertyDef.symbol.externalGet = (External)func;
1428
1429                      func.dontMangle = true;
1430
1431                      newDef = MkClassDefFunction(func);
1432                      definitions.Insert(after, newDef);
1433                      after = newDef;
1434
1435                      decl = MkDeclaratorFunction(propertyDef.declarator, null);
1436                      func.type = ProcessType(propertyDef.specifiers, decl);
1437                      decl.declarator = null;
1438                      FreeDeclarator(decl);
1439
1440                      if(func.type.returnType.kind == TypeKind::classType && func.type.returnType._class && func.type.returnType._class.registered && func.type.returnType._class.registered.type == structClass)
1441                         func.type.returnType.byReference = true;
1442
1443                      if(inCompiler)
1444                         propertyDef.getStmt = null;
1445                      else
1446                         func.body = null;
1447                   }
1448                   if(propertyDef.setStmt && propertyDef.id)
1449                   {
1450                      Context prevCurContext;
1451                      OldList * specifiers = MkList();
1452                      Statement body = propertyDef.setStmt;
1453                      Declarator ptrDecl;
1454
1455                      strcpy(name, "class::__ecereClassProp_");
1456                      FullClassNameCat(name, symbol.string, false);
1457                      strcat(name, "_Set_");
1458                      strcat(name, propertyDef.id.string);
1459                      //MangleClassName(name);
1460
1461                      params = MkList();
1462                      /*
1463                      ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier),
1464                         PlugDeclarator(propertyDef.declarator,
1465                            MkDeclaratorIdentifier(MkIdentifier("value")))));
1466                      */
1467
1468                      prevCurContext = curContext;
1469                      curContext = body.compound.context;
1470
1471                      ListAdd(params, MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorIdentifier(MkIdentifier("_value"))));
1472
1473                      decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params);
1474                      if(!body.compound.declarations)
1475                         body.compound.declarations = MkList();
1476
1477                      if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1478                         propertyDef.symbol.type._class.registered.type == structClass)
1479                         ptrDecl = MkDeclaratorPointer(MkPointer(null, null), PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier("value"))));
1480                      else
1481                         ptrDecl = PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier("value")));
1482
1483                      ListAdd(body.compound.declarations,
1484                         MkDeclaration(CopyList(propertyDef.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(ptrDecl,
1485                               MkInitializerAssignment(MkExpCast(MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), CopyDeclarator(propertyDef.declarator)),
1486                               MkExpIdentifier(MkIdentifier("_value"))))))));
1487
1488                      curContext = prevCurContext;
1489
1490                      {
1491                         Symbol sym = ptrDecl.symbol;
1492                         sym.isParam = true;
1493                         FreeType(sym.type);
1494                         sym.type = ProcessType(propertyDef.specifiers, propertyDef.declarator);
1495                      }
1496                      ListAdd(specifiers, MkSpecifier(VOID));
1497
1498                      func = MkClassFunction(specifiers, null, decl, null);
1499                      ProcessClassFunctionBody(func, propertyDef.setStmt);
1500                      func.dontMangle = true;
1501                      func.declarator.symbol = propertyDef.symbol;
1502                      propertyDef.symbol.externalSet = (External)func;
1503
1504                      newDef = MkClassDefFunction(func);
1505                      definitions.Insert(after, newDef);
1506                      after = newDef;
1507
1508                      if(inCompiler)
1509                         propertyDef.setStmt = null;
1510                      else
1511                         func.body = null;
1512
1513                   }
1514                }
1515             }
1516          }
1517          else if(def.type == functionClassDef && def.function.declarator)
1518          {
1519             ClassFunction func = def.function;
1520
1521             func._class = regClass;
1522             // Add ecereMethod_[class]_ to the declarator
1523             if(!func.dontMangle)
1524             {
1525                Declarator funcDecl = GetFuncDecl(func.declarator);
1526                Identifier id = GetDeclId(funcDecl);
1527                Method method;
1528
1529                if(!funcDecl.function.parameters || !funcDecl.function.parameters->first)
1530                {
1531                   if(!funcDecl.function.parameters)
1532                      funcDecl.function.parameters = MkList();
1533                   ListAdd(funcDecl.function.parameters, MkTypeName(MkListOne(MkSpecifier(VOID)), null));
1534                }
1535
1536                method = eClass_FindMethod(regClass, id.string, privateModule);
1537
1538                FreeSpecifier(id._class);
1539                id._class = null;
1540                if(inCompiler && method)
1541                {
1542                   char * newId = new char[strlen(id.string) + strlen("__ecereMethod___ecereNameSpace__") + strlen(symbol.string) + 2];
1543                   newId[0] = '\0';
1544
1545                   ProcessMethodType(method);
1546                   yylloc = def.loc;
1547                   if(!NameSpaceContained(regClass.nameSpace, &regClass.module.privateNameSpace) && method.memberAccess == publicAccess)
1548                      CheckPublicDataType(method.dataType, publicAccess, "class method");
1549                   /* HAVE TO RELAX THIS SINCE static CAN'T QUALIFY METHODS YET... (Conflict with C++ static meaning)
1550                   else if(!symbol.isStatic)
1551                      CheckPublicDataType(method.dataType, privateAccess, "class method");
1552                   */
1553
1554                   strcpy(newId, "__ecereMethod_");
1555                   FullClassNameCat(newId, symbol.string, false);
1556                   strcat(newId, "_");
1557                   strcat(newId, id.string);
1558
1559                   delete id.string;
1560
1561                   id.string = newId;
1562
1563                   if(method.type != virtualMethod)
1564                   {
1565                      if(method.symbol)
1566                      {
1567                         delete ((Symbol)method.symbol).string;
1568                         ((Symbol)method.symbol).string = CopyString(newId);
1569                      }
1570                   }
1571                }
1572             }
1573          }
1574       }
1575    }
1576
1577    if(initDeclarators != null)
1578       FreeList(initDeclarators, FreeInitDeclarator);
1579 }
1580
1581 public void PreProcessClassDefinitions()
1582 {
1583    External external, next;
1584
1585    curExternal = null;
1586
1587    if(ast)
1588    {
1589       for(external = ast->first; external; external = next)
1590       {
1591          next = external.next;
1592          curExternal = external;
1593          if(external.type == classExternal)
1594          {
1595             ClassDefinition _class = external._class;
1596             if(_class.definitions)
1597             {
1598                ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, null);
1599             }
1600          }
1601          else if(external.type == declarationExternal)
1602          {
1603             Declaration declaration = external.declaration;
1604             if(declaration.type == initDeclaration)
1605             {
1606                if(declaration.specifiers)
1607                {
1608                   Specifier specifier;
1609                   for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
1610                   {
1611                      if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
1612                         (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
1613                      {
1614                         Symbol symbol = FindClass(specifier.id.string);
1615                         if(symbol)
1616                         {
1617                            OldList * initDeclarators = null;
1618                            ExtDecl extDecl = specifier.extDeclStruct;
1619                            specifier.extDeclStruct = null;
1620                            if(inCompiler)
1621                            {
1622                               // Give the declarators away to ProcessClass
1623                               // It will include the declarators in the class if appropriate, otherwise free them
1624                               initDeclarators = declaration.declarators;
1625                               declaration.declarators = null;
1626                            }
1627                            ProcessClass((specifier.type == unionSpecifier) ? unionClass : normalClass, specifier.definitions,
1628                               symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev,
1629                               initDeclarators, extDecl);
1630                         }
1631                      }
1632                   }
1633                }
1634             }
1635             else if(inCompiler && declaration.type == defineDeclaration)
1636             {
1637                yylloc = declaration.loc;
1638                if(declaration.declMode == publicAccess)
1639                   CheckPublicExpression(declaration.exp, publicAccess);
1640                else if(declaration.declMode != staticAccess)
1641                   CheckPublicExpression(declaration.exp, privateAccess);
1642             }
1643          }
1644          else if(external.type == importExternal)
1645          {
1646             //ImportModule(external._import);
1647          }
1648          else if(inCompiler && external.type == functionExternal)
1649          {
1650             yylloc = external.function.loc;
1651             if(!external.function.type)
1652                external.function.type = ProcessType(external.function.specifiers, external.function.declarator);
1653             if(external.function.declMode == publicAccess)
1654                CheckPublicDataType(external.function.type, publicAccess, "function");
1655             else if(external.function.declMode != staticAccess)
1656                CheckPublicDataType(external.function.type, privateAccess, "function");
1657          }
1658       }
1659    }
1660 }