3 #define YYLTYPE Location
6 static void AddDefinitions(Class regClass, DataMember member, OldList definitions)
8 if(definitions != null)
11 for(def = definitions.first; def; def = def.next)
13 if(def.type == declarationClassDef)
15 Declaration decl = def.decl;
16 DataMember dataMember;
19 if(decl.type == structDeclaration)
22 // Add data members to the class
25 for(d = decl.declarators->first; d; d = d.next)
27 Identifier declId = GetDeclId(d);
30 if(regClass && regClass.type == bitClass)
32 Expression sizeExp = d.structDecl.exp, posExp = d.structDecl.posExp;
33 int bitSize = 0, bitPos = -1;
34 char dataTypeString[1024] = "";
38 // Should this be processed/computed later?
39 ProcessExpressionType(sizeExp);
40 ComputeExpression(sizeExp);
42 if(sizeExp.isConstant)
43 bitSize = strtol(sizeExp.constant, null, 0);
44 FreeExpression(sizeExp);
49 // Should this be processed/computed later?
50 ProcessExpressionType(posExp);
51 ComputeExpression(posExp);
54 bitPos = strtol(posExp.constant, null, 0);
55 FreeExpression(posExp);
58 d.structDecl.posExp = null;
59 d.structDecl.exp = null;
61 dataType = ProcessType(decl.specifiers, d);
62 PrintType(dataType, dataTypeString, false, true);
64 //if(!eClass_FindDataMember(regClass, declId.string))
66 BitMember member = eClass_AddBitMember(regClass, declId.string, dataTypeString, 0, 0, def.memberAccess);
69 member.size = bitSize;
72 dataMember = (DataMember)member;
76 dataMember.dataType = dataType;
79 Compiler_Error($"Member with same name already exists %s in class %s\n", declId.string, regClass.name);
85 //if(isMember || !eClass_FindDataMember(regClass, declId.string))
87 //char * dataTypeString = StringFromSpecDecl(decl.specifiers, d);
88 char typeString[1024] = "";
89 dataType = ProcessType(decl.specifiers, d);
90 PrintType(dataType, typeString, false, true);
94 dataMember = eMember_AddDataMember(member, declId.string,
95 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
97 Compiler_Error($"Member with same name already exists %s in member %s\n", declId.string, member.name);
101 dataMember = eClass_AddDataMember(regClass, declId.string,
102 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
104 Compiler_Error($"Member with same name already exists %s in class %s\n", declId.string, regClass.name);
107 //delete dataTypeString;
109 dataMember.dataType = dataType;
117 else if(decl.specifiers)
120 // Unnamed struct/union
121 for(spec = decl.specifiers->first; spec; spec = spec.next)
123 if(spec.type == structSpecifier || spec.type == unionSpecifier)
125 if(spec.definitions && !spec.id)
127 DataMember dataMember = eMember_New((spec.type == unionSpecifier) ? unionMember : structMember, def.memberAccess);
129 AddDefinitions(null, dataMember, spec.definitions);
133 eMember_AddMember(member, dataMember);
137 eClass_AddMember(regClass, dataMember);
140 else if(spec.definitions && spec.id)
142 //if(isMember || !eClass_FindDataMember(regClass, spec.id.string))
144 Identifier id = spec.id;
145 char typeString[1024] = "";
148 decl.declarators = MkListOne(MkDeclaratorIdentifier(id));
150 dataType = ProcessType(decl.specifiers, null);
151 PrintType(dataType, typeString, false, true);
155 dataMember = eMember_AddDataMember(member, id.string,
156 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
158 Compiler_Error($"Member with same name already exists %s in member %s\n", id.string, member.name);
162 dataMember = eClass_AddDataMember(regClass, id.string,
163 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
165 Compiler_Error($"Member with same name already exists %s in class %s\n", id.string, regClass.name);
169 // delete dataTypeString;
171 dataMember.dataType = dataType;
180 else if(decl.type == instDeclaration)
182 Instantiation inst = decl.inst;
183 Expression exp = inst.exp;
186 // Add data member to the class
187 char * string = exp.identifier.string;
188 //if(isMember || !eClass_FindDataMember(regClass, string))
193 _class = inst._class.symbol; // FindClass(inst._class.name);
198 dataMember = eMember_AddDataMember(member, string, inst._class.name, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
200 Compiler_Error($"Member with same name already exists %s in member %s\n", string, member.name);
205 dataMember = eClass_AddDataMember(regClass, string, inst._class.name, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
207 Compiler_Error($"Member with same name already exists %s in class %s\n", string, regClass.name);
210 dataMember.dataType = dataType;
217 // TODO: Decide whether property ID should go after member ID, if so this should move back to ProcessClass
218 else if(def.type == propertyClassDef && def.propertyDef)
220 PropertyDef propertyDef = def.propertyDef;
223 // Register the property in the list
224 // MOVED THIS UP HERE BEFORE NEXT BLOCK BECAUSE WE NULL OUT SPECIFIERS/DECLARATORS... OK?
226 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
227 prop = eClass_AddProperty(regClass, propertyDef.conversion ? null : propertyDef.id.string,
229 inCompiler ? propertyDef.setStmt : null, inCompiler ? propertyDef.getStmt : null, def.memberAccess);
230 delete dataTypeString;
233 if(inCompiler) prop.IsSet = (void *)propertyDef.issetStmt;
235 prop.compiled = false;
237 // prop.symbol = propertyDef.symbol;
240 string = CopyString(propertyDef.symbol.string);
241 id = propertyDef.symbol.id;
242 type = propertyDef.symbol.type;
245 /*if(propertyDef.category)
248 ReadString(temp, propertyDef.category);
249 prop.category = CopyString(temp); // LEAK: To free in parsed classes...
251 // TODO: Support property category in parsing mode
252 ((Symbol)prop.symbol).propCategory = propertyDef.category;
253 propertyDef.category = null;
255 if(propertyDef.isWatchable)
256 eProperty_Watchable(prop);
259 // TODO: What happens here?
263 // Testing this... wasn't found anywhere, seems to be useful
264 // (Determining if it's a conversion property in ProcessClassFunction)
265 propertyDef.symbol._property = prop;
267 if(propertyDef.symbol.type)
268 propertyDef.symbol.type.refCount++;
270 else if(def.type == classPropertyClassDef && def.propertyDef)
272 PropertyDef propertyDef = def.propertyDef;
275 // Register the property in the list
276 // MOVED THIS UP HERE BEFORE NEXT BLOCK BECAUSE WE NULL OUT SPECIFIERS/DECLARATORS... OK?
278 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
279 prop = eClass_AddClassProperty(regClass, propertyDef.id.string, dataTypeString,
280 inCompiler ? propertyDef.setStmt : null, inCompiler ? propertyDef.getStmt : null);
282 delete dataTypeString;
288 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, Location loc, OldList defs, void * after, OldList initDeclarators, AccessMode declMode)
292 bool redefinition = false;
294 regClass = eSystem_FindClass(privateModule /*__thisModule*/, symbol.string);
295 if(regClass && !regClass.internalDecl)
297 if(symbol.parent || (Symbol)globalContext.classes.root == symbol)
299 globalContext.classes.Remove((BTNode)symbol);
300 excludedSymbols->Add(symbol);
306 Compiler_Error($"redefinition of class %s\n", symbol.string /*_class._class.name*/);
312 char baseName[1024] = "";
313 bool unitType = false;
314 bool wouldBeEnum = false;
315 AccessMode inheritanceAccess = publicAccess;
317 if(baseSpecs != null)
319 Type baseType = ProcessType(baseSpecs, null);
320 PrintType(baseType, baseName, false, true);
321 if(baseType.kind == TypeKind::classType)
323 if(baseType._class.registered && classType == normalClass)
325 if(baseType._class.registered.type == unitClass)
326 classType = unitClass;
327 else if(baseType._class.registered.type == bitClass)
328 classType = bitClass;
329 else if(baseType._class.registered.type == noHeadClass)
330 classType = noHeadClass;
331 else if(baseType._class.registered.type == enumClass)
334 //classType = enumClass;
338 else if(baseType.kind == structType || baseType.kind == unionType)
340 classType = noHeadClass;
347 if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
348 inheritanceAccess = privateAccess;
351 // If there's any struct declaration in a unit data type, it means this is a bit class
352 if(classType == normalClass)
354 if(unitType) classType = unitClass;
355 if(definitions != null)
357 for(def = definitions.first; def; def = def.next)
359 if(def.type == declarationClassDef)
361 Declaration decl = def.decl;
362 if(decl.type == structDeclaration)
366 classType = bitClass;
373 for(d = decl.declarators->first; d; d = d.next)
377 classType = bitClass;
388 if(classType == normalClass && wouldBeEnum) classType = enumClass;
390 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType,
391 symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, buildingECERECOMModule ? baseSystemAccess : declMode /*publicAccess*/, inheritanceAccess);
393 // HI DANGER: TESTING THIS
395 regClass.symbol = symbol;
398 // First check if there's any declaration or instantiations, we'll need a struct
401 if(classType == unionClass)
403 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
404 AddDefinitions(regClass, unionMember, definitions);
405 eClass_AddMember(regClass, unionMember);
408 AddDefinitions(regClass, null, definitions);
412 if(definitions != null)
414 for(def = definitions.first; def; def = def.next)
416 if(def.type == functionClassDef && def.function.declarator)
418 ClassFunction func = def.function;
420 func._class = regClass;
421 // Add ecereMethod_[class]_ to the declarator
422 if(!redefinition && !func.dontMangle)
424 Declarator funcDecl = GetFuncDecl(func.declarator);
425 Identifier id = GetDeclId(funcDecl);
430 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
431 method = eClass_AddVirtualMethod(regClass, id.string, typeString, inCompiler ? func.declarator.symbol : null, def.memberAccess);
436 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
437 method = eClass_AddMethod(regClass, id.string, typeString,
438 inCompiler ? func.declarator.symbol : null, def.memberAccess);
440 Compiler_Error($"Redefinition of method %s in class %s\n", id.string, regClass.name);
443 if(method && (method.type != virtualMethod || method._class == regClass))
445 //method.symbol = func.declarator.symbol;
447 // Make a copy here...
448 method.symbol = Symbol
450 string = CopyString(func.declarator.symbol.string);
451 id = func.declarator.symbol.id;
452 type = func.declarator.symbol.type;
455 if(func.declarator.symbol.type)
456 func.declarator.symbol.type.refCount++;
458 func.declarator.symbol.method = method;
463 method.symbol = Symbol
465 string = CopyString(func.declarator.symbol.string);
466 id = func.declarator.symbol.id;
467 type = func.declarator.symbol.type;
470 if(func.declarator.symbol.type)
471 func.declarator.symbol.type.refCount++;
473 func.declarator.symbol.method = method;
479 if(regClass && symbol.templateParams)
481 TemplateParameter param;
482 // Add template parameters here
483 for(param = symbol.templateParams->first; param; param = param.next)
485 ClassTemplateArgument defaultArg { };
486 if(param.defaultArgument)
491 defaultArg.dataTypeString =
492 StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
496 char memberString[1024];
497 memberString[0] = '\0';
499 if(param.defaultArgument.identifier._class)
501 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
503 if(param.defaultArgument.identifier._class.templateParameter)
504 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
508 if(param.defaultArgument.identifier._class.name)
509 strcpy(memberString, param.defaultArgument.identifier._class.name);
515 strcat(memberString, "::");
517 strcat(memberString, param.defaultArgument.identifier.string);
518 defaultArg.memberString = CopyString(memberString);
524 param.defaultArgument.expression.destType = ProcessType(param.dataType.specifiers, param.dataType.decl);
525 ProcessExpressionType(param.defaultArgument.expression);
526 ComputeExpression(param.defaultArgument.expression);
527 op = GetOperand(param.defaultArgument.expression);
528 defaultArg.expression.ui64 = op.ui64;
533 if(param.type == identifier)
535 eClass_AddTemplateParameter(regClass, param.identifier.string, identifier, (void *)param.memberType, defaultArg);
539 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
540 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
543 if(param.type == type || param.type == identifier)
544 delete defaultArg.dataTypeString;
547 eClass_DoneAddingTemplateParameters(regClass);
551 extern External curExternal;
553 public void PrePreProcessClassDefinitions()
555 External external, next;
561 for(external = ast->first; external; external = next)
563 next = external.next;
564 curExternal = external;
565 if(external.type == classExternal)
567 ClassDefinition _class = external._class;
568 if(_class.definitions && (!_class.symbol.registered || !inCompiler))
570 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, _class.declMode);
571 _class.symbol.isStatic = _class.declMode == staticAccess;
574 else if(external.type == declarationExternal)
576 Declaration declaration = external.declaration;
577 if(declaration.type == initDeclaration)
579 if(declaration.specifiers)
582 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
584 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
585 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
587 Symbol type = FindType(globalContext, specifier.id.string);
588 Symbol symbol = FindClass(specifier.id.string);
591 declaration.declMode = defaultAccess;
594 globalContext.classes.Remove((BTNode)symbol);
595 excludedSymbols->Add(symbol);
598 else if(symbol && !symbol.registered)
602 if(specifier.type == enumSpecifier)
603 classType = enumClass;
604 else if(specifier.type == unionSpecifier)
605 classType = unionClass;
607 classType = structClass;
608 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev, declaration.declarators, declaration.declMode);
609 symbol.isStatic = declaration.declMode == staticAccess;
616 else if(external.type == importExternal)
618 //ImportModule(external._import);
623 // Update templated classes
625 for(external = ast->first; external; external = external.next)
627 if(external.type == classExternal)
629 ClassDefinition _class = external._class;
633 for(link = _class.symbol.templatedClasses.first; link; link = link.next)
635 Symbol symbol = link.data;
636 symbol.registered = eSystem_FindClass(privateModule, symbol.string);
640 else if(external.type == declarationExternal)
642 Declaration declaration = external.declaration;
643 if(declaration.type == initDeclaration)
645 if(declaration.specifiers)
648 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
650 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
651 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
653 Symbol type = FindType(globalContext, specifier.id.string);
654 Symbol symbol = FindClass(specifier.id.string);
661 for(link = symbol.templatedClasses.first; link; link = link.next)
663 Symbol tplSymbol = link.data;
664 tplSymbol.registered = eSystem_FindClass(privateModule, tplSymbol.string);
665 tplSymbol.module = symbol.module ? symbol.module : mainModule;