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)
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)&((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)
435 if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
437 PropertyDefine propDefine;
439 prop = eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
442 propDefine = PropertyDefine
444 isProperty = propertyMember;
445 name = CopyString(prop.name);
446 memberAccess = def.memberAccess;
448 classDefine.propertiesAndMembers.Add(propDefine);
451 else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
453 DataMemberDefine dataMemberDefine;
455 member = eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
457 dataMemberDefine = DataMemberDefine
459 isProperty = dataMember;
460 memberType = normalMember;
461 name = CopyString(def.id.string);
462 memberAccess = def.memberAccess;
464 parentMemberDefine.dataMembers.Add(dataMemberDefine);
471 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, bool isWatchable, AccessMode declMode)
475 ClassDefine classDefine;
477 bool unitType = false;
478 bool wouldBeEnum = false;
479 AccessMode inheritanceAccess = publicAccess;
482 if(baseSpecs != null)
484 Type baseType = ProcessType(baseSpecs, null);
485 PrintType(baseType, baseName, false, true);
486 if(baseType.kind == TypeKind::classType)
488 if(baseType._class.registered && classType == normalClass)
490 if(baseType._class.registered.type == unitClass)
491 classType = unitClass;
492 else if(baseType._class.registered.type == bitClass)
493 classType = bitClass;
494 else if(baseType._class.registered.type == noHeadClass)
495 classType = noHeadClass;
496 else if(baseType._class.registered.type == enumClass)
499 // classType = enumClass;
503 else if(baseType.kind == structType || baseType.kind == unionType)
505 classType = noHeadClass;
512 if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
513 inheritanceAccess = privateAccess;
516 // Eventually compute size with declarations for optional constant size offset...
518 // If there's any struct declaration in a unit data type, it means this is a bit class
519 if(classType == normalClass)
521 if(unitType) classType = unitClass;
522 if(definitions != null)
524 for(def = definitions.first; def; def = def.next)
526 if(def.type == declarationClassDef)
528 Declaration decl = def.decl;
529 if(decl.type == structDeclaration)
533 classType = bitClass;
540 for(d = decl.declarators->first; d; d = d.next)
544 classType = bitClass;
555 if(classType == normalClass && wouldBeEnum) classType = enumClass;
557 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType, symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, publicAccess, inheritanceAccess);
559 regClass.symbol = symbol;
561 classDefine = ClassDefine
563 type = classDefinition;
564 name = CopyString(symbol.string);
565 base = baseName[0] ? CopyString(baseName) : null;
566 isStatic = declMode == staticAccess;
567 isRemote = symbol.isRemote;
568 isWatchable = isWatchable;
570 precompDefines.Add(classDefine);
572 if(classType == unionClass)
574 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
575 DataMemberDefine unionDefine;
577 unionDefine = DataMemberDefine
579 isProperty = dataMember;
580 memberType = DataMemberType::unionMember;
582 classDefine.propertiesAndMembers.Add(unionDefine);
584 AddDefinitions(classDefine, unionDefine, regClass, unionMember, definitions);
585 eClass_AddMember(regClass, unionMember);
588 AddDefinitions(classDefine, (DataMemberDefine)classDefine, regClass, null, definitions);
591 if(definitions != null)
593 for(def = definitions.first; def; def = def.next)
595 if(def.type == functionClassDef)
597 ClassFunction func = def.function;
598 // Add ecereMethod_[class]_ to the declarator
599 if(!func.dontMangle && func.declarator)
601 Identifier id = GetDeclId(func.declarator);
603 MethodDefine methodDefine;
606 char * dataTypeString = StringFromSpecDecl(func.specifiers, func.declarator);
608 method = eClass_AddVirtualMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
610 method = eClass_AddMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
611 delete dataTypeString;
614 // Should we make a copy here? We make a copy in pass0.c ...
615 //method.symbol = func.declarator.symbol;
619 method.symbol = Symbol
621 string = CopyString(func.declarator.symbol.string);
622 id = func.declarator.symbol.id;
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 *)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 = PrintUInt((uint)l.data);
788 FreeType(e.exp.expType);
789 e.exp.expType = ProcessTypeString("uint", 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 ? (int)op.c : (int)op.uc;
809 value = op.type.isSigned ? (int)op.s : (int) op.us;
814 eEnum_AddFixedValue(regClass, e.id.string, value);
818 char expString[8192];
820 PrintExpression(e.exp, expString);
821 printf($"error: could not resolve value %s for enum %s in precompiler\n", expString, regClass.name);
822 ((PrecompApp)__thisModule).exitCode = 1;
823 eEnum_AddValue(regClass, e.id.string);
827 eEnum_AddValue(regClass, e.id.string);
832 void PreCompPreProcessClassDefinitions()
834 OldList * ast = GetAST();
835 External external, next;
836 for(external = ast->first; external; external = next)
838 next = external.next;
839 if(external.type == classExternal)
841 ClassDefinition _class = external._class;
842 if(_class.declMode == publicAccess || _class.declMode == privateAccess || _class.declMode == staticAccess)
844 if(_class.definitions)
846 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.deleteWatchable, _class.declMode);
850 else if(external.type == declarationExternal)
852 Declaration declaration = external.declaration;
854 if(declaration.type == initDeclaration)
856 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess || external.declaration.declMode == staticAccess)
858 if(declaration.specifiers)
861 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
863 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
864 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
866 Symbol symbol = FindClass(specifier.id.string);
871 if(specifier.type == enumSpecifier)
872 classType = enumClass;
873 else if(specifier.type == unionSpecifier)
874 classType = unionClass;
876 classType = structClass;
877 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, false, external.declaration.declMode);
882 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
884 if(declaration.declarators)
887 for(d = declaration.declarators->first; d; d = d.next)
891 Symbol symbol = d.declarator.symbol;
894 DataDefine dataDefine;
895 char typeString[1024];
896 typeString[0] = '\0';
897 PrintType(symbol.type, typeString, false, true);
898 dataDefine = DataDefine
900 type = dataDefinition;
901 name = CopyString(symbol.string);
902 dataType = CopyString(typeString);
904 precompDefines.Add(dataDefine);
912 else if(declaration.type == instDeclaration)
914 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
916 Symbol symbol = declaration.inst.symbol;
919 DataDefine dataDefine;
920 char typeString[1024];
921 typeString[0] = '\0';
922 PrintType(symbol.type, typeString, false, true);
923 dataDefine = DataDefine
925 type = dataDefinition;
926 name = CopyString(symbol.string);
927 dataType = CopyString(typeString);
929 precompDefines.Add(dataDefine);
932 globalInstance = true;
934 else if(declaration.type == defineDeclaration)
936 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
940 type = defineDefinition;
941 name = CopyString(declaration.id.string);
942 exp = declaration.exp;
944 precompDefines.Add(definition);
948 else if(external.type == functionExternal && (external.function.declMode == publicAccess || external.function.declMode == privateAccess))
950 FunctionDefinition function = external.function;
951 FunctionDefine functionDefine;
952 char typeString[1024];
953 typeString[0] = '\0';
954 PrintType(function.declarator.symbol.type, typeString, true, true);
955 functionDefine = FunctionDefine
957 type = functionDefinition;
958 name = CopyString(function.declarator.symbol.string);
959 dataType = CopyString(typeString);
961 precompDefines.Add(functionDefine);
963 else if(external.type == nameSpaceExternal)
965 SetCurrentNameSpace(external.id.string); //currentNameSpace = external.id.string;
966 //currentNameSpaceLen = currentNameSpace ? strlen(currentNameSpace) : 0;
970 ComputeModuleClasses(privateModule);
972 // Second pass for enumeration values
973 for(external = ast->first; external; external = next)
975 next = external.next;
976 if(external.type == declarationExternal && (external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess))
978 Declaration declaration = external.declaration;
980 if(declaration.type == initDeclaration)
982 if(declaration.specifiers)
985 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
987 if((specifier.type == enumSpecifier) && specifier.id && specifier.id.string &&
988 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
990 Symbol symbol = FindClass(specifier.id.string);
993 ProcessClassEnumValues(enumClass, specifier.definitions, symbol, specifier.baseSpecs, specifier.list);
1003 static void OutputDataMembers(ClassDefine classDefine, Class _class, File f)
1005 if(classDefine.propertiesAndMembers.first)
1007 DataMemberDefine member = classDefine.propertiesAndMembers.first;
1008 MemberType last = unresolvedMember;
1010 for(member = classDefine.propertiesAndMembers.first; member; member = member.next)
1012 if(member.isProperty == propertyMember)
1014 PropertyDefine prop = (PropertyDefine)member;
1015 if(last != propertyMember)
1019 f.Printf(" [Defined Properties]\n");
1023 f.Printf(" %s\n", prop.name);
1025 f.Printf(" [Conversion]\n");
1026 if(prop.memberAccess == publicAccess)
1027 f.Printf(" [Public]\n");
1029 f.Printf(" [Private]\n");
1031 f.Printf(" [Virtual]\n");
1033 f.Printf(" [Set]\n");
1035 f.Printf(" [Get]\n");
1036 if(prop.isWatchable)
1037 f.Printf(" [Watchable]\n");
1038 f.Printf(" [Type]\n");
1039 f.Printf(" %s\n", prop.type ? prop.type : "");
1043 if(last != dataMember)
1047 f.Printf(" [Defined Data Members]\n");
1049 if(member.memberType == normalMember)
1051 f.Printf(" %s\n", member.name);
1052 if(member.memberAccess == publicAccess)
1053 f.Printf(" [Public]\n");
1055 f.Printf(" [Private]\n");
1056 if(_class && _class.type == bitClass)
1060 f.Printf(" [Size]\n");
1061 f.Printf(" %d\n", member.size);
1063 if(member.bitPos != -1)
1065 f.Printf(" [Pos]\n");
1066 f.Printf(" %d\n", member.bitPos);
1069 f.Printf(" [Type]\n");
1070 f.Printf(" %s\n", member.type ? member.type : "");
1074 if(member.memberAccess == publicAccess)
1075 f.Printf(" [Public]\n");
1077 f.Printf(" [Private]\n");
1078 f.Printf((member.memberType == unionMember) ? " [Union]\n" : " [Struct]\n");
1079 OutputDataMembers((ClassDefine)member, null, f);
1082 last = member.isProperty;
1087 if(classDefine.classProperties.first)
1089 PropertyDefine prop = classDefine.propertiesAndMembers.first;
1090 f.Printf(" [Defined Class Properties]\n");
1091 for(prop = classDefine.classProperties.first; prop; prop = prop.next)
1094 f.Printf(" %s\n", prop.name);
1096 f.Printf(" [Set]\n");
1098 f.Printf(" [Get]\n");
1099 f.Printf(" [Type]\n");
1100 f.Printf(" %s\n", prop.type ? prop.type : "");
1106 static void OutputSymbols(const char * fileName)
1108 File f = FileOpen(fileName, write);
1111 DefinitionType lastType = (DefinitionType)-1;
1112 Definition definition;
1115 f.Printf("[Global Instance]\n");
1117 for(definition = precompDefines.first; definition; definition = definition.next)
1119 if(definition.type != lastType)
1121 if(lastType != (DefinitionType)-1)
1123 if(definition.type == moduleDefinition)
1124 f.Printf("[Imported Modules]\n");
1125 else if(definition.type == classDefinition)
1126 f.Printf("[Defined Classes]\n");
1127 else if(definition.type == defineDefinition)
1128 f.Printf("[Defined Expressions]\n");
1129 else if(definition.type == functionDefinition)
1130 f.Printf("[Defined Functions]\n");
1131 else if(definition.type == dataDefinition)
1132 f.Printf("[Defined Data]\n");
1133 lastType = definition.type;
1135 if(definition.type == moduleDefinition)
1137 ImportedModule module = (ImportedModule) definition;
1139 if(module.importType == staticImport)
1140 f.Printf(" [Static]\n");
1141 else if(module.importType == remoteImport)
1142 f.Printf(" [Remote]\n");
1143 if(module.importAccess == privateAccess)
1144 f.Printf(" [Private]\n");
1145 f.Printf(" %s\n", module.name);
1147 else if(definition.type == classDefinition)
1149 // Can we do this? Or should we fill up the definition?
1150 Class _class = eSystem_FindClass(privateModule, definition.name);
1151 ClassDefine classDefine = (ClassDefine) definition;
1153 f.Printf(" %s\n", definition.name);
1154 if(classDefine.isStatic)
1155 f.Printf(" [Static]\n");
1156 if(classDefine.fixed)
1157 f.Printf(" [Fixed]\n");
1158 if(classDefine.noExpansion)
1159 f.Printf(" [No Expansion]\n");
1160 if(classDefine.isRemote)
1161 f.Printf(" [Remote]\n");
1162 if(classDefine.isWatchable)
1163 f.Printf(" [Watchable]\n");
1164 if(_class.type == enumClass)
1165 f.Printf(" [Enum]\n");
1166 else if(_class.type == bitClass)
1167 f.Printf(" [Bit]\n");
1168 else if(_class.type == structClass)
1169 f.Printf(" [Struct]\n");
1170 else if(_class.type == unitClass)
1171 f.Printf(" [Unit]\n");
1172 else if(_class.type == noHeadClass)
1173 f.Printf(" [NoHead]\n");
1175 if(_class.inheritanceAccess == privateAccess)
1176 f.Printf(" [Private Base]\n");
1178 f.Printf(" [Base]\n");
1179 if(classDefine.base)
1180 f.Printf(" %s\n", classDefine.base);
1182 f.Printf(" [None]\n");
1184 if(_class.templateParams.count)
1186 ClassTemplateParameter param;
1187 TemplateParameter tp;
1189 f.Printf(" [Template Parameters]\n");
1191 for(tp = ((Symbol)_class.symbol).templateParams->first, param = _class.templateParams.first; param && tp; param = param.next, tp = tp.next)
1193 f.Printf(" %s\n", param.name);
1197 f.Printf(" [Type]\n");
1198 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1199 f.Printf(" %s\n", param.defaultArg.dataTypeString ? param.defaultArg.dataTypeString : "[None]");
1202 f.Printf(" [Expression]\n");
1203 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1204 if(tp.defaultArgument && tp.defaultArgument.expression)
1208 PrintExpression(tp.defaultArgument.expression, temp);
1209 ChangeCh(temp, '\n', ' ');
1215 f.Printf(" [None]\n");
1218 f.Printf(" [Identifier]\n");
1219 f.Printf(" %s\n", (param.memberType == dataMember) ? "[Data member]" : ((param.memberType == method) ? "[Method]" : "[Property]"));
1220 if(tp.defaultArgument && tp.defaultArgument.identifier)
1223 if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == nameSpecifier &&
1224 tp.defaultArgument.identifier._class.name)
1226 f.Printf("%s::", tp.defaultArgument.identifier._class.name);
1228 else if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == templateTypeSpecifier &&
1229 tp.defaultArgument.identifier._class.templateParameter.identifier)
1231 f.Printf("%s::", tp.defaultArgument.identifier._class.templateParameter.identifier.string);
1233 f.Printf("%s\n", tp.defaultArgument.identifier.string);
1237 f.Printf(" [None]\n");
1245 if(!classDefine.isStatic)
1247 if(classDefine.methods.first)
1249 MethodDefine method;
1251 f.Printf(" [Defined Methods]\n");
1252 for(method = classDefine.methods.first; method; method = method.next)
1254 f.Printf(" %s\n", method.name);
1255 if(method.memberAccess == publicAccess)
1256 f.Printf(" [Public]\n");
1258 f.Printf(" [Private]\n");
1259 if(method.isVirtual)
1260 f.Printf(" [Virtual]\n");
1261 f.Printf(" [Type]\n");
1262 f.Printf(" %s\n", method.type ? method.type : "");
1267 OutputDataMembers(classDefine, _class, f);
1269 if(_class.type == enumClass)
1272 Class enumClass = eSystem_FindClass(privateModule, "enum");
1273 EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
1275 f.Printf(" [Enum Values]\n");
1276 for(value = e.values.first; value; value = value.next)
1278 f.Printf(" %s = %d\n", value.name, value.data);
1284 else if(definition.type == defineDefinition)
1286 DefinedExpression defExp = eSystem_FindDefine(privateModule, definition.name);
1287 Define defineDefine = (Define) definition;
1288 f.Printf(" %s\n", definition.name);
1289 f.Printf(" [Value]\n");
1291 OutputExpression(defineDefine.exp, f);
1294 else if(definition.type == functionDefinition)
1296 FunctionDefine functionDefine = (FunctionDefine) definition;
1297 f.Printf(" %s\n", functionDefine.name);
1298 f.Printf(" [Type]\n");
1299 f.Printf(" %s\n", functionDefine.dataType);
1301 else if(definition.type == dataDefinition)
1303 DataDefine dataDefine = (DataDefine) definition;
1304 f.Printf(" %s\n", dataDefine.name);
1305 f.Printf(" [Type]\n");
1306 f.Printf(" %s\n", dataDefine.dataType);
1314 class PrecompApp : Application
1320 char defaultSymFile[MAX_LOCATION];
1321 char * cppCommand = null;
1322 char * cppOptions = null;
1323 int cppOptionsLen = 0;
1324 /*char ** argv = null;
1327 Platform targetPlatform = GetRuntimePlatform();
1328 int targetBits = GetHostBits();
1330 for(c = 0; c<this.argc; c++)
1332 char * arg = this.argv[c];
1333 int argLen = strlen(arg);
1335 argv = renew argv char *[argc + 1];
1336 argv[argc] = new char[argLen+1];
1337 strcpy(argv[argc], arg);
1339 while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
1346 argv[argc] = renew argv[argc] char[argLen + len + 1];
1348 argv[argc][argLen-1] = ' ';
1349 strcpy(argv[argc] + argLen, arg);
1356 printf("\nArguments given:\n");
1357 for(c=1; c<argc; c++)
1358 printf(" %s", argv[c]);
1360 for(c=1; c<argc; c++)
1361 PrintLn("Arg", c, ": ", argv[c]);
1366 for(c = 1; c<argc; c++)
1368 const char * arg = argv[c];
1371 if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
1373 int newLen = cppOptionsLen + 1 + strlen(arg);
1374 cppOptions = renew cppOptions char[newLen + 1];
1375 cppOptions[cppOptionsLen] = ' ';
1376 strcpy(cppOptions + cppOptionsLen + 1, arg);
1377 cppOptionsLen = newLen;
1378 targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
1380 else if(!strcmp(arg + 1, "t32") || !strcmp(arg + 1, "t64"))
1382 targetBits = !strcmp(arg + 1, "t32") ? 32 : 64;
1384 else if(arg[1] == 'D' || arg[1] == 'I')
1387 int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1388 cppOptions = renew cppOptions char[size];
1389 buf = cppOptions + cppOptionsLen;
1392 cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1394 else if(!strcmp(arg+1, "t"))
1397 targetPlatform = argv[c];
1401 else if(!strcmp(arg+1, "cpp"))
1404 cppCommand = CopyString(argv[c]);
1408 else if(!strcmp(arg+1, "o"))
1410 if(!GetOutputFile() && c + 1 < argc)
1412 SetOutputFile(argv[c+1]);
1418 else if(!strcmp(arg+1, "c"))
1420 if(!GetSourceFile() && c + 1 < argc)
1422 SetSourceFile(argv[c+1]);
1428 else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot"))
1433 const char * arg1 = argv[++c];
1434 int size = cppOptionsLen + 1 + strlen(arg) * 2 + strlen(arg1) * 2 + 1;
1435 cppOptions = renew cppOptions char[size];
1436 buf = cppOptions + cppOptionsLen;
1438 buf = PassArg(buf, arg);
1440 buf = PassArg(buf, arg1);
1441 cppOptionsLen = buf - cppOptions;
1446 else if(!strcmp(arg+1, "fno-diagnostics-show-caret"))
1449 int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
1450 cppOptions = renew cppOptions char[size];
1451 buf = cppOptions + cppOptionsLen;
1454 cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
1456 else if(!strcmp(arg+1, "symbols"))
1460 SetSymbolsDir(argv[c+1]);
1466 else if(!strcmp(arg+1, "defaultns"))
1470 SetDefaultNameSpace(argv[c+1]);
1471 //defaultNameSpaceLen = strlen(argv[c+1]);
1477 else if(!strcmp(arg+1, "strictns"))
1479 SetStrictNameSpaces(true);
1481 else if(!strcmp(arg+1, "module"))
1485 SetI18nModuleName(argv[c+1]);
1498 cppCommand = CopyString("gcc");
1499 if(!GetSourceFile())
1501 else if(!GetOutputFile())
1503 strcpy(defaultSymFile, GetSymbolsDir());
1504 PathCat(defaultSymFile, GetSourceFile());
1505 ChangeExtension(defaultSymFile, "sym", defaultSymFile);
1506 SetOutputFile(defaultSymFile);
1512 printf($"Syntax:\n ecp [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
1517 // TODO: Improve this
1518 char command[MAX_F_STRING*3];
1519 SetGlobalData(&globalData);
1520 SetExcludedSymbols(&_excludedSymbols);
1521 SetGlobalContext(globalContext);
1522 SetCurrentContext(globalContext);
1523 SetTopContext(globalContext);
1524 SetDefines(&::defines);
1525 SetImports(&imports);
1526 SetInPreCompiler(true);
1527 SetPrecompDefines(&precompDefines);
1528 SetTargetPlatform(targetPlatform);
1529 SetTargetBits(targetBits);
1532 privateModule = (Module)__ecere_COM_Initialize((bool)(true | (targetBits == sizeof(uintptr)*8 ? 0 : targetBits == 64 ? 2 : targetBits==32 ? 4 : 0) | 8), 1, null);
1533 SetPrivateModule(privateModule);
1535 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
1536 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
1537 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
1538 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
1539 globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
1540 globalContext.types.Add((BTNode)Symbol { string = CopyString("intptr_t"), type = ProcessTypeString("intptr", false) });
1541 globalContext.types.Add((BTNode)Symbol { string = CopyString("uintptr_t"), type = ProcessTypeString("uintptr", false) });
1542 globalContext.types.Add((BTNode)Symbol { string = CopyString("ssize_t"), type = ProcessTypeString("intsize", false) });
1543 globalContext.types.Add((BTNode)Symbol { string = CopyString("size_t"), type = ProcessTypeString("uintsize", false) });
1546 const char * outputFilePath = GetOutputFile();
1547 if(FileExists(outputFilePath))
1548 DeleteFile(outputFilePath);
1551 snprintf(command, sizeof(command), "%s%s -x c -E \"%s\"", cppCommand, cppOptions ? cppOptions : "", GetSourceFile());
1552 command[sizeof(command)-1] = 0;
1554 PrintLn("ECP Executing:");
1557 if((cppOutput = DualPipeOpen({ output = true }, command)))
1561 TempFile fileInput { };
1562 ModuleImport mainModule { };
1563 //fileInput = TempFile { };
1564 SetFileInput(fileInput);
1566 SetMainModule(mainModule);
1567 imports.Add(/*(*/mainModule/* = ModuleImport { })*/);
1571 for(;!cppOutput.Eof();)
1574 int count = cppOutput.Read(junk, 1, 4096);
1575 fileInput.Write(junk, 1, count);
1577 exitCode = cppOutput.GetExitCode();
1580 fileInput.Seek(0, start);
1583 // SetYydebug(true);
1586 SetCurrentNameSpace(null);
1596 ProcessDBTableDefinitions();
1597 PreCompPreProcessClassDefinitions();
1600 OutputSymbols(GetOutputFile());
1603 this.exitCode = exitCode;
1611 FreeContext(globalContext);
1612 FreeExcludedSymbols(_excludedSymbols);
1614 ::defines.Free(FreeModuleDefine);
1615 imports.Free(FreeModuleImport);
1617 precompDefines.Free(FreeDefinition);
1619 FreeTypeData(privateModule);
1621 FreeGlobalData(globalData);
1623 delete privateModule;
1630 for(c = 0; c<argc; c++)
1634 SetSymbolsDir(null); // Free symbols dir
1636 #if 0 //defined(_DEBUG) && defined(__WIN32__)