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)
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 //if(d.type != DeclaratorFunction)
165 Identifier declId = GetDeclId(d);
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)
422 classDefine.fixed = true;
424 else if(def.type == classNoExpansionClassDef)
426 classDefine.noExpansion = true;
428 else if(def.type == accessOverrideClassDef)
433 if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
435 PropertyDefine propDefine;
437 prop = eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
440 propDefine = PropertyDefine
442 isProperty = propertyMember;
443 name = CopyString(prop.name);
444 memberAccess = def.memberAccess;
446 classDefine.propertiesAndMembers.Add(propDefine);
449 else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
451 DataMemberDefine dataMemberDefine;
453 member = eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
455 dataMemberDefine = DataMemberDefine
457 isProperty = dataMember;
458 memberType = normalMember;
459 name = CopyString(def.id.string);
460 memberAccess = def.memberAccess;
462 parentMemberDefine.dataMembers.Add(dataMemberDefine);
469 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, bool isWatchable, AccessMode declMode)
473 ClassDefine classDefine;
475 bool unitType = false;
476 bool wouldBeEnum = false;
477 AccessMode inheritanceAccess = publicAccess;
480 if(baseSpecs != null)
482 Type baseType = ProcessType(baseSpecs, null);
483 PrintType(baseType, baseName, false, true);
484 if(baseType.kind == TypeKind::classType)
486 if(baseType._class.registered && classType == normalClass)
488 if(baseType._class.registered.type == unitClass)
489 classType = unitClass;
490 else if(baseType._class.registered.type == bitClass)
491 classType = bitClass;
492 else if(baseType._class.registered.type == noHeadClass)
493 classType = noHeadClass;
494 else if(baseType._class.registered.type == enumClass)
497 // classType = enumClass;
501 else if(baseType.kind == structType || baseType.kind == unionType)
503 classType = noHeadClass;
510 if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
511 inheritanceAccess = privateAccess;
514 // Eventually compute size with declarations for optional constant size offset...
516 // If there's any struct declaration in a unit data type, it means this is a bit class
517 if(classType == normalClass)
519 if(unitType) classType = unitClass;
520 if(definitions != null)
522 for(def = definitions.first; def; def = def.next)
524 if(def.type == declarationClassDef)
526 Declaration decl = def.decl;
527 if(decl.type == structDeclaration)
531 classType = bitClass;
538 for(d = decl.declarators->first; d; d = d.next)
542 classType = bitClass;
553 if(classType == normalClass && wouldBeEnum) classType = enumClass;
555 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType, symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, publicAccess, inheritanceAccess);
557 regClass.symbol = symbol;
559 classDefine = ClassDefine
561 type = classDefinition;
562 name = CopyString(symbol.string);
563 base = baseName[0] ? CopyString(baseName) : null;
564 isStatic = declMode == staticAccess;
565 isRemote = symbol.isRemote;
566 isWatchable = isWatchable;
568 precompDefines.Add(classDefine);
570 if(classType == unionClass)
572 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
573 DataMemberDefine unionDefine;
575 unionDefine = DataMemberDefine
577 isProperty = dataMember;
578 memberType = DataMemberType::unionMember;
580 classDefine.propertiesAndMembers.Add(unionDefine);
582 AddDefinitions(classDefine, unionDefine, regClass, unionMember, definitions);
583 eClass_AddMember(regClass, unionMember);
586 AddDefinitions(classDefine, (DataMemberDefine)classDefine, regClass, null, definitions);
589 if(definitions != null)
591 for(def = definitions.first; def; def = def.next)
593 if(def.type == functionClassDef)
595 ClassFunction func = def.function;
596 // Add ecereMethod_[class]_ to the declarator
597 if(!func.dontMangle && func.declarator)
599 Identifier id = GetDeclId(func.declarator);
601 MethodDefine methodDefine;
604 char * dataTypeString = StringFromSpecDecl(func.specifiers, func.declarator);
606 method = eClass_AddVirtualMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
608 method = eClass_AddMethod(regClass, id.string, dataTypeString, func.declarator.symbol, def.memberAccess);
609 delete dataTypeString;
612 // Should we make a copy here? We make a copy in pass0.c ...
613 //method.symbol = func.declarator.symbol;
617 method.symbol = Symbol
619 string = CopyString(func.declarator.symbol.string);
620 id = func.declarator.symbol.id;
621 type = func.declarator.symbol.type;
623 if(func.declarator.symbol.type)
624 func.declarator.symbol.type.refCount++;
626 ((Symbol)method.symbol).method = method;
629 func.declarator.symbol = null;
631 if(method.type != virtualMethod || method._class == regClass)
633 methodDefine = MethodDefine
635 name = CopyString(method.name);
636 type = CopyString(method.dataTypeString);
637 memberAccess = def.memberAccess;
638 isVirtual = method.type == virtualMethod;
640 classDefine.methods.Add(methodDefine);
645 else if(def.type == accessOverrideClassDef)
648 if((method = eClass_FindMethod(regClass, def.id.string, privateModule)))
650 MethodDefine methodDefine;
652 method = eClass_AddMethod(regClass, def.id.string, null, null, def.memberAccess);
654 methodDefine = MethodDefine
656 name = CopyString(method.name);
657 memberAccess = def.memberAccess;
659 classDefine.methods.Add(methodDefine);
664 if(regClass && symbol.templateParams)
666 TemplateParameter param;
667 // Add template parameters here
668 for(param = symbol.templateParams->first; param; param = param.next)
670 ClassTemplateArgument defaultArg { };
671 if(param.defaultArgument)
676 defaultArg.dataTypeString =
677 StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
681 char memberString[1024];
682 memberString[0] = '\0';
684 if(param.defaultArgument.identifier._class && param.defaultArgument.identifier._class.name)
686 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
687 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
689 strcpy(memberString, param.defaultArgument.identifier._class.name);
694 strcat(memberString, "::");
696 strcat(memberString, param.defaultArgument.identifier.string);
697 defaultArg.memberString = CopyString(memberString);
700 /* switch(param.memberType)
703 defaultArg.member = eClass_FindDataMember(regClass, param.defaultArgument.identifier.string, regClass.module, null, null);
706 defaultArg.method = eClass_FindMethod(regClass, param.defaultArgument.identifier.string, regClass.module);
709 defaultArg.prop = eClass_FindProperty(regClass, param.defaultArgument.identifier.string, regClass.module);
716 ProcessExpressionType(param.defaultArgument.expression);
717 ComputeExpression(param.defaultArgument.expression);
718 op = GetOperand(param.defaultArgument.expression);
719 defaultArg.expression.ui64 = op.ui64;
724 if(param.type == identifier)
726 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, (void *)param.memberType, defaultArg);
730 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
731 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
733 /*eClass_AddTemplateParameter(regClass, param.identifier.string, param.type,
734 (param.type == type) ? eSystem_FindClass(regClass.module, typeString) : CopyString(typeString), defaultArg);*/
735 // delete typeString;
742 static void ProcessClassEnumValues(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues)
744 Class regClass = symbol.registered;
745 if(regClass && enumValues)
748 for(e = enumValues.first; e; e = e.next)
757 e.exp.destType = destType;
759 // Set parsingType to avoid producing errors
760 SetParsingType(true);
761 ProcessExpressionType(e.exp);
762 SetParsingType(false);
766 destType.kind = TypeKind::classType;
767 destType._class = symbol;
768 ProcessExpressionType(e.exp);
770 ComputeExpression(e.exp);
771 if(e.exp.isConstant && e.exp.type == constantExp)
773 Operand op = GetOperand(e.exp);
775 //value = strtol(e.exp.string, null, 0);
779 value = op.type.isSigned ? (int)op.c : (int)op.uc;
782 value = op.type.isSigned ? (int)op.s : (int) op.us;
787 eEnum_AddFixedValue(regClass, e.id.string, value);
791 eEnum_AddValue(regClass, e.id.string);
794 eEnum_AddValue(regClass, e.id.string);
799 void PreCompPreProcessClassDefinitions()
801 OldList * ast = GetAST();
802 External external, next;
803 for(external = ast->first; external; external = next)
805 next = external.next;
806 if(external.type == classExternal)
808 ClassDefinition _class = external._class;
809 if(_class.declMode == publicAccess || _class.declMode == privateAccess || _class.declMode == staticAccess)
811 if(_class.definitions)
813 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.deleteWatchable, _class.declMode);
817 else if(external.type == declarationExternal)
819 Declaration declaration = external.declaration;
821 if(declaration.type == initDeclaration)
823 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess || external.declaration.declMode == staticAccess)
825 if(declaration.specifiers)
828 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
830 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
831 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
833 Symbol symbol = FindClass(specifier.id.string);
838 if(specifier.type == enumSpecifier)
839 classType = enumClass;
840 else if(specifier.type == unionSpecifier)
841 classType = unionClass;
843 classType = structClass;
844 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, false, external.declaration.declMode);
849 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
851 if(declaration.declarators)
854 for(d = declaration.declarators->first; d; d = d.next)
858 Symbol symbol = d.declarator.symbol;
861 DataDefine dataDefine;
862 char typeString[1024];
863 typeString[0] = '\0';
864 PrintType(symbol.type, typeString, false, true);
865 dataDefine = DataDefine
867 type = dataDefinition;
868 name = CopyString(symbol.string);
869 dataType = CopyString(typeString);
871 precompDefines.Add(dataDefine);
879 else if(declaration.type == instDeclaration)
881 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
883 Symbol symbol = declaration.inst.symbol;
886 DataDefine dataDefine;
887 char typeString[1024];
888 typeString[0] = '\0';
889 PrintType(symbol.type, typeString, false, true);
890 dataDefine = DataDefine
892 type = dataDefinition;
893 name = CopyString(symbol.string);
894 dataType = CopyString(typeString);
896 precompDefines.Add(dataDefine);
899 globalInstance = true;
901 else if(declaration.type == defineDeclaration)
903 if(external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess)
907 type = defineDefinition;
908 name = CopyString(declaration.id.string);
909 exp = declaration.exp;
911 precompDefines.Add(definition);
915 else if(external.type == functionExternal && (external.function.declMode == publicAccess || external.function.declMode == privateAccess))
917 FunctionDefinition function = external.function;
918 FunctionDefine functionDefine;
919 char typeString[1024];
920 typeString[0] = '\0';
921 PrintType(function.declarator.symbol.type, typeString, true, true);
922 functionDefine = FunctionDefine
924 type = functionDefinition;
925 name = CopyString(function.declarator.symbol.string);
926 dataType = CopyString(typeString);
928 precompDefines.Add(functionDefine);
930 else if(external.type == nameSpaceExternal)
932 SetCurrentNameSpace(external.id.string); //currentNameSpace = external.id.string;
933 //currentNameSpaceLen = currentNameSpace ? strlen(currentNameSpace) : 0;
937 ComputeModuleClasses(privateModule);
939 // Second pass for enumeration values
940 for(external = ast->first; external; external = next)
942 next = external.next;
943 if(external.type == declarationExternal && (external.declaration.declMode == publicAccess || external.declaration.declMode == privateAccess))
945 Declaration declaration = external.declaration;
947 if(declaration.type == initDeclaration)
949 if(declaration.specifiers)
952 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
954 if((specifier.type == enumSpecifier) && specifier.id && specifier.id.string &&
955 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
957 Symbol symbol = FindClass(specifier.id.string);
960 ProcessClassEnumValues(enumClass, specifier.definitions, symbol, specifier.baseSpecs, specifier.list);
970 static void OutputDataMembers(ClassDefine classDefine, Class _class, File f)
972 if(classDefine.propertiesAndMembers.first)
974 DataMemberDefine member = classDefine.propertiesAndMembers.first;
975 MemberType last = unresolvedMember;
977 for(member = classDefine.propertiesAndMembers.first; member; member = member.next)
979 if(member.isProperty == propertyMember)
981 PropertyDefine prop = (PropertyDefine)member;
982 if(last != propertyMember)
986 f.Printf(" [Defined Properties]\n");
990 f.Printf(" %s\n", prop.name);
992 f.Printf(" [Conversion]\n");
993 if(prop.memberAccess == publicAccess)
994 f.Printf(" [Public]\n");
996 f.Printf(" [Private]\n");
998 f.Printf(" [Virtual]\n");
1000 f.Printf(" [Set]\n");
1002 f.Printf(" [Get]\n");
1003 if(prop.isWatchable)
1004 f.Printf(" [Watchable]\n");
1005 f.Printf(" [Type]\n");
1006 f.Printf(" %s\n", prop.type ? prop.type : "");
1010 if(last != dataMember)
1014 f.Printf(" [Defined Data Members]\n");
1016 if(member.memberType == normalMember)
1018 f.Printf(" %s\n", member.name);
1019 if(member.memberAccess == publicAccess)
1020 f.Printf(" [Public]\n");
1022 f.Printf(" [Private]\n");
1023 if(_class && _class.type == bitClass)
1027 f.Printf(" [Size]\n");
1028 f.Printf(" %d\n", member.size);
1030 if(member.bitPos != -1)
1032 f.Printf(" [Pos]\n");
1033 f.Printf(" %d\n", member.bitPos);
1036 f.Printf(" [Type]\n");
1037 f.Printf(" %s\n", member.type ? member.type : "");
1041 if(member.memberAccess == publicAccess)
1042 f.Printf(" [Public]\n");
1044 f.Printf(" [Private]\n");
1045 f.Printf((member.memberType == unionMember) ? " [Union]\n" : " [Struct]\n");
1046 OutputDataMembers((ClassDefine)member, null, f);
1049 last = member.isProperty;
1054 if(classDefine.classProperties.first)
1056 PropertyDefine prop = classDefine.propertiesAndMembers.first;
1057 f.Printf(" [Defined Class Properties]\n");
1058 for(prop = classDefine.classProperties.first; prop; prop = prop.next)
1061 f.Printf(" %s\n", prop.name);
1063 f.Printf(" [Set]\n");
1065 f.Printf(" [Get]\n");
1066 f.Printf(" [Type]\n");
1067 f.Printf(" %s\n", prop.type ? prop.type : "");
1073 static void OutputSymbols(char * fileName)
1075 File f = FileOpen(fileName, write);
1078 DefinitionType lastType = (DefinitionType)-1;
1079 Definition definition;
1082 f.Printf("[Global Instance]\n");
1084 for(definition = precompDefines.first; definition; definition = definition.next)
1086 if(definition.type != lastType)
1088 if(lastType != (DefinitionType)-1)
1090 if(definition.type == moduleDefinition)
1091 f.Printf("[Imported Modules]\n");
1092 else if(definition.type == classDefinition)
1093 f.Printf("[Defined Classes]\n");
1094 else if(definition.type == defineDefinition)
1095 f.Printf("[Defined Expressions]\n");
1096 else if(definition.type == functionDefinition)
1097 f.Printf("[Defined Functions]\n");
1098 else if(definition.type == dataDefinition)
1099 f.Printf("[Defined Data]\n");
1100 lastType = definition.type;
1102 if(definition.type == moduleDefinition)
1104 ImportedModule module = (ImportedModule) definition;
1106 if(module.importType == staticImport)
1107 f.Printf(" [Static]\n");
1108 else if(module.importType == remoteImport)
1109 f.Printf(" [Remote]\n");
1110 if(module.importAccess == privateAccess)
1111 f.Printf(" [Private]\n");
1112 f.Printf(" %s\n", module.name);
1114 else if(definition.type == classDefinition)
1116 // Can we do this? Or should we fill up the definition?
1117 Class _class = eSystem_FindClass(privateModule, definition.name);
1118 ClassDefine classDefine = (ClassDefine) definition;
1120 f.Printf(" %s\n", definition.name);
1121 if(classDefine.isStatic)
1122 f.Printf(" [Static]\n");
1123 if(classDefine.fixed)
1124 f.Printf(" [Fixed]\n");
1125 if(classDefine.noExpansion)
1126 f.Printf(" [No Expansion]\n");
1127 if(classDefine.isRemote)
1128 f.Printf(" [Remote]\n");
1129 if(classDefine.isWatchable)
1130 f.Printf(" [Watchable]\n");
1131 if(_class.type == enumClass)
1132 f.Printf(" [Enum]\n");
1133 else if(_class.type == bitClass)
1134 f.Printf(" [Bit]\n");
1135 else if(_class.type == structClass)
1136 f.Printf(" [Struct]\n");
1137 else if(_class.type == unitClass)
1138 f.Printf(" [Unit]\n");
1139 else if(_class.type == noHeadClass)
1140 f.Printf(" [NoHead]\n");
1142 if(_class.inheritanceAccess == privateAccess)
1143 f.Printf(" [Private Base]\n");
1145 f.Printf(" [Base]\n");
1146 if(classDefine.base)
1147 f.Printf(" %s\n", classDefine.base);
1149 f.Printf(" [None]\n");
1151 if(_class.templateParams.count)
1153 ClassTemplateParameter param;
1154 TemplateParameter tp;
1156 f.Printf(" [Template Parameters]\n");
1158 for(tp = ((Symbol)_class.symbol).templateParams->first, param = _class.templateParams.first; param && tp; param = param.next, tp = tp.next)
1160 f.Printf(" %s\n", param.name);
1164 f.Printf(" [Type]\n");
1165 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1166 f.Printf(" %s\n", param.defaultArg.dataTypeString ? param.defaultArg.dataTypeString : "[None]");
1169 f.Printf(" [Expression]\n");
1170 f.Printf(" %s\n", param.dataTypeString ? param.dataTypeString : "[None]");
1171 if(tp.defaultArgument && tp.defaultArgument.expression)
1175 PrintExpression(tp.defaultArgument.expression, temp);
1176 ChangeCh(temp, '\n', ' ');
1182 f.Printf(" [None]\n");
1185 f.Printf(" [Identifier]\n");
1186 f.Printf(" %s\n", (param.memberType == dataMember) ? "[Data member]" : ((param.memberType == method) ? "[Method]" : "[Property]"));
1187 if(tp.defaultArgument && tp.defaultArgument.identifier)
1190 if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == nameSpecifier &&
1191 tp.defaultArgument.identifier._class.name)
1193 f.Printf("%s::", tp.defaultArgument.identifier._class.name);
1195 else if(tp.defaultArgument.identifier._class && tp.defaultArgument.identifier._class.type == templateTypeSpecifier &&
1196 tp.defaultArgument.identifier._class.templateParameter.identifier)
1198 f.Printf("%s::", tp.defaultArgument.identifier._class.templateParameter.identifier.string);
1200 f.Printf("%s\n", tp.defaultArgument.identifier.string);
1204 f.Printf(" [None]\n");
1212 if(!classDefine.isStatic)
1214 if(classDefine.methods.first)
1216 MethodDefine method;
1218 f.Printf(" [Defined Methods]\n");
1219 for(method = classDefine.methods.first; method; method = method.next)
1221 f.Printf(" %s\n", method.name);
1222 if(method.memberAccess == publicAccess)
1223 f.Printf(" [Public]\n");
1225 f.Printf(" [Private]\n");
1226 if(method.isVirtual)
1227 f.Printf(" [Virtual]\n");
1228 f.Printf(" [Type]\n");
1229 f.Printf(" %s\n", method.type ? method.type : "");
1234 OutputDataMembers(classDefine, _class, f);
1236 if(_class.type == enumClass)
1239 Class enumClass = eSystem_FindClass(privateModule, "enum");
1240 EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
1242 f.Printf(" [Enum Values]\n");
1243 for(value = e.values.first; value; value = value.next)
1245 f.Printf(" %s = %d\n", value.name, value.data);
1251 else if(definition.type == defineDefinition)
1253 DefinedExpression defExp = eSystem_FindDefine(privateModule, definition.name);
1254 Define defineDefine = (Define) definition;
1255 f.Printf(" %s\n", definition.name);
1256 f.Printf(" [Value]\n");
1258 OutputExpression(defineDefine.exp, f);
1261 else if(definition.type == functionDefinition)
1263 FunctionDefine functionDefine = (FunctionDefine) definition;
1264 f.Printf(" %s\n", functionDefine.name);
1265 f.Printf(" [Type]\n");
1266 f.Printf(" %s\n", functionDefine.dataType);
1268 else if(definition.type == dataDefinition)
1270 DataDefine dataDefine = (DataDefine) definition;
1271 f.Printf(" %s\n", dataDefine.name);
1272 f.Printf(" [Type]\n");
1273 f.Printf(" %s\n", dataDefine.dataType);
1281 class PrecompApp : Application
1287 char defaultSymFile[MAX_LOCATION];
1288 char * cppCommand = null;
1289 char * cppOptions = null;
1290 int cppOptionsLen = 0;
1291 /*char ** argv = null;
1294 Platform targetPlatform = GetRuntimePlatform();
1295 int targetBits = GetHostBits();
1297 for(c = 0; c<this.argc; c++)
1299 char * arg = this.argv[c];
1300 int argLen = strlen(arg);
1302 argv = renew argv char *[argc + 1];
1303 argv[argc] = new char[argLen+1];
1304 strcpy(argv[argc], arg);
1306 while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
1313 argv[argc] = renew argv[argc] char[argLen + len + 1];
1315 argv[argc][argLen-1] = ' ';
1316 strcpy(argv[argc] + argLen, arg);
1322 for(c = 1; c<argc; c++)
1324 char * arg = argv[c];
1327 if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
1329 int argLen = strlen(arg);
1330 int newLen = cppOptionsLen + 1 + argLen;
1331 cppOptions = renew cppOptions char[newLen + 1];
1332 cppOptions[cppOptionsLen] = ' ';
1333 strcpy(cppOptions + cppOptionsLen + 1, arg);
1334 cppOptionsLen = newLen;
1335 targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
1337 else if(arg[1] == 'D')
1339 int argLen = strlen(arg);
1340 int newLen = cppOptionsLen + 1 + argLen;
1341 cppOptions = renew cppOptions char[newLen + 1];
1342 cppOptions[cppOptionsLen] = ' ';
1343 strcpy(cppOptions + cppOptionsLen + 1, arg);
1344 cppOptionsLen = newLen;
1346 else if(arg[1] == 'I')
1348 int argLen = strlen(arg);
1349 int newLen = cppOptionsLen + argLen + 3;
1350 cppOptions = renew cppOptions char[newLen + 1];
1351 cppOptions[cppOptionsLen] = ' ';
1352 cppOptions[cppOptionsLen+1] = '-';
1353 cppOptions[cppOptionsLen+2] = 'I';
1354 cppOptions[cppOptionsLen+3] = '"';
1355 strcpy(cppOptions + cppOptionsLen + 4, arg+2);
1356 cppOptions[newLen-1] = '\"';
1357 cppOptions[newLen] = '\0';
1358 cppOptionsLen = newLen;
1360 else if(!strcmp(arg+1, "t"))
1363 targetPlatform = argv[c];
1367 else if(!strcmp(arg+1, "cpp"))
1370 cppCommand = CopyString(argv[c]);
1374 else if(!strcmp(arg+1, "o"))
1376 if(!GetOutputFile() && c + 1 < argc)
1378 SetOutputFile(argv[c+1]);
1384 else if(!strcmp(arg+1, "c"))
1386 if(!GetSourceFile() && c + 1 < argc)
1388 SetSourceFile(argv[c+1]);
1394 else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot"))
1398 int argLen = strlen(arg);
1399 int arg1Len = strlen(argv[c+1]);
1400 int newLen = cppOptionsLen + argLen + arg1Len + 4;
1401 cppOptions = renew cppOptions char[newLen + 1];
1402 cppOptions[cppOptionsLen] = ' ';
1403 strcpy(cppOptions + cppOptionsLen + 1, arg);
1404 cppOptions[cppOptionsLen+argLen+1] = ' ';
1405 cppOptions[cppOptionsLen+argLen+2] = '"';
1407 strcpy(cppOptions + cppOptionsLen + argLen + 3, arg);
1408 cppOptions[newLen-1] = '\"';
1409 cppOptions[newLen] = '\0';
1410 cppOptionsLen = newLen;
1415 else if(!strcmp(arg+1, "symbols"))
1419 SetSymbolsDir(argv[c+1]);
1425 else if(!strcmp(arg+1, "defaultns"))
1429 SetDefaultNameSpace(argv[c+1]); //defaultNameSpace = argv[c+1];
1430 //defaultNameSpaceLen = strlen(argv[c+1]);
1436 else if(!strcmp(arg+1, "strictns"))
1438 SetStrictNameSpaces(true);
1447 cppCommand = CopyString("gcc");
1448 if(!GetSourceFile())
1450 else if(!GetOutputFile())
1452 strcpy(defaultSymFile, GetSymbolsDir());
1453 PathCat(defaultSymFile, GetSourceFile());
1454 ChangeExtension(defaultSymFile, "sym", defaultSymFile);
1455 SetOutputFile(defaultSymFile);
1460 printf($"Syntax:\n ecp [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
1463 // TODO: Improve this
1464 char command[MAX_F_STRING*3];
1467 SetGlobalContext(globalContext);
1468 SetTopContext(globalContext);
1469 SetCurrentContext(globalContext);
1470 SetExcludedSymbols(&_excludedSymbols);
1471 SetGlobalData(&globalData);
1472 SetDefines(&::defines);
1473 SetImports(&imports);
1474 SetPrecompDefines(&precompDefines);
1475 SetInPreCompiler(true);
1476 SetTargetPlatform(targetPlatform);
1477 SetTargetBits(targetBits);
1480 privateModule = (Module)__ecere_COM_Initialize(true | ((targetBits == 64)?2:0), 1, null);
1481 SetPrivateModule(privateModule);
1483 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
1484 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
1485 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
1486 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
1487 globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
1488 globalContext.types.Add((BTNode)Symbol { string = CopyString("intptr_t"), type = ProcessTypeString("intptr", false) });
1489 globalContext.types.Add((BTNode)Symbol { string = CopyString("uintptr_t"), type = ProcessTypeString("uintptr", false) });
1492 char * outputFilePath = GetOutputFile();
1493 if(FileExists(outputFilePath))
1494 DeleteFile(outputFilePath);
1497 snprintf(command, sizeof(command), "%s%s -x c -E \"%s\"", cppCommand, cppOptions ? cppOptions : "", GetSourceFile());
1498 command[sizeof(command)-1] = 0;
1500 if((cppOutput = DualPipeOpen({ output = true }, command)))
1504 TempFile fileInput { };
1505 ModuleImport mainModule { };
1506 //fileInput = TempFile { };
1507 SetFileInput(fileInput);
1509 SetMainModule(mainModule);
1510 imports.Add(/*(*/mainModule/* = ModuleImport { })*/);
1514 for(;!cppOutput.Eof();)
1517 int count = cppOutput.Read(junk, 1, 4096);
1518 fileInput.Write(junk, 1, count);
1520 exitCode = cppOutput.GetExitCode();
1523 fileInput.Seek(0, start);
1526 // SetYydebug(true);
1529 SetCurrentNameSpace(null);
1539 ProcessDBTableDefinitions();
1540 PreCompPreProcessClassDefinitions();
1543 OutputSymbols(GetOutputFile());
1546 this.exitCode = exitCode;
1554 FreeContext(globalContext);
1555 FreeExcludedSymbols(_excludedSymbols);
1557 ::defines.Free(FreeModuleDefine);
1558 imports.Free(FreeModuleImport);
1560 precompDefines.Free(FreeDefinition);
1562 FreeTypeData(privateModule);
1564 FreeGlobalData(globalData);
1566 delete privateModule;
1573 for(c = 0; c<argc; c++)
1577 SetSymbolsDir(null); // Free symbols dir