9 #define YYLTYPE Location
10 #include "../libec/src/grammar.h"
12 // UNTIL IMPLEMENTED IN GRAMMAR
13 #define ACCESS_CLASSDATA(_class, baseClass) \
14 (_class ? ((void *)(((char *)_class.data) + baseClass.offsetClass)) : null)
16 // #include <stdarg.h>
18 // WARNING: PropertyDefine, ClassDefine and DataMemberDefine must remain compatible
19 struct ClassDefine : Definition
22 OldList propertiesAndMembers;
23 OldList classProperties;
32 struct Define : Definition
37 struct FunctionDefine : Definition
42 struct DataDefine : Definition
47 class MethodDefine : struct
49 MethodDefine prev, next;
51 AccessMode memberAccess;
56 // WARNING: PropertyDefine, ClassDefine and DataMemberDefine must remain compatible
57 class PropertyDefine : struct
59 PropertyDefine prev, next;
61 MemberType isProperty;
65 AccessMode memberAccess;
70 // WARNING: PropertyDefine, ClassDefine and DataMemberDefine must remain compatible
71 class DataMemberDefine : struct
73 DataMemberDefine prev, next;
75 MemberType isProperty;
78 OldList classProperties; // For binary compatibility with ClassDefine
80 AccessMode memberAccess;
81 DataMemberType memberType;
85 void FreeMethodDefine(MethodDefine method)
91 void FreeDataMemberDefine(DataMemberDefine dataMember)
93 delete dataMember.name;
94 delete dataMember.type;
97 void FreeDataDefine(DataDefine data)
100 delete data.dataType;
103 void FreeDefinition(Definition definition)
105 delete definition.name;
106 switch(definition.type)
108 case classDefinition:
110 ClassDefine classDefine = (ClassDefine)definition;
111 delete classDefine.base;
112 classDefine.methods.Free(FreeMethodDefine);
113 classDefine.propertiesAndMembers.Free(FreeDataMemberDefine);
116 case functionDefinition:
117 delete ((FunctionDefine)definition).dataType;
120 delete ((DataDefine)definition).dataType;
122 case defineDefinition:
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)(uintptr)&((Symbol)0).left };
133 static NameSpace globalData
135 classes.CompareKey = (void *)BinaryTree::CompareString;
136 defines.CompareKey = (void *)BinaryTree::CompareString;
137 functions.CompareKey = (void *)BinaryTree::CompareString;
138 nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
141 static void AddDefinitions(ClassDefine classDefine, DataMemberDefine parentMemberDefine, Class regClass, DataMember member, OldList definitions)
143 if(definitions != null)
146 for(def = definitions.first; def; def = def.next)
148 if(def.type == declarationClassDef)
150 Declaration decl = def.decl;
151 DataMember dataMember;
153 DataMemberDefine dataMemberDefine;
155 if(decl.type == structDeclaration)
161 for(d = decl.declarators->first; d; d = d.next)
163 Identifier declId = GetDeclId(d);
164 //if(d.type != DeclaratorFunction)
167 dataMemberDefine = DataMemberDefine
169 isProperty = MemberType::dataMember;
170 memberType = normalMember;
171 name = CopyString(declId.string);
173 parentMemberDefine.dataMembers.Add(dataMemberDefine);
174 if(regClass && regClass.type == bitClass)
176 Expression sizeExp = d.structDecl.exp, posExp = d.structDecl.posExp;
177 int bitSize = 0, bitPos = -1;
178 char dataTypeString[1024];
179 dataTypeString[0] = '\0';
183 ProcessExpressionType(sizeExp);
184 ComputeExpression(sizeExp);
185 if(sizeExp.isConstant)
186 bitSize = strtol(sizeExp.constant, null, 0);
187 FreeExpression(sizeExp);
192 ProcessExpressionType(posExp);
193 ComputeExpression(posExp);
194 if(posExp.isConstant)
195 bitPos = strtol(posExp.constant, null, 0);
196 FreeExpression(posExp);
200 d.structDecl.exp = null;
201 d.structDecl.posExp = null;
203 dataType = ProcessType(decl.specifiers, d);
204 PrintType(dataType, dataTypeString, false, true);
206 //if(!eClass_FindDataMember(regClass, declId.string))
208 BitMember member = eClass_AddBitMember(regClass, declId.string, dataTypeString, 0, 0, def.memberAccess);
211 member.size = bitSize;
214 dataMember = (DataMember)member;
217 dataMember.dataType = dataType;
219 dataMemberDefine.size = bitSize;
220 dataMemberDefine.bitPos = bitPos;
222 dataMemberDefine.type = CopyString(dataTypeString);
226 //if(!eClass_FindDataMember(regClass, declId.string))
228 char typeString[1024];
229 typeString[0] = '\0';
230 dataType = ProcessType(decl.specifiers, d);
231 PrintType(dataType, typeString, false, true);
234 dataMember = eMember_AddDataMember(member, declId.string,
235 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
237 dataMember = eClass_AddDataMember(regClass, declId.string,
238 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
240 dataMember.dataType = dataType;
242 dataMemberDefine.type = CopyString(typeString);
245 dataMemberDefine.memberAccess = def.memberAccess; //(!isMember && regClass.type == structClass) ? true : false;
249 else if(decl.specifiers)
252 // Unnamed struct/union
253 for(spec = decl.specifiers->first; spec; spec = spec.next)
255 if(spec.type == structSpecifier || spec.type == unionSpecifier)
257 if(spec.definitions && !spec.id)
259 DataMember dataMember = eMember_New((spec.type == unionSpecifier) ? unionMember : structMember, def.memberAccess);
261 dataMemberDefine = DataMemberDefine
263 isProperty = MemberType::dataMember;
264 memberType = (spec.type == SpecifierType::unionSpecifier) ? unionMember : structMember;
266 parentMemberDefine.dataMembers.Add(dataMemberDefine);
268 AddDefinitions(null, dataMemberDefine, null, dataMember, spec.definitions);
271 eMember_AddMember(member, dataMember);
273 eClass_AddMember(regClass, dataMember);
275 else if(spec.definitions && spec.id && spec.definitions->count)
277 //if(isMember || !eClass_FindDataMember(regClass, spec.id.string))
279 Identifier id = spec.id;
280 char typeString[1024];
281 typeString[0] = '\0';
284 decl.declarators = MkListOne(MkDeclaratorIdentifier(id));
286 dataType = ProcessType(decl.specifiers, null);
287 PrintType(dataType, typeString, false, true);
290 dataMember = eMember_AddDataMember(member, id.string,
291 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
293 dataMember = eClass_AddDataMember(regClass, id.string,
294 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
296 //delete dataTypeString;
298 dataMember.dataType = dataType;
305 else if(decl.type == instDeclaration)
307 Instantiation inst = decl.inst;
308 Expression exp = inst.exp;
311 // Add data member to the class
314 char * string = exp.identifier.string;
315 //if(!eClass_FindDataMember(regClass, string))
320 _class = inst._class.symbol; // FindClass(inst._class.name);
324 dataMember = eMember_AddDataMember(member, string, inst._class.name, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
326 dataMember = eClass_AddDataMember(regClass, string, inst._class.name, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
328 dataMember.dataType = dataType;
331 dataMemberDefine = DataMemberDefine
333 isProperty = MemberType::dataMember;
334 memberType = normalMember;
335 name = CopyString(string);
336 type = CopyString(inst._class.name);
338 parentMemberDefine.dataMembers.Add(dataMemberDefine);
343 else if(def.type == propertyClassDef && def.propertyDef)
345 PropertyDef propertyDef = def.propertyDef;
347 //if(propertyDef.id && (propertyDef.hasGet || propertyDef.hasSet))
350 PropertyDefine propDefine;
352 // Register the property in the list
354 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
355 prop = eClass_AddProperty(regClass, propertyDef.conversion ? null : propertyDef.id.string, dataTypeString, propertyDef.setStmt, propertyDef.getStmt, def.memberAccess);
358 prop.IsSet = (void *)propertyDef.issetStmt;
359 prop.compiled = false;
361 delete dataTypeString;
363 //prop.symbol = propertyDef.symbol;
365 //method.symbol = func.declarator.symbol;
371 string = CopyString(propertyDef.symbol.string);
372 type = propertyDef.symbol.type;
374 if(propertyDef.symbol.type)
375 propertyDef.symbol.type.refCount++;
377 //((Symbol)method.symbol).method = method;
380 propDefine = PropertyDefine
382 isProperty = propertyMember;
383 name = prop.conversion ? null : CopyString(prop.name);
384 type = CopyString(prop.dataTypeString);
385 isVirtual = false; // No virtual properties for now...
386 memberAccess = def.memberAccess;
387 hasSet = propertyDef.setStmt ? true : false;
388 hasGet = propertyDef.getStmt ? true : false;
389 isWatchable = propertyDef.isWatchable;
391 classDefine.propertiesAndMembers.Add(propDefine);
395 else if(def.type == classPropertyClassDef && def.propertyDef)
397 PropertyDef propertyDef = def.propertyDef;
399 //if(propertyDef.id && (propertyDef.hasGet || propertyDef.hasSet))
402 PropertyDefine propDefine;
403 // Register the property in the list
405 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
406 prop = eClass_AddClassProperty(regClass, propertyDef.id.string, dataTypeString, propertyDef.setStmt, propertyDef.getStmt);
407 delete dataTypeString;
411 propDefine = PropertyDefine
413 name = CopyString(prop.name);
414 type = CopyString(prop.dataTypeString);
415 hasSet = propertyDef.setStmt ? true : false;
416 hasGet = propertyDef.getStmt ? true : false;
418 classDefine.classProperties.Add(propDefine);
422 else if(def.type == classFixedClassDef)
425 classDefine.fixed = true;
427 else if(def.type == classNoExpansionClassDef)
430 classDefine.noExpansion = true;
432 else if(def.type == accessOverrideClassDef)
436 if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
438 PropertyDefine propDefine;
440 prop = eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
443 propDefine = PropertyDefine
445 isProperty = propertyMember;
446 name = CopyString(prop.name);
447 memberAccess = def.memberAccess;
449 classDefine.propertiesAndMembers.Add(propDefine);
452 else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
454 DataMemberDefine dataMemberDefine;
456 member = eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
458 dataMemberDefine = DataMemberDefine
460 isProperty = dataMember;
461 memberType = normalMember;
462 name = CopyString(def.id.string);
463 memberAccess = def.memberAccess;
465 parentMemberDefine.dataMembers.Add(dataMemberDefine);
472 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, bool isWatchable, AccessMode declMode)
476 ClassDefine classDefine;
478 bool unitType = false;
479 bool wouldBeEnum = false;
480 AccessMode inheritanceAccess = publicAccess;
483 if(baseSpecs != null)
485 Type baseType = ProcessType(baseSpecs, null);
486 PrintType(baseType, baseName, false, true);
487 if(baseType.kind == TypeKind::classType)
489 if(baseType._class.registered && classType == normalClass)
491 if(baseType._class.registered.type == unitClass)
492 classType = unitClass;
493 else if(baseType._class.registered.type == bitClass)
494 classType = bitClass;
495 else if(baseType._class.registered.type == noHeadClass)
496 classType = noHeadClass;
497 else if(baseType._class.registered.type == enumClass)
500 // classType = enumClass;
504 else if(baseType.kind == structType || baseType.kind == unionType)
506 classType = noHeadClass;
513 if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
514 inheritanceAccess = privateAccess;
517 // Eventually compute size with declarations for optional constant size offset...
519 // If there's any struct declaration in a unit data type, it means this is a bit class
520 if(classType == normalClass)
522 if(unitType) classType = unitClass;
523 if(definitions != null)
525 for(def = definitions.first; def; def = def.next)
527 if(def.type == declarationClassDef)
529 Declaration decl = def.decl;
530 if(decl.type == structDeclaration)
534 classType = bitClass;
541 for(d = decl.declarators->first; d; d = d.next)
545 classType = bitClass;
556 if(classType == normalClass && wouldBeEnum) classType = enumClass;
558 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType, symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, publicAccess, inheritanceAccess);
560 regClass.symbol = symbol;
562 classDefine = ClassDefine
564 type = classDefinition;
565 name = CopyString(symbol.string);
566 base = baseName[0] ? CopyString(baseName) : null;
567 isStatic = declMode == staticAccess;
568 isRemote = symbol.isRemote;
569 isWatchable = isWatchable;
571 precompDefines.Add(classDefine);
573 if(classType == unionClass)
575 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
576 DataMemberDefine unionDefine;
578 unionDefine = DataMemberDefine
580 isProperty = dataMember;
581 memberType = DataMemberType::unionMember;
583 classDefine.propertiesAndMembers.Add(unionDefine);
585 AddDefinitions(classDefine, unionDefine, regClass, unionMember, definitions);
586 eClass_AddMember(regClass, unionMember);
589 AddDefinitions(classDefine, (DataMemberDefine)classDefine, regClass, null, definitions);
592 if(definitions != null)
594 for(def = definitions.first; def; def = def.next)
596 if(def.type == functionClassDef)
598 ClassFunction func = def.function;
599 // Add ecereMethod_[class]_ to the declarator
600 if(!func.dontMangle && func.declarator)
602 Identifier id = GetDeclId(func.declarator);
604 MethodDefine methodDefine;
607 char * dataTypeString = StringFromSpecDecl(func.specifiers, func.declarator);
609 method = eClass_AddVirtualMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
611 method = eClass_AddMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
612 delete dataTypeString;
615 // Should we make a copy here? We make a copy in pass0.c ...
616 //method.symbol = func.declarator.symbol;
620 method.symbol = Symbol
622 string = CopyString(func.declarator.symbol.string);
623 type = func.declarator.symbol.type;
625 if(func.declarator.symbol.type)
626 func.declarator.symbol.type.refCount++;
628 ((Symbol)method.symbol).method = method;
631 func.declarator.symbol = null;
633 if(method.type != virtualMethod || method._class == regClass)
635 methodDefine = MethodDefine
637 name = CopyString(method.name);
638 type = CopyString(method.dataTypeString);
639 memberAccess = def.memberAccess;
640 isVirtual = method.type == virtualMethod;
642 classDefine.methods.Add(methodDefine);
647 else if(def.type == accessOverrideClassDef)
650 if((method = eClass_FindMethod(regClass, def.id.string, privateModule)))
652 MethodDefine methodDefine;
654 method = eClass_AddMethod(regClass, def.id.string, null, null, def.memberAccess);
656 methodDefine = MethodDefine
658 name = CopyString(method.name);
659 memberAccess = def.memberAccess;
661 classDefine.methods.Add(methodDefine);
666 if(regClass && symbol.templateParams)
668 TemplateParameter param;
669 // Add template parameters here
670 for(param = symbol.templateParams->first; param; param = param.next)
672 ClassTemplateArgument defaultArg { };
673 if(param.defaultArgument)
678 defaultArg.dataTypeString =
679 StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
683 char memberString[1024];
684 memberString[0] = '\0';
686 if(param.defaultArgument.identifier._class && param.defaultArgument.identifier._class.name)
688 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
689 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
691 strcpy(memberString, param.defaultArgument.identifier._class.name);
696 strcat(memberString, "::");
698 strcat(memberString, param.defaultArgument.identifier.string);
699 defaultArg.memberString = CopyString(memberString);
702 /* switch(param.memberType)
705 defaultArg.member = eClass_FindDataMember(regClass, param.defaultArgument.identifier.string, regClass.module, null, null);
708 defaultArg.method = eClass_FindMethod(regClass, param.defaultArgument.identifier.string, regClass.module);
711 defaultArg.prop = eClass_FindProperty(regClass, param.defaultArgument.identifier.string, regClass.module);
718 ProcessExpressionType(param.defaultArgument.expression);
719 ComputeExpression(param.defaultArgument.expression);
720 op = GetOperand(param.defaultArgument.expression);
721 defaultArg.expression.ui64 = op.ui64;
726 if(param.type == identifier)
728 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, (void *)(uintptr)param.memberType, defaultArg);
732 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
733 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
735 /*eClass_AddTemplateParameter(regClass, param.identifier.string, param.type,
736 (param.type == type) ? eSystem_FindClass(regClass.module, typeString) : CopyString(typeString), defaultArg);*/
737 // delete typeString;
744 static void ProcessClassEnumValues(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues)
746 Class regClass = symbol.registered;
747 if(regClass && enumValues)
750 for(e = enumValues.first; e; e = e.next)
759 e.exp.destType = destType;
761 // Set parsingType to avoid producing errors
762 SetParsingType(true);
763 ProcessExpressionType(e.exp);
764 SetParsingType(false);
768 destType.kind = TypeKind::classType;
769 destType._class = symbol;
770 ProcessExpressionType(e.exp);
774 if(e.exp.type == identifierExp && e.exp.expType && e.exp.identifier && e.exp.identifier.string && e.exp.expType.kind == enumType)
776 // Resolve enums here
778 char * string = e.exp.identifier.string;
779 for(l = e.exp.expType.members.first; l; l = l.next)
781 if(!strcmp(l.name, string))
785 FreeExpContents(e.exp);
786 e.exp.type = constantExp;
787 e.exp.constant = PrintInt64(l.data);
788 FreeType(e.exp.expType);
789 e.exp.expType = ProcessTypeString("int64", false);
796 ComputeExpression(e.exp);
798 if(e.exp.isConstant && e.exp.type == constantExp)
800 Operand op = GetOperand(e.exp);
802 //value = strtol(e.exp.string, null, 0);
806 value = op.type.isSigned ? (int64)op.c : (int64)op.uc;
809 value = op.type.isSigned ? (int64)op.s : (int64)op.us;
812 value = op.type.isSigned ? (int64)op.i64 : (int64)op.ui64;
816 value = op.type.isSigned ? (int64)op.i : (int)op.ui;
818 eEnum_AddFixedValue(regClass, e.id.string, value);
822 char expString[8192];
824 PrintExpression(e.exp, expString);
825 printf($"error: could not resolve value %s for enum %s in precompiler\n", expString, regClass.name);
826 ((PrecompApp)__thisModule).exitCode = 1;
827 eEnum_AddValue(regClass, e.id.string);
831 eEnum_AddValue(regClass, e.id.string);
836 void PreCompPreProcessClassDefinitions()
838 OldList * ast = GetAST();
839 External external, next;
840 for(external = ast->first; external; external = next)
842 next = external.next;
843 if(external.type == classExternal)
845 ClassDefinition _class = external._class;
846 if(_class.declMode == publicAccess || _class.declMode == privateAccess || _class.declMode == staticAccess)
848 if(_class.definitions)
850 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.deleteWatchable, _class.declMode);
854 else if(external.type == declarationExternal)
856 Declaration declaration = external.declaration;
858 if(declaration.type == initDeclaration)
860 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess || external.declaration.declMode == staticAccess)
862 if(declaration.specifiers)
865 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
867 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
868 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
870 Symbol symbol = FindClass(specifier.id.string);
875 if(specifier.type == enumSpecifier)
876 classType = enumClass;
877 else if(specifier.type == unionSpecifier)
878 classType = unionClass;
880 classType = structClass;
881 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, false, external.declaration.declMode);
886 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
888 if(declaration.declarators)
891 for(d = declaration.declarators->first; d; d = d.next)
895 Symbol symbol = d.declarator.symbol;
898 DataDefine dataDefine;
899 char typeString[1024];
900 typeString[0] = '\0';
901 PrintType(symbol.type, typeString, false, true);
902 dataDefine = DataDefine
904 type = dataDefinition;
905 name = CopyString(symbol.string);
906 dataType = CopyString(typeString);
908 precompDefines.Add(dataDefine);
916 else if(declaration.type == instDeclaration)
918 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
920 Symbol symbol = declaration.inst.symbol;
923 DataDefine dataDefine;
924 char typeString[1024];
925 typeString[0] = '\0';
926 PrintType(symbol.type, typeString, false, true);
927 dataDefine = DataDefine
929 type = dataDefinition;
930 name = CopyString(symbol.string);
931 dataType = CopyString(typeString);
933 precompDefines.Add(dataDefine);
936 globalInstance = true;
938 else if(declaration.type == defineDeclaration)
940 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
944 type = defineDefinition;
945 name = CopyString(declaration.id.string);
946 exp = declaration.exp;
948 precompDefines.Add(definition);
952 else if(external.type == functionExternal && (external.function.declMode == publicAccess || external.function.declMode == privateAccess))
954 FunctionDefinition function = external.function;
955 FunctionDefine functionDefine;
956 char typeString[1024];
957 typeString[0] = '\0';
958 PrintType(function.declarator.symbol.type, typeString, true, true);
959 functionDefine = FunctionDefine
961 type = functionDefinition;
962 name = CopyString(function.declarator.symbol.string);
963 dataType = CopyString(typeString);
965 precompDefines.Add(functionDefine);
967 else if(external.type == nameSpaceExternal)
969 SetCurrentNameSpace(external.id.string); //currentNameSpace = external.id.string;
970 //currentNameSpaceLen = currentNameSpace ? strlen(currentNameSpace) : 0;
974 ComputeModuleClasses(privateModule);
976 // Second pass for enumeration values
977 for(external = ast->first; external; external = next)
979 next = external.next;
980 if(external.type == declarationExternal && (external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess))
982 Declaration declaration = external.declaration;
984 if(declaration.type == initDeclaration)
986 if(declaration.specifiers)
989 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
991 if((specifier.type == enumSpecifier) && specifier.id && specifier.id.string &&
992 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
994 Symbol symbol = FindClass(specifier.id.string);
997 ProcessClassEnumValues(enumClass, specifier.definitions, symbol, specifier.baseSpecs, specifier.list);
1007 static void OutputDataMembers(ClassDefine classDefine, Class _class, File f)
1009 if(classDefine.propertiesAndMembers.first)
1011 DataMemberDefine member = classDefine.propertiesAndMembers.first;
1012 MemberType last = unresolvedMember;
1014 for(member = classDefine.propertiesAndMembers.first; member; member = member.next)
1016 if(member.isProperty == propertyMember)
1018 PropertyDefine prop = (PropertyDefine)member;
1019 if(last != propertyMember)
1023 f.Printf(" [Defined Properties]\n");
1027 f.Printf(" %s\n", prop.name);
1029 f.Printf(" [Conversion]\n");
1030 if(prop.memberAccess == publicAccess)
1031 f.Printf(" [Public]\n");
1033 f.Printf(" [Private]\n");
1035 f.Printf(" [Virtual]\n");
1037 f.Printf(" [Set]\n");
1039 f.Printf(" [Get]\n");
1040 if(prop.isWatchable)
1041 f.Printf(" [Watchable]\n");
1042 f.Printf(" [Type]\n");
1043 f.Printf(" %s\n", prop.type ? prop.type : "");
1047 if(last != dataMember)
1051 f.Printf(" [Defined Data Members]\n");
1053 if(member.memberType == normalMember)
1055 f.Printf(" %s\n", member.name);
1056 if(member.memberAccess == publicAccess)
1057 f.Printf(" [Public]\n");
1059 f.Printf(" [Private]\n");
1060 if(_class && _class.type == bitClass)
1064 f.Printf(" [Size]\n");
1065 f.Printf(" %d\n", member.size);
1067 if(member.bitPos != -1)
1069 f.Printf(" [Pos]\n");
1070 f.Printf(" %d\n", member.bitPos);
1073 f.Printf(" [Type]\n");
1074 f.Printf(" %s\n", member.type ? member.type : "");
1078 if(member.memberAccess == publicAccess)
1079 f.Printf(" [Public]\n");
1081 f.Printf(" [Private]\n");
1082 f.Printf((member.memberType == unionMember) ? " [Union]\n" : " [Struct]\n");
1083 OutputDataMembers((ClassDefine)member, null, f);
1086 last = member.isProperty;
1091 if(classDefine.classProperties.first)
1093 PropertyDefine prop = classDefine.propertiesAndMembers.first;
1094 f.Printf(" [Defined Class Properties]\n");
1095 for(prop = classDefine.classProperties.first; prop; prop = prop.next)
1098 f.Printf(" %s\n", prop.name);
1100 f.Printf(" [Set]\n");
1102 f.Printf(" [Get]\n");
1103 f.Printf(" [Type]\n");
1104 f.Printf(" %s\n", prop.type ? prop.type : "");
1110 static void OutputSymbols(const char * fileName)
1112 File f = FileOpen(fileName, write);
1115 DefinitionType lastType = (DefinitionType)-1;
1116 Definition definition;
1119 f.Printf("[Global Instance]\n");
1121 for(definition = precompDefines.first; definition; definition = definition.next)
1123 if(definition.type != lastType)
1125 if(lastType != (DefinitionType)-1)
1127 if(definition.type == moduleDefinition)
1128 f.Printf("[Imported Modules]\n");
1129 else if(definition.type == classDefinition)
1130 f.Printf("[Defined Classes]\n");
1131 else if(definition.type == defineDefinition)
1132 f.Printf("[Defined Expressions]\n");
1133 else if(definition.type == functionDefinition)
1134 f.Printf("[Defined Functions]\n");
1135 else if(definition.type == dataDefinition)
1136 f.Printf("[Defined Data]\n");
1137 lastType = definition.type;
1139 if(definition.type == moduleDefinition)
1141 ImportedModule module = (ImportedModule) definition;
1143 if(module.importType == staticImport)
1144 f.Printf(" [Static]\n");
1145 else if(module.importType == remoteImport)
1146 f.Printf(" [Remote]\n");
1147 if(module.importAccess == privateAccess)
1148 f.Printf(" [Private]\n");
1149 f.Printf(" %s\n", module.name);
1151 else if(definition.type == classDefinition)
1153 // Can we do this? Or should we fill up the definition?
1154 Class _class = eSystem_FindClass(privateModule, definition.name);
1155 ClassDefine classDefine = (ClassDefine) definition;
1157 f.Printf(" %s\n", definition.name);
1158 if(classDefine.isStatic)
1159 f.Printf(" [Static]\n");
1160 if(classDefine.fixed)
1161 f.Printf(" [Fixed]\n");
1162 if(classDefine.noExpansion)
1163 f.Printf(" [No Expansion]\n");
1164 if(classDefine.isRemote)
1165 f.Printf(" [Remote]\n");
1166 if(classDefine.isWatchable)
1167 f.Printf(" [Watchable]\n");
1168 if(_class.type == enumClass)
1169 f.Printf(" [Enum]\n");
1170 else if(_class.type == bitClass)
1171 f.Printf(" [Bit]\n");
1172 else if(_class.type == structClass)
1173 f.Printf(" [Struct]\n");
1174 else if(_class.type == unitClass)
1175 f.Printf(" [Unit]\n");
1176 else if(_class.type == noHeadClass)
1177 f.Printf(" [NoHead]\n");
1179 if(_class.inheritanceAccess == privateAccess)
1180 f.Printf(" [Private Base]\n");
1182 f.Printf(" [Base]\n");
1183 if(classDefine.base)
1184 f.Printf(" %s\n", classDefine.base);
1186 f.Printf(" [None]\n");
1188 if(_class.templateParams.count)
1190 ClassTemplateParameter param;
1191 TemplateParameter tp;
1193 f.Printf(" [Template Parameters]\n");
1195 for(tp = ((Symbol)_class.symbol).templateParams->first, param = _class.templateParams.first; param && tp; param = param.next, tp = tp.next)
1197 f.Printf(" %s\n", param.name);
1201 f.Printf(" [Type]\n");
1202 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1203 f.Printf(" %s\n", param.defaultArg.dataTypeString ? param.defaultArg.dataTypeString : "[None]");
1206 f.Printf(" [Expression]\n");
1207 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1208 if(tp.defaultArgument && tp.defaultArgument.expression)
1212 PrintExpression(tp.defaultArgument.expression, temp);
1213 ChangeCh(temp, '\n', ' ');
1219 f.Printf(" [None]\n");
1222 f.Printf(" [Identifier]\n");
1223 f.Printf(" %s\n", (param.memberType == dataMember) ? "[Data member]" : ((param.memberType == method) ? "[Method]" : "[Property]"));
1224 if(tp.defaultArgument && tp.defaultArgument.identifier)
1227 if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == nameSpecifier &&
1228 tp.defaultArgument.identifier._class.name)
1230 f.Printf("%s::", tp.defaultArgument.identifier._class.name);
1232 else if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == templateTypeSpecifier &&
1233 tp.defaultArgument.identifier._class.templateParameter.identifier)
1235 f.Printf("%s::", tp.defaultArgument.identifier._class.templateParameter.identifier.string);
1237 f.Printf("%s\n", tp.defaultArgument.identifier.string);
1241 f.Printf(" [None]\n");
1249 if(!classDefine.isStatic)
1251 if(classDefine.methods.first)
1253 MethodDefine method;
1255 f.Printf(" [Defined Methods]\n");
1256 for(method = classDefine.methods.first; method; method = method.next)
1258 f.Printf(" %s\n", method.name);
1259 if(method.memberAccess == publicAccess)
1260 f.Printf(" [Public]\n");
1262 f.Printf(" [Private]\n");
1263 if(method.isVirtual)
1264 f.Printf(" [Virtual]\n");
1265 f.Printf(" [Type]\n");
1266 f.Printf(" %s\n", method.type ? method.type : "");
1271 OutputDataMembers(classDefine, _class, f);
1273 if(_class.type == enumClass)
1276 Class enumClass = eSystem_FindClass(privateModule, "enum");
1277 EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
1279 f.Printf(" [Enum Values]\n");
1280 for(value = e.values.first; value; value = value.next)
1282 f.Printf(" %s = ", value.name);
1283 // We can have a null _class.dataTypeString here if the enum uses a base defined in another module yet to be precompiled
1284 if(_class.dataTypeString && !strcmp(_class.dataTypeString, "uint64") && *(uint64 *)&value.data > MAXINT64)
1285 f.Printf(FORMAT64HEX, *(uint64 *)&value.data);
1287 f.Printf(FORMAT64D, value.data);
1294 else if(definition.type == defineDefinition)
1296 Define defineDefine = (Define) definition;
1297 f.Printf(" %s\n", definition.name);
1298 f.Printf(" [Value]\n");
1300 OutputExpression(defineDefine.exp, f);
1303 else if(definition.type == functionDefinition)
1305 FunctionDefine functionDefine = (FunctionDefine) definition;
1306 f.Printf(" %s\n", functionDefine.name);
1307 f.Printf(" [Type]\n");
1308 f.Printf(" %s\n", functionDefine.dataType);
1310 else if(definition.type == dataDefinition)
1312 DataDefine dataDefine = (DataDefine) definition;
1313 f.Printf(" %s\n", dataDefine.name);
1314 f.Printf(" [Type]\n");
1315 f.Printf(" %s\n", dataDefine.dataType);
1323 class PrecompApp : Application
1329 char defaultSymFile[MAX_LOCATION];
1330 char * cppCommand = null;
1331 char * cppOptions = null;
1332 int cppOptionsLen = 0;
1333 /*char ** argv = null;
1336 Platform targetPlatform = __runtimePlatform;
1337 int targetBits = GetHostBits();
1339 for(c = 0; c<this.argc; c++)
1341 char * arg = this.argv[c];
1342 int argLen = strlen(arg);
1344 argv = renew argv char *[argc + 1];
1345 argv[argc] = new char[argLen+1];
1346 strcpy(argv[argc], arg);
1348 while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
1355 argv[argc] = renew argv[argc] char[argLen + len + 1];
1357 argv[argc][argLen-1] = ' ';
1358 strcpy(argv[argc] + argLen, arg);
1365 printf("\nArguments given:\n");
1366 for(c=1; c<argc; c++)
1367 printf(" %s", argv[c]);
1369 for(c=1; c<argc; c++)
1370 PrintLn("Arg", c, ": ", argv[c]);
1375 for(c = 1; c<argc; c++)
1377 const char * arg = argv[c];
1380 if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
1382 int newLen = cppOptionsLen + 1 + strlen(arg);
1383 cppOptions = renew cppOptions char[newLen + 1];
1384 cppOptions[cppOptionsLen] = ' ';
1385 strcpy(cppOptions + cppOptionsLen + 1, arg);
1386 cppOptionsLen = newLen;
1387 targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
1389 else if(!strcmp(arg + 1, "t32") || !strcmp(arg + 1, "t64"))
1391 targetBits = !strcmp(arg + 1, "t32") ? 32 : 64;
1393 else if(arg[1] == 'D' || arg[1] == 'I')
1396 int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1397 cppOptions = renew cppOptions char[size];
1398 buf = cppOptions + cppOptionsLen;
1401 cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1403 else if(!strcmp(arg+1, "t"))
1406 targetPlatform = argv[c];
1410 else if(!strcmp(arg+1, "cpp"))
1413 cppCommand = CopyString(argv[c]);
1417 else if(!strcmp(arg+1, "o"))
1419 if(!GetOutputFile() && c + 1 < argc)
1421 SetOutputFile(argv[c+1]);
1427 else if(!strcmp(arg+1, "c"))
1429 if(!GetSourceFile() && c + 1 < argc)
1431 SetSourceFile(argv[c+1]);
1437 else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot") || !strcmp(arg+1, "s"))
1442 const char * arg1 = argv[++c];
1443 int size = cppOptionsLen + 1 + strlen(arg) * 2 + strlen(arg1) * 2 + 1;
1444 cppOptions = renew cppOptions char[size];
1445 buf = cppOptions + cppOptionsLen;
1447 buf = PassArg(buf, arg);
1449 buf = PassArg(buf, arg1);
1450 cppOptionsLen = buf - cppOptions;
1455 else if(!strcmp(arg+1, "fno-diagnostics-show-caret"))
1458 int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1459 cppOptions = renew cppOptions char[size];
1460 buf = cppOptions + cppOptionsLen;
1463 cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1465 else if(!strcmp(arg+1, "symbols"))
1469 SetSymbolsDir(argv[c+1]);
1475 else if(!strcmp(arg+1, "defaultns"))
1479 SetDefaultNameSpace(argv[c+1]);
1480 //defaultNameSpaceLen = strlen(argv[c+1]);
1486 else if(!strcmp(arg+1, "strictns"))
1488 SetStrictNameSpaces(true);
1490 else if(!strcmp(arg+1, "module"))
1494 SetI18nModuleName(argv[c+1]);
1507 cppCommand = CopyString("gcc");
1508 if(!GetSourceFile())
1510 else if(!GetOutputFile())
1512 strcpy(defaultSymFile, GetSymbolsDir());
1513 PathCat(defaultSymFile, GetSourceFile());
1514 ChangeExtension(defaultSymFile, "sym", defaultSymFile);
1515 SetOutputFile(defaultSymFile);
1521 printf("%s", $"Syntax:\n ecp [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
1526 // TODO: Improve this
1527 char command[MAX_F_STRING*3];
1528 SetGlobalData(&globalData);
1529 SetExcludedSymbols(&_excludedSymbols);
1530 SetGlobalContext(globalContext);
1531 SetCurrentContext(globalContext);
1532 SetTopContext(globalContext);
1533 SetDefines(&::defines);
1534 SetImports(&imports);
1535 SetInPreCompiler(true);
1536 SetPrecompDefines(&precompDefines);
1537 SetTargetPlatform(targetPlatform);
1538 SetTargetBits(targetBits);
1541 privateModule = (Module)__ecere_COM_Initialize((bool)(true | (targetBits == sizeof(uintptr)*8 ? 0 : targetBits == 64 ? 2 : targetBits==32 ? 4 : 0) | 8), 1, null);
1542 SetPrivateModule(privateModule);
1544 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
1545 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
1546 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
1547 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
1548 globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
1549 globalContext.types.Add((BTNode)Symbol { string = CopyString("intptr_t"), type = ProcessTypeString("intptr", false) });
1550 globalContext.types.Add((BTNode)Symbol { string = CopyString("uintptr_t"), type = ProcessTypeString("uintptr", false) });
1551 globalContext.types.Add((BTNode)Symbol { string = CopyString("ssize_t"), type = ProcessTypeString("intsize", false) });
1552 globalContext.types.Add((BTNode)Symbol { string = CopyString("size_t"), type = ProcessTypeString("uintsize", false) });
1555 const char * outputFilePath = GetOutputFile();
1556 if(FileExists(outputFilePath))
1557 DeleteFile(outputFilePath);
1560 snprintf(command, sizeof(command), "%s%s -x c -E \"%s\"", cppCommand, cppOptions ? cppOptions : "", GetSourceFile());
1561 command[sizeof(command)-1] = 0;
1563 PrintLn("ECP Executing:");
1566 if((cppOutput = DualPipeOpen({ output = true }, command)))
1570 TempFile fileInput { };
1571 ModuleImport mainModule { };
1572 //fileInput = TempFile { };
1573 SetFileInput(fileInput);
1575 SetMainModule(mainModule);
1576 imports.Add(/*(*/mainModule/* = ModuleImport { })*/);
1580 for(;!cppOutput.Eof();)
1583 int count = cppOutput.Read(junk, 1, 4096);
1584 fileInput.Write(junk, 1, count);
1586 exitCode = cppOutput.GetExitCode();
1589 fileInput.Seek(0, start);
1592 // SetYydebug(true);
1595 SetCurrentNameSpace(null);
1605 ProcessDBTableDefinitions();
1606 PreCompPreProcessClassDefinitions();
1609 OutputSymbols(GetOutputFile());
1612 this.exitCode = exitCode;
1620 FreeContext(globalContext);
1621 FreeExcludedSymbols(_excludedSymbols);
1623 ::defines.Free(FreeModuleDefine);
1624 imports.Free(FreeModuleImport);
1626 precompDefines.Free(FreeDefinition);
1628 FreeTypeData(privateModule);
1630 FreeGlobalData(globalData);
1632 delete privateModule;
1639 for(c = 0; c<argc; c++)
1643 SetSymbolsDir(null); // Free symbols dir
1645 #if 0 //defined(_DEBUG) && defined(__WIN32__)