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)
381 classType = bitClass;
392 if(classType == normalClass && wouldBeEnum) classType = enumClass;
394 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType,
395 symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, buildingECERECOMModule ? baseSystemAccess : declMode /*publicAccess*/, inheritanceAccess);
397 // HI DANGER: TESTING THIS
399 regClass.symbol = symbol;
402 // First check if there's any declaration or instantiations, we'll need a struct
405 if(classType == unionClass)
407 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
408 AddDefinitions(regClass, unionMember, definitions);
409 eClass_AddMember(regClass, unionMember);
412 AddDefinitions(regClass, null, definitions);
416 if(definitions != null)
418 for(def = definitions.first; def; def = def.next)
420 if(def.type == functionClassDef && def.function.declarator)
422 ClassFunction func = def.function;
424 func._class = regClass;
425 // Add ecereMethod_[class]_ to the declarator
426 if(!redefinition && !func.dontMangle)
428 Declarator funcDecl = GetFuncDecl(func.declarator);
429 Identifier id = GetDeclId(funcDecl);
434 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
435 method = eClass_AddVirtualMethod(regClass, id.string, typeString, inCompiler ? func.declarator.symbol : null, def.memberAccess);
440 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
441 method = eClass_AddMethod(regClass, id.string, typeString,
442 inCompiler ? func.declarator.symbol : null, def.memberAccess);
444 Compiler_Error($"Redefinition of method %s in class %s\n", id.string, regClass.name);
447 if(method && (method.type != virtualMethod || method._class == regClass))
449 //method.symbol = func.declarator.symbol;
451 // Make a copy here...
452 method.symbol = Symbol
454 string = CopyString(func.declarator.symbol.string);
455 id = func.declarator.symbol.id;
456 type = func.declarator.symbol.type;
459 if(func.declarator.symbol.type)
460 func.declarator.symbol.type.refCount++;
462 func.declarator.symbol.method = method;
467 method.symbol = Symbol
469 string = CopyString(func.declarator.symbol.string);
470 id = func.declarator.symbol.id;
471 type = func.declarator.symbol.type;
474 if(func.declarator.symbol.type)
475 func.declarator.symbol.type.refCount++;
477 func.declarator.symbol.method = method;
483 if(regClass && symbol.templateParams)
485 TemplateParameter param;
486 // Add template parameters here
487 for(param = symbol.templateParams->first; param; param = param.next)
489 ClassTemplateArgument defaultArg { };
490 if(param.defaultArgument)
495 defaultArg.dataTypeString =
496 StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
500 char memberString[1024];
501 memberString[0] = '\0';
503 if(param.defaultArgument.identifier._class)
505 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
507 if(param.defaultArgument.identifier._class.templateParameter)
508 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
512 if(param.defaultArgument.identifier._class.name)
513 strcpy(memberString, param.defaultArgument.identifier._class.name);
519 strcat(memberString, "::");
521 strcat(memberString, param.defaultArgument.identifier.string);
522 defaultArg.memberString = CopyString(memberString);
528 param.defaultArgument.expression.destType = ProcessType(param.dataType.specifiers, param.dataType.decl);
529 ProcessExpressionType(param.defaultArgument.expression);
530 ComputeExpression(param.defaultArgument.expression);
531 op = GetOperand(param.defaultArgument.expression);
532 defaultArg.expression.ui64 = op.ui64;
537 if(param.type == identifier)
539 eClass_AddTemplateParameter(regClass, param.identifier.string, identifier, (void *)param.memberType, defaultArg);
543 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
544 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
547 if(param.type == type || param.type == identifier)
548 delete defaultArg.dataTypeString;
551 eClass_DoneAddingTemplateParameters(regClass);
555 extern External curExternal;
557 public void PrePreProcessClassDefinitions()
559 External external, next;
565 for(external = ast->first; external; external = next)
567 next = external.next;
568 curExternal = external;
569 if(external.type == classExternal)
571 ClassDefinition _class = external._class;
572 if(_class.definitions && (!_class.symbol.registered || !inCompiler))
574 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, _class.declMode);
575 _class.symbol.isStatic = _class.declMode == staticAccess;
578 else if(external.type == declarationExternal)
580 Declaration declaration = external.declaration;
581 if(declaration.type == initDeclaration)
583 if(declaration.specifiers)
586 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
588 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
589 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
591 Symbol type = FindType(globalContext, specifier.id.string);
592 Symbol symbol = FindClass(specifier.id.string);
595 declaration.declMode = defaultAccess;
598 globalContext.classes.Remove((BTNode)symbol);
599 excludedSymbols->Add(symbol);
602 else if(symbol && !symbol.registered)
606 if(specifier.type == enumSpecifier)
607 classType = enumClass;
608 else if(specifier.type == unionSpecifier)
609 classType = unionClass;
611 classType = structClass;
612 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev, declaration.declarators, declaration.declMode);
613 symbol.isStatic = declaration.declMode == staticAccess;
620 else if(external.type == importExternal)
622 //ImportModule(external._import);
627 // Update templated classes
629 for(external = ast->first; external; external = external.next)
631 if(external.type == classExternal)
633 ClassDefinition _class = external._class;
637 for(link = _class.symbol.templatedClasses.first; link; link = link.next)
639 Symbol symbol = link.data;
640 symbol.registered = eSystem_FindClass(privateModule, symbol.string);
644 else if(external.type == declarationExternal)
646 Declaration declaration = external.declaration;
647 if(declaration.type == initDeclaration)
649 if(declaration.specifiers)
652 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
654 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
655 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
657 Symbol type = FindType(globalContext, specifier.id.string);
658 Symbol symbol = FindClass(specifier.id.string);
665 for(link = symbol.templatedClasses.first; link; link = link.next)
667 Symbol tplSymbol = link.data;
668 tplSymbol.registered = eSystem_FindClass(privateModule, tplSymbol.string);
669 tplSymbol.module = symbol.module ? symbol.module : mainModule;