sdk: Fixed many warnings and related problems
[sdk] / compiler / libec / src / pass1.ec
1 import "ecdefs"
2
3 // UNTIL IMPLEMENTED IN GRAMMAR
4 #define ACCESS_CLASSDATA(_class, baseClass) \
5    (_class ? ((void *)(((char *)_class.data) + baseClass.offsetClass)) : null)
6
7 #define YYLTYPE Location
8 #include "grammar.h"
9
10 static Statement registerModuleBody;
11 static External registerModuleExternal;
12 static Statement unregisterModuleBody;
13 static External unregisterModuleExternal;
14
15 extern int propWatcherID;
16
17 bool buildingECERECOM = false;
18 public void SetBuildingEcereCom(bool b) { buildingECERECOM = b; } public bool GetBuildingEcereCom() { return buildingECERECOM; }
19 bool buildingECERECOMModule = false;
20 public void SetBuildingEcereComModule(bool b) { buildingECERECOMModule = b; } public bool GetBuildingEcereComModule() { return buildingECERECOMModule; }
21
22 // This will also be called by the instance processer to make the instance methods... (pass 1.5)
23 External ProcessClassFunction(Class owningClass, ClassFunction func, OldList defs, External after, bool makeStatic)
24 {
25    Type type = null;
26    Symbol symbol;
27    External external = null;
28
29    if(defs && func.declarator)
30    {
31       FunctionDefinition function = null;
32       Symbol propSymbol;
33       int symid = func.declarator.symbol.id;
34       int symidCode = func.declarator.symbol.idCode;
35
36       if(inCompiler)
37       {
38          if(!func.specifiers)
39             func.specifiers = MkList();
40          // Add static to the specifiers
41          if(makeStatic)
42             func.specifiers->Insert(null, MkSpecifier(STATIC));
43       }
44
45       propSymbol = func.declarator.symbol;
46
47       ReplaceThisClassSpecifiers(func.specifiers, owningClass);
48
49       if(propSymbol.externalGet == (External)func)
50          func.declarator.symbol = null;
51       else if(propSymbol.externalSet == (External)func)
52       {
53          func.declarator.symbol = null;
54          symid++;
55       }
56       else if(propSymbol.externalIsSet == (External)func)
57       {
58          func.declarator.symbol = null;
59          symid += 2; // TOFIX: What should we do with this? Where are 2 IDs allocated for properties? In MkProperty...
60       }
61
62       //if(inCompiler)
63       {
64          /*FunctionDefinition*/ function = _MkFunction(func.specifiers, func.declarator, null, false);
65          function.propSet = func.propSet;
66          function.type = func.type;
67          if(func.type) func.type.refCount++;
68          ProcessFunctionBody(function, func.body);
69          external = MkExternalFunction(function);
70
71          external.symbol = func.declarator.symbol;
72          external.function._class = func._class;
73       }
74
75       symbol = func.declarator.symbol;
76       //symbol.id = func.id; //symid;
77       symbol.id = symid;
78       symbol.idCode = symidCode;
79
80       if(!func.dontMangle)
81       {
82          // Normal method
83          Method method = func.declarator.symbol.method;
84          func.declarator.symbol.methodExternal = external;
85
86          // DANGER: Added this one...
87
88          if(method && method.symbol)
89             //((Symbol)method.symbol).methodExternal = external;
90             ((Symbol)method.symbol).methodCodeExternal = external;
91
92          if(method && method.type == virtualMethod)
93          {
94             Type methodDataType;
95             ProcessMethodType(method);
96
97             methodDataType = method.dataType;
98
99             // Do type checking here of type against method.dataType
100             // ThisClass must be the owning class for types not specified, static for static, or inherit from method's ThisClass is specified
101             // If not specified, defaults to ThisClass if ThisClass specified in method, otherwise overiding class or static
102
103             type = symbol.type;
104
105             if(!type.staticMethod && !type.thisClass && !type.thisClassTemplate)
106             {
107                if(method.dataType.thisClassTemplate)
108                {
109                   if(owningClass.templateArgs)
110                   {
111                      ClassTemplateArgument * arg = FindTemplateArg(owningClass, method.dataType.thisClassTemplate);
112                      type.byReference = method.dataType.byReference;
113
114                      methodDataType = ProcessTypeString(method.dataTypeString, false);
115                      type.thisClass = methodDataType.thisClass = arg ? FindClass(arg->dataTypeString) : null;
116                   }
117                }
118                else if(method.dataType.staticMethod)
119                   type.staticMethod = true;
120                else if(method.dataType.thisClass)
121                {
122                   type.thisClass = method.dataType.thisClass;
123                   type.byReference = method.dataType.byReference;
124                }
125                else
126                {
127                   if(!owningClass.symbol)
128                      owningClass.symbol = FindClass(owningClass.fullName);
129
130                   type.thisClass = owningClass.symbol;
131                   // WORKING ON THIS TO SUPPORT : pass.NotifyClicked(this, pass, 0, 0, key.modifiers);
132                   type.extraParam = true;
133                }
134             }
135
136             yylloc = func.loc;
137             if(!MatchTypes(type, methodDataType, null, owningClass, method._class /*owningClass*/, true, true, true, false, true))
138             {
139 #ifdef _DEBUG
140                // MatchTypes(type, methodDataType, null, owningClass, owningClass, true, true, true, false);
141 #endif
142                Compiler_Error($"Incompatible virtual function %s\n", method.name);
143             }
144             else
145             {
146                // Mark typed_object/any_object parameters as such according to method type
147                Type typeParam;
148                Declarator funcDecl = GetFuncDecl(func.declarator);
149                if(funcDecl.function.parameters && funcDecl.function.parameters->first)
150                {
151                   TypeName param = funcDecl.function.parameters->first;
152
153                   for(typeParam = methodDataType.params.first; typeParam && param; typeParam = typeParam.next)
154                   {
155                      if(typeParam.classObjectType)
156                      {
157                         param.classObjectType = typeParam.classObjectType;
158                         if(param.declarator && param.declarator.symbol)
159                            param.declarator.symbol.type.classObjectType = typeParam.classObjectType;
160                      }
161                      param = param ? param.next : null;
162                   }
163                }
164             }
165             if(methodDataType != method.dataType)
166                FreeType(methodDataType);
167          }
168          else
169          {
170             type = symbol.type;
171             if(!type.staticMethod && !type.thisClass)
172             {
173                if(owningClass && !owningClass.symbol)
174                   owningClass.symbol = FindClass(owningClass.fullName);
175
176                type.thisClass = owningClass ? FindClass(owningClass.fullName) : null;
177             }
178          }
179       }
180       else
181       {
182          // TESTING THIS HERE: (Implementing Class Properties)
183          if(symbol.type && !symbol.type.staticMethod && !symbol.type.thisClass)
184          {
185             if(!owningClass.symbol)
186                owningClass.symbol = FindClass(owningClass.fullName);
187             symbol.type.thisClass = owningClass.symbol;
188          }
189
190          // Those type of classes don't need a this parameter for Set methods, null thisClass before changing the externals
191          if(propSymbol.externalSet == (External)func && propSymbol._property && propSymbol._property.conversion)
192          {
193             if(symbol.type.thisClass && symbol.type.classObjectType != classPointer)
194             {
195                // TODO: Perhaps improve this so as to support both "this =" and "return " syntax for all types of classes
196                if(owningClass.type != structClass)
197                   //function.propertyNoThis = true;
198                   symbol.type.thisClass = null;
199             }
200          }
201
202          // Property
203          if(propSymbol.externalGet == (External)func)
204          {
205             propSymbol.externalGet = external;
206          }
207          else if(propSymbol.externalSet == (External)func)
208          {
209             propSymbol.externalSet = external;
210          }
211          else if(propSymbol.externalIsSet == (External)func)
212          {
213             propSymbol.externalIsSet = external;
214          }
215          else
216          {
217             // Constructor destructor
218             //symbol.type = Type { };
219          }
220       }
221       if(inCompiler)
222       {
223          if(func.body)
224          {
225             func.declarator = null;
226             func.specifiers = null;
227             func.body = null;
228
229             defs.Insert(after, external);
230          }
231          else
232          {
233             Method method = func.declarator.symbol.method;
234             if(method && method.symbol)
235                ((Symbol)method.symbol).methodCodeExternal = null;
236             if(func.declarator.symbol && func.declarator.symbol.methodExternal == external)
237                func.declarator.symbol.methodExternal = null;
238
239             //external.function = null;
240             func.declarator = null;
241             func.specifiers = null;
242
243             FreeExternal(external); // Free external here?
244          }
245       }
246       else
247       {
248          globalContext /*curContext*/.symbols.Remove((BTNode)symbol);
249          excludedSymbols->Add(symbol);
250
251          // Testing this...
252          defs.Insert(after, external);
253
254          external.function.declarator = CopyDeclarator(external.function.declarator);
255          external.function.specifiers = CopyList(external.function.specifiers, CopySpecifier);
256          external.function.body = null;
257       }
258    }
259    return external;
260 }
261
262 void CreateRegisterModuleBody()
263 {
264    if(!registerModuleBody && inCompiler)
265    {
266       char registerName[1024], moduleName[MAX_FILENAME];
267       OldList * specifiers;
268       Declarator declarator;
269       TypeName moduleParam;
270
271       registerModuleBody = MkCompoundStmt(MkList(), MkList());
272       registerModuleBody.compound.context = Context { parent = globalContext };
273
274       #if 0
275       ListAdd(registerModuleBody.compound.declarations,
276          MkDeclaration(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null) /*MkSpecifierName("ecere::com::Class")*/ /*MkStructOrUnion(SpecifierStruct, MkIdentifier("Class"), null)*/),
277                        MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class"))), null))));
278       #endif
279       ListAdd(registerModuleBody.compound.declarations,
280          MkDeclaration((specifiers = MkListOne(MkSpecifierName("ecere::com::Class"))),
281                        MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("class")), null))));
282       // Avoid unused warning here
283       specifiers->Add(MkSpecifierExtended(MkExtDeclAttrib(MkAttrib(ATTRIB, MkListOne(MkAttribute(CopyString("unused"), null))))));
284
285       specifiers = MkList();
286       ListAdd(specifiers, MkSpecifier(VOID));
287
288       moduleParam = MkTypeName(MkListOne(/*MkSpecifier(VOID)*/MkSpecifierName("Module")),
289          //MkDeclaratorPointer(MkPointer(null, null),
290          MkDeclaratorIdentifier(MkIdentifier("module")));
291
292       GetLastDirectory(outputFile, moduleName);
293       //strcpy(moduleName, argv[2]);
294       StripExtension(moduleName);
295       FixModuleName(moduleName);
296       sprintf(registerName, "__ecereRegisterModule_%s", moduleName);
297
298       declarator = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(registerName)),
299          MkListOne(moduleParam));
300
301       {
302          FunctionDefinition function = _MkFunction(specifiers, declarator, null, false);
303          ProcessFunctionBody(function, registerModuleBody);
304          function.declMode = defaultAccess;
305          if(!ast) ast = MkList();
306          ListAdd(ast, (registerModuleExternal = MkExternalFunction(function)));
307       }
308    }
309
310    // Unregister Module
311    if(!unregisterModuleBody && inCompiler)
312    {
313       char registerName[1024], moduleName[MAX_FILENAME];
314       OldList * specifiers;
315       Declarator declarator;
316       TypeName moduleParam;
317
318       unregisterModuleBody = MkCompoundStmt(MkList(), MkList());
319       unregisterModuleBody.compound.context = Context { parent = globalContext };
320
321       specifiers = MkList();
322       ListAdd(specifiers, MkSpecifier(VOID));
323
324       moduleParam = MkTypeName(MkListOne(/*MkSpecifier(VOID)*/ MkSpecifierName("Module")),
325          //MkDeclaratorPointer(MkPointer(null, null),
326          MkDeclaratorIdentifier(MkIdentifier("module")));
327
328       GetLastDirectory(outputFile, moduleName);
329       StripExtension(moduleName);
330       FixModuleName(moduleName);
331       //strcpy(moduleName, argv[2]);
332       sprintf(registerName, "__ecereUnregisterModule_%s", moduleName);
333
334       declarator = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(registerName)),
335          MkListOne(moduleParam));
336
337       {
338          FunctionDefinition function = _MkFunction(specifiers, declarator, null, false);
339          ProcessFunctionBody(function, unregisterModuleBody);
340          function.declMode = defaultAccess;
341          if(!ast) ast = MkList();
342          ListAdd(ast, (unregisterModuleExternal = MkExternalFunction(function)));
343       }
344    }
345 }
346
347 void RegisterMembersAndProperties(Class regClass, bool isMember, const char * className, Statement statement)
348 {
349    DataMember dataMember = isMember ? (DataMember)regClass : null;
350    DataMember member;
351    Property prop;
352    Expression exp;
353    Statement stmt;
354    char dataMemberSize[16];
355
356    uint lastOffset = 0;
357    int privateID = 0;
358    bool privateMembers = false;
359
360    sprintf(dataMemberSize, "%d", (int)sizeof(DataMember));
361    if(!isMember)
362    {
363       for(prop = regClass.conversions.first; prop; prop = prop.next)
364       {
365          OldList * args = MkList();
366          char name[1024];
367
368          // Class class
369          ListAdd(args, MkExpIdentifier(MkIdentifier(className)));
370          // char * name
371          ListAdd(args, MkExpConstant("0"));
372
373          // char * type
374          {
375             char * string = QMkString(prop.dataTypeString);
376             ListAdd(args, MkExpString(string));
377             delete string;
378          }
379          // void * Set
380          if(prop.Set)
381          {
382             strcpy(name, "__ecereProp_");
383             FullClassNameCat(name, regClass.fullName, false);
384             strcat(name, "_Set_");
385             // strcat(name, prop.name);
386             FullClassNameCat(name, prop.name, true);
387             //MangleClassName(name);
388             ListAdd(args, MkExpIdentifier(MkIdentifier(name)));
389          }
390          else
391             ListAdd(args, MkExpConstant("0"));
392          // void * Get
393          if(prop.Get)
394          {
395             strcpy(name, "__ecereProp_");
396             FullClassNameCat(name, regClass.fullName, false);
397             strcat(name, "_Get_");
398             // strcat(name, prop.name);
399             FullClassNameCat(name, prop.name, true);
400             //MangleClassName(name);
401
402             ListAdd(args, MkExpIdentifier(MkIdentifier(name)));
403          }
404          else
405             ListAdd(args, MkExpConstant("0"));
406
407
408          // Declaration Mode
409          switch(prop.memberAccess)
410          {
411             case staticAccess:
412                ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
413                break;
414             case privateAccess:
415                ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
416                break;
417             case publicAccess:
418             default:
419                ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
420                break;
421          }
422
423          strcpy(name, "__ecereProp_");
424          FullClassNameCat(name, regClass.fullName, false);
425          strcat(name, "_");
426          FullClassNameCat(name, prop.name, true);
427          // strcat(name, prop.name);
428          //MangleClassName(name);
429
430          stmt = MkExpressionStmt(MkListOne(
431             MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=',
432             MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddProperty")), args))));
433          ListAdd(registerModuleBody.compound.statements, stmt);
434       }
435    }
436
437    for(member = isMember ? dataMember.members.first : regClass.membersAndProperties.first; member; member = member.next)
438    {
439       if(member.isProperty)
440       {
441          prop = (Property) member;
442          {
443             OldList * args = MkList();
444             char name[1024], nameM[1024];
445             char * string = QMkString(prop.name);
446
447             // Class class
448             ListAdd(args, MkExpIdentifier(MkIdentifier(className)));
449
450             // char * name
451             ListAdd(args, MkExpString(string));
452             delete string;
453
454             // char * type
455             {
456                char * string = QMkString(prop.dataTypeString);
457                ListAdd(args, MkExpString(string));
458                delete string;
459             }
460             // void * Set
461             if(prop.Set)
462             {
463                strcpy(name, "__ecereProp_");
464                FullClassNameCat(name, regClass.fullName, false);
465                strcat(name, "_Set_");
466                FullClassNameCat(name, prop.name, true);
467                // strcat(name, prop.name);
468                //MangleClassName(name);
469                ListAdd(args, MkExpIdentifier(MkIdentifier(name)));
470             }
471             else
472                ListAdd(args, MkExpConstant("0"));
473             // void * Get
474             if(prop.Get)
475             {
476                strcpy(name, "__ecereProp_");
477                FullClassNameCat(name, regClass.fullName, false);
478                strcat(name, "_Get_");
479                FullClassNameCat(name, prop.name, true);
480                // strcat(name, prop.name);
481                //MangleClassName(name);
482                ListAdd(args, MkExpIdentifier(MkIdentifier(name)));
483             }
484             else
485                ListAdd(args, MkExpConstant("0"));
486
487             // Declaration Mode
488             switch(prop.memberAccess)
489             {
490                case staticAccess:
491                   ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
492                   break;
493                case privateAccess:
494                   ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
495                   break;
496                case publicAccess:
497                default:
498                   ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
499                   break;
500             }
501
502             strcpy(name, "__ecereProp_");
503             FullClassNameCat(name, regClass.fullName, false);
504             strcat(name, "_");
505             FullClassNameCat(name, prop.name, true);
506             // strcat(name, prop.name);
507             //MangleClassName(name);
508
509             strcpy(nameM, "__ecerePropM_");
510             FullClassNameCat(nameM, regClass.fullName, false);
511             strcat(nameM, "_");
512             FullClassNameCat(nameM, prop.name, true);
513             // strcat(nameM, prop.name);
514             //MangleClassName(nameM);
515
516             if(prop.dataTypeString)
517             {
518                stmt = MkExpressionStmt(MkListOne(
519                   MkExpOp(MkExpIdentifier(MkIdentifier(nameM)), '=',
520                   MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddProperty")), args))));
521             }
522             else
523             {
524                stmt = MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddProperty")), args)));
525             }
526             ListAdd(registerModuleBody.compound.statements, stmt);
527
528             if(prop.IsSet)
529             {
530                char name[1024];
531                strcpy(name, "__ecereProp_");
532                FullClassNameCat(name, regClass.fullName, true);
533                strcat(name, "_IsSet_");
534                FullClassNameCat(name, prop.name, false);
535                // strcat(name, prop.name);
536                //MangleClassName(name);
537
538                stmt = MkExpressionStmt(MkListOne(
539                   MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier(nameM)), MkIdentifier("IsSet")), '=',
540                   MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)), MkExpIdentifier(MkIdentifier(name))))));
541                ListAdd(registerModuleBody.compound.statements, stmt);
542             }
543             if(prop.symbol && ((Symbol)prop.symbol).propCategory)
544             {
545                stmt = MkExpressionStmt(MkListOne(
546                   MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier(nameM)), MkIdentifier("category")), '=',
547                   CopyExpression(((Symbol)prop.symbol).propCategory))));
548                ListAdd(registerModuleBody.compound.statements, stmt);
549             }
550
551             if(prop.dataTypeString)
552             {
553                OldList * list = MkList();
554                ListAdd(list, MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', MkExpIdentifier(MkIdentifier(nameM))));
555                ListAdd(list, MkExpOp(MkExpIdentifier(MkIdentifier(nameM)), '=', MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)), MkExpConstant("0"))));
556                // stmt = MkIfStmt(MkListOne(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier(name)))), MkExpressionStmt(list), null);
557                stmt = MkIfStmt(MkListOne(MkExpOp(
558                      MkExpMember(MkExpIdentifier(MkIdentifier("module")), MkIdentifier("application")), EQ_OP,
559                      MkExpMember(MkExpIdentifier(MkIdentifier("__thisModule")), MkIdentifier("application")))), MkExpressionStmt(list), null);
560
561                ListAdd(registerModuleBody.compound.statements, stmt);
562
563                // Unregister 2nd property
564                stmt = MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(nameM)), '=',
565                   MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)), MkExpConstant("0")))));
566                ListAdd(unregisterModuleBody.compound.statements, stmt);
567             }
568          }
569       }
570       else if(member.type == normalMember && !isMember && regClass.type == bitClass)
571       {
572          BitMember bitMember = (BitMember) member;
573          OldList * args = MkList();
574
575          // Class class
576          ListAdd(args, MkExpIdentifier(MkIdentifier(className)));
577
578          // char * name
579          {
580             char * string = QMkString(bitMember.name);
581             ListAdd(args, MkExpString(string));
582             delete string;
583          }
584          // char * type
585          {
586             char * string = QMkString(bitMember.dataTypeString);
587             ListAdd(args, MkExpString(string));
588             delete string;
589          }
590          // int bitSize
591          {
592             char string[256];
593             sprintf(string, "%d", bitMember.size);
594             ListAdd(args, (exp = MkExpConstant(string)));
595          }
596          // int bitPos
597          {
598             char string[256];
599             sprintf(string, "%d", bitMember.pos);
600             ListAdd(args, (exp = MkExpConstant(string)));
601          }
602
603          // Declaration Mode
604          switch(member.memberAccess)
605          {
606             case staticAccess:
607                ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
608                break;
609             case privateAccess:
610                ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
611                break;
612             case publicAccess:
613             default:
614                ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
615                break;
616          }
617
618          stmt = MkExpressionStmt(MkListOne(
619             MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddBitMember")), args)));
620
621          ListAdd(statement.compound.statements, stmt);
622       }
623       else if(member.memberAccess == publicAccess || (member.type == normalMember && !member.dataTypeString))
624       {
625          OldList * args;
626          // ADD PRIVATE DATA PADDING HERE...
627          if(privateMembers)
628          {
629             uint offset = member.offset - lastOffset;
630
631             args = MkList();
632
633             // Class class
634             ListAdd(args, MkExpIdentifier(MkIdentifier(className)));
635
636             // char * name
637             {
638                char string[200];
639                sprintf(string, "\"__ecerePrivateData%d\"", privateID++);
640                ListAdd(args, MkExpString(string));
641             }
642             // char * type
643             {
644                char string[200];
645                sprintf(string, "\"byte[%d]\"", offset);
646                ListAdd(args, MkExpString(string));
647             }
648             // int size
649             {
650                char string[256];
651                sprintf(string, "%d", offset);
652                ListAdd(args, (exp = MkExpConstant(string)));
653             }
654
655             // int alignment
656             ListAdd(args, (exp = MkExpConstant("1")));
657
658             // Declaration Mode
659             ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
660
661             stmt = MkExpressionStmt(MkListOne(
662                MkExpCall(MkExpIdentifier(MkIdentifier(isMember ? "eMember_AddDataMember" : "eClass_AddDataMember")), args)));
663
664             ListAdd(statement.compound.statements, stmt);
665             privateMembers = false;
666          }
667
668          if(member.type == normalMember)
669          {
670             if(!member.dataType)
671                member.dataType = ProcessTypeString(member.dataTypeString, false);
672
673             ComputeTypeSize(member.dataType);
674
675             args = MkList();
676
677             // Class class
678             ListAdd(args, MkExpIdentifier(MkIdentifier(className)));
679
680             // char * name
681             {
682                char * string = QMkString(member.name);
683                ListAdd(args, MkExpString(string));
684                delete string;
685             }
686             // char * type
687             {
688                char * string = QMkString(member.dataTypeString);
689                ListAdd(args, MkExpString(string));
690                delete string;
691             }
692             // int size
693             {
694                char string[256];
695                sprintf(string, "%d", member.dataType.size);
696                ListAdd(args, (exp = MkExpConstant(string)));
697             }
698
699             // int alignment
700             {
701                char string[256];
702                sprintf(string, "%d", member.dataType.alignment);
703                ListAdd(args, (exp = MkExpConstant(string)));
704             }
705
706             // Declaration Mode
707             switch(member.memberAccess)
708             {
709                case staticAccess:
710                   ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
711                   break;
712                case privateAccess:
713                   ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
714                   break;
715                case publicAccess:
716                default:
717                   ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
718                   break;
719             }
720
721             stmt = MkExpressionStmt(MkListOne(
722                MkExpCall(MkExpIdentifier(MkIdentifier(isMember ? "eMember_AddDataMember" : "eClass_AddDataMember")), args)));
723
724             ListAdd(statement.compound.statements, stmt);
725
726             lastOffset = member.offset + member.dataType.size;
727          }
728          else
729          {
730             static int memberCount = 0;
731
732             Context context;
733             Statement compound;
734             char memberName[256];
735             sprintf(memberName, "dataMember%d", memberCount);
736             memberCount++;
737
738             curContext = statement.compound.context;
739             context = PushContext();
740
741             args = MkListOne(MkExpIdentifier(MkIdentifier((member.type == unionMember) ? "unionMember" : "structMember")));
742
743             // Declaration Mode
744             switch(member.memberAccess)
745             {
746                case staticAccess:
747                   ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
748                   break;
749                case privateAccess:
750                   ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
751                   break;
752                case publicAccess:
753                default:
754                   ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
755                   break;
756             }
757
758             compound = MkCompoundStmt(MkListOne(MkDeclaration(MkListOne(MkSpecifierName("DataMember")),
759                MkListOne(MkInitDeclarator(/*MkDeclaratorPointer(MkPointer(null, null), */MkDeclaratorIdentifier(MkIdentifier(memberName))/*)*/,
760                   MkInitializerAssignment(MkExpCall(MkExpIdentifier(MkIdentifier("eMember_New")), args)))))), MkList());
761             compound.compound.context = context;
762
763             args = MkList();
764
765             // Class class / DataMember member
766             ListAdd(args, MkExpIdentifier(MkIdentifier(className)));
767
768             // DataMember dataMember
769             ListAdd(args, MkExpIdentifier(MkIdentifier(memberName)));
770
771             RegisterMembersAndProperties((Class)member, true, memberName, compound);
772
773             if(isMember)
774                stmt = MkExpressionStmt(MkListOne(
775                   MkExpCall(MkExpIdentifier(MkIdentifier("eMember_AddMember")), args)));
776             else
777                stmt = MkExpressionStmt(MkListOne(
778                   MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddMember")), args)));
779
780             ListAdd(compound.compound.statements, stmt);
781
782             PopContext(context);
783
784             ListAdd(statement.compound.statements, compound);
785
786             memberCount--;
787
788             lastOffset = member.offset + member.memberOffset;
789          }
790       }
791       else
792          privateMembers = true;
793    }
794
795    if(!isMember)
796    {
797       ClassProperty classProperty;
798
799       // Watchable properties
800       for(prop = regClass.membersAndProperties.first; prop; prop = prop.next)
801       {
802          if(prop.isProperty && prop.isWatchable)
803          {
804             OldList * args;
805             char name[1024], nameM[1024];
806
807             strcpy(name, "__ecereProp_");
808             FullClassNameCat(name, regClass.fullName, true);
809             strcat(name, "_");
810             FullClassNameCat(name, prop.name, false);
811             // strcat(name, prop.name);
812             //MangleClassName(name);
813
814             strcpy(nameM, "__ecerePropM_");
815             FullClassNameCat(nameM, regClass.fullName, true);
816             strcat(nameM, "_");
817             FullClassNameCat(nameM, prop.name, false);
818             // strcat(nameM, prop.name);
819             //MangleClassName(nameM);
820
821             args = MkListOne(MkExpCondition(MkExpIdentifier(MkIdentifier(nameM)), MkListOne(MkExpIdentifier(MkIdentifier(nameM))), MkExpIdentifier(MkIdentifier(name))));
822             stmt = MkExpressionStmt(MkListOne(
823                MkExpCall(MkExpIdentifier(MkIdentifier("eProperty_Watchable")), args)));
824             ListAdd(registerModuleBody.compound.statements, stmt);
825          }
826       }
827
828       // Add Class Properties
829       for(classProperty = (ClassProperty)regClass.classProperties.first; classProperty; classProperty = (ClassProperty)((BTNode)classProperty).next)
830       {
831          OldList * args = MkList();
832          char name[1024];
833          char * string = QMkString(classProperty.name);
834
835          // Class * class
836          ListAdd(args, MkExpIdentifier(MkIdentifier(className)));
837
838          // char * name
839          ListAdd(args, MkExpString(string));
840          delete string;
841
842          // char * type
843          {
844             char * string = QMkString(classProperty.dataTypeString);
845             ListAdd(args, MkExpString(string));
846             delete string;
847          }
848          // void * Set
849          if(classProperty.Set)
850          {
851             strcpy(name, "__ecereClassProp_");
852             FullClassNameCat(name, regClass.fullName, true);
853             strcat(name, "_Set_");
854             strcat(name, classProperty.name);
855             //MangleClassName(name);
856             ListAdd(args, MkExpIdentifier(MkIdentifier(name)));
857          }
858          else
859             ListAdd(args, MkExpConstant("0"));
860          // void * Get
861          if(classProperty.Get)
862          {
863             strcpy(name, "__ecereClassProp_");
864             FullClassNameCat(name, regClass.fullName, true);
865             strcat(name, "_Get_");
866             strcat(name, classProperty.name);
867             //MangleClassName(name);
868
869             ListAdd(args, MkExpIdentifier(MkIdentifier(name)));
870          }
871          else
872             ListAdd(args, MkExpConstant("0"));
873
874          stmt = MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddClassProperty")), args)));
875          ListAdd(registerModuleBody.compound.statements, stmt);
876       }
877    }
878 }
879
880 extern External curExternal;
881
882 void GetNameSpaceString(NameSpace ns, char * string)
883 {
884    if(ns.parent)
885       GetNameSpaceString(ns.parent, string);
886    if(ns.name)
887    {
888       strcat(string, ns.name);
889       strcat(string, "::");
890    }
891 }
892
893 // *******************************************************************
894 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, OldList defs, External external, AccessMode declMode)
895 {
896    ClassDef def;
897    Class regClass = symbol.registered;
898
899    if(regClass)
900    {
901       classType = regClass.type;
902       if(classType == enumClass && enumValues && (inCompiler || !buildingECERECOMModule))
903       {
904          Enumerator e;
905          for(e = enumValues.first; e; e = e.next)
906          {
907             if(e.exp)
908             {
909                Type destType
910                {
911                   kind = intType;
912                   refCount = 1;
913                };
914                e.exp.destType = destType;
915
916                // Set parsingType to avoid producing errors
917                parsingType = true;
918                ProcessExpressionType(e.exp);
919                parsingType = false;
920
921                if(!e.exp.expType)
922                {
923                   destType.kind = TypeKind::classType;
924                   destType._class = symbol;
925                   ProcessExpressionType(e.exp);
926                }
927                if(e.exp.type == identifierExp && e.exp.expType && e.exp.identifier && e.exp.identifier.string && e.exp.expType.kind == enumType)
928                {
929                   // Resolve enums here
930                   NamedLink l;
931                   char * string = e.exp.identifier.string;
932                   for(l = e.exp.expType.members.first; l; l = l.next)
933                   {
934                      if(!strcmp(l.name, string))
935                      {
936                         if(l.data)
937                         {
938                            FreeExpContents(e.exp);
939                            e.exp.type = constantExp;
940                            e.exp.constant = PrintUInt((uint)l.data);
941                            FreeType(e.exp.expType);
942                            e.exp.expType = ProcessTypeString("uint", false);
943                         }
944                         break;
945                      }
946                   }
947                }
948                else
949                   ComputeExpression(e.exp);
950                if(e.exp.isConstant && /*e.exp.expType.kind == intType*/ e.exp.type == constantExp)
951                {
952                   Operand op = GetOperand(e.exp);
953                   int value;
954                   // TODO: 64 BIT ENUM SUPPORT...
955                   switch(op.kind)
956                   {
957                      case charType: value = op.c; break;
958                      case shortType: value = op.s; break;
959                      default: value = op.i;
960                   }
961
962                   // value = op.i; //strtol(e.exp.string, null, 0);
963                   eEnum_AddFixedValue(regClass, e.id.string, value);
964                }
965                else
966                   // Sort of an error
967                   eEnum_AddValue(regClass, e.id.string);
968             }
969             else
970                eEnum_AddValue(regClass, e.id.string);
971          }
972          // Fix up derivatives enums largest
973          {
974             EnumClassData baseData = regClass.data;
975             OldLink deriv;
976             for(deriv = regClass.derivatives.first; deriv; deriv = deriv.next)
977             {
978                Class c = deriv.data;
979                if(c && c.type == enumClass)
980                {
981                   EnumClassData data = c.data;
982                   data.largest = baseData.largest;
983                }
984             }
985          }
986       }
987
988       // Process all functions
989       if(definitions != null)
990       {
991          if(inCompiler)
992          {
993             for(def = definitions.first; def; def = def.next)
994             {
995                if(def.type == propertyWatchClassDef && def.propertyWatch)
996                {
997                   PropertyWatch propWatch = def.propertyWatch;
998                   ClassFunction func;
999                   char watcherName[1024];
1000                   Identifier propID;
1001                   Statement stmt = MkExpressionStmt(MkList());
1002                   Declarator decl;
1003
1004                   sprintf(watcherName,"__ecerePropertySelfWatcher_%d", propWatcherID++);
1005                   for(propID = propWatch.properties->first; propID; propID = propID.next)
1006                   {
1007                      strcat(watcherName, "_");
1008                      strcat(watcherName, propID.string);
1009                   }
1010
1011                   // TESTING THIS STUFF... BEWARE OF SYMBOL ID ISSUES
1012                   decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(watcherName)), MkListOne(MkTypeName(MkListOne(MkSpecifier(VOID)), null)));
1013                   func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, decl, null);
1014                   ProcessClassFunctionBody(func, propWatch.compound);
1015
1016                   // TESTING WITH SAME SYMBOL ID AS CLASS
1017                   decl.symbol = Symbol
1018                   {
1019                      id = symbol.id;
1020                      idCode = symbol.idCode;
1021                   };
1022                   excludedSymbols->Add(decl.symbol);
1023
1024                   func.id = symbol.id;
1025                   func.idCode = symbol.idCode;
1026                   func.dontMangle = true;
1027
1028                   // Create a declaration above for constructor to see
1029                   {
1030                      External externalDecl = MkExternalDeclaration(null);
1031                      Declaration decl;
1032                      OldList * specifiers = MkList();
1033                      ListAdd(specifiers, MkSpecifier(STATIC));
1034                      ListAdd(specifiers, MkSpecifier(VOID));
1035
1036                      ast->Insert(curExternal.prev, externalDecl);
1037
1038                      decl = MkDeclaration(specifiers,
1039                         MkListOne(MkInitDeclarator(MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(watcherName)),
1040                            MkListOne(MkTypeName(MkListOne(MkSpecifierName(regClass.fullName)), null))), null)));
1041                      externalDecl.declaration = decl;
1042                      if(decl.symbol && !decl.symbol.methodExternal)
1043                      {
1044                         decl.symbol.methodExternal = externalDecl;
1045
1046                         // PATCHED THIS, 2 SYMBOLS WERE THERE.. THIS ONE HAD AN ID TOO BIG
1047                         decl.symbol.id = symbol.id;
1048                         decl.symbol.idCode = symbol.idCode;
1049                      }
1050                   }
1051
1052                   propWatch.compound = null;
1053                   definitions.Insert(null, MkClassDefFunction(func));
1054
1055                   for(propID = propWatch.properties->first; propID; propID = propID.next)
1056                   {
1057                      Property prop = eClass_FindProperty(regClass, propID.string, privateModule);
1058                      if(prop)
1059                      {
1060                         // eProperty_SelfWatch(_class, name, callback);
1061                         OldList * args = MkList();
1062                         ListAdd(args, MkExpIdentifier(MkIdentifier("class")));
1063                         {
1064                            char * s = QMkString(propID.string);
1065                            ListAdd(args, MkExpString(s));
1066                            delete s;
1067                         }
1068                         ListAdd(args, MkExpIdentifier(MkIdentifier(watcherName)));
1069
1070                         ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("eProperty_SelfWatch")), args));
1071                      }
1072                      else
1073                         Compiler_Error($"Property %s not found in class %s\n", propID.string, regClass.fullName);
1074                   }
1075                   FreePropertyWatch(def.propertyWatch);
1076                   def.propertyWatch = (PropertyWatch)stmt; // Store this here to use it after CreateRegisterModuleBody is done
1077
1078                   // ListAdd(statements, stmt);
1079                }
1080             }
1081          }
1082
1083          for(def = definitions.first; def; def = def.next)
1084          {
1085             if(def.type == functionClassDef)
1086             {
1087                ProcessClassFunction(regClass, def.function, defs, external.prev, declMode == staticAccess);
1088             }
1089          }
1090       }
1091
1092       // Make the RegisterClass section
1093
1094       if(inCompiler && symbol.id != MAXINT && regClass)
1095       {
1096          Statement stmt;
1097          OldList * args = MkList();
1098          Method method;
1099          Expression exp;
1100          const char * registerFunction = null;
1101          AccessMode inheritanceAccess = publicAccess;
1102
1103          CreateRegisterModuleBody();
1104
1105          curExternal = registerModuleExternal;
1106
1107           // Class Type
1108          switch(regClass.type)
1109          {
1110             case structClass: ListAdd(args, MkExpIdentifier(MkIdentifier("structClass"))); break;
1111             case bitClass:    ListAdd(args, MkExpIdentifier(MkIdentifier("bitClass"))); break;
1112             case enumClass:   ListAdd(args, MkExpIdentifier(MkIdentifier("enumClass"))); break;
1113             case noHeadClass: ListAdd(args, MkExpIdentifier(MkIdentifier("noHeadClass"))); break;
1114             case unitClass:   ListAdd(args, MkExpIdentifier(MkIdentifier("unitClass"))); break;
1115             case normalClass: ListAdd(args, MkExpIdentifier(MkIdentifier("normalClass"))); break;
1116          }
1117
1118          {
1119             char nameSpace[1024] = "";
1120             char className[1024] = "";
1121             char * string;
1122             GetNameSpaceString(regClass.nameSpace, nameSpace);
1123
1124             if(declMode == staticAccess)
1125             {
1126                GetLastDirectory(sourceFile, className);
1127                ChangeCh(className, '.', '_');
1128                strcat(className, "}");
1129             }
1130             strcat(className, nameSpace);
1131             strcat(className, regClass.name);
1132             string = QMkString(className);
1133             ListAdd(args, MkExpString(string));
1134             delete string;
1135          }
1136
1137          /*
1138          {
1139             char * string = QMkString(regClass.base.name);
1140             ListAdd(args, regClass.base ? MkExpString(string) :
1141                MkExpConstant("0"));
1142             delete string;
1143          }
1144          */
1145
1146          if(baseSpecs != null)
1147          {
1148             Type baseType = ProcessType(baseSpecs, null);
1149             if(baseType.kind != structType && baseType.kind != unionType)
1150             {
1151                char baseName[1024] = "";
1152                char * string;
1153                if(baseType.kind == TypeKind::classType && baseType._class && baseType._class.isStatic)
1154                {
1155                   // TODO: Handle static classes and complex declarators...
1156                   GetLastDirectory(sourceFile, baseName);
1157                   ChangeCh(baseName, '.', '_');
1158                   strcat(baseName, "}");
1159                   strcat(baseName, baseType._class.string);
1160                }
1161                else
1162                   PrintType(baseType, baseName, false, true);
1163
1164                string = QMkString(baseName);
1165                ListAdd(args, MkExpString(string));
1166                delete string;
1167             }
1168             else
1169                ListAdd(args, MkExpConstant("0"));
1170             FreeType(baseType);
1171             if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
1172                inheritanceAccess = privateAccess;
1173          }
1174          else
1175             ListAdd(args, MkExpConstant("0"));
1176
1177          //ListAdd(args, class.declaredStruct ? MkExpTypeSize(MkTypeName(MkListOne(
1178             //MkSpecifierName(class.structName)), null)) : MkExpConstant("0"));
1179
1180          if(regClass.type == structClass || regClass.type == normalClass || regClass.type == noHeadClass)
1181          {
1182             // Check if we have a data member in this class
1183             DataMember member = null;
1184             {
1185                Class base;
1186                for(base = regClass.base; base && base.type != systemClass; base = base.next)
1187                {
1188                   for(member = base.membersAndProperties.first; member; member = member.next)
1189                      if(!member.isProperty)
1190                         break;
1191                   if(member)
1192                      break;
1193                }
1194             }
1195
1196             if(regClass.type == structClass && symbol.declaredStruct && member)
1197             {
1198                char baseStructName[1024];
1199                baseStructName[0] = 0;
1200                // TESTING THIS HERE
1201                // FullClassNameCat(baseStructName, regClass.base.fullName, false);
1202                strcpy(baseStructName, (regClass.base.templateClass ? regClass.base.templateClass : regClass.base).fullName);
1203
1204                ListAdd(args, MkExpOp(
1205                   MkExpTypeSize(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(symbol.structName), null)), null)), '-',
1206                   MkExpTypeSize(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(baseStructName), null)), null))));
1207             }
1208             else
1209                ListAdd(args, symbol.declaredStruct ? MkExpTypeSize(MkTypeName(MkListOne(
1210                   MkStructOrUnion(structSpecifier, MkIdentifier(symbol.structName), null)), null)) : MkExpConstant("0"));
1211          }
1212          else
1213          {
1214             ListAdd(args, MkExpConstant("0"));
1215          }
1216
1217          //if(regClass.type == normalClass)
1218          {
1219             char classDataStructName[1024];
1220             strcpy(classDataStructName, "__ecereClassData_");
1221             FullClassNameCat(classDataStructName, symbol.string, false);
1222
1223             ListAdd(args, symbol.classData ? MkExpTypeSize(MkTypeName(MkListOne(
1224                MkStructOrUnion(structSpecifier, MkIdentifier(classDataStructName), null)), null)) : MkExpConstant("0"));
1225          }
1226          /*else
1227             // TODO: Support Class Data for all other types of classes
1228             ListAdd(args, MkExpConstant("0"));
1229             */
1230
1231          if(regClass.type == normalClass || regClass.type == noHeadClass)
1232          {
1233             // Constructor
1234             ListAdd(args, symbol.needConstructor ?
1235                MkExpIdentifier(MkIdentifier(symbol.constructorName)) :
1236                MkExpConstant("0"));
1237             // Destructor
1238             ListAdd(args, symbol.needDestructor ?
1239                MkExpIdentifier(MkIdentifier(symbol.destructorName)) :
1240                MkExpConstant("0"));
1241          }
1242          else
1243          {
1244             // TODO: Support Constructors / Destructors for structs
1245
1246             // Constructor
1247             ListAdd(args, MkExpConstant("0"));
1248             // Destructor
1249             ListAdd(args, MkExpConstant("0"));
1250          }
1251
1252          // Module
1253          ListAdd(args, MkExpIdentifier(MkIdentifier("module")));
1254
1255          // Declaration Mode
1256          switch(declMode)
1257          {
1258             case staticAccess:
1259                ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
1260                break;
1261             case privateAccess:
1262                ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
1263                break;
1264             case publicAccess:
1265             default:
1266                ListAdd(args, MkExpIdentifier(MkIdentifier(buildingECERECOMModule ? "baseSystemAccess" : "publicAccess")));
1267                break;
1268          }
1269
1270          // Declaration Mode
1271          switch(inheritanceAccess)
1272          {
1273             case privateAccess:
1274                ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
1275                break;
1276             case publicAccess:
1277             default:
1278                ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
1279                break;
1280          }
1281
1282          registerFunction = "eSystem_RegisterClass";
1283
1284          stmt = MkExpressionStmt(MkListOne(
1285             MkExpOp(MkExpIdentifier(MkIdentifier("class")), '=',
1286             MkExpCall((exp = MkExpIdentifier(MkIdentifier(registerFunction))), args))));
1287
1288          ListAdd(registerModuleBody.compound.statements, stmt);
1289
1290          /*
1291          stmt = MkIfStmt(MkListOne(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier(symbol.className)))),
1292                MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(symbol.className)), '=',
1293             MkExpIdentifier(MkIdentifier("class"))))), null);
1294          */
1295
1296          stmt = MkIfStmt(MkListOne(
1297                   MkExpOp(MkExpOp(
1298                      MkExpMember(MkExpIdentifier(MkIdentifier("module")), MkIdentifier("application")), EQ_OP,
1299                      MkExpMember(MkExpIdentifier(MkIdentifier("__thisModule")), MkIdentifier("application"))), AND_OP, MkExpIdentifier(MkIdentifier("class")))),
1300                MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(symbol.className)), '=',
1301             MkExpIdentifier(MkIdentifier("class"))))), null);
1302          /*
1303          stmt = MkIfStmt(MkListOne(
1304                   MkExpOp(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier(symbol.className))), AND_OP, MkExpIdentifier(MkIdentifier("class")))),
1305                MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(symbol.className)), '=',
1306             MkExpIdentifier(MkIdentifier("class"))))), null);
1307          */
1308
1309          ListAdd(registerModuleBody.compound.statements, stmt);
1310
1311          if(external && external.type == classExternal && external._class.deleteWatchable)
1312          {
1313             args = MkListOne(MkExpIdentifier(MkIdentifier("class")));
1314             stmt = MkExpressionStmt(MkListOne(
1315                MkExpCall(MkExpIdentifier(MkIdentifier("eClass_DestructionWatchable")), args)));
1316             ListAdd(registerModuleBody.compound.statements, stmt);
1317          }
1318
1319          // Add Virtual Methods
1320          if(regClass.base)
1321          {
1322             Class base = regClass.base;
1323             int c;
1324             for(c = 0; c<base.vTblSize; c++)
1325             {
1326                Symbol method = (Symbol)regClass._vTbl[c];
1327                if((void *) method != DummyMethod && base._vTbl[c] != (void *)method && method.methodExternal) // TOLOOKAT: Module check here?
1328                {
1329                   External external = method.methodExternal;
1330                   OldList * args = MkList();
1331                   Identifier id = external.function ? GetDeclId(external.function.declarator) : null;
1332
1333                   // Class class
1334                   ListAdd(args, MkExpIdentifier(MkIdentifier("class")));
1335                   // char * name
1336                   {
1337                      //char * string = QMkString(method.string);
1338
1339                      char * string = QMkString(method.method.name);
1340                      ListAdd(args, MkExpString(string));
1341                      delete string;
1342                   }
1343                   // char * type
1344                   ListAdd(args, MkExpConstant("0"));
1345                   // void * function
1346                   ListAdd(args, (exp = MkExpIdentifier(MkIdentifier(
1347                      id.string))));
1348
1349                   // Declaration Mode
1350                   ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
1351
1352                   exp.expType = Type { refCount = 1 };
1353                   stmt = MkExpressionStmt(MkListOne(
1354                      MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddMethod")), args)));
1355                   ListAdd(registerModuleBody.compound.statements, stmt);
1356                }
1357             }
1358          }
1359
1360          // Add Virtual Methods in order
1361          {
1362             int c;
1363             for(c = regClass.base ? regClass.base.vTblSize : 0; c < regClass.vTblSize; c++)
1364             {
1365                for(method = (Method)regClass.methods.first; method; method = (Method)((BTNode)method).next)
1366                {
1367                   if(method.type == virtualMethod && method._class == regClass && method.vid == c)
1368                   {
1369                      char name[1024];
1370                      Expression exp;
1371
1372                      //External external = method->symbol ? ((Symbol)method.symbol).methodExternal : null;
1373                      External external = method.symbol ? ((Symbol)method.symbol).methodCodeExternal : null;
1374                      OldList * args = MkList();
1375                      Identifier id = (external && external.function) ? GetDeclId(external.function.declarator) : null;
1376
1377                      // Class * class
1378                      ListAdd(args, MkExpIdentifier(MkIdentifier("class")));
1379                      // char * name
1380                      {
1381                         char * string = QMkString(method.name);
1382                         ListAdd(args, MkExpString(string));
1383                         delete string;
1384                      }
1385                      // char * type
1386                      {
1387                         char * string = QMkString(method.dataTypeString);
1388                         ListAdd(args, MkExpString(string));
1389                         delete string;
1390                      }
1391                      // void * function
1392                      if(id && external.function.body)
1393                      {
1394                         ListAdd(args, (exp = MkExpIdentifier(MkIdentifier(id.string))));
1395                         exp.expType = Type { refCount = 1 };
1396                      }
1397                      else
1398                      {
1399                         ListAdd(args, (exp = MkExpConstant("0")));
1400                      }
1401
1402                      // Declaration Mode
1403                      switch(method.memberAccess)
1404                      {
1405                         case staticAccess:
1406                            ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
1407                            break;
1408                         case privateAccess:
1409                            ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
1410                            break;
1411                         case publicAccess:
1412                         default:
1413                            ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
1414                            break;
1415                      }
1416
1417                      //sprintf(name, "__ecereVMethodID_%s_%s", method._class.fullName, method.name);
1418                      strcpy(name, "__ecereVMethodID_");
1419                      FullClassNameCat(name, method._class.fullName, false);
1420                      strcat(name, "_");
1421                      strcat(name, method.name);
1422
1423                      exp = /*MkExpPointer(*/MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddVirtualMethod")), args)/*, MkIdentifier("vid"))*/;
1424                      /*
1425                      exp->expType = eSystem_New(sizeof(Type));
1426                      exp->expType->refCount++;
1427                      exp->expType->isSigned = true;
1428                      exp->expType->kind = TypeInt;
1429                      */
1430
1431                      stmt = MkExpressionStmt(MkListOne(/*
1432                         MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', */exp/*)*/));
1433
1434                      DeclareMethod(method, name);
1435
1436                      ListAdd(registerModuleBody.compound.statements, stmt);
1437                   }
1438                }
1439             }
1440          }
1441
1442
1443          // Add Public Methods (all for now)
1444          for(method = (Method)regClass.methods.first; method; method = (Method)((BTNode)method).next)
1445          {
1446             if(method.type == virtualMethod && method._class == regClass);
1447             else if(method.memberAccess == publicAccess || !method.dataTypeString)
1448             {
1449                //External external = method.symbol ? ((Symbol )method.symbol).methodExternal : null;
1450                External external = method.symbol ? ((Symbol )method.symbol).methodCodeExternal : null;
1451                OldList * args = MkList();
1452                Identifier id = (external && external.function) ? GetDeclId(external.function.declarator) : null;
1453
1454                // Class class
1455                ListAdd(args, MkExpIdentifier(MkIdentifier("class")));
1456                // char * name
1457                {
1458                   char * string = QMkString(method.name);
1459                   ListAdd(args, MkExpString(string));
1460                   delete string;
1461                }
1462                // char * type
1463                {
1464                   char * string = QMkString(method.dataTypeString);
1465                   ListAdd(args, MkExpString(string));
1466                   delete string;
1467                }
1468                // void * function
1469                if(id && external.function.body)
1470                {
1471                   ListAdd(args, (exp = MkExpIdentifier(MkIdentifier(
1472                      id.string))));
1473                   exp.expType = Type { refCount = 1 };
1474                }
1475                else
1476                {
1477                   ListAdd(args, (exp = MkExpConstant("0")));
1478                }
1479
1480                // Declaration Mode
1481                switch(method.memberAccess)
1482                {
1483                   case staticAccess:
1484                      ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
1485                      break;
1486                   case privateAccess:
1487                      ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
1488                      break;
1489                   case publicAccess:
1490                   default:
1491                      ListAdd(args, MkExpIdentifier(MkIdentifier("publicAccess")));
1492                      break;
1493                }
1494
1495                stmt = MkExpressionStmt(MkListOne(
1496                   MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddMethod")), args)));
1497                ListAdd(registerModuleBody.compound.statements, stmt);
1498             }
1499          }
1500
1501          RegisterMembersAndProperties(regClass, false, "class", registerModuleBody);
1502
1503          // Add Enumeration Values
1504          if(classType == enumClass)
1505          {
1506             NamedLink value;
1507             Class enumClass = eSystem_FindClass(privateModule, "enum");
1508             EnumClassData e = ACCESS_CLASSDATA(regClass, enumClass);
1509
1510             for(value = e.values.first; value; value = value.next)
1511             {
1512                OldList * args = MkList();
1513
1514                // Class class
1515                ListAdd(args, MkExpIdentifier(MkIdentifier("class")));
1516                // char * name
1517                {
1518                   char * string = QMkString(value.name);
1519                   ListAdd(args, MkExpString(string));
1520                   delete string;
1521                }
1522                // uint value
1523                {
1524                   char temp[1024];
1525                   // TODO: Support 64 bit enums
1526                   sprintf(temp, "%d", (int)value.data);
1527                   ListAdd(args, MkExpConstant(temp));
1528                }
1529
1530                stmt = MkExpressionStmt(MkListOne(
1531                   MkExpCall(MkExpIdentifier(MkIdentifier("eEnum_AddFixedValue")), args)));
1532                ListAdd(registerModuleBody.compound.statements, stmt);
1533             }
1534          }
1535
1536          // Add Template Parameters
1537          if(symbol.templateParams)
1538          {
1539             TemplateParameter param;
1540             for(param = symbol.templateParams->first; param; param = param.next)
1541             {
1542                OldList * args = MkList();
1543
1544                // Class
1545                ListAdd(args, MkExpIdentifier(MkIdentifier("class")));
1546
1547                // Name
1548                {
1549                   char * string = QMkString(param.identifier.string);
1550                   ListAdd(args, MkExpString(string));
1551                   delete string;
1552                }
1553
1554                // Type
1555                ListAdd(args, MkExpIdentifier(MkIdentifier((param.type == type) ? "type" : ((param.type == identifier) ? "identifier" : "expression"))));
1556
1557                // Parameter
1558                switch(param.type)
1559                {
1560                   case type:
1561                   case expression:
1562                   {
1563                      char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
1564                      char * string = QMkString(typeString);
1565                      ListAdd(args, MkExpString(string));
1566                      delete typeString;
1567                      delete string;
1568                      break;
1569                   }
1570                   case identifier:
1571                   {
1572                      char memberTypeString[132] = "TemplateMemberType::";
1573                      bool needClass = true;
1574
1575                      param.memberType.OnGetString(memberTypeString + strlen(memberTypeString), null, &needClass);
1576                      ListAdd(args,
1577                         MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)),
1578                            MkExpIdentifier(MkIdentifier(memberTypeString))));
1579                      break;
1580                   }
1581                }
1582
1583                // Default Argument
1584                if(param.defaultArgument)
1585                {
1586                   OldList * members = MkList();
1587                   switch(param.type)
1588                   {
1589                      case type:
1590                      {
1591                         char * typeString = param.defaultArgument.templateDatatype ?
1592                            StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl) : null;
1593                         char * string = QMkString(typeString);
1594
1595                         members->Add(MkMemberInit(MkListOne(MkIdentifier("dataTypeString")), MkInitializerAssignment(MkExpString(string))));
1596
1597                         delete typeString;
1598                         delete string;
1599                         break;
1600                      }
1601                      case identifier:
1602                      {
1603                         char memberString[1024];
1604                         char * string;
1605                         memberString[0] = '\0';
1606
1607                         if(param.defaultArgument.identifier._class)
1608                         {
1609                            if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
1610                               strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
1611                            else if(param.defaultArgument.identifier._class.name)
1612                               strcpy(memberString, param.defaultArgument.identifier._class.name);
1613                         }
1614                         if(memberString[0])
1615                            strcat(memberString, "::");
1616
1617                         strcat(memberString, param.defaultArgument.identifier.string);
1618
1619                         string = QMkString(memberString);
1620
1621                         // TOFIX: UNIONS ARE BROKEN FOR ASSIGNMENTS, USING dataTypeString INSTEAD
1622                         // members->Add(MkMemberInit(MkListOne(MkIdentifier("memberString")), MkInitializerAssignment(MkExpString(string))));
1623                         members->Add(MkMemberInit(MkListOne(MkIdentifier("dataTypeString")), MkInitializerAssignment(MkExpString(string))));
1624
1625                         delete string;
1626                         break;
1627                      }
1628                      case expression:
1629                      {
1630                         Operand op { };
1631                         OldList * ids = MkList();
1632                         char * ui64String;
1633                         char * string = null;
1634
1635                         //ProcessExpressionType(param.defaultArgument.expression);
1636                         //ComputeExpression(param.defaultArgument.expression);
1637
1638                         op = GetOperand(param.defaultArgument.expression);
1639                         ui64String = PrintUInt64(op.ui64);
1640                         ids->Add(MkIdentifier("expression"));
1641                         ids->Add(MkIdentifier("ui64"));
1642
1643                         //string = QMkString(ui64String);
1644                         members->Add(MkMemberInit(ids, MkInitializerAssignment(MkExpConstant(ui64String))));
1645
1646                         delete string;
1647                         delete ui64String;
1648                         break;
1649                      }
1650                   }
1651                   ListAdd(args, MkExpInstance(MkInstantiation(MkSpecifierName("ClassTemplateArgument"), null,
1652                      MkListOne(MkMembersInitList(members)))));
1653                }
1654                else
1655                   ListAdd(args, MkExpIdentifier(MkIdentifier("null")));
1656
1657                stmt = MkExpressionStmt(MkListOne(
1658                   MkExpCall(MkExpIdentifier(MkIdentifier("eClass_AddTemplateParameter")), args)));
1659                ListAdd(registerModuleBody.compound.statements, stmt);
1660             }
1661             stmt = MkExpressionStmt(MkListOne(
1662                MkExpCall(MkExpIdentifier(MkIdentifier("eClass_DoneAddingTemplateParameters")),
1663                   MkListOne(MkExpIdentifier(MkIdentifier("class"))))));
1664             ListAdd(registerModuleBody.compound.statements, stmt);
1665          }
1666
1667          if(definitions != null)
1668          {
1669             for(def = definitions.first; def; def = def.next)
1670             {
1671                if(def.type == propertyWatchClassDef && def.propertyWatch)
1672                {
1673                   ListAdd(registerModuleBody.compound.statements, (Statement)def.propertyWatch);
1674                   def.propertyWatch = null;
1675                }
1676                else if(def.type == classDesignerClassDef)
1677                {
1678                   /*
1679                   char className[1024];
1680                   sprintf(className, "__ecereClass_%s", def.designer);
1681                   MangleClassName(className);
1682
1683                   DeclareClass(FindClass(def.designer), className);
1684                   */
1685
1686                   {
1687                      char * s = QMkString(def.designer);
1688                      stmt = MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("class"))), MkExpressionStmt(MkListOne(
1689                         MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("designerClass")), '=',
1690                            MkExpString(s)))), null);
1691                      delete s;
1692                   }
1693                   ListAdd(registerModuleBody.compound.statements, stmt);
1694                }
1695                else if(def.type == classNoExpansionClassDef)
1696                {
1697                   stmt = MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("class"))), MkExpressionStmt(MkListOne(
1698                      MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("noExpansion")), '=',
1699                         MkExpConstant("1")))), null);
1700                   ListAdd(registerModuleBody.compound.statements, stmt);
1701                }
1702                else if(def.type == classFixedClassDef)
1703                {
1704                   stmt = MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("class"))), MkExpressionStmt(MkListOne(
1705                      MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("fixed")), '=',
1706                         MkExpConstant("1")))), null);
1707                   ListAdd(registerModuleBody.compound.statements, stmt);
1708                   if(regClass)
1709                      regClass.fixed = true;
1710                }
1711                else if(def.type == designerDefaultPropertyClassDef)
1712                {
1713                   char * s = QMkString(def.defaultProperty.string);
1714                   stmt = MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("class"))), MkExpressionStmt(MkListOne(
1715                      MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("defaultProperty")), '=',
1716                         MkExpString(s)))), null);
1717                   ListAdd(registerModuleBody.compound.statements, stmt);
1718                   delete s;
1719                }
1720                else if(def.type == classPropertyValueClassDef)
1721                {
1722                   classPropValues.Add(ClassPropertyValue { regClass = regClass, id = def.id, exp = def.initializer.exp });
1723                   def.id = null;
1724                   def.initializer.exp = null;
1725                }
1726             }
1727          }
1728       }
1729    }
1730 }
1731
1732 class ClassPropertyValue
1733 {
1734    Class regClass;
1735    Identifier id;
1736    Expression exp;
1737
1738    ~ClassPropertyValue()
1739    {
1740       FreeIdentifier(id);
1741    }
1742 };
1743
1744 static List<ClassPropertyValue> classPropValues { };
1745
1746 public void ProcessClassDefinitions()
1747 {
1748    External external, next;
1749
1750    CreateRegisterModuleBody();
1751    if(ast)
1752    {
1753       // (Need to do those things after in case something is not yet defined)
1754       for(external = ast->first; external; external = next)
1755       {
1756          next = external.next;
1757          curExternal = external;
1758          if(external.type == classExternal)
1759          {
1760             ClassDefinition _class = external._class;
1761             if(_class.definitions)
1762             {
1763                ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, ast, external, _class.declMode);
1764             }
1765             if(inCompiler)
1766             {
1767                ast->Remove(external);
1768                FreeExternal(external);
1769             }
1770          }
1771          else if(external.type == functionExternal)
1772          {
1773             bool setStaticMethod = false;
1774             // Mark
1775             if(external.symbol && !external.symbol.type.thisClass && !external.symbol.type.staticMethod)
1776             {
1777                // TOCHECK: Where do we actually need this to be set?
1778                external.symbol.type.staticMethod = true;
1779                setStaticMethod = true;
1780             }
1781
1782             if(inCompiler)
1783             {
1784                FunctionDefinition function = external.function;
1785                Statement stmt;
1786                OldList * args;
1787
1788                if(!strcmp(function.declarator.symbol.string, "__on_register_module"))
1789                {
1790                   ListAdd(registerModuleBody.compound.statements, function.body);
1791                   function.body.compound.context.parent = registerModuleBody.compound.context;
1792                   ast->Remove(external);
1793                   function.body = null;
1794                   FreeExternal(external);
1795                   continue;
1796                }
1797
1798                if(function.declMode != privateAccess && function.declMode != publicAccess) continue;
1799
1800                args = MkList();
1801
1802                CreateRegisterModuleBody();
1803
1804                // Identifier
1805                {
1806                   char * string = QMkString(function.declarator.symbol.string);
1807                   ListAdd(args, MkExpString(string));
1808                   delete string;
1809                }
1810
1811                // Type
1812                {
1813                   char * string;
1814                   char type[1024] = "";
1815                   // We don't want functions to be marked as static methods
1816                   if(setStaticMethod)
1817                      function.declarator.symbol.type.staticMethod = false;
1818                   PrintType(function.declarator.symbol.type, type, true, true);
1819                   if(setStaticMethod)
1820                      function.declarator.symbol.type.staticMethod = true;
1821                   string = QMkString(type);
1822                   ListAdd(args, MkExpString(string));
1823                   delete string;
1824                }
1825
1826                // Function
1827                {
1828                   ListAdd(args, MkExpIdentifier(MkIdentifier(function.declarator.symbol.string)));
1829                }
1830
1831                // Module
1832                ListAdd(args, MkExpIdentifier(MkIdentifier("module")));
1833
1834                // Declaration Mode
1835                switch(function.declMode)
1836                {
1837                   case staticAccess:
1838                      ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
1839                      break;
1840                   case privateAccess:
1841                      ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
1842                      break;
1843                   case publicAccess:
1844                   default:
1845                      ListAdd(args, MkExpIdentifier(MkIdentifier(buildingECERECOMModule ? "baseSystemAccess" : "publicAccess")));
1846                      break;
1847                }
1848
1849                stmt = MkExpressionStmt(MkListOne(
1850                   MkExpCall((MkExpIdentifier(MkIdentifier("eSystem_RegisterFunction"))), args)));
1851
1852                ListAdd(registerModuleBody.compound.statements, stmt);
1853             }
1854          }
1855          else if(external.type == declarationExternal)
1856          {
1857             Declaration declaration = external.declaration;
1858
1859             if(external.symbol)
1860             {
1861                if(external.symbol.type && external.symbol.type.kind == functionType && !external.symbol.type.thisClass)
1862                   external.symbol.type.staticMethod = true;
1863             }
1864
1865             if(external.symbol && declaration.type == initDeclaration)
1866             {
1867                if(declaration.specifiers)
1868                {
1869                   Specifier specifier;
1870                   bool removeExternal = false;
1871
1872                   for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
1873                   {
1874                      if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
1875                         (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
1876                      {
1877                         Symbol symbol = FindClass(specifier.id.string);
1878                         if(symbol)
1879                         {
1880                            ClassType classType;
1881                            if(specifier.type == enumSpecifier)
1882                               classType = enumClass;
1883                            else
1884                               classType = structClass;
1885
1886                            removeExternal = true;
1887                            // Transfer Context over to Symbol
1888                            symbol.ctx = specifier.ctx;
1889                            specifier.ctx = null;
1890
1891                            ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list,ast, external, declaration.declMode);
1892                         }
1893                      }
1894                   }
1895                   if(inCompiler && removeExternal)
1896                   {
1897                      ast->Remove(external);
1898                      FreeExternal(external);
1899                   }
1900                }
1901             }
1902             else if(declaration.type == defineDeclaration)
1903             {
1904                if(inCompiler && declaration.declMode != staticAccess)
1905                {
1906                   Statement stmt;
1907                   OldList * args = MkList();
1908
1909                   CreateRegisterModuleBody();
1910
1911                   // Identifier
1912                   {
1913                      char * string = QMkString(declaration.id.string);
1914                      ListAdd(args, MkExpString(string));
1915                      delete string;
1916                   }
1917
1918                   // Expression
1919                   {
1920                      char * string;
1921                      char type[1024] = "";
1922                      PrintExpression(declaration.exp, type);
1923                      string = QMkString(type);
1924                      ListAdd(args, MkExpString(string));
1925                      delete string;
1926                   }
1927
1928                   // Module
1929                   ListAdd(args, MkExpIdentifier(MkIdentifier("module")));
1930
1931                   // Declaration Mode
1932                   switch(declaration.declMode)
1933                   {
1934                      case staticAccess:
1935                         ListAdd(args, MkExpIdentifier(MkIdentifier("staticAccess")));
1936                         break;
1937                      case privateAccess:
1938                         ListAdd(args, MkExpIdentifier(MkIdentifier("privateAccess")));
1939                         break;
1940                      case publicAccess:
1941                      default:
1942                         ListAdd(args, MkExpIdentifier(MkIdentifier(buildingECERECOMModule ? "baseSystemAccess" : "publicAccess")));
1943                         break;
1944                   }
1945
1946                   stmt = MkExpressionStmt(MkListOne(
1947                      MkExpCall((MkExpIdentifier(MkIdentifier("eSystem_RegisterDefine"))), args)));
1948
1949                   ListAdd(registerModuleBody.compound.statements, stmt);
1950                }
1951             }
1952          }
1953       }
1954
1955       // Set the class properties at the very end
1956       for(v : classPropValues)
1957       {
1958          OldList * findClassArgs = MkList();
1959          OldList * args = MkList();
1960          Statement compoundStmt;
1961          String s;
1962
1963          if(v.exp)
1964             yylloc = v.exp.loc;
1965
1966          ListAdd(findClassArgs, MkExpIdentifier(MkIdentifier("module")));
1967          s = QMkString(v.regClass.name);
1968          ListAdd(findClassArgs, MkExpString(s));
1969          delete s;
1970
1971          ListAdd(args, MkExpIdentifier(MkIdentifier("_class")));
1972          s = QMkString(v.id.string);
1973          ListAdd(args, MkExpString(s));
1974          delete s;
1975          ListAdd(args, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), v.exp));
1976          compoundStmt = MkCompoundStmt(MkListOne(MkDeclaration(MkListOne(MkSpecifierName("ecere::com::Class")),
1977                        MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("_class")),
1978                         MkInitializerAssignment(MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eSystem_FindClass")), findClassArgs)))))),
1979             MkListOne(MkExpressionStmt(MkListOne(
1980                MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty")), args)))));
1981          compoundStmt.compound.context = Context { parent = registerModuleBody.compound.context };
1982          ListAdd(registerModuleBody.compound.statements, compoundStmt);
1983       }
1984
1985       classPropValues.Free();
1986    }
1987 }