buildsystem,ide; (#1036) fix failure to go to added project source file from error...
[sdk] / compiler / ecp / ecp.ec
1 #ifdef ECERE_STATIC
2 import static "ecere"
3 import static "ec"
4 #else
5 import "ecere"
6 import "ec"
7 #endif
8
9 #define YYLTYPE Location
10 #include "../libec/src/grammar.h"
11
12 // UNTIL IMPLEMENTED IN GRAMMAR
13 #define ACCESS_CLASSDATA(_class, baseClass) \
14    (_class ? ((void *)(((char *)_class.data) + baseClass.offsetClass)) : null)
15
16 // #include <stdarg.h>
17
18 // WARNING: PropertyDefine, ClassDefine and DataMemberDefine must remain compatible
19 struct ClassDefine : Definition
20 {
21    char * base;
22    OldList propertiesAndMembers;
23    OldList classProperties;
24    OldList methods;
25    bool isRemote;
26    bool isWatchable;
27    bool fixed;
28    bool isStatic;
29    bool noExpansion;
30 };
31
32 struct Define : Definition
33 {
34    Expression exp;
35 };
36
37 struct FunctionDefine : Definition
38 {
39    char * dataType;
40 };
41
42 struct DataDefine : Definition
43 {
44    char * dataType;
45 };
46
47 class MethodDefine : struct
48 {
49    MethodDefine prev, next;
50    char * name;
51    AccessMode memberAccess;
52    char * type;
53    bool isVirtual;
54 };
55
56 // WARNING: PropertyDefine, ClassDefine and DataMemberDefine must remain compatible
57 class PropertyDefine : struct
58 {
59    PropertyDefine prev, next;
60    char * name;
61    MemberType isProperty;
62    char * type;
63
64    bool isWatchable;
65    AccessMode memberAccess;
66    bool isVirtual;
67    bool hasSet, hasGet;
68 };
69
70 // WARNING: PropertyDefine, ClassDefine and DataMemberDefine must remain compatible
71 class DataMemberDefine : struct
72 {
73    DataMemberDefine prev, next;
74    char * name;
75    MemberType isProperty;
76    char * type;
77    OldList dataMembers;
78    OldList classProperties;   // For binary compatibility with ClassDefine
79
80    AccessMode memberAccess;
81    DataMemberType memberType;
82    int size, bitPos;
83 };
84
85 void FreeMethodDefine(MethodDefine method)
86 {
87    delete method.name;
88    delete method.type;
89 }
90
91 void FreeDataMemberDefine(DataMemberDefine dataMember)
92 {
93    delete dataMember.name;
94    delete dataMember.type;
95 }
96
97 void FreeDataDefine(DataDefine data)
98 {
99    delete data.name;
100    delete data.type;
101 }
102
103 void FreeDefinition(Definition definition)
104 {
105    delete definition.name;
106    switch(definition.type)
107    {
108       case classDefinition:
109       {
110          ClassDefine classDefine = (ClassDefine)definition;
111          delete classDefine.base;
112          classDefine.methods.Free(FreeMethodDefine);
113          classDefine.propertiesAndMembers.Free(FreeDataMemberDefine);
114          break;
115       }
116       case functionDefinition:
117          delete ((FunctionDefine)definition).dataType;
118          break;
119       case dataDefinition:
120          delete ((DataDefine)definition).dataType;
121          break;
122       case defineDefinition:
123          break;
124    }
125 }
126
127 /////////////////////////////////////
128 static bool globalInstance = false;
129 static Context globalContext { };
130 static OldList defines, imports, precompDefines;
131 static Module privateModule;
132 static OldList _excludedSymbols { offset = (uint)&((Symbol)0).left };
133 static NameSpace globalData
134 {
135    classes.CompareKey = (void *)BinaryTree::CompareString;
136    defines.CompareKey = (void *)BinaryTree::CompareString;
137    functions.CompareKey = (void *)BinaryTree::CompareString;
138    nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
139 };
140
141 static void AddDefinitions(ClassDefine classDefine, DataMemberDefine parentMemberDefine, Class regClass, DataMember member, OldList definitions)
142 {
143    if(definitions != null)
144    {
145       ClassDef def;
146       for(def = definitions.first; def; def = def.next)
147       {
148          if(def.type == declarationClassDef)
149          {
150             Declaration decl = def.decl;
151             DataMember dataMember;
152             Type dataType;
153             DataMemberDefine dataMemberDefine;
154
155             if(decl.type == structDeclaration)
156             {
157                Declarator d;
158
159                if(decl.declarators)
160                {
161                   for(d = decl.declarators->first; d; d = d.next)
162                   {
163                      Identifier declId = GetDeclId(d);
164                      //if(d.type != DeclaratorFunction)
165                      if(declId)
166                      {
167                         dataMemberDefine = DataMemberDefine
168                         {
169                            isProperty = MemberType::dataMember;
170                            memberType = normalMember;
171                            name = CopyString(declId.string);
172                         };
173                         parentMemberDefine.dataMembers.Add(dataMemberDefine);
174                         if(regClass && regClass.type == bitClass)
175                         {
176                            Expression sizeExp = d.structDecl.exp, posExp = d.structDecl.posExp;
177                            int bitSize = 0, bitPos = -1;
178                            char dataTypeString[1024];
179                            dataTypeString[0] = '\0';
180
181                            if(sizeExp)
182                            {
183                               ProcessExpressionType(sizeExp);
184                               ComputeExpression(sizeExp);
185                               if(sizeExp.isConstant)
186                                  bitSize = strtol(sizeExp.constant, null, 0);
187                               FreeExpression(sizeExp);
188                            }
189
190                            if(posExp)
191                            {
192                               ProcessExpressionType(posExp);
193                               ComputeExpression(posExp);
194                               if(posExp.isConstant)
195                                  bitPos = strtol(posExp.constant, null, 0);
196                               FreeExpression(posExp);
197
198                            }
199
200                            d.structDecl.exp = null;
201                            d.structDecl.posExp = null;
202
203                            dataType = ProcessType(decl.specifiers, d);
204                            PrintType(dataType, dataTypeString, false, true);
205
206                            //if(!eClass_FindDataMember(regClass, declId.string))
207                            {
208                               BitMember member = eClass_AddBitMember(regClass, declId.string, dataTypeString, 0, 0, def.memberAccess);
209                               member.size = bitSize;
210                               member.pos = bitPos;
211                               dataMember = (DataMember)member;
212                            }
213                            if(dataMember)
214                               dataMember.dataType = dataType;
215
216                            dataMemberDefine.size = bitSize;
217                            dataMemberDefine.bitPos = bitPos;
218
219                            dataMemberDefine.type = CopyString(dataTypeString);
220                         }
221                         else
222                         {
223                            //if(!eClass_FindDataMember(regClass, declId.string))
224                            {
225                               char typeString[1024];
226                               typeString[0] = '\0';
227                               dataType = ProcessType(decl.specifiers, d);
228                               PrintType(dataType, typeString, false, true);
229
230                               if(member)
231                                  dataMember = eMember_AddDataMember(member, declId.string,
232                                     typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
233                               else
234                                  dataMember = eClass_AddDataMember(regClass, declId.string,
235                                     typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
236                               if(dataMember)
237                                  dataMember.dataType = dataType;
238
239                               dataMemberDefine.type = CopyString(typeString);
240                            }
241                         }
242                         dataMemberDefine.memberAccess = def.memberAccess; //(!isMember && regClass.type == structClass) ? true : false;
243                      }
244                   }
245                }
246                else if(decl.specifiers)
247                {
248                   Specifier spec;
249                   // Unnamed struct/union
250                   for(spec = decl.specifiers->first; spec; spec = spec.next)
251                   {
252                      if(spec.type == structSpecifier || spec.type == unionSpecifier)
253                      {
254                         if(spec.definitions && !spec.id)
255                         {
256                            DataMember dataMember = eMember_New((spec.type == unionSpecifier) ? unionMember : structMember, def.memberAccess);
257
258                            dataMemberDefine = DataMemberDefine
259                            {
260                               isProperty = MemberType::dataMember;
261                               memberType = (spec.type == SpecifierType::unionSpecifier) ? unionMember : structMember;
262                            };
263                            parentMemberDefine.dataMembers.Add(dataMemberDefine);
264
265                            AddDefinitions(null, dataMemberDefine, null, dataMember, spec.definitions);
266
267                            if(member)
268                               eMember_AddMember(member, dataMember);
269                            else
270                               eClass_AddMember(regClass, dataMember);
271                         }
272                         else if(spec.definitions && spec.id && spec.definitions->count)
273                         {
274                            //if(isMember || !eClass_FindDataMember(regClass, spec.id.string))
275                            {
276                               Identifier id = spec.id;
277                               char typeString[1024];
278                               typeString[0] = '\0';
279
280                               spec.id = null;
281                               decl.declarators = MkListOne(MkDeclaratorIdentifier(id));
282
283                               dataType = ProcessType(decl.specifiers, null);
284                               PrintType(dataType, typeString, false, true);
285
286                               if(member)
287                                  dataMember = eMember_AddDataMember(member, id.string,
288                                     typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
289                               else
290                                  dataMember = eClass_AddDataMember(regClass, id.string,
291                                     typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
292
293                               //delete dataTypeString;
294                               if(dataMember)
295                                  dataMember.dataType = dataType;
296                            }
297                         }
298                      }
299                   }
300                }
301             }
302             else if(decl.type == instDeclaration)
303             {
304                Instantiation inst = decl.inst;
305                Expression exp = inst.exp;
306                if(exp)
307                {
308                   // Add data member to the class
309                   //if(!redefinition)
310                   {
311                      char * string = exp.identifier.string;
312                      //if(!eClass_FindDataMember(regClass, string))
313                      {
314                         Type dataType = Type
315                         {
316                            kind = classType;
317                            _class = inst._class.symbol; // FindClass(inst._class.name);
318                            refCount = 1;
319                         };
320                         if(member)
321                            dataMember = eMember_AddDataMember(member, string, inst._class.name, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
322                         else
323                            dataMember = eClass_AddDataMember(regClass, string, inst._class.name, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
324                         if(dataMember)
325                            dataMember.dataType = dataType;
326                      }
327
328                      dataMemberDefine = DataMemberDefine
329                      {
330                         isProperty = MemberType::dataMember;
331                         memberType = normalMember;
332                         name = CopyString(string);
333                         type = CopyString(inst._class.name);
334                      };
335                      parentMemberDefine.dataMembers.Add(dataMemberDefine);
336                   }
337                }
338             }
339          }
340          else if(def.type == propertyClassDef && def.propertyDef)
341          {
342             PropertyDef propertyDef = def.propertyDef;
343
344             //if(propertyDef.id && (propertyDef.hasGet || propertyDef.hasSet))
345             {
346                Property prop;
347                PropertyDefine propDefine;
348
349                // Register the property in the list
350                {
351                   char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
352                   prop = eClass_AddProperty(regClass, propertyDef.conversion ? null : propertyDef.id.string, dataTypeString, propertyDef.setStmt, propertyDef.getStmt, def.memberAccess);
353                   if(prop)
354                   {
355                      prop.IsSet = (void *)propertyDef.issetStmt;
356                      prop.compiled = false;
357                   }
358                   delete dataTypeString;
359                }
360                //prop.symbol = propertyDef.symbol;
361
362                //method.symbol = func.declarator.symbol;
363
364                if(prop)
365                {
366                   prop.symbol = Symbol
367                   {
368                      string = CopyString(propertyDef.symbol.string);
369                      id = propertyDef.symbol.id;
370                      type = propertyDef.symbol.type;
371                   };
372                   if(propertyDef.symbol.type)
373                      propertyDef.symbol.type.refCount++;
374
375                   //((Symbol)method.symbol).method = method;
376
377
378                   propDefine = PropertyDefine
379                   {
380                      isProperty = propertyMember;
381                      name = prop.conversion ? null : CopyString(prop.name);
382                      type = CopyString(prop.dataTypeString);
383                      isVirtual = false; // No virtual properties for now...
384                      memberAccess = def.memberAccess;
385                      hasSet = propertyDef.setStmt ? true : false;
386                      hasGet = propertyDef.getStmt ? true : false;
387                      isWatchable = propertyDef.isWatchable;
388                   };
389                   classDefine.propertiesAndMembers.Add(propDefine);
390                }
391             }
392          }
393          else if(def.type == classPropertyClassDef && def.propertyDef)
394          {
395             PropertyDef propertyDef = def.propertyDef;
396
397             //if(propertyDef.id && (propertyDef.hasGet || propertyDef.hasSet))
398             {
399                ClassProperty prop;
400                PropertyDefine propDefine;
401                // Register the property in the list
402                {
403                   char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
404                   prop = eClass_AddClassProperty(regClass, propertyDef.id.string, dataTypeString, propertyDef.setStmt, propertyDef.getStmt);
405                   delete dataTypeString;
406                }
407                if(prop)
408                {
409                   propDefine = PropertyDefine
410                   {
411                      name = CopyString(prop.name);
412                      type = CopyString(prop.dataTypeString);
413                      hasSet = propertyDef.setStmt ? true : false;
414                      hasGet = propertyDef.getStmt ? true : false;
415                   };
416                   classDefine.classProperties.Add(propDefine);
417                }
418             }
419          }
420          else if(def.type == classFixedClassDef)
421          {
422             classDefine.fixed = true;
423          }
424          else if(def.type == classNoExpansionClassDef)
425          {
426             classDefine.noExpansion = true;
427          }
428          else if(def.type == accessOverrideClassDef)
429          {
430             DataMember member;
431             Property prop;
432             Method method;
433             if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
434             {
435                PropertyDefine propDefine;
436
437                prop = eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
438                if(prop)
439                {
440                   propDefine = PropertyDefine
441                   {
442                      isProperty = propertyMember;
443                      name = CopyString(prop.name);
444                      memberAccess = def.memberAccess;
445                   };
446                   classDefine.propertiesAndMembers.Add(propDefine);
447                }
448             }
449             else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
450             {
451                DataMemberDefine dataMemberDefine;
452
453                member = eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
454
455                dataMemberDefine = DataMemberDefine
456                {
457                   isProperty = dataMember;
458                   memberType = normalMember;
459                   name = CopyString(def.id.string);
460                   memberAccess = def.memberAccess;
461                };
462                parentMemberDefine.dataMembers.Add(dataMemberDefine);
463             }
464          }
465       }
466    }
467 }
468
469 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, bool isWatchable, AccessMode declMode)
470 {
471    Class regClass;
472    ClassDef def;
473    ClassDefine classDefine;
474    char baseName[1024];
475    bool unitType = false;
476    bool wouldBeEnum = false;
477    AccessMode inheritanceAccess = publicAccess;
478    baseName[0] = '\0';
479
480    if(baseSpecs != null)
481    {
482       Type baseType = ProcessType(baseSpecs, null);
483       PrintType(baseType, baseName, false, true);
484       if(baseType.kind == TypeKind::classType)
485       {
486          if(baseType._class.registered && classType == normalClass)
487          {
488             if(baseType._class.registered.type == unitClass)
489                classType = unitClass;
490             else if(baseType._class.registered.type == bitClass)
491                classType = bitClass;
492             else if(baseType._class.registered.type == noHeadClass)
493                classType = noHeadClass;
494             else if(baseType._class.registered.type == enumClass)
495             {
496                wouldBeEnum = true;
497                // classType = enumClass;
498             }
499          }
500       }
501       else if(baseType.kind == structType || baseType.kind == unionType)
502       {
503          classType = noHeadClass;
504          baseName[0] = '\0';
505       }
506       else
507          unitType = true;
508       FreeType(baseType);
509
510       if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
511          inheritanceAccess = privateAccess;
512    }
513
514    // Eventually compute size with declarations for optional constant size offset...
515
516    // If there's any struct declaration in a unit data type, it means this is a bit class
517    if(classType == normalClass)
518    {
519       if(unitType) classType = unitClass;
520       if(definitions != null)
521       {
522          for(def = definitions.first; def; def = def.next)
523          {
524             if(def.type == declarationClassDef)
525             {
526                Declaration decl = def.decl;
527                if(decl.type == structDeclaration)
528                {
529                   if(unitType)
530                   {
531                      classType = bitClass;
532                      break;
533                   }
534                   if(decl.declarators)
535                   {
536                      Declarator d;
537
538                      for(d = decl.declarators->first; d; d = d.next)
539                      {
540                         if(d.structDecl.exp)
541                         {
542                            classType = bitClass;
543                            break;
544                         }
545                      }
546                      if(d) break;
547                   }
548                }
549             }
550          }
551       }
552    }
553    if(classType == normalClass && wouldBeEnum) classType = enumClass;
554
555    regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType, symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, publicAccess, inheritanceAccess);
556    if(regClass)
557       regClass.symbol = symbol;
558
559    classDefine = ClassDefine
560    {
561       type = classDefinition;
562       name = CopyString(symbol.string);
563       base = baseName[0] ? CopyString(baseName) : null;
564       isStatic = declMode == staticAccess;
565       isRemote = symbol.isRemote;
566       isWatchable = isWatchable;
567    };
568    precompDefines.Add(classDefine);
569
570    if(classType == unionClass)
571    {
572       DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
573       DataMemberDefine unionDefine;
574
575       unionDefine = DataMemberDefine
576       {
577          isProperty = dataMember;
578          memberType = DataMemberType::unionMember;
579       };
580       classDefine.propertiesAndMembers.Add(unionDefine);
581
582       AddDefinitions(classDefine, unionDefine, regClass, unionMember, definitions);
583       eClass_AddMember(regClass, unionMember);
584    }
585    else if(regClass)
586       AddDefinitions(classDefine, (DataMemberDefine)classDefine, regClass, null, definitions);
587
588    // Do the functions
589    if(definitions != null)
590    {
591       for(def = definitions.first; def; def = def.next)
592       {
593          if(def.type == functionClassDef)
594          {
595             ClassFunction func = def.function;
596             // Add ecereMethod_[class]_ to the declarator
597             if(!func.dontMangle && func.declarator)
598             {
599                Identifier id = GetDeclId(func.declarator);
600                Method method;
601                MethodDefine methodDefine;
602
603                {
604                   char * dataTypeString  = StringFromSpecDecl(func.specifiers, func.declarator);
605                   if(func.isVirtual)
606                      method = eClass_AddVirtualMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
607                   else
608                      method = eClass_AddMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
609                   delete dataTypeString;
610                }
611
612                // Should we make a copy here? We make a copy in pass0.c ...
613                //method.symbol = func.declarator.symbol;
614
615                if(method)
616                {
617                   method.symbol = Symbol
618                   {
619                      string = CopyString(func.declarator.symbol.string);
620                      id = func.declarator.symbol.id;
621                      type = func.declarator.symbol.type;
622                   };
623                   if(func.declarator.symbol.type)
624                      func.declarator.symbol.type.refCount++;
625
626                   ((Symbol)method.symbol).method = method;
627
628
629                   func.declarator.symbol = null;
630
631                   if(method.type != virtualMethod || method._class == regClass)
632                   {
633                      methodDefine = MethodDefine
634                      {
635                         name = CopyString(method.name);
636                         type = CopyString(method.dataTypeString);
637                         memberAccess = def.memberAccess;
638                         isVirtual = method.type == virtualMethod;
639                      };
640                      classDefine.methods.Add(methodDefine);
641                   }
642                }
643             }
644          }
645          else if(def.type == accessOverrideClassDef)
646          {
647             Method method;
648             if((method = eClass_FindMethod(regClass, def.id.string, privateModule)))
649             {
650                MethodDefine methodDefine;
651
652                method = eClass_AddMethod(regClass, def.id.string, null, null, def.memberAccess);
653
654                methodDefine = MethodDefine
655                {
656                   name = CopyString(method.name);
657                   memberAccess = def.memberAccess;
658                };
659                classDefine.methods.Add(methodDefine);
660             }
661          }
662       }
663    }
664    if(regClass && symbol.templateParams)
665    {
666       TemplateParameter param;
667       // Add template parameters here
668       for(param = symbol.templateParams->first; param; param = param.next)
669       {
670          ClassTemplateArgument defaultArg { };
671          if(param.defaultArgument)
672          {
673             switch(param.type)
674             {
675                case type:
676                   defaultArg.dataTypeString =
677                      StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
678                   break;
679                case identifier:
680                {
681                   char memberString[1024];
682                   memberString[0] = '\0';
683
684                   if(param.defaultArgument.identifier._class && param.defaultArgument.identifier._class.name)
685                   {
686                      if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
687                         strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
688                      else
689                         strcpy(memberString, param.defaultArgument.identifier._class.name);
690                   }
691
692                   if(memberString[0])
693                   {
694                      strcat(memberString, "::");
695                   }
696                   strcat(memberString, param.defaultArgument.identifier.string);
697                   defaultArg.memberString = CopyString(memberString);
698                   break;
699                }
700 /*                  switch(param.memberType)
701                   {
702                      case dataMember:
703                         defaultArg.member = eClass_FindDataMember(regClass, param.defaultArgument.identifier.string, regClass.module, null, null);
704                         break;
705                      case method:
706                         defaultArg.method = eClass_FindMethod(regClass, param.defaultArgument.identifier.string, regClass.module);
707                         break;
708                      case prop:
709                         defaultArg.prop = eClass_FindProperty(regClass, param.defaultArgument.identifier.string, regClass.module);
710                         break;
711                   }
712                   break;*/
713                case expression:
714                {
715                   Operand op;
716                   ProcessExpressionType(param.defaultArgument.expression);
717                   ComputeExpression(param.defaultArgument.expression);
718                   op = GetOperand(param.defaultArgument.expression);
719                   defaultArg.expression.ui64 = op.ui64;
720                   break;
721                }
722             }
723          }
724          if(param.type == identifier)
725          {
726             eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, (void *)param.memberType, defaultArg);
727          }
728          else
729          {
730             char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
731             eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
732
733             /*eClass_AddTemplateParameter(regClass, param.identifier.string, param.type,
734                (param.type == type) ? eSystem_FindClass(regClass.module, typeString) : CopyString(typeString), defaultArg);*/
735             // delete typeString;
736          }
737
738       }
739    }
740 }
741
742 static void ProcessClassEnumValues(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues)
743 {
744    Class regClass = symbol.registered;
745    if(regClass && enumValues)
746    {
747       Enumerator e;
748       for(e = enumValues.first; e; e = e.next)
749       {
750          if(e.exp)
751          {
752             Type destType
753             {
754                kind = intType;
755                refCount = 1;
756             };
757             e.exp.destType = destType;
758
759             // Set parsingType to avoid producing errors
760             SetParsingType(true);
761             ProcessExpressionType(e.exp);
762             SetParsingType(false);
763
764             if(!e.exp.expType)
765             {
766                destType.kind = TypeKind::classType;
767                destType._class = symbol;
768                ProcessExpressionType(e.exp);
769             }
770             ComputeExpression(e.exp);
771             if(e.exp.isConstant && e.exp.type == constantExp)
772             {
773                Operand op = GetOperand(e.exp);
774                int value;
775                //value = strtol(e.exp.string, null, 0);
776                switch(op.kind)
777                {
778                   case charType:
779                      value = op.type.isSigned ? (int)op.c : (int)op.uc;
780                      break;
781                   case shortType:
782                      value = op.type.isSigned ? (int)op.s : (int) op.us;
783                      break;
784                   default:
785                      value = op.i;
786                }
787                eEnum_AddFixedValue(regClass, e.id.string, value);
788             }
789             else
790                // Sort of an error
791                eEnum_AddValue(regClass, e.id.string);
792          }
793          else
794             eEnum_AddValue(regClass, e.id.string);
795       }
796    }
797 }
798
799 void PreCompPreProcessClassDefinitions()
800 {
801    OldList * ast = GetAST();
802    External external, next;
803    for(external = ast->first; external; external = next)
804    {
805       next = external.next;
806       if(external.type == classExternal)
807       {
808          ClassDefinition _class = external._class;
809          if(_class.declMode == publicAccess || _class.declMode == privateAccess || _class.declMode == staticAccess)
810          {
811             if(_class.definitions)
812             {
813                ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.deleteWatchable, _class.declMode);
814             }
815          }
816       }
817       else if(external.type == declarationExternal)
818       {
819          Declaration declaration = external.declaration;
820
821          if(declaration.type == initDeclaration)
822          {
823             if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess || external.declaration.declMode == staticAccess)
824             {
825                if(declaration.specifiers)
826                {
827                   Specifier specifier;
828                   for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
829                   {
830                      if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
831                         (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
832                      {
833                         Symbol symbol = FindClass(specifier.id.string);
834                         if(symbol)
835                         {
836                            ClassType classType;
837
838                            if(specifier.type == enumSpecifier)
839                               classType = enumClass;
840                            else if(specifier.type == unionSpecifier)
841                               classType = unionClass;
842                            else
843                               classType = structClass;
844                            ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, false, external.declaration.declMode);
845                         }
846                      }
847                   }
848                }
849                if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
850                {
851                   if(declaration.declarators)
852                   {
853                      InitDeclarator d;
854                      for(d = declaration.declarators->first; d; d = d.next)
855                      {
856                         if(d.declarator)
857                         {
858                            Symbol symbol = d.declarator.symbol;
859                            if(symbol)
860                            {
861                               DataDefine dataDefine;
862                               char typeString[1024];
863                               typeString[0] = '\0';
864                               PrintType(symbol.type, typeString, false, true);
865                               dataDefine = DataDefine
866                               {
867                                  type = dataDefinition;
868                                  name = CopyString(symbol.string);
869                                  dataType = CopyString(typeString);
870                               };
871                               precompDefines.Add(dataDefine);
872                            }
873                         }
874                      }
875                   }
876                }
877             }
878          }
879          else if(declaration.type == instDeclaration)
880          {
881             if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
882             {
883                Symbol symbol = declaration.inst.symbol;
884                if(symbol)
885                {
886                   DataDefine dataDefine;
887                   char typeString[1024];
888                   typeString[0] = '\0';
889                   PrintType(symbol.type, typeString, false, true);
890                   dataDefine = DataDefine
891                   {
892                      type = dataDefinition;
893                      name = CopyString(symbol.string);
894                      dataType = CopyString(typeString);
895                   };
896                   precompDefines.Add(dataDefine);
897                }
898             }
899             globalInstance = true;
900          }
901          else if(declaration.type == defineDeclaration)
902          {
903             if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
904             {
905                Define definition
906                {
907                   type = defineDefinition;
908                   name = CopyString(declaration.id.string);
909                   exp = declaration.exp;
910                };
911                precompDefines.Add(definition);
912             }
913          }
914       }
915       else if(external.type == functionExternal && (external.function.declMode == publicAccess || external.function.declMode == privateAccess))
916       {
917          FunctionDefinition function = external.function;
918          FunctionDefine functionDefine;
919          char typeString[1024];
920          typeString[0] = '\0';
921          PrintType(function.declarator.symbol.type, typeString, true, true);
922          functionDefine = FunctionDefine
923          {
924             type = functionDefinition;
925             name = CopyString(function.declarator.symbol.string);
926             dataType = CopyString(typeString);
927          };
928          precompDefines.Add(functionDefine);
929       }
930       else if(external.type == nameSpaceExternal)
931       {
932          SetCurrentNameSpace(external.id.string); //currentNameSpace = external.id.string;
933          //currentNameSpaceLen = currentNameSpace ? strlen(currentNameSpace) : 0;
934       }
935    }
936
937    ComputeModuleClasses(privateModule);
938
939    // Second pass for enumeration values
940    for(external = ast->first; external; external = next)
941    {
942       next = external.next;
943       if(external.type == declarationExternal && (external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess))
944       {
945          Declaration declaration = external.declaration;
946
947          if(declaration.type == initDeclaration)
948          {
949             if(declaration.specifiers)
950             {
951                Specifier specifier;
952                for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
953                {
954                   if((specifier.type == enumSpecifier) && specifier.id && specifier.id.string &&
955                      (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
956                   {
957                      Symbol symbol = FindClass(specifier.id.string);
958                      if(symbol)
959                      {
960                         ProcessClassEnumValues(enumClass, specifier.definitions, symbol, specifier.baseSpecs, specifier.list);
961                      }
962                   }
963                }
964             }
965          }
966       }
967    }
968 }
969
970 static void OutputDataMembers(ClassDefine classDefine, Class _class, File f)
971 {
972    if(classDefine.propertiesAndMembers.first)
973    {
974       DataMemberDefine member = classDefine.propertiesAndMembers.first;
975       MemberType last = unresolvedMember;
976
977       for(member = classDefine.propertiesAndMembers.first; member; member = member.next)
978       {
979          if(member.isProperty == propertyMember)
980          {
981             PropertyDefine prop = (PropertyDefine)member;
982             if(last != propertyMember)
983             {
984                if(last)
985                   f.Printf("         .\n");
986                f.Printf("      [Defined Properties]\n");
987             }
988
989             if(prop.name)
990                f.Printf("         %s\n", prop.name);
991             else
992                f.Printf("         [Conversion]\n");
993             if(prop.memberAccess == publicAccess)
994                f.Printf("            [Public]\n");
995             else
996                f.Printf("            [Private]\n");
997             if(prop.isVirtual)
998                f.Printf("            [Virtual]\n");
999             if(prop.hasSet)
1000                f.Printf("            [Set]\n");
1001             if(prop.hasGet)
1002                f.Printf("            [Get]\n");
1003             if(prop.isWatchable)
1004                f.Printf("            [Watchable]\n");
1005             f.Printf("            [Type]\n");
1006             f.Printf("               %s\n", prop.type ? prop.type : "");
1007          }
1008          else
1009          {
1010             if(last != dataMember)
1011             {
1012                if(last)
1013                   f.Printf("         .\n");
1014                f.Printf("      [Defined Data Members]\n");
1015             }
1016             if(member.memberType == normalMember)
1017             {
1018                f.Printf("         %s\n", member.name);
1019                if(member.memberAccess == publicAccess)
1020                   f.Printf("            [Public]\n");
1021                else
1022                   f.Printf("            [Private]\n");
1023                if(_class && _class.type == bitClass)
1024                {
1025                   if(member.size)
1026                   {
1027                      f.Printf("            [Size]\n");
1028                      f.Printf("               %d\n", member.size);
1029                   }
1030                   if(member.bitPos != -1)
1031                   {
1032                      f.Printf("            [Pos]\n");
1033                      f.Printf("               %d\n", member.bitPos);
1034                   }
1035                }
1036                f.Printf("            [Type]\n");
1037                f.Printf("               %s\n", member.type ? member.type : "");
1038             }
1039             else
1040             {
1041                if(member.memberAccess == publicAccess)
1042                   f.Printf("            [Public]\n");
1043                else
1044                   f.Printf("            [Private]\n");
1045                f.Printf((member.memberType == unionMember) ? "      [Union]\n" : "      [Struct]\n");
1046                OutputDataMembers((ClassDefine)member, null, f);
1047             }
1048          }
1049          last = member.isProperty;
1050       }
1051       f.Printf("         .\n");
1052    }
1053
1054    if(classDefine.classProperties.first)
1055    {
1056       PropertyDefine prop = classDefine.propertiesAndMembers.first;
1057       f.Printf("      [Defined Class Properties]\n");
1058       for(prop = classDefine.classProperties.first; prop; prop = prop.next)
1059       {
1060          if(prop.name)
1061             f.Printf("         %s\n", prop.name);
1062          if(prop.hasSet)
1063             f.Printf("            [Set]\n");
1064          if(prop.hasGet)
1065             f.Printf("            [Get]\n");
1066          f.Printf("            [Type]\n");
1067          f.Printf("               %s\n", prop.type ? prop.type : "");
1068       }
1069       f.Printf("         .\n");
1070    }
1071 }
1072
1073 static void OutputSymbols(char * fileName)
1074 {
1075    File f = FileOpen(fileName, write);
1076    if(f)
1077    {
1078       DefinitionType lastType = (DefinitionType)-1;
1079       Definition definition;
1080
1081       if(globalInstance)
1082          f.Printf("[Global Instance]\n");
1083
1084       for(definition = precompDefines.first; definition; definition = definition.next)
1085       {
1086          if(definition.type != lastType)
1087          {
1088             if(lastType != (DefinitionType)-1)
1089                f.Printf("   .\n");
1090             if(definition.type == moduleDefinition)
1091                f.Printf("[Imported Modules]\n");
1092             else if(definition.type == classDefinition)
1093                f.Printf("[Defined Classes]\n");
1094             else if(definition.type == defineDefinition)
1095                f.Printf("[Defined Expressions]\n");
1096             else if(definition.type == functionDefinition)
1097                f.Printf("[Defined Functions]\n");
1098             else if(definition.type == dataDefinition)
1099                f.Printf("[Defined Data]\n");
1100             lastType = definition.type;
1101          }
1102          if(definition.type == moduleDefinition)
1103          {
1104             ImportedModule module = (ImportedModule) definition;
1105
1106             if(module.importType == staticImport)
1107                f.Printf("   [Static]\n");
1108             else if(module.importType == remoteImport)
1109                f.Printf("   [Remote]\n");
1110             if(module.importAccess == privateAccess)
1111                f.Printf("   [Private]\n");
1112             f.Printf("   %s\n", module.name);
1113          }
1114          else if(definition.type == classDefinition)
1115          {
1116             // Can we do this? Or should we fill up the definition?
1117             Class _class = eSystem_FindClass(privateModule, definition.name);
1118             ClassDefine classDefine = (ClassDefine) definition;
1119
1120             f.Printf("   %s\n", definition.name);
1121             if(classDefine.isStatic)
1122                f.Printf("      [Static]\n");
1123             if(classDefine.fixed)
1124                f.Printf("      [Fixed]\n");
1125             if(classDefine.noExpansion)
1126                f.Printf("      [No Expansion]\n");
1127             if(classDefine.isRemote)
1128                f.Printf("      [Remote]\n");
1129             if(classDefine.isWatchable)
1130                f.Printf("      [Watchable]\n");
1131             if(_class.type == enumClass)
1132                f.Printf("      [Enum]\n");
1133             else if(_class.type == bitClass)
1134                f.Printf("      [Bit]\n");
1135             else if(_class.type == structClass)
1136                f.Printf("      [Struct]\n");
1137             else if(_class.type == unitClass)
1138                f.Printf("      [Unit]\n");
1139             else if(_class.type == noHeadClass)
1140                f.Printf("      [NoHead]\n");
1141
1142             if(_class.inheritanceAccess == privateAccess)
1143                f.Printf("      [Private Base]\n");
1144             else
1145                f.Printf("      [Base]\n");
1146             if(classDefine.base)
1147                f.Printf("         %s\n", classDefine.base);
1148             else
1149                f.Printf("         [None]\n");
1150
1151             if(_class.templateParams.count)
1152             {
1153                ClassTemplateParameter param;
1154                TemplateParameter tp;
1155
1156                f.Printf("         [Template Parameters]\n");
1157
1158                for(tp = ((Symbol)_class.symbol).templateParams->first, param = _class.templateParams.first; param && tp; param = param.next, tp = tp.next)
1159                {
1160                   f.Printf("               %s\n", param.name);
1161                   switch(param.type)
1162                   {
1163                      case type:
1164                         f.Printf("               [Type]\n");
1165                         f.Printf("               %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1166                         f.Printf("               %s\n", param.defaultArg.dataTypeString ? param.defaultArg.dataTypeString : "[None]");
1167                         break;
1168                      case expression:
1169                         f.Printf("               [Expression]\n");
1170                         f.Printf("               %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1171                         if(tp.defaultArgument && tp.defaultArgument.expression)
1172                         {
1173                            char temp[8192];
1174                            temp[0] = 0;
1175                            PrintExpression(tp.defaultArgument.expression, temp);
1176                            ChangeCh(temp, '\n', ' ');
1177                            f.Printf("               ");
1178                            f.Puts(temp);
1179                            f.Puts("\n");
1180                         }
1181                         else
1182                            f.Printf("               [None]\n");
1183                         break;
1184                      case identifier:
1185                         f.Printf("               [Identifier]\n");
1186                         f.Printf("               %s\n", (param.memberType == dataMember) ? "[Data member]" : ((param.memberType == method) ? "[Method]" : "[Property]"));
1187                         if(tp.defaultArgument && tp.defaultArgument.identifier)
1188                         {
1189                            f.Printf("               ");
1190                            if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == nameSpecifier &&
1191                               tp.defaultArgument.identifier._class.name)
1192                            {
1193                               f.Printf("%s::", tp.defaultArgument.identifier._class.name);
1194                            }
1195                            else if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == templateTypeSpecifier &&
1196                               tp.defaultArgument.identifier._class.templateParameter.identifier)
1197                            {
1198                               f.Printf("%s::", tp.defaultArgument.identifier._class.templateParameter.identifier.string);
1199                            }
1200                            f.Printf("%s\n", tp.defaultArgument.identifier.string);
1201                         }
1202                         else
1203                         {
1204                            f.Printf("               [None]\n");
1205                         }
1206                         break;
1207                   }
1208                }
1209                f.Printf("         .\n");
1210             }
1211
1212             if(!classDefine.isStatic)
1213             {
1214                if(classDefine.methods.first)
1215                {
1216                   MethodDefine method;
1217
1218                   f.Printf("      [Defined Methods]\n");
1219                   for(method = classDefine.methods.first; method; method = method.next)
1220                   {
1221                      f.Printf("         %s\n", method.name);
1222                      if(method.memberAccess == publicAccess)
1223                         f.Printf("            [Public]\n");
1224                      else
1225                         f.Printf("            [Private]\n");
1226                      if(method.isVirtual)
1227                         f.Printf("            [Virtual]\n");
1228                      f.Printf("            [Type]\n");
1229                      f.Printf("               %s\n", method.type ? method.type : "");
1230                   }
1231                   f.Printf("         .\n");
1232                }
1233
1234                OutputDataMembers(classDefine, _class, f);
1235
1236                if(_class.type == enumClass)
1237                {
1238                   NamedLink value;
1239                   Class enumClass = eSystem_FindClass(privateModule, "enum");
1240                   EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
1241
1242                   f.Printf("      [Enum Values]\n");
1243                   for(value = e.values.first; value; value = value.next)
1244                   {
1245                      f.Printf("         %s = %d\n", value.name, value.data);
1246                   }
1247                   f.Printf("         .\n");
1248                }
1249             }
1250          }
1251          else if(definition.type == defineDefinition)
1252          {
1253             DefinedExpression defExp = eSystem_FindDefine(privateModule, definition.name);
1254             Define defineDefine = (Define) definition;
1255             f.Printf("   %s\n", definition.name);
1256             f.Printf("      [Value]\n");
1257             f.Printf("         ");
1258             OutputExpression(defineDefine.exp, f);
1259             f.Printf("\n");
1260          }
1261          else if(definition.type == functionDefinition)
1262          {
1263             FunctionDefine functionDefine = (FunctionDefine) definition;
1264             f.Printf("   %s\n", functionDefine.name);
1265             f.Printf("      [Type]\n");
1266             f.Printf("         %s\n", functionDefine.dataType);
1267          }
1268          else if(definition.type == dataDefinition)
1269          {
1270             DataDefine dataDefine = (DataDefine) definition;
1271             f.Printf("   %s\n", dataDefine.name);
1272             f.Printf("      [Type]\n");
1273             f.Printf("         %s\n", dataDefine.dataType);
1274          }
1275       }
1276       f.Printf("   .\n");
1277       delete f;
1278    }
1279 }
1280
1281 class PrecompApp : Application
1282 {
1283    void Main()
1284    {
1285       int c;
1286       bool valid = true;
1287       char defaultSymFile[MAX_LOCATION];
1288       char * cppCommand = null;
1289       char * cppOptions = null;
1290       int cppOptionsLen = 0;
1291       /*char ** argv = null;
1292       int argc = 0;*/
1293
1294       Platform targetPlatform = GetRuntimePlatform();
1295       int targetBits = GetHostBits();
1296       /*
1297       for(c = 0; c<this.argc; c++)
1298       {
1299          char * arg = this.argv[c];
1300          int argLen = strlen(arg);
1301
1302          argv = renew argv char *[argc + 1];
1303          argv[argc] = new char[argLen+1];
1304          strcpy(argv[argc], arg);
1305
1306          while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
1307          {
1308             int len;
1309
1310             c++;
1311             arg = this.argv[c];
1312             len = strlen(arg);
1313             argv[argc] = renew argv[argc] char[argLen + len + 1];
1314
1315             argv[argc][argLen-1] = ' ';
1316             strcpy(argv[argc] + argLen, arg);
1317             argLen += len;
1318          }
1319          argc++;
1320       }*/
1321
1322 #ifdef _DEBUG
1323       printf("\nArguments given:\n");
1324       for(c=1; c<argc; c++)
1325          printf(" %s", argv[c]);
1326       printf("\n\n");
1327       for(c=1; c<argc; c++)
1328          PrintLn("Arg", c, ": ", argv[c]);
1329       printf("\n");
1330       //getch();
1331 #endif
1332
1333       for(c = 1; c<argc; c++)
1334       {
1335          char * arg = argv[c];
1336          if(arg[0] == '-')
1337          {
1338             if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
1339             {
1340                int newLen = cppOptionsLen + 1 + strlen(arg);
1341                cppOptions = renew cppOptions char[newLen + 1];
1342                cppOptions[cppOptionsLen] = ' ';
1343                strcpy(cppOptions + cppOptionsLen + 1, arg);
1344                cppOptionsLen = newLen;
1345                targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
1346             }
1347             else if(arg[1] == 'D' || arg[1] == 'I')
1348             {
1349                char * buf;
1350                int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1351                cppOptions = renew cppOptions char[size];
1352                buf = cppOptions + cppOptionsLen;
1353                *buf++ = ' ';
1354                PassArg(buf, arg);
1355                cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1356             }
1357             else if(!strcmp(arg+1, "t"))
1358             {
1359                if(++c < argc)
1360                   targetPlatform = argv[c];
1361                else
1362                   valid = false;
1363             }
1364             else if(!strcmp(arg+1, "cpp"))
1365             {
1366                if(++c < argc)
1367                   cppCommand = CopyString(argv[c]);
1368                else
1369                   valid = false;
1370             }
1371             else if(!strcmp(arg+1, "o"))
1372             {
1373                if(!GetOutputFile() && c + 1 < argc)
1374                {
1375                   SetOutputFile(argv[c+1]);
1376                   c++;
1377                }
1378                else
1379                   valid = false;
1380             }
1381             else if(!strcmp(arg+1, "c"))
1382             {
1383                if(!GetSourceFile() && c + 1 < argc)
1384                {
1385                   SetSourceFile(argv[c+1]);
1386                   c++;
1387                }
1388                else
1389                   valid = false;
1390             }
1391             else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot"))
1392             {
1393                if(c + 1 < argc)
1394                {
1395                   char * buf;
1396                   char * arg1 = argv[++c];
1397                   int size = cppOptionsLen + 1 + strlen(arg) * 2 + strlen(arg1) * 2 + 1;
1398                   cppOptions = renew cppOptions char[size];
1399                   buf = cppOptions + cppOptionsLen;
1400                   *buf++ = ' ';
1401                   buf = PassArg(buf, arg);
1402                   *buf++ = ' ';
1403                   buf = PassArg(buf, arg1);
1404                   cppOptionsLen = buf - cppOptions;
1405                }
1406                else
1407                   valid = false;
1408             }
1409             else if(!strcmp(arg+1, "fno-diagnostics-show-caret"))
1410             {
1411                char * buf;
1412                int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1413                cppOptions = renew cppOptions char[size];
1414                buf = cppOptions + cppOptionsLen;
1415                *buf++ = ' ';
1416                PassArg(buf, arg);
1417                cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1418             }
1419             else if(!strcmp(arg+1, "symbols"))
1420             {
1421                if(c + 1 < argc)
1422                {
1423                   SetSymbolsDir(argv[c+1]);
1424                   c++;
1425                }
1426                else
1427                   valid = false;
1428             }
1429             else if(!strcmp(arg+1, "defaultns"))
1430             {
1431                if(c + 1 < argc)
1432                {
1433                   SetDefaultNameSpace(argv[c+1]);
1434                   //defaultNameSpaceLen = strlen(argv[c+1]);
1435                   c++;
1436                }
1437                else
1438                   valid = false;
1439             }
1440             else if(!strcmp(arg+1, "strictns"))
1441             {
1442                SetStrictNameSpaces(true);
1443             }
1444          }
1445          else
1446             valid = false;
1447       }
1448       if(valid)
1449       {
1450          if(!cppCommand)
1451             cppCommand = CopyString("gcc");
1452          if(!GetSourceFile())
1453             valid = false;
1454          else if(!GetOutputFile())
1455          {
1456             strcpy(defaultSymFile, GetSymbolsDir());
1457             PathCat(defaultSymFile, GetSourceFile());
1458             ChangeExtension(defaultSymFile, "sym", defaultSymFile);
1459             SetOutputFile(defaultSymFile);
1460          }
1461       }
1462
1463       if(!valid)
1464       {
1465          printf($"Syntax:\n   ecp [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
1466       }
1467       else
1468       {
1469          DualPipe cppOutput;
1470          // TODO: Improve this
1471          char command[MAX_F_STRING*3];
1472          SetGlobalData(&globalData);
1473          SetExcludedSymbols(&_excludedSymbols);
1474          SetGlobalContext(globalContext);
1475          SetCurrentContext(globalContext);
1476          SetTopContext(globalContext);
1477          SetDefines(&::defines);
1478          SetImports(&imports);
1479          SetInPreCompiler(true);
1480          SetPrecompDefines(&precompDefines);
1481          SetTargetPlatform(targetPlatform);
1482          SetTargetBits(targetBits);
1483          SetEchoOn(false);
1484
1485          privateModule = (Module)__ecere_COM_Initialize(true | (targetBits == sizeof(uintptr)*8 ? 0 : targetBits == 64 ? 2 : targetBits==32 ? 4 : 0) | 8, 1, null);
1486          SetPrivateModule(privateModule);
1487
1488          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
1489          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
1490          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
1491          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
1492          globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
1493          globalContext.types.Add((BTNode)Symbol { string = CopyString("intptr_t"), type = ProcessTypeString("intptr", false) });
1494          globalContext.types.Add((BTNode)Symbol { string = CopyString("uintptr_t"), type = ProcessTypeString("uintptr", false) });
1495          globalContext.types.Add((BTNode)Symbol { string = CopyString("ssize_t"), type = ProcessTypeString("intsize", false) });
1496          globalContext.types.Add((BTNode)Symbol { string = CopyString("size_t"), type = ProcessTypeString("uintsize", false) });
1497
1498          {
1499             char * outputFilePath = GetOutputFile();
1500             if(FileExists(outputFilePath))
1501                DeleteFile(outputFilePath);
1502          }
1503
1504          snprintf(command, sizeof(command), "%s%s -x c -E \"%s\"", cppCommand, cppOptions ? cppOptions : "", GetSourceFile());
1505          command[sizeof(command)-1] = 0;
1506 #ifdef _DEBUG
1507          PrintLn("ECP Executing:");
1508          PrintLn(command);
1509 #endif
1510          if((cppOutput = DualPipeOpen({ output = true }, command)))
1511          {
1512             int exitCode;
1513             OldList * ast;
1514             TempFile fileInput { };
1515             ModuleImport mainModule { };
1516             //fileInput = TempFile { };
1517             SetFileInput(fileInput);
1518
1519             SetMainModule(mainModule);
1520             imports.Add(/*(*/mainModule/* = ModuleImport { })*/);
1521
1522             resetScanner();
1523
1524             for(;!cppOutput.Eof();)
1525             {
1526                char junk[4096];
1527                int count = cppOutput.Read(junk, 1, 4096);
1528                fileInput.Write(junk, 1, count);
1529             }
1530             exitCode = cppOutput.GetExitCode();
1531             delete cppOutput;
1532
1533             fileInput.Seek(0, start);
1534
1535    #ifdef _DEBUG
1536             // SetYydebug(true);
1537    #endif
1538             ParseEc();
1539             SetCurrentNameSpace(null);
1540             SetYydebug(false);
1541             delete fileInput;
1542             SetFileInput(null);
1543
1544             ast = GetAST();
1545             if(!exitCode)
1546             {
1547                if(ast)
1548                {
1549                   ProcessDBTableDefinitions();
1550                   PreCompPreProcessClassDefinitions();
1551                }
1552                if(!this.exitCode)
1553                   OutputSymbols(GetOutputFile());
1554             }
1555             else
1556                this.exitCode = exitCode;
1557
1558             if(ast)
1559             {
1560                FreeASTTree(ast);
1561             }
1562          }
1563
1564          FreeContext(globalContext);
1565          FreeExcludedSymbols(_excludedSymbols);
1566
1567          ::defines.Free(FreeModuleDefine);
1568          imports.Free(FreeModuleImport);
1569
1570          precompDefines.Free(FreeDefinition);
1571
1572          FreeTypeData(privateModule);
1573          FreeIncludeFiles();
1574          FreeGlobalData(globalData);
1575
1576          delete privateModule;
1577       }
1578
1579       delete cppCommand;
1580       delete cppOptions;
1581
1582       /*
1583       for(c = 0; c<argc; c++)
1584          delete argv[c];
1585       delete argv;
1586       */
1587       SetSymbolsDir(null); // Free symbols dir
1588
1589 #if defined(_DEBUG) && defined(__WIN32__)
1590       // CheckMemory();
1591       PrintLn("Done.");
1592       getch();
1593 #endif
1594    }
1595 }