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);
209 member.size = bitSize;
211 dataMember = (DataMember)member;
214 dataMember.dataType = dataType;
216 dataMemberDefine.size = bitSize;
217 dataMemberDefine.bitPos = bitPos;
219 dataMemberDefine.type = CopyString(dataTypeString);
223 //if(!eClass_FindDataMember(regClass, declId.string))
225 char typeString[1024];
226 typeString[0] = '\0';
227 dataType = ProcessType(decl.specifiers, d);
228 PrintType(dataType, typeString, false, true);
231 dataMember = eMember_AddDataMember(member, declId.string,
232 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
234 dataMember = eClass_AddDataMember(regClass, declId.string,
235 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
237 dataMember.dataType = dataType;
239 dataMemberDefine.type = CopyString(typeString);
242 dataMemberDefine.memberAccess = def.memberAccess; //(!isMember && regClass.type == structClass) ? true : false;
246 else if(decl.specifiers)
249 // Unnamed struct/union
250 for(spec = decl.specifiers->first; spec; spec = spec.next)
252 if(spec.type == structSpecifier || spec.type == unionSpecifier)
254 if(spec.definitions && !spec.id)
256 DataMember dataMember = eMember_New((spec.type == unionSpecifier) ? unionMember : structMember, def.memberAccess);
258 dataMemberDefine = DataMemberDefine
260 isProperty = MemberType::dataMember;
261 memberType = (spec.type == SpecifierType::unionSpecifier) ? unionMember : structMember;
263 parentMemberDefine.dataMembers.Add(dataMemberDefine);
265 AddDefinitions(null, dataMemberDefine, null, dataMember, spec.definitions);
268 eMember_AddMember(member, dataMember);
270 eClass_AddMember(regClass, dataMember);
272 else if(spec.definitions && spec.id && spec.definitions->count)
274 //if(isMember || !eClass_FindDataMember(regClass, spec.id.string))
276 Identifier id = spec.id;
277 char typeString[1024];
278 typeString[0] = '\0';
281 decl.declarators = MkListOne(MkDeclaratorIdentifier(id));
283 dataType = ProcessType(decl.specifiers, null);
284 PrintType(dataType, typeString, false, true);
287 dataMember = eMember_AddDataMember(member, id.string,
288 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
290 dataMember = eClass_AddDataMember(regClass, id.string,
291 typeString, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
293 //delete dataTypeString;
295 dataMember.dataType = dataType;
302 else if(decl.type == instDeclaration)
304 Instantiation inst = decl.inst;
305 Expression exp = inst.exp;
308 // Add data member to the class
311 char * string = exp.identifier.string;
312 //if(!eClass_FindDataMember(regClass, string))
317 _class = inst._class.symbol; // FindClass(inst._class.name);
321 dataMember = eMember_AddDataMember(member, string, inst._class.name, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
323 dataMember = eClass_AddDataMember(regClass, string, inst._class.name, /*ComputeTypeSize(dataType)*/ 0, 0, def.memberAccess);
325 dataMember.dataType = dataType;
328 dataMemberDefine = DataMemberDefine
330 isProperty = MemberType::dataMember;
331 memberType = normalMember;
332 name = CopyString(string);
333 type = CopyString(inst._class.name);
335 parentMemberDefine.dataMembers.Add(dataMemberDefine);
340 else if(def.type == propertyClassDef && def.propertyDef)
342 PropertyDef propertyDef = def.propertyDef;
344 //if(propertyDef.id && (propertyDef.hasGet || propertyDef.hasSet))
347 PropertyDefine propDefine;
349 // Register the property in the list
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);
355 prop.IsSet = (void *)propertyDef.issetStmt;
356 prop.compiled = false;
358 delete dataTypeString;
360 //prop.symbol = propertyDef.symbol;
362 //method.symbol = func.declarator.symbol;
368 string = CopyString(propertyDef.symbol.string);
369 id = propertyDef.symbol.id;
370 type = propertyDef.symbol.type;
372 if(propertyDef.symbol.type)
373 propertyDef.symbol.type.refCount++;
375 //((Symbol)method.symbol).method = method;
378 propDefine = PropertyDefine
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;
389 classDefine.propertiesAndMembers.Add(propDefine);
393 else if(def.type == classPropertyClassDef && def.propertyDef)
395 PropertyDef propertyDef = def.propertyDef;
397 //if(propertyDef.id && (propertyDef.hasGet || propertyDef.hasSet))
400 PropertyDefine propDefine;
401 // Register the property in the list
403 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
404 prop = eClass_AddClassProperty(regClass, propertyDef.id.string, dataTypeString, propertyDef.setStmt, propertyDef.getStmt);
405 delete dataTypeString;
409 propDefine = PropertyDefine
411 name = CopyString(prop.name);
412 type = CopyString(prop.dataTypeString);
413 hasSet = propertyDef.setStmt ? true : false;
414 hasGet = propertyDef.getStmt ? true : false;
416 classDefine.classProperties.Add(propDefine);
420 else if(def.type == classFixedClassDef)
423 classDefine.fixed = true;
425 else if(def.type == classNoExpansionClassDef)
428 classDefine.noExpansion = true;
430 else if(def.type == accessOverrideClassDef)
434 if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
436 PropertyDefine propDefine;
438 prop = eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
441 propDefine = PropertyDefine
443 isProperty = propertyMember;
444 name = CopyString(prop.name);
445 memberAccess = def.memberAccess;
447 classDefine.propertiesAndMembers.Add(propDefine);
450 else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
452 DataMemberDefine dataMemberDefine;
454 member = eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
456 dataMemberDefine = DataMemberDefine
458 isProperty = dataMember;
459 memberType = normalMember;
460 name = CopyString(def.id.string);
461 memberAccess = def.memberAccess;
463 parentMemberDefine.dataMembers.Add(dataMemberDefine);
470 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, bool isWatchable, AccessMode declMode)
474 ClassDefine classDefine;
476 bool unitType = false;
477 bool wouldBeEnum = false;
478 AccessMode inheritanceAccess = publicAccess;
481 if(baseSpecs != null)
483 Type baseType = ProcessType(baseSpecs, null);
484 PrintType(baseType, baseName, false, true);
485 if(baseType.kind == TypeKind::classType)
487 if(baseType._class.registered && classType == normalClass)
489 if(baseType._class.registered.type == unitClass)
490 classType = unitClass;
491 else if(baseType._class.registered.type == bitClass)
492 classType = bitClass;
493 else if(baseType._class.registered.type == noHeadClass)
494 classType = noHeadClass;
495 else if(baseType._class.registered.type == enumClass)
498 // classType = enumClass;
502 else if(baseType.kind == structType || baseType.kind == unionType)
504 classType = noHeadClass;
511 if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
512 inheritanceAccess = privateAccess;
515 // Eventually compute size with declarations for optional constant size offset...
517 // If there's any struct declaration in a unit data type, it means this is a bit class
518 if(classType == normalClass)
520 if(unitType) classType = unitClass;
521 if(definitions != null)
523 for(def = definitions.first; def; def = def.next)
525 if(def.type == declarationClassDef)
527 Declaration decl = def.decl;
528 if(decl.type == structDeclaration)
532 classType = bitClass;
539 for(d = decl.declarators->first; d; d = d.next)
543 classType = bitClass;
554 if(classType == normalClass && wouldBeEnum) classType = enumClass;
556 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType, symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, publicAccess, inheritanceAccess);
558 regClass.symbol = symbol;
560 classDefine = ClassDefine
562 type = classDefinition;
563 name = CopyString(symbol.string);
564 base = baseName[0] ? CopyString(baseName) : null;
565 isStatic = declMode == staticAccess;
566 isRemote = symbol.isRemote;
567 isWatchable = isWatchable;
569 precompDefines.Add(classDefine);
571 if(classType == unionClass)
573 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
574 DataMemberDefine unionDefine;
576 unionDefine = DataMemberDefine
578 isProperty = dataMember;
579 memberType = DataMemberType::unionMember;
581 classDefine.propertiesAndMembers.Add(unionDefine);
583 AddDefinitions(classDefine, unionDefine, regClass, unionMember, definitions);
584 eClass_AddMember(regClass, unionMember);
587 AddDefinitions(classDefine, (DataMemberDefine)classDefine, regClass, null, definitions);
590 if(definitions != null)
592 for(def = definitions.first; def; def = def.next)
594 if(def.type == functionClassDef)
596 ClassFunction func = def.function;
597 // Add ecereMethod_[class]_ to the declarator
598 if(!func.dontMangle && func.declarator)
600 Identifier id = GetDeclId(func.declarator);
602 MethodDefine methodDefine;
605 char * dataTypeString = StringFromSpecDecl(func.specifiers, func.declarator);
607 method = eClass_AddVirtualMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
609 method = eClass_AddMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
610 delete dataTypeString;
613 // Should we make a copy here? We make a copy in pass0.c ...
614 //method.symbol = func.declarator.symbol;
618 method.symbol = Symbol
620 string = CopyString(func.declarator.symbol.string);
621 id = func.declarator.symbol.id;
622 type = func.declarator.symbol.type;
624 if(func.declarator.symbol.type)
625 func.declarator.symbol.type.refCount++;
627 ((Symbol)method.symbol).method = method;
630 func.declarator.symbol = null;
632 if(method.type != virtualMethod || method._class == regClass)
634 methodDefine = MethodDefine
636 name = CopyString(method.name);
637 type = CopyString(method.dataTypeString);
638 memberAccess = def.memberAccess;
639 isVirtual = method.type == virtualMethod;
641 classDefine.methods.Add(methodDefine);
646 else if(def.type == accessOverrideClassDef)
649 if((method = eClass_FindMethod(regClass, def.id.string, privateModule)))
651 MethodDefine methodDefine;
653 method = eClass_AddMethod(regClass, def.id.string, null, null, def.memberAccess);
655 methodDefine = MethodDefine
657 name = CopyString(method.name);
658 memberAccess = def.memberAccess;
660 classDefine.methods.Add(methodDefine);
665 if(regClass && symbol.templateParams)
667 TemplateParameter param;
668 // Add template parameters here
669 for(param = symbol.templateParams->first; param; param = param.next)
671 ClassTemplateArgument defaultArg { };
672 if(param.defaultArgument)
677 defaultArg.dataTypeString =
678 StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
682 char memberString[1024];
683 memberString[0] = '\0';
685 if(param.defaultArgument.identifier._class && param.defaultArgument.identifier._class.name)
687 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
688 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
690 strcpy(memberString, param.defaultArgument.identifier._class.name);
695 strcat(memberString, "::");
697 strcat(memberString, param.defaultArgument.identifier.string);
698 defaultArg.memberString = CopyString(memberString);
701 /* switch(param.memberType)
704 defaultArg.member = eClass_FindDataMember(regClass, param.defaultArgument.identifier.string, regClass.module, null, null);
707 defaultArg.method = eClass_FindMethod(regClass, param.defaultArgument.identifier.string, regClass.module);
710 defaultArg.prop = eClass_FindProperty(regClass, param.defaultArgument.identifier.string, regClass.module);
717 ProcessExpressionType(param.defaultArgument.expression);
718 ComputeExpression(param.defaultArgument.expression);
719 op = GetOperand(param.defaultArgument.expression);
720 defaultArg.expression.ui64 = op.ui64;
725 if(param.type == identifier)
727 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, (void *)(uintptr)param.memberType, defaultArg);
731 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
732 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
734 /*eClass_AddTemplateParameter(regClass, param.identifier.string, param.type,
735 (param.type == type) ? eSystem_FindClass(regClass.module, typeString) : CopyString(typeString), defaultArg);*/
736 // delete typeString;
743 static void ProcessClassEnumValues(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues)
745 Class regClass = symbol.registered;
746 if(regClass && enumValues)
749 for(e = enumValues.first; e; e = e.next)
758 e.exp.destType = destType;
760 // Set parsingType to avoid producing errors
761 SetParsingType(true);
762 ProcessExpressionType(e.exp);
763 SetParsingType(false);
767 destType.kind = TypeKind::classType;
768 destType._class = symbol;
769 ProcessExpressionType(e.exp);
773 if(e.exp.type == identifierExp && e.exp.expType && e.exp.identifier && e.exp.identifier.string && e.exp.expType.kind == enumType)
775 // Resolve enums here
777 char * string = e.exp.identifier.string;
778 for(l = e.exp.expType.members.first; l; l = l.next)
780 if(!strcmp(l.name, string))
784 FreeExpContents(e.exp);
785 e.exp.type = constantExp;
786 e.exp.constant = PrintInt64(l.data);
787 FreeType(e.exp.expType);
788 e.exp.expType = ProcessTypeString("int64", false);
795 ComputeExpression(e.exp);
797 if(e.exp.isConstant && e.exp.type == constantExp)
799 Operand op = GetOperand(e.exp);
801 //value = strtol(e.exp.string, null, 0);
805 value = op.type.isSigned ? (int64)op.c : (int64)op.uc;
808 value = op.type.isSigned ? (int64)op.s : (int64)op.us;
811 value = op.type.isSigned ? (int64)op.i64 : (int64)op.ui64;
815 value = op.type.isSigned ? (int64)op.i : (int)op.ui;
817 eEnum_AddFixedValue(regClass, e.id.string, value);
821 char expString[8192];
823 PrintExpression(e.exp, expString);
824 printf($"error: could not resolve value %s for enum %s in precompiler\n", expString, regClass.name);
825 ((PrecompApp)__thisModule).exitCode = 1;
826 eEnum_AddValue(regClass, e.id.string);
830 eEnum_AddValue(regClass, e.id.string);
835 void PreCompPreProcessClassDefinitions()
837 OldList * ast = GetAST();
838 External external, next;
839 for(external = ast->first; external; external = next)
841 next = external.next;
842 if(external.type == classExternal)
844 ClassDefinition _class = external._class;
845 if(_class.declMode == publicAccess || _class.declMode == privateAccess || _class.declMode == staticAccess)
847 if(_class.definitions)
849 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.deleteWatchable, _class.declMode);
853 else if(external.type == declarationExternal)
855 Declaration declaration = external.declaration;
857 if(declaration.type == initDeclaration)
859 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess || external.declaration.declMode == staticAccess)
861 if(declaration.specifiers)
864 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
866 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
867 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
869 Symbol symbol = FindClass(specifier.id.string);
874 if(specifier.type == enumSpecifier)
875 classType = enumClass;
876 else if(specifier.type == unionSpecifier)
877 classType = unionClass;
879 classType = structClass;
880 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, false, external.declaration.declMode);
885 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
887 if(declaration.declarators)
890 for(d = declaration.declarators->first; d; d = d.next)
894 Symbol symbol = d.declarator.symbol;
897 DataDefine dataDefine;
898 char typeString[1024];
899 typeString[0] = '\0';
900 PrintType(symbol.type, typeString, false, true);
901 dataDefine = DataDefine
903 type = dataDefinition;
904 name = CopyString(symbol.string);
905 dataType = CopyString(typeString);
907 precompDefines.Add(dataDefine);
915 else if(declaration.type == instDeclaration)
917 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
919 Symbol symbol = declaration.inst.symbol;
922 DataDefine dataDefine;
923 char typeString[1024];
924 typeString[0] = '\0';
925 PrintType(symbol.type, typeString, false, true);
926 dataDefine = DataDefine
928 type = dataDefinition;
929 name = CopyString(symbol.string);
930 dataType = CopyString(typeString);
932 precompDefines.Add(dataDefine);
935 globalInstance = true;
937 else if(declaration.type == defineDeclaration)
939 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
943 type = defineDefinition;
944 name = CopyString(declaration.id.string);
945 exp = declaration.exp;
947 precompDefines.Add(definition);
951 else if(external.type == functionExternal && (external.function.declMode == publicAccess || external.function.declMode == privateAccess))
953 FunctionDefinition function = external.function;
954 FunctionDefine functionDefine;
955 char typeString[1024];
956 typeString[0] = '\0';
957 PrintType(function.declarator.symbol.type, typeString, true, true);
958 functionDefine = FunctionDefine
960 type = functionDefinition;
961 name = CopyString(function.declarator.symbol.string);
962 dataType = CopyString(typeString);
964 precompDefines.Add(functionDefine);
966 else if(external.type == nameSpaceExternal)
968 SetCurrentNameSpace(external.id.string); //currentNameSpace = external.id.string;
969 //currentNameSpaceLen = currentNameSpace ? strlen(currentNameSpace) : 0;
973 ComputeModuleClasses(privateModule);
975 // Second pass for enumeration values
976 for(external = ast->first; external; external = next)
978 next = external.next;
979 if(external.type == declarationExternal && (external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess))
981 Declaration declaration = external.declaration;
983 if(declaration.type == initDeclaration)
985 if(declaration.specifiers)
988 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
990 if((specifier.type == enumSpecifier) && specifier.id && specifier.id.string &&
991 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
993 Symbol symbol = FindClass(specifier.id.string);
996 ProcessClassEnumValues(enumClass, specifier.definitions, symbol, specifier.baseSpecs, specifier.list);
1006 static void OutputDataMembers(ClassDefine classDefine, Class _class, File f)
1008 if(classDefine.propertiesAndMembers.first)
1010 DataMemberDefine member = classDefine.propertiesAndMembers.first;
1011 MemberType last = unresolvedMember;
1013 for(member = classDefine.propertiesAndMembers.first; member; member = member.next)
1015 if(member.isProperty == propertyMember)
1017 PropertyDefine prop = (PropertyDefine)member;
1018 if(last != propertyMember)
1022 f.Printf(" [Defined Properties]\n");
1026 f.Printf(" %s\n", prop.name);
1028 f.Printf(" [Conversion]\n");
1029 if(prop.memberAccess == publicAccess)
1030 f.Printf(" [Public]\n");
1032 f.Printf(" [Private]\n");
1034 f.Printf(" [Virtual]\n");
1036 f.Printf(" [Set]\n");
1038 f.Printf(" [Get]\n");
1039 if(prop.isWatchable)
1040 f.Printf(" [Watchable]\n");
1041 f.Printf(" [Type]\n");
1042 f.Printf(" %s\n", prop.type ? prop.type : "");
1046 if(last != dataMember)
1050 f.Printf(" [Defined Data Members]\n");
1052 if(member.memberType == normalMember)
1054 f.Printf(" %s\n", member.name);
1055 if(member.memberAccess == publicAccess)
1056 f.Printf(" [Public]\n");
1058 f.Printf(" [Private]\n");
1059 if(_class && _class.type == bitClass)
1063 f.Printf(" [Size]\n");
1064 f.Printf(" %d\n", member.size);
1066 if(member.bitPos != -1)
1068 f.Printf(" [Pos]\n");
1069 f.Printf(" %d\n", member.bitPos);
1072 f.Printf(" [Type]\n");
1073 f.Printf(" %s\n", member.type ? member.type : "");
1077 if(member.memberAccess == publicAccess)
1078 f.Printf(" [Public]\n");
1080 f.Printf(" [Private]\n");
1081 f.Printf((member.memberType == unionMember) ? " [Union]\n" : " [Struct]\n");
1082 OutputDataMembers((ClassDefine)member, null, f);
1085 last = member.isProperty;
1090 if(classDefine.classProperties.first)
1092 PropertyDefine prop = classDefine.propertiesAndMembers.first;
1093 f.Printf(" [Defined Class Properties]\n");
1094 for(prop = classDefine.classProperties.first; prop; prop = prop.next)
1097 f.Printf(" %s\n", prop.name);
1099 f.Printf(" [Set]\n");
1101 f.Printf(" [Get]\n");
1102 f.Printf(" [Type]\n");
1103 f.Printf(" %s\n", prop.type ? prop.type : "");
1109 static void OutputSymbols(const char * fileName)
1111 File f = FileOpen(fileName, write);
1114 DefinitionType lastType = (DefinitionType)-1;
1115 Definition definition;
1118 f.Printf("[Global Instance]\n");
1120 for(definition = precompDefines.first; definition; definition = definition.next)
1122 if(definition.type != lastType)
1124 if(lastType != (DefinitionType)-1)
1126 if(definition.type == moduleDefinition)
1127 f.Printf("[Imported Modules]\n");
1128 else if(definition.type == classDefinition)
1129 f.Printf("[Defined Classes]\n");
1130 else if(definition.type == defineDefinition)
1131 f.Printf("[Defined Expressions]\n");
1132 else if(definition.type == functionDefinition)
1133 f.Printf("[Defined Functions]\n");
1134 else if(definition.type == dataDefinition)
1135 f.Printf("[Defined Data]\n");
1136 lastType = definition.type;
1138 if(definition.type == moduleDefinition)
1140 ImportedModule module = (ImportedModule) definition;
1142 if(module.importType == staticImport)
1143 f.Printf(" [Static]\n");
1144 else if(module.importType == remoteImport)
1145 f.Printf(" [Remote]\n");
1146 if(module.importAccess == privateAccess)
1147 f.Printf(" [Private]\n");
1148 f.Printf(" %s\n", module.name);
1150 else if(definition.type == classDefinition)
1152 // Can we do this? Or should we fill up the definition?
1153 Class _class = eSystem_FindClass(privateModule, definition.name);
1154 ClassDefine classDefine = (ClassDefine) definition;
1156 f.Printf(" %s\n", definition.name);
1157 if(classDefine.isStatic)
1158 f.Printf(" [Static]\n");
1159 if(classDefine.fixed)
1160 f.Printf(" [Fixed]\n");
1161 if(classDefine.noExpansion)
1162 f.Printf(" [No Expansion]\n");
1163 if(classDefine.isRemote)
1164 f.Printf(" [Remote]\n");
1165 if(classDefine.isWatchable)
1166 f.Printf(" [Watchable]\n");
1167 if(_class.type == enumClass)
1168 f.Printf(" [Enum]\n");
1169 else if(_class.type == bitClass)
1170 f.Printf(" [Bit]\n");
1171 else if(_class.type == structClass)
1172 f.Printf(" [Struct]\n");
1173 else if(_class.type == unitClass)
1174 f.Printf(" [Unit]\n");
1175 else if(_class.type == noHeadClass)
1176 f.Printf(" [NoHead]\n");
1178 if(_class.inheritanceAccess == privateAccess)
1179 f.Printf(" [Private Base]\n");
1181 f.Printf(" [Base]\n");
1182 if(classDefine.base)
1183 f.Printf(" %s\n", classDefine.base);
1185 f.Printf(" [None]\n");
1187 if(_class.templateParams.count)
1189 ClassTemplateParameter param;
1190 TemplateParameter tp;
1192 f.Printf(" [Template Parameters]\n");
1194 for(tp = ((Symbol)_class.symbol).templateParams->first, param = _class.templateParams.first; param && tp; param = param.next, tp = tp.next)
1196 f.Printf(" %s\n", param.name);
1200 f.Printf(" [Type]\n");
1201 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1202 f.Printf(" %s\n", param.defaultArg.dataTypeString ? param.defaultArg.dataTypeString : "[None]");
1205 f.Printf(" [Expression]\n");
1206 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1207 if(tp.defaultArgument && tp.defaultArgument.expression)
1211 PrintExpression(tp.defaultArgument.expression, temp);
1212 ChangeCh(temp, '\n', ' ');
1218 f.Printf(" [None]\n");
1221 f.Printf(" [Identifier]\n");
1222 f.Printf(" %s\n", (param.memberType == dataMember) ? "[Data member]" : ((param.memberType == method) ? "[Method]" : "[Property]"));
1223 if(tp.defaultArgument && tp.defaultArgument.identifier)
1226 if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == nameSpecifier &&
1227 tp.defaultArgument.identifier._class.name)
1229 f.Printf("%s::", tp.defaultArgument.identifier._class.name);
1231 else if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == templateTypeSpecifier &&
1232 tp.defaultArgument.identifier._class.templateParameter.identifier)
1234 f.Printf("%s::", tp.defaultArgument.identifier._class.templateParameter.identifier.string);
1236 f.Printf("%s\n", tp.defaultArgument.identifier.string);
1240 f.Printf(" [None]\n");
1248 if(!classDefine.isStatic)
1250 if(classDefine.methods.first)
1252 MethodDefine method;
1254 f.Printf(" [Defined Methods]\n");
1255 for(method = classDefine.methods.first; method; method = method.next)
1257 f.Printf(" %s\n", method.name);
1258 if(method.memberAccess == publicAccess)
1259 f.Printf(" [Public]\n");
1261 f.Printf(" [Private]\n");
1262 if(method.isVirtual)
1263 f.Printf(" [Virtual]\n");
1264 f.Printf(" [Type]\n");
1265 f.Printf(" %s\n", method.type ? method.type : "");
1270 OutputDataMembers(classDefine, _class, f);
1272 if(_class.type == enumClass)
1275 Class enumClass = eSystem_FindClass(privateModule, "enum");
1276 EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
1278 f.Printf(" [Enum Values]\n");
1279 for(value = e.values.first; value; value = value.next)
1281 f.Printf(" %s = ", value.name);
1282 if(!strcmp(_class.dataTypeString, "uint64") && *(uint64 *)&value.data > MAXINT64)
1283 f.Printf(FORMAT64HEX, *(uint64 *)&value.data);
1285 f.Printf(FORMAT64D, value.data);
1292 else if(definition.type == defineDefinition)
1294 Define defineDefine = (Define) definition;
1295 f.Printf(" %s\n", definition.name);
1296 f.Printf(" [Value]\n");
1298 OutputExpression(defineDefine.exp, f);
1301 else if(definition.type == functionDefinition)
1303 FunctionDefine functionDefine = (FunctionDefine) definition;
1304 f.Printf(" %s\n", functionDefine.name);
1305 f.Printf(" [Type]\n");
1306 f.Printf(" %s\n", functionDefine.dataType);
1308 else if(definition.type == dataDefinition)
1310 DataDefine dataDefine = (DataDefine) definition;
1311 f.Printf(" %s\n", dataDefine.name);
1312 f.Printf(" [Type]\n");
1313 f.Printf(" %s\n", dataDefine.dataType);
1321 class PrecompApp : Application
1327 char defaultSymFile[MAX_LOCATION];
1328 char * cppCommand = null;
1329 char * cppOptions = null;
1330 int cppOptionsLen = 0;
1331 /*char ** argv = null;
1334 Platform targetPlatform = GetRuntimePlatform();
1335 int targetBits = GetHostBits();
1337 for(c = 0; c<this.argc; c++)
1339 char * arg = this.argv[c];
1340 int argLen = strlen(arg);
1342 argv = renew argv char *[argc + 1];
1343 argv[argc] = new char[argLen+1];
1344 strcpy(argv[argc], arg);
1346 while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
1353 argv[argc] = renew argv[argc] char[argLen + len + 1];
1355 argv[argc][argLen-1] = ' ';
1356 strcpy(argv[argc] + argLen, arg);
1363 printf("\nArguments given:\n");
1364 for(c=1; c<argc; c++)
1365 printf(" %s", argv[c]);
1367 for(c=1; c<argc; c++)
1368 PrintLn("Arg", c, ": ", argv[c]);
1373 for(c = 1; c<argc; c++)
1375 const char * arg = argv[c];
1378 if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
1380 int newLen = cppOptionsLen + 1 + strlen(arg);
1381 cppOptions = renew cppOptions char[newLen + 1];
1382 cppOptions[cppOptionsLen] = ' ';
1383 strcpy(cppOptions + cppOptionsLen + 1, arg);
1384 cppOptionsLen = newLen;
1385 targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
1387 else if(!strcmp(arg + 1, "t32") || !strcmp(arg + 1, "t64"))
1389 targetBits = !strcmp(arg + 1, "t32") ? 32 : 64;
1391 else if(arg[1] == 'D' || arg[1] == 'I')
1394 int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1395 cppOptions = renew cppOptions char[size];
1396 buf = cppOptions + cppOptionsLen;
1399 cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1401 else if(!strcmp(arg+1, "t"))
1404 targetPlatform = argv[c];
1408 else if(!strcmp(arg+1, "cpp"))
1411 cppCommand = CopyString(argv[c]);
1415 else if(!strcmp(arg+1, "o"))
1417 if(!GetOutputFile() && c + 1 < argc)
1419 SetOutputFile(argv[c+1]);
1425 else if(!strcmp(arg+1, "c"))
1427 if(!GetSourceFile() && c + 1 < argc)
1429 SetSourceFile(argv[c+1]);
1435 else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot"))
1440 const char * arg1 = argv[++c];
1441 int size = cppOptionsLen + 1 + strlen(arg) * 2 + strlen(arg1) * 2 + 1;
1442 cppOptions = renew cppOptions char[size];
1443 buf = cppOptions + cppOptionsLen;
1445 buf = PassArg(buf, arg);
1447 buf = PassArg(buf, arg1);
1448 cppOptionsLen = buf - cppOptions;
1453 else if(!strcmp(arg+1, "fno-diagnostics-show-caret"))
1456 int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1457 cppOptions = renew cppOptions char[size];
1458 buf = cppOptions + cppOptionsLen;
1461 cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1463 else if(!strcmp(arg+1, "symbols"))
1467 SetSymbolsDir(argv[c+1]);
1473 else if(!strcmp(arg+1, "defaultns"))
1477 SetDefaultNameSpace(argv[c+1]);
1478 //defaultNameSpaceLen = strlen(argv[c+1]);
1484 else if(!strcmp(arg+1, "strictns"))
1486 SetStrictNameSpaces(true);
1488 else if(!strcmp(arg+1, "module"))
1492 SetI18nModuleName(argv[c+1]);
1505 cppCommand = CopyString("gcc");
1506 if(!GetSourceFile())
1508 else if(!GetOutputFile())
1510 strcpy(defaultSymFile, GetSymbolsDir());
1511 PathCat(defaultSymFile, GetSourceFile());
1512 ChangeExtension(defaultSymFile, "sym", defaultSymFile);
1513 SetOutputFile(defaultSymFile);
1519 printf($"Syntax:\n ecp [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
1524 // TODO: Improve this
1525 char command[MAX_F_STRING*3];
1526 SetGlobalData(&globalData);
1527 SetExcludedSymbols(&_excludedSymbols);
1528 SetGlobalContext(globalContext);
1529 SetCurrentContext(globalContext);
1530 SetTopContext(globalContext);
1531 SetDefines(&::defines);
1532 SetImports(&imports);
1533 SetInPreCompiler(true);
1534 SetPrecompDefines(&precompDefines);
1535 SetTargetPlatform(targetPlatform);
1536 SetTargetBits(targetBits);
1539 privateModule = (Module)__ecere_COM_Initialize((bool)(true | (targetBits == sizeof(uintptr)*8 ? 0 : targetBits == 64 ? 2 : targetBits==32 ? 4 : 0) | 8), 1, null);
1540 SetPrivateModule(privateModule);
1542 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
1543 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
1544 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
1545 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
1546 globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
1547 globalContext.types.Add((BTNode)Symbol { string = CopyString("intptr_t"), type = ProcessTypeString("intptr", false) });
1548 globalContext.types.Add((BTNode)Symbol { string = CopyString("uintptr_t"), type = ProcessTypeString("uintptr", false) });
1549 globalContext.types.Add((BTNode)Symbol { string = CopyString("ssize_t"), type = ProcessTypeString("intsize", false) });
1550 globalContext.types.Add((BTNode)Symbol { string = CopyString("size_t"), type = ProcessTypeString("uintsize", false) });
1553 const char * outputFilePath = GetOutputFile();
1554 if(FileExists(outputFilePath))
1555 DeleteFile(outputFilePath);
1558 snprintf(command, sizeof(command), "%s%s -x c -E \"%s\"", cppCommand, cppOptions ? cppOptions : "", GetSourceFile());
1559 command[sizeof(command)-1] = 0;
1561 PrintLn("ECP Executing:");
1564 if((cppOutput = DualPipeOpen({ output = true }, command)))
1568 TempFile fileInput { };
1569 ModuleImport mainModule { };
1570 //fileInput = TempFile { };
1571 SetFileInput(fileInput);
1573 SetMainModule(mainModule);
1574 imports.Add(/*(*/mainModule/* = ModuleImport { })*/);
1578 for(;!cppOutput.Eof();)
1581 int count = cppOutput.Read(junk, 1, 4096);
1582 fileInput.Write(junk, 1, count);
1584 exitCode = cppOutput.GetExitCode();
1587 fileInput.Seek(0, start);
1590 // SetYydebug(true);
1593 SetCurrentNameSpace(null);
1603 ProcessDBTableDefinitions();
1604 PreCompPreProcessClassDefinitions();
1607 OutputSymbols(GetOutputFile());
1610 this.exitCode = exitCode;
1618 FreeContext(globalContext);
1619 FreeExcludedSymbols(_excludedSymbols);
1621 ::defines.Free(FreeModuleDefine);
1622 imports.Free(FreeModuleImport);
1624 precompDefines.Free(FreeDefinition);
1626 FreeTypeData(privateModule);
1628 FreeGlobalData(globalData);
1630 delete privateModule;
1637 for(c = 0; c<argc; c++)
1641 SetSymbolsDir(null); // Free symbols dir
1643 #if 0 //defined(_DEBUG) && defined(__WIN32__)