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 = null;
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.type == structDeclarator) ? d.structDecl.exp : null;
33 Expression posExp = (d.type == structDeclarator) ? d.structDecl.posExp : null;
34 int bitSize = 0, bitPos = -1;
35 char dataTypeString[1024] = "";
39 // Should this be processed/computed later?
40 ProcessExpressionType(sizeExp);
41 ComputeExpression(sizeExp);
43 if(sizeExp.isConstant)
44 bitSize = strtol(sizeExp.constant, null, 0);
45 FreeExpression(sizeExp);
50 // Should this be processed/computed later?
51 ProcessExpressionType(posExp);
52 ComputeExpression(posExp);
55 bitPos = strtol(posExp.constant, null, 0);
56 FreeExpression(posExp);
59 if(d.type == structDeclarator)
61 d.structDecl.posExp = null;
62 d.structDecl.exp = null;
65 dataType = ProcessType(decl.specifiers, d);
66 PrintType(dataType, dataTypeString, false, true);
68 //if(!eClass_FindDataMember(regClass, declId.string))
70 BitMember member = eClass_AddBitMember(regClass, declId.string, dataTypeString, 0, 0, def.memberAccess);
73 member.size = bitSize;
76 dataMember = (DataMember)member;
80 dataMember.dataType = dataType;
83 Compiler_Error($"Member with same name already exists %s in class %s\n", declId.string, regClass.name);
89 //if(isMember || !eClass_FindDataMember(regClass, declId.string))
91 //char * dataTypeString = StringFromSpecDecl(decl.specifiers, d);
92 char typeString[1024] = "";
93 dataType = ProcessType(decl.specifiers, d);
94 PrintType(dataType, typeString, false, true);
98 dataMember = eMember_AddDataMember(member, declId.string,
99 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
101 Compiler_Error($"Member with same name already exists %s in member %s\n", declId.string, member.name);
105 dataMember = eClass_AddDataMember(regClass, declId.string,
106 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
108 Compiler_Error($"Member with same name already exists %s in class %s\n", declId.string, regClass.name);
111 //delete dataTypeString;
113 dataMember.dataType = dataType;
121 else if(decl.specifiers)
124 // Unnamed struct/union
125 for(spec = decl.specifiers->first; spec; spec = spec.next)
127 if(spec.type == structSpecifier || spec.type == unionSpecifier)
129 if(spec.definitions && !spec.id)
131 DataMember dataMember = eMember_New((spec.type == unionSpecifier) ? unionMember : structMember, def.memberAccess);
133 AddDefinitions(null, dataMember, spec.definitions);
137 eMember_AddMember(member, dataMember);
141 eClass_AddMember(regClass, dataMember);
144 else if(spec.definitions && spec.id)
146 //if(isMember || !eClass_FindDataMember(regClass, spec.id.string))
148 Identifier id = spec.id;
149 char typeString[1024] = "";
152 decl.declarators = MkListOne(MkDeclaratorIdentifier(id));
154 dataType = ProcessType(decl.specifiers, null);
155 PrintType(dataType, typeString, false, true);
159 dataMember = eMember_AddDataMember(member, id.string,
160 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
162 Compiler_Error($"Member with same name already exists %s in member %s\n", id.string, member.name);
166 dataMember = eClass_AddDataMember(regClass, id.string,
167 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
169 Compiler_Error($"Member with same name already exists %s in class %s\n", id.string, regClass.name);
173 // delete dataTypeString;
175 dataMember.dataType = dataType;
184 else if(decl.type == instDeclaration)
186 Instantiation inst = decl.inst;
187 Expression exp = inst.exp;
190 // Add data member to the class
191 char * string = exp.identifier.string;
192 //if(isMember || !eClass_FindDataMember(regClass, string))
197 _class = inst._class.symbol; // FindClass(inst._class.name);
202 dataMember = eMember_AddDataMember(member, string, inst._class.name, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
204 Compiler_Error($"Member with same name already exists %s in member %s\n", string, member.name);
209 dataMember = eClass_AddDataMember(regClass, string, inst._class.name, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
211 Compiler_Error($"Member with same name already exists %s in class %s\n", string, regClass.name);
214 dataMember.dataType = dataType;
221 // TODO: Decide whether property ID should go after member ID, if so this should move back to ProcessClass
222 else if(def.type == propertyClassDef && def.propertyDef)
224 PropertyDef propertyDef = def.propertyDef;
227 // Register the property in the list
228 // MOVED THIS UP HERE BEFORE NEXT BLOCK BECAUSE WE NULL OUT SPECIFIERS/DECLARATORS... OK?
230 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
231 prop = eClass_AddProperty(regClass, propertyDef.conversion ? null : propertyDef.id.string,
233 inCompiler ? propertyDef.setStmt : null, inCompiler ? propertyDef.getStmt : null, def.memberAccess);
234 delete dataTypeString;
237 if(inCompiler) prop.IsSet = (void *)propertyDef.issetStmt;
239 prop.compiled = false;
241 // prop.symbol = propertyDef.symbol;
244 string = CopyString(propertyDef.symbol.string);
245 id = propertyDef.symbol.id;
246 type = propertyDef.symbol.type;
249 /*if(propertyDef.category)
252 ReadString(temp, propertyDef.category);
253 prop.category = CopyString(temp); // LEAK: To free in parsed classes...
255 // TODO: Support property category in parsing mode
256 ((Symbol)prop.symbol).propCategory = propertyDef.category;
257 propertyDef.category = null;
259 if(propertyDef.isWatchable)
260 eProperty_Watchable(prop);
263 // TODO: What happens here?
267 // Testing this... wasn't found anywhere, seems to be useful
268 // (Determining if it's a conversion property in ProcessClassFunction)
269 propertyDef.symbol._property = prop;
271 if(propertyDef.symbol.type)
272 propertyDef.symbol.type.refCount++;
274 else if(def.type == classPropertyClassDef && def.propertyDef)
276 PropertyDef propertyDef = def.propertyDef;
279 // Register the property in the list
280 // MOVED THIS UP HERE BEFORE NEXT BLOCK BECAUSE WE NULL OUT SPECIFIERS/DECLARATORS... OK?
282 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
283 prop = eClass_AddClassProperty(regClass, propertyDef.id.string, dataTypeString,
284 inCompiler ? propertyDef.setStmt : null, inCompiler ? propertyDef.getStmt : null);
286 delete dataTypeString;
292 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, Location loc, OldList defs, void * after, OldList initDeclarators, AccessMode declMode)
296 bool redefinition = false;
298 regClass = eSystem_FindClass(privateModule /*__thisModule*/, symbol.string);
299 if(regClass && !regClass.internalDecl)
301 if(symbol.parent || (Symbol)globalContext.classes.root == symbol)
303 globalContext.classes.Remove((BTNode)symbol);
304 excludedSymbols->Add(symbol);
310 Compiler_Error($"redefinition of class %s\n", symbol.string /*_class._class.name*/);
316 char baseName[1024] = "";
317 bool unitType = false;
318 bool wouldBeEnum = false;
319 AccessMode inheritanceAccess = publicAccess;
321 if(baseSpecs != null)
323 Type baseType = ProcessType(baseSpecs, null);
324 PrintType(baseType, baseName, false, true);
325 if(baseType.kind == TypeKind::classType)
327 if(baseType._class.registered && classType == normalClass)
329 if(baseType._class.registered.type == unitClass)
330 classType = unitClass;
331 else if(baseType._class.registered.type == bitClass)
332 classType = bitClass;
333 else if(baseType._class.registered.type == noHeadClass)
334 classType = noHeadClass;
335 else if(baseType._class.registered.type == enumClass)
338 //classType = enumClass;
342 else if(baseType.kind == structType || baseType.kind == unionType)
344 classType = noHeadClass;
351 if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
352 inheritanceAccess = privateAccess;
355 // If there's any struct declaration in a unit data type, it means this is a bit class
356 if(classType == normalClass)
358 if(unitType) classType = unitClass;
359 if(definitions != null)
361 for(def = definitions.first; def; def = def.next)
363 if(def.type == declarationClassDef)
365 Declaration decl = def.decl;
366 if(decl.type == structDeclaration)
370 classType = bitClass;
377 for(d = decl.declarators->first; d; d = d.next)
379 if(d.type != structDeclarator)
380 continue; // This should always be a structDeclarator (There's a bug somewhere else if it's not)
383 classType = bitClass;
394 if(classType == normalClass && wouldBeEnum) classType = enumClass;
396 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType,
397 symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, buildingECERECOMModule ? baseSystemAccess : declMode /*publicAccess*/, inheritanceAccess);
399 // HI DANGER: TESTING THIS
401 regClass.symbol = symbol;
404 // First check if there's any declaration or instantiations, we'll need a struct
407 if(classType == unionClass)
409 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
410 AddDefinitions(regClass, unionMember, definitions);
411 eClass_AddMember(regClass, unionMember);
414 AddDefinitions(regClass, null, definitions);
418 if(definitions != null)
420 for(def = definitions.first; def; def = def.next)
422 if(def.type == functionClassDef && def.function.declarator)
424 ClassFunction func = def.function;
426 func._class = regClass;
427 // Add ecereMethod_[class]_ to the declarator
428 if(!redefinition && !func.dontMangle)
430 Declarator funcDecl = GetFuncDecl(func.declarator);
431 Identifier id = GetDeclId(funcDecl);
436 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
437 method = eClass_AddVirtualMethod(regClass, id.string, typeString, inCompiler ? func.declarator.symbol : null, def.memberAccess);
442 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
443 method = eClass_AddMethod(regClass, id.string, typeString,
444 inCompiler ? func.declarator.symbol : null, def.memberAccess);
446 Compiler_Error($"Redefinition of method %s in class %s\n", id.string, regClass.name);
449 if(method && (method.type != virtualMethod || method._class == regClass))
451 //method.symbol = func.declarator.symbol;
453 // Make a copy here...
454 method.symbol = Symbol
456 string = CopyString(func.declarator.symbol.string);
457 id = func.declarator.symbol.id;
458 type = func.declarator.symbol.type;
461 if(func.declarator.symbol.type)
462 func.declarator.symbol.type.refCount++;
464 func.declarator.symbol.method = method;
469 method.symbol = Symbol
471 string = CopyString(func.declarator.symbol.string);
472 id = func.declarator.symbol.id;
473 type = func.declarator.symbol.type;
476 if(func.declarator.symbol.type)
477 func.declarator.symbol.type.refCount++;
479 func.declarator.symbol.method = method;
485 if(regClass && symbol.templateParams)
487 TemplateParameter param;
488 // Add template parameters here
489 for(param = symbol.templateParams->first; param; param = param.next)
491 ClassTemplateArgument defaultArg { };
492 if(param.defaultArgument)
497 defaultArg.dataTypeString =
498 StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
502 char memberString[1024];
503 memberString[0] = '\0';
505 if(param.defaultArgument.identifier._class)
507 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
509 if(param.defaultArgument.identifier._class.templateParameter)
510 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
514 if(param.defaultArgument.identifier._class.name)
515 strcpy(memberString, param.defaultArgument.identifier._class.name);
521 strcat(memberString, "::");
523 strcat(memberString, param.defaultArgument.identifier.string);
524 defaultArg.memberString = CopyString(memberString);
530 param.defaultArgument.expression.destType = ProcessType(param.dataType.specifiers, param.dataType.decl);
531 ProcessExpressionType(param.defaultArgument.expression);
532 ComputeExpression(param.defaultArgument.expression);
533 op = GetOperand(param.defaultArgument.expression);
534 defaultArg.expression.ui64 = op.ui64;
539 if(param.type == identifier)
541 eClass_AddTemplateParameter(regClass, param.identifier.string, identifier, (void *)param.memberType, defaultArg);
545 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
546 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
549 if(param.type == type || param.type == identifier)
550 delete defaultArg.dataTypeString;
553 eClass_DoneAddingTemplateParameters(regClass);
557 extern External curExternal;
559 public void PrePreProcessClassDefinitions()
561 External external, next;
567 for(external = ast->first; external; external = next)
569 next = external.next;
570 curExternal = external;
571 if(external.type == classExternal)
573 ClassDefinition _class = external._class;
574 if(_class.definitions && (!_class.symbol.registered || !inCompiler))
576 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, _class.declMode);
577 _class.symbol.isStatic = _class.declMode == staticAccess;
580 else if(external.type == declarationExternal)
582 Declaration declaration = external.declaration;
583 if(declaration.type == initDeclaration)
585 if(declaration.specifiers)
588 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
590 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
591 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
593 Symbol type = FindType(globalContext, specifier.id.string);
594 Symbol symbol = FindClass(specifier.id.string);
597 declaration.declMode = defaultAccess;
600 globalContext.classes.Remove((BTNode)symbol);
601 excludedSymbols->Add(symbol);
604 else if(symbol && !symbol.registered)
608 if(specifier.type == enumSpecifier)
609 classType = enumClass;
610 else if(specifier.type == unionSpecifier)
611 classType = unionClass;
613 classType = structClass;
614 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev, declaration.declarators, declaration.declMode);
615 symbol.isStatic = declaration.declMode == staticAccess;
622 else if(external.type == importExternal)
624 //ImportModule(external._import);
629 // Update templated classes
631 for(external = ast->first; external; external = external.next)
633 if(external.type == classExternal)
635 ClassDefinition _class = external._class;
639 for(link = _class.symbol.templatedClasses.first; link; link = link.next)
641 Symbol symbol = link.data;
642 symbol.registered = eSystem_FindClass(privateModule, symbol.string);
646 else if(external.type == declarationExternal)
648 Declaration declaration = external.declaration;
649 if(declaration.type == initDeclaration)
651 if(declaration.specifiers)
654 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
656 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
657 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
659 Symbol type = FindType(globalContext, specifier.id.string);
660 Symbol symbol = FindClass(specifier.id.string);
667 for(link = symbol.templatedClasses.first; link; link = link.next)
669 Symbol tplSymbol = link.data;
670 tplSymbol.registered = eSystem_FindClass(privateModule, tplSymbol.string);
671 tplSymbol.module = symbol.module ? symbol.module : mainModule;