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