3 #define YYLTYPE Location
6 extern External curExternal;
8 public void FullClassNameCat(char * output, const char * className, bool includeTemplateParams)
14 if(!strchr(className, ':'))
20 //if(strchr(className, ':'))
21 for(c = 0; (ch = className[c]) && ch != '<'; c++)
25 strcat(output, "__ecereNameSpace__");
33 if(!strncmp(className, "const ", 6)) c += 6;
35 for(; (ch = className[c]); c++)
59 if(!includeTemplateParams) break;
60 if(!strncmp(className + c + 1, "const ", 6)) c += 6;
73 if(!strncmp(className + c + 1, "const ", 6)) c += 6;
82 static void AddSimpleBaseMembers(External external, OldList list, Class _class, Class topClass)
84 if(_class.type != systemClass)
85 AddMembers(external, list, _class, false, null, topClass, null);
88 static bool NameSpaceContained(NameSpace * ns, NameSpace * parent)
93 return NameSpaceContained(ns->parent, parent);
98 static void CheckPublicClass(Symbol classSym, AccessMode access, const char * word)
100 Class regClass = classSym ? classSym.registered : null;
103 if(regClass.templateClass)
104 regClass = regClass.templateClass;
105 // TODO: Will need to add checks for template parameter classes
106 if(classSym.isStatic && access != staticAccess)
108 Compiler_Error($"Non-static %s making use of a static class\n", word);
110 else if(access == publicAccess)
112 if(!NameSpaceContained(regClass.nameSpace, regClass.module.application.systemNameSpace))
114 if(NameSpaceContained(regClass.nameSpace, regClass.module.privateNameSpace) || !ModuleAccess(privateModule, regClass.module))
115 Compiler_Error($"Public %s making use of a private class\n", word);
121 static void CheckPublicTypeName(TypeName type, AccessMode access)
126 for(spec = type.qualifiers->first; spec; spec = spec.next)
128 // Only check for classes here...
129 // Skip structs etc. for now
130 if(spec.type == nameSpecifier)
132 Symbol classSym = spec.symbol; // FindClass(spec.name);
133 CheckPublicClass(classSym, access, "define");
139 static void CheckPublicInitializer(Initializer init, AccessMode access)
144 CheckPublicExpression(init.exp, access);
146 case listInitializer:
149 for(i = init.list->first; i; i = i.next)
150 CheckPublicInitializer(i, access);
156 static void CheckPublicExpression(Expression exp, AccessMode access)
170 CheckPublicExpression(exp.op.exp1, access);
172 CheckPublicExpression(exp.op.exp2, access);
177 for(e = exp.list->first; e; e = e.next)
178 CheckPublicExpression(e, access);
184 CheckPublicExpression(exp.index.exp, access);
185 for(e = exp.index.index->first; e; e = e.next)
186 CheckPublicExpression(e, access);
192 CheckPublicExpression(exp.call.exp, access);
193 if(exp.call.arguments)
195 for(e = exp.call.arguments->first; e; e = e.next)
196 CheckPublicExpression(e, access);
202 CheckPublicExpression(exp.member.exp, access);
207 CheckPublicExpression(exp.member.exp, access);
211 CheckPublicTypeName(exp.typeName, access);
215 CheckPublicTypeName(exp.cast.typeName, access);
217 CheckPublicExpression(exp.cast.exp, access);
223 CheckPublicExpression(exp.cond.cond, access);
224 for(e = exp.cond.exp->first; e; e = e.next)
225 CheckPublicExpression(e, access);
226 CheckPublicExpression(exp.cond.elseExp, access);
231 CheckPublicExpression(exp._new.size, access);
235 CheckPublicExpression(exp._renew.size, access);
236 CheckPublicExpression(exp._renew.exp, access);
241 CheckPublicClass(exp.instance._class.symbol /*FindClass(exp.instance._class.name)*/, access, "define");
242 for(members = exp.instance.members->first; members; members = members.next)
244 if(members.type == dataMembersInit)
247 for(member = members.dataMembers->first; member; member = member.next)
249 CheckPublicInitializer(member.initializer, access);
259 static void CheckPublicDataType(Type type, AccessMode access, const char * word)
267 CheckPublicClass(type._class, access, word);
273 // Do we want to overlook these C constructs when doing checks? Most likely... Recursion nightmare.
279 typeSym = FindSymbol(type.enumName, globalContext, globalContext, true, false);
280 if(typeSym) type = typeSym.type;
282 for(member = type.members.first; member; member = member.next)
283 CheckPublicDataType(member, access, word);
290 CheckPublicDataType(type.returnType, access, word);
291 for(param = type.params.first; param; param = param.next)
292 CheckPublicDataType(param, access, word);
293 CheckPublicClass(type.thisClass, access, word);
297 CheckPublicDataType(type.arrayType, access, word);
299 CheckPublicClass(type.enumClass, access, word);
303 CheckPublicDataType(type.type, access, word);
308 // Where is this used? Needed?
313 CheckPublicClass(type._class, access, word);
320 static void CheckMembersDefinitions(Class regClass, DataMember member, OldList definitions, AccessMode access)
322 if(definitions != null)
325 for(def = definitions.first; def; def = def.next)
327 if(def.type == declarationClassDef)
329 Declaration decl = def.decl;
330 DataMember dataMember;
333 if(decl.type == structDeclaration)
338 for(d = decl.declarators->first; d; d = d.next)
340 Identifier declId = GetDeclId(d);
345 BTNamedLink link = (BTNamedLink)member.membersAlpha.FindString(declId.string);
346 dataMember = link ? link.data : null;
349 dataMember = eClass_FindDataMember(regClass, declId.string, privateModule, null, null);
351 CheckPublicDataType(dataMember.dataType, (def.memberAccess == privateAccess) ? privateAccess : access, $"class data member");
355 else if(decl.specifiers)
358 // Unnamed struct/union
359 for(spec = decl.specifiers->first; spec; spec = spec.next)
361 if(spec.type == structSpecifier || spec.type == unionSpecifier)
363 if(spec.definitions && !spec.id)
365 CheckMembersDefinitions(regClass, member, spec.definitions, (def.memberAccess == privateAccess) ? privateAccess : access);
367 else if(spec.definitions && spec.id)
371 BTNamedLink link = (BTNamedLink)member.membersAlpha.FindString(spec.id.string);
372 dataMember = link ? link.data : null;
375 dataMember = eClass_FindDataMember(regClass, spec.id.string, privateModule, null, null);
377 CheckPublicDataType(dataMember.dataType, (def.memberAccess == privateAccess) ? privateAccess : access, $"class data member");
383 else if(decl.type == instDeclaration)
385 CheckPublicClass(decl.inst._class.symbol /*FindClass(decl.inst._class.name)*/, (def.memberAccess == privateAccess) ? privateAccess : access, $"class member instance");
392 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, Location loc, OldList defs, void * after, OldList initDeclarators, ExtDecl extDecl)
394 char structName[1024];
395 char className[1024];
396 char constructorName[1024];
397 char destructorName[1024];
399 ClassFunction destructor = null, constructor = null;
400 //bool redefinition = false;
401 bool isUnion = classType == unionClass;
403 External external = null;
406 OldList * list = null;
407 OldList * classDataList = null;
412 classDataList = MkList();
425 regClass = eSystem_FindClass(privateModule, symbol.string);
427 return; // TODO: Notify of an error?
428 classType = regClass.type;
430 // PUBLISHING CHECK ON BASE CLASS
431 if(inCompiler && regClass.base) // The base check saves a crash trying to inherit from itself
435 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace) && regClass.inheritanceAccess == publicAccess)
437 if(!regClass.base.symbol)
438 regClass.base.symbol = FindClass(regClass.base.fullName);
439 CheckPublicClass(regClass.base.symbol, publicAccess, $"class");
441 else if(!symbol.isStatic && regClass.base)
443 if(!regClass.base.symbol)
444 regClass.base.symbol = FindClass(regClass.base.fullName);
445 CheckPublicClass(regClass.base.symbol, privateAccess, $"class");
450 if(NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace))
452 if(regClass.inheritanceAccess == publicAccess &&
453 (regClass.base.nameSpace == ®Class.base.module.privateNameSpace || !ModuleAccess(privateModule, regClass.base.module)))
454 Compiler_Error($"Public class publicly inheriting off private base class\n");
456 else if(!symbol.isStatic)
458 Symbol baseSym = FindClass(regClass.base.fullName);
459 if(baseSym && baseSym.isStatic)
460 Compiler_Error($"Non-static class inheriting off static base class\n");
465 MOVED ENUM VALUES TO PASS1
467 if(classType == enumClass && enumValues)
470 for(e = enumValues.first; e; e = e.next)
479 e.exp.destType = destType;
481 ProcessExpressionType(e.exp);
482 ComputeExpression(e.exp);
483 if(e.exp.isConstant && e.exp.type == ExpConstant)
486 value = strtol(e.exp.string, null, 0);
487 eEnum_AddFixedValue(regClass, e.id.string, value);
491 eEnum_AddValue(regClass, e.id.string);
494 eEnum_AddValue(regClass, e.id.string);
499 // ACCESS OVERRIDING CODE
500 if(definitions != null)
502 for(def = definitions.first; def; def = def.next)
504 if(def.type == accessOverrideClassDef)
509 if((prop = eClass_FindProperty(regClass, def.id.string, privateModule)))
511 eClass_AddProperty(regClass, def.id.string, null, null, null, def.memberAccess);
513 else if((member = eClass_FindDataMember(regClass, def.id.string, privateModule, null, null)))
515 eClass_AddDataMember(regClass, def.id.string, null, 0, 0, def.memberAccess);
517 else if((method = eClass_FindMethod(regClass, def.id.string, privateModule)))
519 eClass_AddMethod(regClass, def.id.string, null, null, def.memberAccess);
524 Compiler_Error($"Couldn't find member %s to override\n", def.id.string);
532 external = MkExternalDeclaration(null);
533 defs.Insert(after, external);
534 curExternal = external;
535 curExternal.symbol = symbol;
538 if((classType == structClass || classType == noHeadClass) && inCompiler)
540 AddSimpleBaseMembers(external, list, regClass.base, regClass);
543 // First check if there's any declaration or instantiations, we'll need a struct
544 if(definitions != null)
548 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace))
549 CheckMembersDefinitions(regClass, null, definitions, publicAccess);
550 else if(!symbol.isStatic)
551 CheckMembersDefinitions(regClass, null, definitions, privateAccess);
553 for(def = definitions.first; def; def = def.next)
556 if(def.type == declarationClassDef)
558 Declaration decl = def.decl;
561 if(decl.type == structDeclaration)
563 if(inCompiler && classType != bitClass)
565 ListAdd(list, MkClassDefDeclaration(decl));
567 // Take it out from here...
571 else if(decl.type == instDeclaration)
573 Instantiation inst = decl.inst;
574 Expression exp = inst.exp;
578 // Eventually support multiple instance creations in the same ';'
579 OldList * specifiers = MkList();
582 ListAdd(specifiers, MkSpecifierName/*MkClassName*/(inst._class.name));
583 d = MkDeclaratorIdentifier(MkIdentifier(exp.identifier.string));
587 OldList * declarators = MkList();
588 ListAdd(declarators, d);
590 decl = MkStructDeclaration(specifiers, declarators, null);
591 ListAdd(list, MkClassDefDeclaration(decl));
593 // Add the this pointer to the instance expression
594 exp.type = memberExp;
595 exp.member.member = exp.identifier;
596 exp.member.exp = QMkExpId("this");
597 exp.member.memberType = dataMember;
598 exp.member.thisPtr = true;
603 FreeList(specifiers, FreeSpecifier);
607 // Check if it is a simple class
608 // If it is, we only need a constructor if there is data set,
609 // and we don't need a destructor
610 classSym = inst._class.symbol; // FindClass(inst._class.name);
611 if(classSym && classSym.registered &&
612 (classSym.registered.type == structClass ||
613 classSym.registered.type == bitClass ||
614 classSym.registered.type == unitClass))
616 if(inst.members && inst.members->count)
617 symbol.needConstructor = true;
621 symbol.needConstructor = true;
622 symbol.needDestructor = true;
626 else if(def.type == classDataClassDef)
628 Declaration decl = def.decl;
630 if(decl.type == structDeclaration)
632 if(inCompiler && classType != bitClass)
634 ListAdd(classDataList, MkClassDefDeclaration(decl));
636 // Take it out from here...
641 else if(def.type == defaultPropertiesClassDef)
642 symbol.needConstructor = true;
643 else if(def.type == propertyWatchClassDef)
644 symbol.needConstructor = true;
645 else if(def.type == functionClassDef)
647 ClassFunction func = def.function;
648 if(func.isDestructor)
653 Compiler_Error($"redefinition of destructor for class %s\n", symbol.string);
657 symbol.needDestructor = true;
659 if(!inCompiler && func.body)
661 // Add this to the context
664 string = CopyString("this");
665 type = MkClassType(regClass.fullName);
667 func.body.compound.context.symbols.Add((BTNode)thisSymbol);
671 if(func.isConstructor)
676 Compiler_Error($"redefinition of constructor for class %s\n", symbol.string);
680 symbol.needConstructor = true;
683 if(!inCompiler && func.body)
685 // Add this to the context
688 string = CopyString("this");
689 type = MkClassType(regClass.fullName);
691 func.body.compound.context.symbols.Add((BTNode)thisSymbol);
701 external.symbol = null;
706 OldList * specs = MkList(), * declarators = (initDeclarators != null) ? initDeclarators : MkList();
707 initDeclarators = null;
709 // TESTING THIS HERE INSTEAD:
710 strcpy(structName, symbol.string);
711 symbol.structName = CopyString(structName);
714 Specifier spec = MkStructOrUnion(structSpecifier, MkIdentifier(structName),
715 isUnion ? MkListOne(MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkStructOrUnion(unionSpecifier, null, list)), null, null))) : list);
716 spec.extDeclStruct = extDecl;
717 ListAdd(specs, spec);
720 external.symbol = symbol;
721 if(symbol.structExternal)
723 for(e : symbol.structExternal.incoming)
724 external.CreateUniqueEdge(e.from, e.breakable);
725 for(e : symbol.structExternal.outgoing)
726 e.to.CreateUniqueEdge(external, e.breakable);
727 ast->Remove(symbol.structExternal);
728 FreeExternal(symbol.structExternal);
730 symbol.structExternal = external;
732 external.declaration = MkDeclaration(specs, declarators);
735 symbol.declaredStruct = true;
739 curExternal = external.prev;
740 defs.Remove(external);
741 FreeExternal(external);
745 if(classDataList->count)
748 char classDataStructName[1024];
749 OldList * specs = MkList();
752 strcpy(classDataStructName, "__ecereClassData_");
753 FullClassNameCat(classDataStructName, symbol.string, false);
755 declMode = structDeclMode = defaultAccess;
756 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(classDataStructName), classDataList));
757 external = MkExternalDeclaration(MkDeclaration(specs, null));
758 defs.Insert(after, external);
760 symbol.classData = true;
763 delete classDataList;
770 OldList * specs = MkList(), * declarators = MkList();
771 strcpy(className, "__ecereClass_");
772 FullClassNameCat(className, symbol.string, true);
774 symbol.className = CopyString(className);
776 if(!strstr(sourceFile, ".main.ec"))
777 ListAdd(specs, MkSpecifier(STATIC));
778 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
779 ListAdd(declarators, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null),
780 MkDeclaratorIdentifier(MkIdentifier(className))), null));
782 symbol.pointerExternal = MkExternalDeclaration(MkDeclaration(specs, declarators));
783 DeclareStruct(symbol.pointerExternal, "ecere::com::Class", false, true);
785 defs.Insert(after, symbol.pointerExternal);
786 after = symbol.methodExternal;
789 // Build the destructor
790 if(symbol.needDestructor)
792 ClassFunction function;
793 OldList * specs = MkList();
797 OldList * declarations = null, * statements;
799 strcpy(destructorName, "__ecereDestructor_");
800 FullClassNameCat(destructorName, symbol.string, false);
802 symbol.destructorName = CopyString(destructorName);
804 ListAdd(specs, MkSpecifier(VOID));
806 context = PushContext();
808 statements = MkList();
810 if(definitions != null)
812 for(def = definitions.first; def; def = def.next)
815 if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
817 Instantiation inst = def.decl.inst;
818 Symbol classSym = inst._class.symbol;
820 classSym = inst._class.symbol = FindClass(inst._class.name);*/
821 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass))
823 /* FIX a DecRef declaration problem...
824 // Decrement counter if it isn't a simple class
826 MkExpressionStmt(MkListOne(MkExpCall(
827 MkExpIdentifier(MkIdentifier("ecere::com::eInstance_DecRef")),
828 MkListOne(CopyExpression(inst.exp))))));
830 Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
831 ListAdd(statements, MkExpressionStmt(MkListOne(exp)));
833 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == noHeadClass))
835 Expression exp = MkExpOp(null, DELETE, CopyExpression(inst.exp));
836 ListAdd(statements, MkExpressionStmt(MkListOne(exp)));
842 if(destructor && destructor.body)
845 declarations = destructor.body.compound.declarations;
846 if(destructor.body.compound.statements)
849 while(stmt = destructor.body.compound.statements.first)
851 destructor.body.compound.statements->Remove(stmt);
852 statements->Add(stmt);
856 // statements->Add(destructor.body);
857 statements->Insert(null, destructor.body);
858 destructor.body.compound.context.parent = context;
859 destructor.body = null;
862 body = MkCompoundStmt(declarations, statements);
864 body.compound.context = context;
866 decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(destructorName)), null);
868 decl.symbol = Symbol { };
869 excludedSymbols->Add(decl.symbol);
871 function = MkClassFunction(specs, null, decl, null);
872 ProcessClassFunctionBody(function, body);
873 function.dontMangle = true;
874 definitions.Insert(null, MkClassDefFunction(function));
877 // Build the constructor
879 if(symbol.needConstructor && inCompiler)
881 ClassFunction function;
882 OldList * specs = MkList();
886 OldList * declarations = null, * statements;
888 strcpy(constructorName, "__ecereConstructor_");
889 FullClassNameCat(constructorName, symbol.string, false);
891 symbol.constructorName = CopyString(constructorName);
893 ListAdd(specs, MkSpecifierName/*MkClassName*/("bool"));
895 context = PushContext();
897 statements = MkList();
899 if(definitions != null)
901 for(def = definitions.first; def; def = def.next)
903 if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
905 Instantiation inst = def.decl.inst;
906 Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
908 classSym = inst._class.symbol = FindClass(inst._class.name);*/
910 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass))
912 Instantiation newInst { };
914 newInst.members = null;
915 newInst.exp = CopyExpression(inst.exp);
916 newInst._class = CopySpecifier(inst._class);
919 MkExpressionStmt(MkListOne(MkExpInstance(newInst))));
923 // Increment counter if it isn't a simple class
924 if(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass))
927 MkExpressionStmt(MkListOne(MkExpCall(
928 MkExpIdentifier(MkIdentifier("ecere::com::eInstance_IncRef")),
929 MkListOne(CopyExpression(inst.exp))))));
934 for(def = definitions.first; def; def = def.next)
936 // Add the default data properties/members
937 if(def.type == defaultPropertiesClassDef && def.defProperties)
939 MemberInit propertyDef;
940 for(propertyDef = def.defProperties->first; propertyDef; propertyDef = propertyDef.next)
942 Expression memberExp;
943 Identifier id = propertyDef.identifiers->first;
946 memberExp = MkExpMember(MkExpIdentifier(MkIdentifier("this")), id);
947 for(id = id.next; id; id = id.next)
948 memberExp = MkExpMember(memberExp, id);
950 // ASSUME: No list initializers here
952 MkExpressionStmt(MkListOne(MkExpOp(memberExp, '=',
953 (propertyDef.initializer && propertyDef.initializer.type == expInitializer ? propertyDef.initializer.exp : null)))));
956 // Take it out of there...
957 if(propertyDef.initializer)
959 if(propertyDef.initializer.type == expInitializer)
960 propertyDef.initializer.exp = null;
961 FreeInitializer(propertyDef.initializer);
963 propertyDef.initializer = null;
964 propertyDef.identifiers->Clear();
968 for(def = definitions.first; def; def = def.next)
971 if(def.type == declarationClassDef && def.decl && def.decl.type == instDeclaration)
973 Instantiation inst = def.decl.inst;
974 Symbol classSym = inst._class.symbol; // FindClass(inst._class.name);
976 classSym = inst._class.symbol = FindClass(inst._class.name);*/
978 if(inst.exp || (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass))
980 // Only needed here if members are set...
981 if(!(inst.exp && (!classSym || !classSym.registered || classSym.registered.type == normalClass || classSym.registered.type == noHeadClass)) || (inst.members && inst.members->count))
983 // Is it safe to take it out here?
984 def.decl.inst = null;
987 MkExpressionStmt(MkListOne(MkExpInstance(inst))));
994 if(constructor && constructor.body)
997 declarations = constructor.body.compound.declarations;
999 if(constructor.body.compound.declarations)
1002 while(decl = constructor.body.compound.declarations.first)
1004 constructor.body.compound.declarations->Remove(decl);
1005 declarations->Add(decl);
1009 // We want to keep the context here...
1010 if(constructor.body.compound.statements)
1013 while(stmt = constructor.body.compound.statements.first)
1015 constructor.body.compound.statements->Remove(stmt);
1016 statements->Add(stmt);
1020 statements->Add(constructor.body);
1021 constructor.body.compound.context.parent = context;
1022 constructor.body = null;
1025 ListAdd(statements, MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("true")))));
1026 body = MkCompoundStmt(declarations, statements);
1027 PopContext(context);
1028 body.compound.context = context;
1030 decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(constructorName)), null);
1032 decl.symbol = Symbol { };
1033 excludedSymbols->Add(decl.symbol);
1035 function = MkClassFunction(specs, null, decl, null);
1036 ProcessClassFunctionBody(function, body);
1037 function.dontMangle = true;
1038 if(definitions != null)
1039 definitions.Insert(null, MkClassDefFunction(function));
1043 // list = null; // Why was this here?
1046 if(definitions != null)
1048 for(def = definitions.first; def; def = def.next)
1050 if(def.type == propertyClassDef && def.propertyDef)
1052 PropertyDef propertyDef = def.propertyDef;
1053 ClassDef after = def;
1058 yylloc = propertyDef.loc;
1059 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace) && def.memberAccess == publicAccess)
1060 CheckPublicDataType(propertyDef.symbol.type, publicAccess, "class property");
1061 else if(!symbol.isStatic)
1062 CheckPublicDataType(propertyDef.symbol.type, privateAccess, "class property");
1066 // Commented this out... Why exactly?
1073 if(propertyDef.getStmt && propertyDef.id)
1075 strcpy(name, "__ecereProp_");
1076 FullClassNameCat(name, symbol.string, false);
1077 strcat(name, "_Get_");
1078 // strcat(name, propertyDef.id.string);
1079 FullClassNameCat(name, propertyDef.id.string, true);
1083 // decl = MkDeclaratorFunction(PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier(name))), params);
1085 if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1086 propertyDef.symbol.type._class.registered.type == structClass)
1088 ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), MkDeclaratorIdentifier(MkIdentifier("value"))));
1089 decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params));
1091 func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, decl, null);
1093 // Take it out here...
1094 //propertyDef.specifiers = null;
1098 decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params));
1100 func = MkClassFunction(CopyList(propertyDef.specifiers, CopySpecifier),
1104 ProcessClassFunctionBody(func, propertyDef.getStmt);
1105 func.declarator.symbol = propertyDef.symbol;
1106 //func.declarator.propSymbol = propertyDef.symbol;
1107 propertyDef.symbol.externalGet = (External)func;
1109 func.dontMangle = true;
1110 newDef = MkClassDefFunction(func);
1111 definitions.Insert(after, newDef);
1115 propertyDef.getStmt = null;
1119 if(propertyDef.setStmt && propertyDef.id)
1121 OldList * specifiers = MkList();
1123 strcpy(name, "__ecereProp_");
1124 FullClassNameCat(name, symbol.string, false);
1125 strcat(name, "_Set_");
1126 //strcat(name, propertyDef.id.string);
1127 FullClassNameCat(name, propertyDef.id.string, true);
1131 ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier),
1132 PlugDeclarator(propertyDef.declarator,
1133 MkDeclaratorIdentifier(MkIdentifier("value")))));
1135 // Add const to DB table rows properties Set
1136 if(propertyDef.isDBProp)
1139 OldList * specs = ((TypeName)params->last).qualifiers;
1141 for(spec = specs->first; spec; spec = spec.next)
1142 if(spec.type == baseSpecifier && spec.specifier == CONST)
1145 specs->Insert(null, MkSpecifier(CONST));
1148 decl = MkDeclaratorFunction(
1149 MkDeclaratorIdentifier(MkIdentifier(name)), params);
1152 bool isConversion = propertyDef.symbol._property && propertyDef.symbol._property.conversion;
1153 bool useVoid = false;
1154 switch(regClass.type)
1156 case structClass: case unionClass: useVoid = true; break;
1157 case noHeadClass: case normalClass: useVoid = !isConversion; break;
1159 useVoid = !isConversion;
1160 if(useVoid && !propertyDef.isDBProp)
1161 Compiler_Warning($"set defined on type without storage for non-conversion property\n");
1163 ListAdd(specifiers, useVoid ? MkSpecifier(VOID) : MkSpecifierName(regClass.fullName));
1166 func = MkClassFunction(specifiers, null, decl, null);
1167 ProcessClassFunctionBody(func, propertyDef.setStmt);
1168 func.dontMangle = true;
1169 func.declarator.symbol = propertyDef.symbol;
1170 propertyDef.symbol.externalSet = (External)func;
1171 if(!propertyDef.conversion && regClass.type == normalClass)
1172 func.propSet = propertyDef.symbol;
1174 newDef = MkClassDefFunction(func);
1175 definitions.Insert(after, newDef);
1179 propertyDef.setStmt = null;
1183 if(propertyDef.issetStmt && propertyDef.id)
1185 OldList * specifiers = MkList();
1187 strcpy(name, "__ecereProp_");
1188 FullClassNameCat(name, symbol.string, false);
1189 strcat(name, "_IsSet_");
1190 //strcat(name, propertyDef.id.string);
1191 FullClassNameCat(name, propertyDef.id.string, true);
1195 decl = MkDeclaratorFunction(
1196 MkDeclaratorIdentifier(MkIdentifier(name)), params);
1198 ListAdd(specifiers, MkSpecifierName("bool"));
1200 func = MkClassFunction(specifiers, null, decl, null);
1201 ProcessClassFunctionBody(func, propertyDef.issetStmt);
1202 func.dontMangle = true;
1203 func.declarator.symbol = propertyDef.symbol;
1204 //func.declarator.propSymbol = propertyDef.symbol;
1205 propertyDef.symbol.externalIsSet = (External)func;
1209 func.declarator.symbol = Symbol { id = propertyDef.symbol,id + 1, external = (External)func };
1212 newDef = MkClassDefFunction(func);
1213 definitions.Insert(after, newDef);
1217 propertyDef.issetStmt = null;
1221 if(propertyDef.id && inCompiler)
1223 // Had to put this here because not all properties go through DeclareProperty
1224 Property prop = eClass_FindProperty(symbol.registered, propertyDef.id.string, privateModule);
1228 OldList * specifiers = MkList();
1229 specifiers->Insert(null, MkSpecifier(STATIC));
1230 specifiers->Add(MkSpecifierExtended(MkExtDeclAttrib(MkAttrib(ATTRIB, MkListOne(MkAttribute(CopyString("unused"), null))))));
1232 ListAdd(specifiers, MkSpecifierName("Property"));
1233 strcpy(name, "__ecereProp_");
1234 FullClassNameCat(name, symbol.string, false);
1236 //strcat(name, propertyDef.id.string);
1237 FullClassNameCat(name, propertyDef.id.string, true);
1240 OldList * list = MkList();
1241 ListAdd(list, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null));
1243 strcpy(name, "__ecerePropM_");
1244 FullClassNameCat(name, symbol.string, false);
1246 //strcat(name, propertyDef.id.string);
1247 FullClassNameCat(name, propertyDef.id.string, true);
1249 ListAdd(list, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null));
1250 decl = MkDeclaration(specifiers, list);
1252 external = MkExternalDeclaration(decl);
1253 ast->Insert(curExternal ? curExternal.prev : null, external);
1254 external.symbol = propertyDef.symbol;
1256 // Setting it in the Property as well here to prevent DeclareProperty to declare it a second time...
1257 propertyDef.symbol.externalPtr = external;
1259 if(inCompiler && prop && prop.symbol)
1260 ((Symbol)prop.symbol).externalPtr = external;
1265 else if(def.type == classPropertyClassDef && def.propertyDef)
1267 PropertyDef propertyDef = def.propertyDef;
1268 ClassDef after = def;
1273 yylloc = propertyDef.loc;
1275 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace))
1276 CheckPublicDataType(propertyDef.symbol.type, publicAccess, "classwide property");
1277 else if(!symbol.isStatic)
1278 CheckPublicDataType(propertyDef.symbol.type, privateAccess, "classwide property");
1281 // Commented this out... Why exactly?
1288 if(propertyDef.getStmt && propertyDef.id)
1292 sprintf(name, "class::__ecereClassProp_");
1293 FullClassNameCat(name, symbol.string, false);
1294 strcat(name, "_Get_");
1295 strcat(name, propertyDef.id.string);
1299 declId = MkDeclaratorIdentifier(MkIdentifier(name));
1301 // Class properties returns a uint64 even for struct types
1302 /*if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1303 propertyDef.symbol.type._class.registered.type == structClass)
1305 // ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), MkDeclaratorIdentifier(MkIdentifier("value"))));
1306 //decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1307 decl = MkDeclaratorFunction(declId, params);
1308 ListAdd(params, MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorIdentifier(MkIdentifier("_value"))));
1310 func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, decl, null);
1313 Statement body = propertyDef.getStmt;
1314 decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1315 if(!body.compound.declarations)
1316 body.compound.declarations = MkList();
1317 ListAdd(body.compound.declarations,
1318 MkDeclaration(CopyList(propertyDef.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(
1319 ptrDecl = MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("value"))), MkInitializerAssignment(MkExpCast(MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), CopyDeclarator(propertyDef.declarator)),
1320 MkExpIdentifier(MkIdentifier("_value"))))))));
1322 Symbol sym = ptrDecl.symbol;
1325 sym.type = ProcessType(propertyDef.specifiers, propertyDef.declarator);
1332 //decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(declId, params));
1333 decl = MkDeclaratorFunction(declId, params);
1334 //func = MkClassFunction(CopyList(propertyDef.specifiers, CopySpecifier), null, decl, null);
1335 func = MkClassFunction(MkListOne(MkSpecifierName("uint64")), null, decl, null);
1338 ProcessClassFunctionBody(func, propertyDef.getStmt);
1339 func.declarator.symbol = propertyDef.symbol;
1340 propertyDef.symbol.externalGet = (External)func;
1342 func.dontMangle = true;
1344 newDef = MkClassDefFunction(func);
1345 definitions.Insert(after, newDef);
1348 decl = PlugDeclarator(propertyDef.declarator, MkDeclaratorFunction(null , null));
1349 func.type = ProcessType(propertyDef.specifiers, decl);
1350 FreeDeclarator(decl);
1352 if(func.type.returnType.kind == TypeKind::classType && func.type.returnType._class && func.type.returnType._class.registered && func.type.returnType._class.registered.type == structClass)
1353 func.type.returnType.byReference = true;
1355 // Leverage the fact that templated types are also boxed in a 64 bit integer
1356 func.type.returnType.passAsTemplate = true;
1359 propertyDef.getStmt = null;
1363 if(propertyDef.setStmt && propertyDef.id)
1365 Context prevCurContext;
1366 OldList * specifiers = MkList();
1367 Statement body = propertyDef.setStmt;
1371 strcpy(name, "class::__ecereClassProp_");
1372 FullClassNameCat(name, symbol.string, false);
1373 strcat(name, "_Set_");
1374 strcat(name, propertyDef.id.string);
1378 ListAdd(params, MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier),
1379 PlugDeclarator(propertyDef.declarator,
1380 MkDeclaratorIdentifier(MkIdentifier("value")))));
1383 prevCurContext = curContext;
1384 curContext = body.compound.context;
1386 ListAdd(params, MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorIdentifier(MkIdentifier("_value"))));
1388 decl = MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(name)), params);
1389 if(!body.compound.declarations)
1390 body.compound.declarations = MkList();
1392 if(propertyDef.symbol.type && propertyDef.symbol.type.kind == TypeKind::classType && propertyDef.symbol.type._class && propertyDef.symbol.type._class.registered &&
1393 propertyDef.symbol.type._class.registered.type == structClass)
1394 ptrDecl = MkDeclaratorPointer(MkPointer(null, null), PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier("value"))));
1396 ptrDecl = PlugDeclarator(propertyDef.declarator, MkDeclaratorIdentifier(MkIdentifier("value")));
1399 e = MkExpIdentifier(MkIdentifier("_value"));
1400 if(propertyDef.symbol.type.isPointerType)
1401 e = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), e);
1403 ListAdd(body.compound.declarations,
1404 MkDeclaration(CopyList(propertyDef.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(ptrDecl,
1405 MkInitializerAssignment(MkExpCast(MkTypeName(CopyList(propertyDef.specifiers, CopySpecifier), CopyDeclarator(propertyDef.declarator)),
1408 curContext = prevCurContext;
1411 Symbol sym = ptrDecl.symbol;
1414 sym.type = ProcessType(propertyDef.specifiers, propertyDef.declarator);
1416 ListAdd(specifiers, MkSpecifier(VOID));
1418 func = MkClassFunction(specifiers, null, decl, null);
1419 ProcessClassFunctionBody(func, propertyDef.setStmt);
1420 func.dontMangle = true;
1421 func.declarator.symbol = propertyDef.symbol;
1422 propertyDef.symbol.externalSet = (External)func;
1424 newDef = MkClassDefFunction(func);
1425 definitions.Insert(after, newDef);
1429 propertyDef.setStmt = null;
1437 else if(def.type == functionClassDef && def.function.declarator)
1439 ClassFunction func = def.function;
1441 func._class = regClass;
1442 // Add ecereMethod_[class]_ to the declarator
1443 if(!func.dontMangle)
1445 Declarator funcDecl = GetFuncDecl(func.declarator);
1446 Identifier id = GetDeclId(funcDecl);
1449 if(!funcDecl.function.parameters || !funcDecl.function.parameters->first)
1451 if(!funcDecl.function.parameters)
1452 funcDecl.function.parameters = MkList();
1453 ListAdd(funcDecl.function.parameters, MkTypeName(MkListOne(MkSpecifier(VOID)), null));
1456 method = eClass_FindMethod(regClass, id.string, privateModule);
1458 FreeSpecifier(id._class);
1460 if(inCompiler && method)
1462 char * newId = new char[strlen(id.string) + strlen("__ecereMethod___ecereNameSpace__") + strlen(symbol.string) + 2];
1465 ProcessMethodType(method);
1467 if(!NameSpaceContained(regClass.nameSpace, ®Class.module.privateNameSpace) && method.memberAccess == publicAccess)
1468 CheckPublicDataType(method.dataType, publicAccess, "class method");
1469 /* HAVE TO RELAX THIS SINCE static CAN'T QUALIFY METHODS YET... (Conflict with C++ static meaning)
1470 else if(!symbol.isStatic)
1471 CheckPublicDataType(method.dataType, privateAccess, "class method");
1474 strcpy(newId, "__ecereMethod_");
1475 FullClassNameCat(newId, symbol.string, false);
1477 strcat(newId, id.string);
1483 if(method.type != virtualMethod)
1487 delete ((Symbol)method.symbol).string;
1488 ((Symbol)method.symbol).string = CopyString(newId);
1497 if(initDeclarators != null)
1498 FreeList(initDeclarators, FreeInitDeclarator);
1501 public void PreProcessClassDefinitions()
1503 External external, next;
1509 for(external = ast->first; external; external = next)
1511 next = external.next;
1512 curExternal = external;
1513 if(external.type == classExternal)
1515 ClassDefinition _class = external._class;
1516 if(_class.definitions)
1518 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, null);
1521 else if(external.type == declarationExternal)
1523 Declaration declaration = external.declaration;
1524 if(declaration && declaration.type == initDeclaration)
1526 if(declaration.specifiers)
1528 Specifier specifier;
1529 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
1531 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
1532 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
1534 Symbol symbol = FindClass(specifier.id.string);
1537 OldList * initDeclarators = null;
1538 ExtDecl extDecl = specifier.extDeclStruct;
1539 specifier.extDeclStruct = null;
1542 // Give the declarators away to ProcessClass
1543 // It will include the declarators in the class if appropriate, otherwise free them
1544 initDeclarators = declaration.declarators;
1545 declaration.declarators = null;
1547 ProcessClass((specifier.type == unionSpecifier) ? unionClass : normalClass, specifier.definitions,
1548 symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev,
1549 initDeclarators, extDecl);
1555 else if(declaration && inCompiler && declaration.type == defineDeclaration)
1557 yylloc = declaration.loc;
1558 if(declaration.declMode == publicAccess)
1559 CheckPublicExpression(declaration.exp, publicAccess);
1560 else if(declaration.declMode != staticAccess)
1561 CheckPublicExpression(declaration.exp, privateAccess);
1564 else if(external.type == importExternal)
1566 //ImportModule(external._import);
1568 else if(inCompiler && external.type == functionExternal)
1570 yylloc = external.function.loc;
1571 if(!external.function.type)
1572 external.function.type = ProcessType(external.function.specifiers, external.function.declarator);
1573 if(external.function.declMode == publicAccess)
1574 CheckPublicDataType(external.function.type, publicAccess, "function");
1575 else if(external.function.declMode != staticAccess)
1576 CheckPublicDataType(external.function.type, privateAccess, "function");