3 #define YYLTYPE Location
6 extern External curExternal;
8 /*public void MangleClassName(char * className)
14 if(!strncmp(className, "const ", 6)) c += 6;
16 for(; (ch = className[c]); c++)
30 if(!strncmp(className + c + 1, "const ", 6)) c += 6;
51 if(!strncmp(className + c + 1, "const ", 6)) c += 6;
58 // ChangeCh(className, ' ', '_');
59 // ChangeCh(className, '*', '_');
62 public void FullClassNameCat(char * output, const char * className, bool includeTemplateParams)
68 if(!strchr(className, ':'))
74 //if(strchr(className, ':'))
75 for(c = 0; (ch = className[c]) && ch != '<'; c++)
79 strcat(output, "__ecereNameSpace__");
87 if(!strncmp(className, "const ", 6)) c += 6;
89 for(; (ch = className[c]); c++)
113 if(!includeTemplateParams) break;
114 if(!strncmp(className + c + 1, "const ", 6)) c += 6;
127 if(!strncmp(className + c + 1, "const ", 6)) c += 6;
136 static void AddSimpleBaseMembers(OldList list, Class _class, Class topClass)
138 /*if(_class.base && _class.type != CLASS_SYSTEM)
139 AddSimpleBaseMembers(list, _class.base, topClass);*/
140 if(_class.type != systemClass)
141 AddMembers(list, _class, false, null, topClass, null);
144 static bool NameSpaceContained(NameSpace * ns, NameSpace * parent)
149 return NameSpaceContained(ns->parent, parent);
154 static void CheckPublicClass(Symbol classSym, AccessMode access, const char * word)
156 Class regClass = classSym ? classSym.registered : null;
159 if(regClass.templateClass)
160 regClass = regClass.templateClass;
161 // TODO: Will need to add checks for template parameter classes
162 if(classSym.isStatic && access != staticAccess)
164 Compiler_Error($"Non-static %s making use of a static class\n", word);
166 else if(access == publicAccess)
168 if(!NameSpaceContained(regClass.nameSpace, regClass.module.application.systemNameSpace))
170 if(NameSpaceContained(regClass.nameSpace, regClass.module.privateNameSpace) || !ModuleAccess(privateModule, regClass.module))
171 Compiler_Error($"Public %s making use of a private class\n", word);
177 static void CheckPublicTypeName(TypeName type, AccessMode access)
182 for(spec = type.qualifiers->first; spec; spec = spec.next)
184 // Only check for classes here...
185 // Skip structs etc. for now
186 if(spec.type == nameSpecifier)
188 Symbol classSym = spec.symbol; // FindClass(spec.name);
189 CheckPublicClass(classSym, access, "define");
195 static void CheckPublicInitializer(Initializer init, AccessMode access)
200 CheckPublicExpression(init.exp, access);
202 case listInitializer:
205 for(i = init.list->first; i; i = i.next)
206 CheckPublicInitializer(i, access);
212 static void CheckPublicExpression(Expression exp, AccessMode access)
226 CheckPublicExpression(exp.op.exp1, access);
228 CheckPublicExpression(exp.op.exp2, access);
233 for(e = exp.list->first; e; e = e.next)
234 CheckPublicExpression(e, access);
240 CheckPublicExpression(exp.index.exp, access);
241 for(e = exp.index.index->first; e; e = e.next)
242 CheckPublicExpression(e, access);
248 CheckPublicExpression(exp.call.exp, access);
249 if(exp.call.arguments)
251 for(e = exp.call.arguments->first; e; e = e.next)
252 CheckPublicExpression(e, access);
258 CheckPublicExpression(exp.member.exp, access);
263 CheckPublicExpression(exp.member.exp, access);
267 CheckPublicTypeName(exp.typeName, access);
271 CheckPublicTypeName(exp.cast.typeName, access);
273 CheckPublicExpression(exp.cast.exp, access);
279 CheckPublicExpression(exp.cond.cond, access);
280 for(e = exp.cond.exp->first; e; e = e.next)
281 CheckPublicExpression(e, access);
282 CheckPublicExpression(exp.cond.elseExp, access);
287 CheckPublicExpression(exp._new.size, access);
291 CheckPublicExpression(exp._renew.size, access);
292 CheckPublicExpression(exp._renew.exp, access);
297 CheckPublicClass(exp.instance._class.symbol /*FindClass(exp.instance._class.name)*/, access, "define");
298 for(members = exp.instance.members->first; members; members = members.next)
300 if(members.type == dataMembersInit)
303 for(member = members.dataMembers->first; member; member = member.next)
305 CheckPublicInitializer(member.initializer, access);
315 static void CheckPublicDataType(Type type, AccessMode access, const char * word)
323 CheckPublicClass(type._class, access, word);
329 // Do we want to overlook these C constructs when doing checks? Most likely... Recursion nightmare.
335 typeSym = FindSymbol(type.enumName, globalContext, globalContext, true, false);
336 if(typeSym) type = typeSym.type;
338 for(member = type.members.first; member; member = member.next)
339 CheckPublicDataType(member, access, word);
346 CheckPublicDataType(type.returnType, access, word);
347 for(param = type.params.first; param; param = param.next)
348 CheckPublicDataType(param, access, word);
349 CheckPublicClass(type.thisClass, access, word);
353 CheckPublicDataType(type.arrayType, access, word);
355 CheckPublicClass(type.enumClass, access, word);
359 CheckPublicDataType(type.type, access, word);
364 // Where is this used? Needed?
369 CheckPublicClass(type._class, access, word);
376 static void CheckMembersDefinitions(Class regClass, DataMember member, OldList definitions, AccessMode access)
378 if(definitions != null)
381 for(def = definitions.first; def; def = def.next)
383 if(def.type == declarationClassDef)
385 Declaration decl = def.decl;
386 DataMember dataMember;
389 if(decl.type == structDeclaration)
394 for(d = decl.declarators->first; d; d = d.next)
396 Identifier declId = GetDeclId(d);
401 BTNamedLink link = (BTNamedLink)member.membersAlpha.FindString(declId.string);
402 dataMember = link ? link.data : null;
405 dataMember = eClass_FindDataMember(regClass, declId.string, privateModule, null, null);
407 CheckPublicDataType(dataMember.dataType, (def.memberAccess == privateAccess) ? privateAccess : access, $"class data member");
411 else if(decl.specifiers)
414 // Unnamed struct/union
415 for(spec = decl.specifiers->first; spec; spec = spec.next)
417 if(spec.type == structSpecifier || spec.type == unionSpecifier)
419 if(spec.definitions && !spec.id)
421 CheckMembersDefinitions(regClass, member, spec.definitions, (def.memberAccess == privateAccess) ? privateAccess : access);
423 else if(spec.definitions && spec.id)
427 BTNamedLink link = (BTNamedLink)member.membersAlpha.FindString(spec.id.string);
428 dataMember = link ? link.data : null;
431 dataMember = eClass_FindDataMember(regClass, spec.id.string, privateModule, null, null);
433 CheckPublicDataType(dataMember.dataType, (def.memberAccess == privateAccess) ? privateAccess : access, $"class data member");
439 else if(decl.type == instDeclaration)
441 CheckPublicClass(decl.inst._class.symbol /*FindClass(decl.inst._class.name)*/, (def.memberAccess == privateAccess) ? privateAccess : access, $"class member instance");
448 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, Location loc, OldList defs, void * after, OldList initDeclarators, ExtDecl extDecl)
450 char structName[1024];
451 char className[1024];
452 char constructorName[1024];
453 char destructorName[1024];
455 ClassFunction destructor = null, constructor = null;
456 //bool redefinition = false;
457 bool isUnion = classType == unionClass;
459 External external = null;
463 OldList * classDataList;
468 classDataList = MkList();
481 regClass = eSystem_FindClass(privateModule, symbol.string);
483 return; // TODO: Notify of an error?
484 classType = regClass.type;
486 // PUBLISHING CHECK ON BASE CLASS
491 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace) && regClass.inheritanceAccess == publicAccess)
493 if(!regClass.base.symbol)
494 regClass.base.symbol = FindClass(regClass.base.fullName);
495 CheckPublicClass(regClass.base.symbol, publicAccess, $"class");
497 else if(!symbol.isStatic && regClass.base)
499 if(!regClass.base.symbol)
500 regClass.base.symbol = FindClass(regClass.base.fullName);
501 CheckPublicClass(regClass.base.symbol, privateAccess, $"class");
506 if(NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace))
508 if(regClass.inheritanceAccess == publicAccess &&
509 (regClass.base.nameSpace == ®Class.base.module.privateNameSpace || !ModuleAccess(privateModule, regClass.base.module)))
510 Compiler_Error($"Public class publicly inheriting off private base class\n");
512 else if(!symbol.isStatic)
514 Symbol baseSym = FindClass(regClass.base.fullName);
515 if(baseSym && baseSym.isStatic)
516 Compiler_Error($"Non-static class inheriting off static base class\n");
521 MOVED ENUM VALUES TO PASS1
523 if(classType == enumClass && enumValues)
526 for(e = enumValues.first; e; e = e.next)
535 e.exp.destType = destType;
537 ProcessExpressionType(e.exp);
538 ComputeExpression(e.exp);
539 if(e.exp.isConstant && e.exp.type == ExpConstant)
542 value = strtol(e.exp.string, null, 0);
543 eEnum_AddFixedValue(regClass, e.id.string, value);
547 eEnum_AddValue(regClass, e.id.string);
550 eEnum_AddValue(regClass, e.id.string);
555 // ACCESS OVERRIDING CODE
556 if(definitions != null)
558 for(def = definitions.first; def; def = def.next)
560 if(def.type == accessOverrideClassDef)
565 if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
567 eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
569 else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
571 eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
573 else if((method = eClass_FindMethod(regClass, def.id.string, privateModule)))
575 eClass_AddMethod(regClass, def.id.string, null, null, def.memberAccess);
580 Compiler_Error($"Couldn't find member %s to override\n", def.id.string);
588 external = MkExternalDeclaration(null);
589 defs.Insert(after, external);
590 curExternal = external;
591 curExternal.symbol = symbol;
594 if((classType == structClass || classType == noHeadClass) && inCompiler)
596 AddSimpleBaseMembers(list, regClass.base, regClass);
599 // First check if there's any declaration or instantiations, we'll need a struct
600 if(definitions != null)
604 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace))
605 CheckMembersDefinitions(regClass, null, definitions, publicAccess);
606 else if(!symbol.isStatic)
607 CheckMembersDefinitions(regClass, null, definitions, privateAccess);
609 for(def = definitions.first; def; def = def.next)
612 if(def.type == declarationClassDef)
614 Declaration decl = def.decl;
617 if(decl.type == structDeclaration)
619 if(inCompiler && classType != bitClass)
621 ListAdd(list, MkClassDefDeclaration(decl));
623 // Take it out from here...
627 else if(decl.type == instDeclaration)
629 Instantiation inst = decl.inst;
630 Expression exp = inst.exp;
634 // Eventually support multiple instance creations in the same ';'
635 OldList * specifiers = MkList();
638 ListAdd(specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
639 d = MkDeclaratorIdentifier(MkIdentifier(exp.identifier.string));
643 OldList * declarators = MkList();
644 ListAdd(declarators, d);
646 decl = MkStructDeclaration(specifiers, declarators, null);
647 ListAdd(list, MkClassDefDeclaration(decl));
649 // Add the this pointer to the instance expression
650 exp.type = memberExp;
651 exp.member.member = exp.identifier;
652 exp.member.exp = QMkExpId("this");
653 exp.member.memberType = dataMember;
654 exp.member.thisPtr = true;
659 FreeList(specifiers, FreeSpecifier);
663 // Check if it is a simple class
664 // If it is, we only need a constructor if there is data set,
665 // and we don't need a destructor
666 classSym = inst._class.symbol; // FindClass(inst._class.name);
667 if(classSym && classSym.registered &&
668 (classSym.registered.type == structClass ||
669 classSym.registered.type == bitClass ||
670 classSym.registered.type == unitClass))
672 if(inst.members && inst.members->count)
673 symbol.needConstructor = true;
677 symbol.needConstructor = true;
678 symbol.needDestructor = true;
682 else if(def.type == classDataClassDef)
684 Declaration decl = def.decl;
686 if(decl.type == structDeclaration)
688 if(inCompiler && classType != bitClass)
690 ListAdd(classDataList, MkClassDefDeclaration(decl));
692 // Take it out from here...
697 else if(def.type == defaultPropertiesClassDef)
698 symbol.needConstructor = true;
699 else if(def.type == propertyWatchClassDef)
700 symbol.needConstructor = true;
701 else if(def.type == functionClassDef)
703 ClassFunction func = def.function;
704 if(func.isDestructor)
709 Compiler_Error($"redefinition of destructor for class %s\n", symbol.string);
713 symbol.needDestructor = true;
715 if(!inCompiler && func.body)
717 // Add this to the context
720 string = CopyString("this");
721 type = MkClassType(regClass.fullName);
723 func.body.compound.context.symbols.Add((BTNode)thisSymbol);
727 if(func.isConstructor)
732 Compiler_Error($"redefinition of constructor for class %s\n", symbol.string);
736 symbol.needConstructor = true;
739 if(!inCompiler && func.body)
741 // Add this to the context
744 string = CopyString("this");
745 type = MkClassType(regClass.fullName);
747 func.body.compound.context.symbols.Add((BTNode)thisSymbol);
757 external.symbol = null; // curExternal.symbol = null;
762 OldList * specs = MkList(), * declarators = (initDeclarators != null) ? initDeclarators : MkList();
763 initDeclarators = null;
767 FullClassNameCat(structName, symbol.string, false);
769 // TESTING THIS HERE INSTEAD:
770 strcpy(structName, symbol.string);
771 symbol.structName = CopyString(structName);
774 Specifier spec = MkStructOrUnion(structSpecifier, MkIdentifier(structName),
775 isUnion ? MkListOne(MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkStructOrUnion(unionSpecifier, null, list)), null, null))) : list);
776 spec.extDeclStruct = extDecl;
777 ListAdd(specs, spec);
780 external.symbol = symbol;
781 // TOFIX : Fix this...
782 symbol.structExternal = external;
784 external.declaration = MkDeclaration(specs, declarators);
787 symbol.declaredStruct = true;
791 curExternal = external.prev;
792 defs.Remove(external);
793 FreeExternal(external);
797 // TODO: Deal with declaration id issues...
798 if(classDataList->count)
801 char classDataStructName[1024];
802 OldList * specs = MkList();
805 strcpy(classDataStructName, "__ecereClassData_");
806 FullClassNameCat(classDataStructName, symbol.string, false);
808 declMode = structDeclMode = defaultAccess;
809 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(classDataStructName), classDataList));
810 external = MkExternalDeclaration(MkDeclaration(specs, null));
811 defs.Insert(after, external);
813 symbol.classData = true;
816 delete classDataList;
823 OldList * specs = MkList(), * declarators = MkList();
824 strcpy(className, "__ecereClass_");
825 FullClassNameCat(className, symbol.string, true);
827 //MangleClassName(className);
829 symbol.className = CopyString(className);
831 if(!strstr(sourceFile, ".main.ec"))
832 ListAdd(specs, MkSpecifier(STATIC));
833 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
834 ListAdd(declarators, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null),
835 MkDeclaratorIdentifier(MkIdentifier(className))), null));
837 symbol.methodExternal = MkExternalDeclaration(MkDeclaration(specs, declarators));
838 defs.Insert(after, symbol.methodExternal);
839 after = symbol.methodExternal;
842 // Build the destructor
843 if(symbol.needDestructor)
845 ClassFunction function;
846 OldList * specs = MkList();
850 OldList * declarations = null, * statements;
852 strcpy(destructorName, "__ecereDestructor_");
853 FullClassNameCat(destructorName, symbol.string, false);
855 symbol.destructorName = CopyString(destructorName);
857 ListAdd(specs, MkSpecifier(VOID));
859 context = PushContext();
861 statements = MkList();
863 if(definitions != null)
865 for(def = definitions.first; def; def = def.next)
868 if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
870 Instantiation inst = def.decl.inst;
871 Symbol classSym = inst._class.symbol;
873 classSym = inst._class.symbol = FindClass(inst._class.name);*/
874 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass))
876 /* FIX a DecRef declaration problem...
877 // Decrement counter if it isn't a simple class
879 MkExpressionStmt(MkListOne(MkExpCall(
880 MkExpIdentifier(MkIdentifier("ecere::com::eInstance_DecRef")),
881 MkListOne(CopyExpression(inst.exp))))));
883 Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
884 ListAdd(statements, MkExpressionStmt(MkListOne(exp)));
886 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == noHeadClass))
888 Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
889 ListAdd(statements, MkExpressionStmt(MkListOne(exp)));
895 if(destructor && destructor.body)
898 declarations = destructor.body.compound.declarations;
899 if(destructor.body.compound.statements)
902 while(stmt = destructor.body.compound.statements.first)
904 destructor.body.compound.statements->Remove(stmt);
905 statements->Add(stmt);
909 // statements->Add(destructor.body);
910 statements->Insert(null, destructor.body);
911 destructor.body.compound.context.parent = context;
912 destructor.body = null;
915 body = MkCompoundStmt(declarations, statements);
917 body.compound.context = context;
919 decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(destructorName)), null);
921 // Destructor will have same Symbol ID as class
925 idCode = symbol.idCode;
928 excludedSymbols->Add(decl.symbol);
930 function = MkClassFunction(specs, null, decl, null);
931 ProcessClassFunctionBody(function, body);
932 function.id = symbol.id;
933 function.idCode = symbol.idCode;
934 //function.id = symbol.endid;
935 function.dontMangle = true;
936 definitions.Insert(null, MkClassDefFunction(function));
939 // Build the constructor
941 if(symbol.needConstructor && inCompiler)
943 ClassFunction function;
944 OldList * specs = MkList();
948 OldList * declarations = null, * statements;
950 strcpy(constructorName, "__ecereConstructor_");
951 FullClassNameCat(constructorName, symbol.string, false);
953 symbol.constructorName = CopyString(constructorName);
955 ListAdd(specs, MkSpecifierName/*MkClassName*/("bool"));
957 context = PushContext();
959 statements = MkList();
961 if(definitions != null)
963 for(def = definitions.first; def; def = def.next)
965 if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
967 Instantiation inst = def.decl.inst;
968 Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
970 classSym = inst._class.symbol = FindClass(inst._class.name);*/
972 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass))
974 Instantiation newInst { };
976 newInst.members = null;
977 newInst.exp = CopyExpression(inst.exp);
978 newInst._class = CopySpecifier(inst._class);
981 MkExpressionStmt(MkListOne(MkExpInstance(newInst))));
985 // Increment counter if it isn't a simple class
986 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass))
989 MkExpressionStmt(MkListOne(MkExpCall(
990 MkExpIdentifier(MkIdentifier("ecere::com::eInstance_IncRef")),
991 MkListOne(CopyExpression(inst.exp))))));
996 for(def = definitions.first; def; def = def.next)
998 // Add the default data properties/members
999 if(def.type == defaultPropertiesClassDef && def.defProperties)
1001 MemberInit propertyDef;
1002 for(propertyDef = def.defProperties->first; propertyDef; propertyDef = propertyDef.next)
1004 Expression memberExp;
1005 Identifier id = propertyDef.identifiers->first;
1008 memberExp = MkExpMember(MkExpIdentifier(MkIdentifier("this")), id);
1009 for(id = id.next; id; id = id.next)
1010 memberExp = MkExpMember(memberExp, id);
1012 // ASSUME: No list initializers here
1014 MkExpressionStmt(MkListOne(MkExpOp(memberExp, '=',
1015 (propertyDef.initializer && propertyDef.initializer.type == expInitializer ? propertyDef.initializer.exp : null)))));
1018 // Take it out of there...
1019 if(propertyDef.initializer)
1021 if(propertyDef.initializer.type == expInitializer)
1022 propertyDef.initializer.exp = null;
1023 FreeInitializer(propertyDef.initializer);
1025 propertyDef.initializer = null;
1026 propertyDef.identifiers->Clear();
1030 for(def = definitions.first; def; def = def.next)
1032 // Instanciate stuff
1033 if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
1035 Instantiation inst = def.decl.inst;
1036 Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
1038 classSym = inst._class.symbol = FindClass(inst._class.name);*/
1040 if(inst.exp || (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass))
1042 // Only needed here if members are set...
1043 if(!(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass)) || (inst.members && inst.members->count))
1045 // Is it safe to take it out here?
1046 def.decl.inst = null;
1049 MkExpressionStmt(MkListOne(MkExpInstance(inst))));
1056 if(constructor && constructor.body)
1059 declarations = constructor.body.compound.declarations;
1061 if(constructor.body.compound.declarations)
1064 while(decl = constructor.body.compound.declarations.first)
1066 constructor.body.compound.declarations->Remove(decl);
1067 declarations->Add(decl);
1071 // We want to keep the context here...
1072 if(constructor.body.compound.statements)
1075 while(stmt = constructor.body.compound.statements.first)
1077 constructor.body.compound.statements->Remove(stmt);
1078 statements->Add(stmt);
1082 statements->Add(constructor.body);
1083 constructor.body.compound.context.parent = context;
1084 constructor.body = null;
1087 ListAdd(statements, MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("true")))));
1088 body = MkCompoundStmt(declarations, statements);
1089 PopContext(context);
1090 body.compound.context = context;
1092 decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(constructorName)), null);
1094 // Constructor will have same Symbol ID as class
1095 decl.symbol = Symbol { };
1096 excludedSymbols->Add(decl.symbol);
1098 //*decl.symbol = *symbol;
1099 decl.symbol.id = symbol.id;
1100 decl.symbol.idCode = symbol.idCode;
1101 //decl.symbol.id = symbol.endid;
1103 function = MkClassFunction(specs, null, decl, null);
1104 ProcessClassFunctionBody(function, body);
1105 function.id = symbol.id;
1106 function.idCode = symbol.idCode;
1107 //function.id = symbol.endid;
1108 function.dontMangle = true;
1109 if(definitions != null)
1110 definitions.Insert(null, MkClassDefFunction(function));
1114 // list = null; // Why was this here?
1117 if(definitions != null)
1119 for(def = definitions.first; def; def = def.next)
1121 if(def.type == propertyClassDef && def.propertyDef)
1123 PropertyDef propertyDef = def.propertyDef;
1124 ClassDef after = def;
1129 yylloc = propertyDef.loc;
1130 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace) && def.memberAccess == publicAccess)
1131 CheckPublicDataType(propertyDef.symbol.type, publicAccess, "class property");
1132 else if(!symbol.isStatic)
1133 CheckPublicDataType(propertyDef.symbol.type, privateAccess, "class property");
1137 // Commented this out... Why exactly?
1144 if(propertyDef.getStmt && propertyDef.id)
1146 strcpy(name, "__ecereProp_");
1147 FullClassNameCat(name, symbol.string, false);
1148 strcat(name, "_Get_");
1149 // strcat(name, propertyDef.id.string);
1150 FullClassNameCat(name, propertyDef.id.string, true);
1151 //MangleClassName(name);
1155 // decl = MkDeclaratorFunction(PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier(name))), params);
1157 if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1158 propertyDef.symbol.type._class.registered.type == structClass)
1160 ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), MkDeclaratorIdentifier(MkIdentifier("value"))));
1161 decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params));
1163 func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, decl, null);
1165 // Take it out here...
1166 //propertyDef.specifiers = null;
1170 decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params));
1172 func = MkClassFunction(CopyList(propertyDef.specifiers, CopySpecifier),
1176 ProcessClassFunctionBody(func, propertyDef.getStmt);
1177 func.declarator.symbol = propertyDef.symbol;
1178 //func.declarator.propSymbol = propertyDef.symbol;
1179 propertyDef.symbol.externalGet = (External)func;
1181 func.dontMangle = true;
1182 newDef = MkClassDefFunction(func);
1183 definitions.Insert(after, newDef);
1187 propertyDef.getStmt = null;
1191 if(propertyDef.setStmt && propertyDef.id)
1193 OldList * specifiers = MkList();
1195 strcpy(name, "__ecereProp_");
1196 FullClassNameCat(name, symbol.string, false);
1197 strcat(name, "_Set_");
1198 //strcat(name, propertyDef.id.string);
1199 FullClassNameCat(name, propertyDef.id.string, true);
1200 //MangleClassName(name);
1204 ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier),
1205 PlugDeclarator(propertyDef.declarator,
1206 MkDeclaratorIdentifier(MkIdentifier("value")))));
1208 // Add const to DB table rows properties Set
1209 if(propertyDef.isDBProp)
1212 OldList * specs = ((TypeName)params->last).qualifiers;
1214 for(spec = specs->first; spec; spec = spec.next)
1215 if(spec.type == baseSpecifier && spec.specifier == CONST)
1218 specs->Insert(null, MkSpecifier(CONST));
1221 // Take it out here...
1222 //propertyDef.specifiers = null;
1224 decl = MkDeclaratorFunction(
1225 MkDeclaratorIdentifier(MkIdentifier(name)), params);
1228 bool isConversion = propertyDef.symbol._property && propertyDef.symbol._property.conversion;
1229 bool useVoid = false;
1230 switch(regClass.type)
1232 case structClass: case unionClass: useVoid = true; break;
1233 case noHeadClass: case normalClass: useVoid = !isConversion; break;
1235 useVoid = !isConversion;
1236 if(useVoid && !propertyDef.isDBProp)
1237 Compiler_Warning($"set defined on type without storage for non-conversion property\n");
1239 ListAdd(specifiers, useVoid ? MkSpecifier(VOID) : MkSpecifierName(regClass.fullName));
1242 func = MkClassFunction(specifiers, null, decl, null);
1243 ProcessClassFunctionBody(func, propertyDef.setStmt);
1244 func.dontMangle = true;
1245 func.declarator.symbol = propertyDef.symbol;
1246 //func.declarator.propSymbol = propertyDef.symbol;
1247 propertyDef.symbol.externalSet = (External)func;
1248 if(!propertyDef.conversion && regClass.type == normalClass)
1249 func.propSet = propertyDef.symbol;
1253 func.declarator.symbol = Symbol { id = propertyDef.symbol.id + 1 };
1254 //func.declarator.symbol.methodExternal = (External)func;
1257 newDef = MkClassDefFunction(func);
1258 definitions.Insert(after, newDef);
1262 propertyDef.setStmt = null;
1266 if(propertyDef.issetStmt && propertyDef.id)
1268 OldList * specifiers = MkList();
1270 strcpy(name, "__ecereProp_");
1271 FullClassNameCat(name, symbol.string, false);
1272 strcat(name, "_IsSet_");
1273 //strcat(name, propertyDef.id.string);
1274 FullClassNameCat(name, propertyDef.id.string, true);
1275 //MangleClassName(name);
1279 decl = MkDeclaratorFunction(
1280 MkDeclaratorIdentifier(MkIdentifier(name)), params);
1282 ListAdd(specifiers, MkSpecifierName("bool"));
1284 func = MkClassFunction(specifiers, null, decl, null);
1285 ProcessClassFunctionBody(func, propertyDef.issetStmt);
1286 func.dontMangle = true;
1287 func.declarator.symbol = propertyDef.symbol;
1288 //func.declarator.propSymbol = propertyDef.symbol;
1289 propertyDef.symbol.externalIsSet = (External)func;
1293 func.declarator.symbol = Symbol { id = propertyDef.symbol,id + 1, external = (External)func };
1296 newDef = MkClassDefFunction(func);
1297 definitions.Insert(after, newDef);
1301 propertyDef.issetStmt = null;
1305 if(propertyDef.id && inCompiler)
1307 // Had to put this here because not all properties go through DeclareProperty
1308 Property prop = eClass_FindProperty(symbol.registered, propertyDef.id.string, privateModule);
1312 OldList * specifiers = MkList();
1313 specifiers->Insert(null, MkSpecifier(STATIC));
1314 ListAdd(specifiers, MkSpecifierName("Property"));
1315 strcpy(name, "__ecereProp_");
1316 FullClassNameCat(name, symbol.string, false);
1318 //strcat(name, propertyDef.id.string);
1319 FullClassNameCat(name, propertyDef.id.string, true);
1320 //MangleClassName(name);
1323 OldList * list = MkList();
1324 ListAdd(list, MkInitDeclarator(/*MkDeclaratorPointer(MkPointer(null, null), */
1325 MkDeclaratorIdentifier(MkIdentifier(name))/*)*/, null));
1327 strcpy(name, "__ecerePropM_");
1328 FullClassNameCat(name, symbol.string, false);
1330 //strcat(name, propertyDef.id.string);
1331 FullClassNameCat(name, propertyDef.id.string, true);
1332 //MangleClassName(name);
1334 ListAdd(list, MkInitDeclarator(/*MkDeclaratorPointer(MkPointer(null, null), */
1335 MkDeclaratorIdentifier(MkIdentifier(name))/*)*/, null));
1336 decl = MkDeclaration(specifiers, list);
1338 external = MkExternalDeclaration(decl);
1339 ast->Insert(curExternal ? curExternal.prev : null, external);
1340 external.symbol = propertyDef.symbol;
1342 // Setting it in the Property as well here to prevent DeclareProperty to declare it a second time...
1343 propertyDef.symbol.externalPtr = external;
1345 if(inCompiler && prop && prop.symbol)
1346 ((Symbol)prop.symbol).externalPtr = external;
1351 else if(def.type == classPropertyClassDef && def.propertyDef)
1353 PropertyDef propertyDef = def.propertyDef;
1354 ClassDef after = def;
1359 yylloc = propertyDef.loc;
1361 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace))
1362 CheckPublicDataType(propertyDef.symbol.type, publicAccess, "classwide property");
1363 else if(!symbol.isStatic)
1364 CheckPublicDataType(propertyDef.symbol.type, privateAccess, "classwide property");
1367 // Commented this out... Why exactly?
1374 if(propertyDef.getStmt && propertyDef.id)
1378 sprintf(name, "class::__ecereClassProp_");
1379 FullClassNameCat(name, symbol.string, false);
1380 strcat(name, "_Get_");
1381 strcat(name, propertyDef.id.string);
1382 //MangleClassName(name);
1386 declId = MkDeclaratorIdentifier(MkIdentifier(name));
1388 // Class properties returns a uint64 even for struct types
1389 /*if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1390 propertyDef.symbol.type._class.registered.type == structClass)
1392 // ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), MkDeclaratorIdentifier(MkIdentifier("value"))));
1393 //decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1394 decl = MkDeclaratorFunction(declId, params);
1395 ListAdd(params, MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorIdentifier(MkIdentifier("_value"))));
1397 func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, decl, null);
1400 Statement body = propertyDef.getStmt;
1401 decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1402 if(!body.compound.declarations)
1403 body.compound.declarations = MkList();
1404 ListAdd(body.compound.declarations,
1405 MkDeclaration(CopyList(propertyDef.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(
1406 ptrDecl = MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("value"))), MkInitializerAssignment(MkExpCast(MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), CopyDeclarator(propertyDef.declarator)),
1407 MkExpIdentifier(MkIdentifier("_value"))))))));
1409 Symbol sym = ptrDecl.symbol;
1412 sym.type = ProcessType(propertyDef.specifiers, propertyDef.declarator);
1419 //decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1420 decl = MkDeclaratorFunction(declId, params);
1421 //func = MkClassFunction(CopyList(propertyDef.specifiers, CopySpecifier), null, decl, null);
1422 func = MkClassFunction(MkListOne(MkSpecifierName("uint64")), null, decl, null);
1425 ProcessClassFunctionBody(func, propertyDef.getStmt);
1426 func.declarator.symbol = propertyDef.symbol;
1427 propertyDef.symbol.externalGet = (External)func;
1429 func.dontMangle = true;
1431 newDef = MkClassDefFunction(func);
1432 definitions.Insert(after, newDef);
1435 decl = MkDeclaratorFunction(propertyDef.declarator, null);
1436 func.type = ProcessType(propertyDef.specifiers, decl);
1437 decl.declarator = null;
1438 FreeDeclarator(decl);
1440 if(func.type.returnType.kind == TypeKind::classType && func.type.returnType._class && func.type.returnType._class.registered && func.type.returnType._class.registered.type == structClass)
1441 func.type.returnType.byReference = true;
1444 propertyDef.getStmt = null;
1448 if(propertyDef.setStmt && propertyDef.id)
1450 Context prevCurContext;
1451 OldList * specifiers = MkList();
1452 Statement body = propertyDef.setStmt;
1455 strcpy(name, "class::__ecereClassProp_");
1456 FullClassNameCat(name, symbol.string, false);
1457 strcat(name, "_Set_");
1458 strcat(name, propertyDef.id.string);
1459 //MangleClassName(name);
1463 ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier),
1464 PlugDeclarator(propertyDef.declarator,
1465 MkDeclaratorIdentifier(MkIdentifier("value")))));
1468 prevCurContext = curContext;
1469 curContext = body.compound.context;
1471 ListAdd(params, MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorIdentifier(MkIdentifier("_value"))));
1473 decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params);
1474 if(!body.compound.declarations)
1475 body.compound.declarations = MkList();
1477 if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1478 propertyDef.symbol.type._class.registered.type == structClass)
1479 ptrDecl = MkDeclaratorPointer(MkPointer(null, null), PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier("value"))));
1481 ptrDecl = PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier("value")));
1483 ListAdd(body.compound.declarations,
1484 MkDeclaration(CopyList(propertyDef.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(ptrDecl,
1485 MkInitializerAssignment(MkExpCast(MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), CopyDeclarator(propertyDef.declarator)),
1486 MkExpIdentifier(MkIdentifier("_value"))))))));
1488 curContext = prevCurContext;
1491 Symbol sym = ptrDecl.symbol;
1494 sym.type = ProcessType(propertyDef.specifiers, propertyDef.declarator);
1496 ListAdd(specifiers, MkSpecifier(VOID));
1498 func = MkClassFunction(specifiers, null, decl, null);
1499 ProcessClassFunctionBody(func, propertyDef.setStmt);
1500 func.dontMangle = true;
1501 func.declarator.symbol = propertyDef.symbol;
1502 propertyDef.symbol.externalSet = (External)func;
1504 newDef = MkClassDefFunction(func);
1505 definitions.Insert(after, newDef);
1509 propertyDef.setStmt = null;
1517 else if(def.type == functionClassDef && def.function.declarator)
1519 ClassFunction func = def.function;
1521 func._class = regClass;
1522 // Add ecereMethod_[class]_ to the declarator
1523 if(!func.dontMangle)
1525 Declarator funcDecl = GetFuncDecl(func.declarator);
1526 Identifier id = GetDeclId(funcDecl);
1529 if(!funcDecl.function.parameters || !funcDecl.function.parameters->first)
1531 if(!funcDecl.function.parameters)
1532 funcDecl.function.parameters = MkList();
1533 ListAdd(funcDecl.function.parameters, MkTypeName(MkListOne(MkSpecifier(VOID)), null));
1536 method = eClass_FindMethod(regClass, id.string, privateModule);
1538 FreeSpecifier(id._class);
1540 if(inCompiler && method)
1542 char * newId = new char[strlen(id.string) + strlen("__ecereMethod___ecereNameSpace__") + strlen(symbol.string) + 2];
1545 ProcessMethodType(method);
1547 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace) && method.memberAccess == publicAccess)
1548 CheckPublicDataType(method.dataType, publicAccess, "class method");
1549 /* HAVE TO RELAX THIS SINCE static CAN'T QUALIFY METHODS YET... (Conflict with C++ static meaning)
1550 else if(!symbol.isStatic)
1551 CheckPublicDataType(method.dataType, privateAccess, "class method");
1554 strcpy(newId, "__ecereMethod_");
1555 FullClassNameCat(newId, symbol.string, false);
1557 strcat(newId, id.string);
1563 if(method.type != virtualMethod)
1567 delete ((Symbol)method.symbol).string;
1568 ((Symbol)method.symbol).string = CopyString(newId);
1577 if(initDeclarators != null)
1578 FreeList(initDeclarators, FreeInitDeclarator);
1581 public void PreProcessClassDefinitions()
1583 External external, next;
1589 for(external = ast->first; external; external = next)
1591 next = external.next;
1592 curExternal = external;
1593 if(external.type == classExternal)
1595 ClassDefinition _class = external._class;
1596 if(_class.definitions)
1598 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, null);
1601 else if(external.type == declarationExternal)
1603 Declaration declaration = external.declaration;
1604 if(declaration.type == initDeclaration)
1606 if(declaration.specifiers)
1608 Specifier specifier;
1609 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
1611 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
1612 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
1614 Symbol symbol = FindClass(specifier.id.string);
1617 OldList * initDeclarators = null;
1618 ExtDecl extDecl = specifier.extDeclStruct;
1619 specifier.extDeclStruct = null;
1622 // Give the declarators away to ProcessClass
1623 // It will include the declarators in the class if appropriate, otherwise free them
1624 initDeclarators = declaration.declarators;
1625 declaration.declarators = null;
1627 ProcessClass((specifier.type == unionSpecifier) ? unionClass : normalClass, specifier.definitions,
1628 symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev,
1629 initDeclarators, extDecl);
1635 else if(inCompiler && declaration.type == defineDeclaration)
1637 yylloc = declaration.loc;
1638 if(declaration.declMode == publicAccess)
1639 CheckPublicExpression(declaration.exp, publicAccess);
1640 else if(declaration.declMode != staticAccess)
1641 CheckPublicExpression(declaration.exp, privateAccess);
1644 else if(external.type == importExternal)
1646 //ImportModule(external._import);
1648 else if(inCompiler && external.type == functionExternal)
1650 yylloc = external.function.loc;
1651 if(!external.function.type)
1652 external.function.type = ProcessType(external.function.specifiers, external.function.declarator);
1653 if(external.function.declMode == publicAccess)
1654 CheckPublicDataType(external.function.type, publicAccess, "function");
1655 else if(external.function.declMode != staticAccess)
1656 CheckPublicDataType(external.function.type, privateAccess, "function");