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] = "";
36 char dataTypeString[8192];
37 dataTypeString[0] = 0;
41 // Should this be processed/computed later?
42 ProcessExpressionType(sizeExp);
43 ComputeExpression(sizeExp);
45 if(sizeExp.isConstant)
46 bitSize = strtol(sizeExp.constant, null, 0);
47 FreeExpression(sizeExp);
52 // Should this be processed/computed later?
53 ProcessExpressionType(posExp);
54 ComputeExpression(posExp);
57 bitPos = strtol(posExp.constant, null, 0);
58 FreeExpression(posExp);
61 if(d.type == structDeclarator)
63 d.structDecl.posExp = null;
64 d.structDecl.exp = null;
67 dataType = ProcessType(decl.specifiers, d);
68 PrintType(dataType, dataTypeString, false, true);
70 //if(!eClass_FindDataMember(regClass, declId.string))
72 BitMember member = eClass_AddBitMember(regClass, declId.string, dataTypeString, 0, 0, def.memberAccess);
75 member.size = bitSize;
78 dataMember = (DataMember)member;
82 dataMember.dataType = dataType;
85 Compiler_Error($"Member with same name already exists %s in class %s\n", declId.string, regClass.name);
91 //if(isMember || !eClass_FindDataMember(regClass, declId.string))
93 //char * dataTypeString = StringFromSpecDecl(decl.specifiers, d);
94 //char typeString[1024] = "";
95 char typeString[8192];
97 dataType = ProcessType(decl.specifiers, d);
98 PrintType(dataType, typeString, false, true);
102 dataMember = eMember_AddDataMember(member, declId.string,
103 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
105 Compiler_Error($"Member with same name already exists %s in member %s\n", declId.string, member.name);
109 dataMember = eClass_AddDataMember(regClass, declId.string,
110 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
112 Compiler_Error($"Member with same name already exists %s in class %s\n", declId.string, regClass.name);
115 //delete dataTypeString;
117 dataMember.dataType = dataType;
125 else if(decl.specifiers)
128 // Unnamed struct/union
129 for(spec = decl.specifiers->first; spec; spec = spec.next)
131 if(spec.type == structSpecifier || spec.type == unionSpecifier)
133 if(spec.definitions && !spec.id)
135 DataMember dataMember = eMember_New((spec.type == unionSpecifier) ? unionMember : structMember, def.memberAccess);
137 AddDefinitions(null, dataMember, spec.definitions);
141 eMember_AddMember(member, dataMember);
145 eClass_AddMember(regClass, dataMember);
148 else if(spec.definitions && spec.id)
150 //if(isMember || !eClass_FindDataMember(regClass, spec.id.string))
152 Identifier id = spec.id;
153 // char typeString[1024] = "";
154 char typeString[8192];
158 decl.declarators = MkListOne(MkDeclaratorIdentifier(id));
160 dataType = ProcessType(decl.specifiers, null);
161 PrintType(dataType, typeString, false, true);
165 dataMember = eMember_AddDataMember(member, id.string,
166 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
168 Compiler_Error($"Member with same name already exists %s in member %s\n", id.string, member.name);
172 dataMember = eClass_AddDataMember(regClass, id.string,
173 typeString, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
175 Compiler_Error($"Member with same name already exists %s in class %s\n", id.string, regClass.name);
179 // delete dataTypeString;
181 dataMember.dataType = dataType;
190 else if(decl.type == instDeclaration)
192 Instantiation inst = decl.inst;
193 Expression exp = inst.exp;
196 // Add data member to the class
197 char * string = exp.identifier.string;
198 //if(isMember || !eClass_FindDataMember(regClass, string))
203 _class = inst._class.symbol; // FindClass(inst._class.name);
208 dataMember = eMember_AddDataMember(member, string, inst._class.name, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
210 Compiler_Error($"Member with same name already exists %s in member %s\n", string, member.name);
215 dataMember = eClass_AddDataMember(regClass, string, inst._class.name, 0, 0 /*ComputeTypeSize(dataType)*/, def.memberAccess);
217 Compiler_Error($"Member with same name already exists %s in class %s\n", string, regClass.name);
220 dataMember.dataType = dataType;
227 // TODO: Decide whether property ID should go after member ID, if so this should move back to ProcessClass
228 else if(def.type == propertyClassDef && def.propertyDef)
230 PropertyDef propertyDef = def.propertyDef;
233 // Register the property in the list
234 // MOVED THIS UP HERE BEFORE NEXT BLOCK BECAUSE WE NULL OUT SPECIFIERS/DECLARATORS... OK?
236 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
237 prop = eClass_AddProperty(regClass, propertyDef.conversion ? null : propertyDef.id.string,
239 inCompiler ? propertyDef.setStmt : null, inCompiler ? propertyDef.getStmt : null, def.memberAccess);
240 delete dataTypeString;
243 if(inCompiler) prop.IsSet = (void *)propertyDef.issetStmt;
245 prop.compiled = false;
247 // prop.symbol = propertyDef.symbol;
250 string = CopyString(propertyDef.symbol.string);
251 id = propertyDef.symbol.id;
252 type = propertyDef.symbol.type;
255 /*if(propertyDef.category)
258 ReadString(temp, propertyDef.category);
259 prop.category = CopyString(temp); // LEAK: To free in parsed classes...
261 // TODO: Support property category in parsing mode
262 ((Symbol)prop.symbol).propCategory = propertyDef.category;
263 propertyDef.category = null;
265 if(propertyDef.isWatchable)
266 eProperty_Watchable(prop);
269 // TODO: What happens here?
273 // Testing this... wasn't found anywhere, seems to be useful
274 // (Determining if it's a conversion property in ProcessClassFunction)
275 propertyDef.symbol._property = prop;
277 if(propertyDef.symbol.type)
278 propertyDef.symbol.type.refCount++;
280 else if(def.type == classPropertyClassDef && def.propertyDef)
282 PropertyDef propertyDef = def.propertyDef;
285 // Register the property in the list
286 // MOVED THIS UP HERE BEFORE NEXT BLOCK BECAUSE WE NULL OUT SPECIFIERS/DECLARATORS... OK?
288 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
289 prop = eClass_AddClassProperty(regClass, propertyDef.id.string, dataTypeString,
290 inCompiler ? propertyDef.setStmt : null, inCompiler ? propertyDef.getStmt : null);
292 delete dataTypeString;
298 static void ProcessClass(ClassType classType, OldList definitions, Symbol symbol, OldList baseSpecs, OldList enumValues, Location loc, OldList defs, void * after, OldList initDeclarators, AccessMode declMode)
302 bool redefinition = false;
304 regClass = eSystem_FindClass(privateModule /*__thisModule*/, symbol.string);
305 if(regClass && !regClass.internalDecl)
307 if(symbol.parent || (Symbol)globalContext.classes.root == symbol)
309 globalContext.classes.Remove((BTNode)symbol);
310 excludedSymbols->Add(symbol);
316 Compiler_Error($"redefinition of class %s\n", symbol.string /*_class._class.name*/);
322 char baseName[1024] = "";
323 bool unitType = false;
324 bool wouldBeEnum = false;
325 AccessMode inheritanceAccess = publicAccess;
327 if(baseSpecs != null)
329 Type baseType = ProcessType(baseSpecs, null);
330 PrintType(baseType, baseName, false, true);
331 if(baseType.kind == TypeKind::classType)
333 if(baseType._class.registered && classType == normalClass)
335 if(baseType._class.registered.type == unitClass)
336 classType = unitClass;
337 else if(baseType._class.registered.type == bitClass)
338 classType = bitClass;
339 else if(baseType._class.registered.type == noHeadClass)
340 classType = noHeadClass;
341 else if(baseType._class.registered.type == enumClass)
344 //classType = enumClass;
348 else if(baseType.kind == structType || baseType.kind == unionType)
350 classType = noHeadClass;
357 if(((Specifier)baseSpecs.first).type == baseSpecifier && ((Specifier)baseSpecs.first).specifier == PRIVATE)
358 inheritanceAccess = privateAccess;
361 // If there's any struct declaration in a unit data type, it means this is a bit class
362 if(classType == normalClass)
364 if(unitType) classType = unitClass;
365 if(definitions != null)
367 for(def = definitions.first; def; def = def.next)
369 if(def.type == declarationClassDef)
371 Declaration decl = def.decl;
372 if(decl.type == structDeclaration)
376 classType = bitClass;
383 for(d = decl.declarators->first; d; d = d.next)
385 if(d.type != structDeclarator)
386 continue; // This should always be a structDeclarator (There's a bug somewhere else if it's not)
389 classType = bitClass;
400 if(classType == normalClass && wouldBeEnum) classType = enumClass;
402 regClass = symbol.registered = eSystem_RegisterClass((classType == unionClass) ? structClass : classType,
403 symbol.string, baseName[0] ? baseName : null, 0, 0, null, null, privateModule, buildingECERECOMModule ? baseSystemAccess : declMode /*publicAccess*/, inheritanceAccess);
405 // HI DANGER: TESTING THIS
407 regClass.symbol = symbol;
410 // First check if there's any declaration or instantiations, we'll need a struct
413 if(classType == unionClass)
415 DataMember unionMember = eMember_New(DataMemberType::unionMember, publicAccess);
416 AddDefinitions(regClass, unionMember, definitions);
417 eClass_AddMember(regClass, unionMember);
420 AddDefinitions(regClass, null, definitions);
424 if(definitions != null)
426 for(def = definitions.first; def; def = def.next)
428 if(def.type == functionClassDef && (def.function.isConstructor || def.function.isDestructor))
430 Specifier spec = def.function.specifiers ? def.function.specifiers->last : null;
431 if(!spec || spec.type != nameSpecifier || !spec.name ||
432 (strcmp(spec.name, regClass.name) && (!spec.symbol || !spec.symbol.registered || strcmp(spec.symbol.registered.name, regClass.name))) )
434 yylloc = def.function.loc;
435 Compiler_Error($"wrong class name specified for %s\n", def.function.isConstructor ? $"constructor" : $"destructor");
437 FreeList(def.function.specifiers, FreeSpecifier);
438 def.function.specifiers = null;
440 if(def.type == functionClassDef && def.function.declarator)
442 ClassFunction func = def.function;
444 func._class = regClass;
445 // Add ecereMethod_[class]_ to the declarator
446 if(!redefinition && !func.dontMangle)
448 Declarator funcDecl = GetFuncDecl(func.declarator);
449 Identifier id = GetDeclId(funcDecl);
454 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
455 method = eClass_AddVirtualMethod(regClass, id.string, typeString, inCompiler ? func.declarator.symbol : null, def.memberAccess);
460 char * typeString = StringFromSpecDecl(func.specifiers, func.declarator);
461 method = eClass_AddMethod(regClass, id.string, typeString,
462 inCompiler ? func.declarator.symbol : null, def.memberAccess);
464 Compiler_Error($"Redefinition of method %s in class %s\n", id.string, regClass.name);
467 if(method && (method.type != virtualMethod || method._class == regClass))
469 //method.symbol = func.declarator.symbol;
471 // Make a copy here...
472 method.symbol = Symbol
474 string = CopyString(func.declarator.symbol.string);
475 id = func.declarator.symbol.id;
476 type = func.declarator.symbol.type;
479 if(func.declarator.symbol.type)
480 func.declarator.symbol.type.refCount++;
482 func.declarator.symbol.method = method;
487 method.symbol = Symbol
489 string = CopyString(func.declarator.symbol.string);
490 id = func.declarator.symbol.id;
491 type = func.declarator.symbol.type;
494 if(func.declarator.symbol.type)
495 func.declarator.symbol.type.refCount++;
497 func.declarator.symbol.method = method;
503 if(regClass && symbol.templateParams)
505 TemplateParameter param;
506 // Add template parameters here
507 for(param = symbol.templateParams->first; param; param = param.next)
509 ClassTemplateArgument defaultArg { };
510 if(param.defaultArgument)
515 defaultArg.dataTypeString =
516 StringFromSpecDecl(param.defaultArgument.templateDatatype.specifiers, param.defaultArgument.templateDatatype.decl);
520 char memberString[1024];
521 memberString[0] = '\0';
523 if(param.defaultArgument.identifier._class)
525 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
527 if(param.defaultArgument.identifier._class.templateParameter)
528 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
532 if(param.defaultArgument.identifier._class.name)
533 strcpy(memberString, param.defaultArgument.identifier._class.name);
539 strcat(memberString, "::");
541 strcat(memberString, param.defaultArgument.identifier.string);
542 defaultArg.memberString = CopyString(memberString);
548 param.defaultArgument.expression.destType = ProcessType(param.dataType.specifiers, param.dataType.decl);
549 ProcessExpressionType(param.defaultArgument.expression);
550 ComputeExpression(param.defaultArgument.expression);
551 op = GetOperand(param.defaultArgument.expression);
552 defaultArg.expression.ui64 = op.ui64;
557 if(param.type == identifier)
559 eClass_AddTemplateParameter(regClass, param.identifier.string, identifier, (void *)param.memberType, defaultArg);
563 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
564 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
567 if(param.type == type || param.type == identifier)
568 delete defaultArg.dataTypeString;
571 eClass_DoneAddingTemplateParameters(regClass);
575 extern External curExternal;
577 public void PrePreProcessClassDefinitions()
579 External external, next;
585 for(external = ast->first; external; external = next)
587 next = external.next;
588 curExternal = external;
589 if(external.type == classExternal)
591 ClassDefinition _class = external._class;
592 if(_class.definitions && (!_class.symbol.registered || !inCompiler))
594 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, _class.declMode);
595 _class.symbol.isStatic = _class.declMode == staticAccess;
598 else if(external.type == declarationExternal)
600 Declaration declaration = external.declaration;
601 if(declaration.type == initDeclaration)
603 if(declaration.specifiers)
606 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
608 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
609 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
611 Symbol type = FindType(globalContext, specifier.id.string);
612 Symbol symbol = FindClass(specifier.id.string);
615 declaration.declMode = defaultAccess;
618 globalContext.classes.Remove((BTNode)symbol);
619 excludedSymbols->Add(symbol);
622 else if(symbol && !symbol.registered)
626 if(specifier.type == enumSpecifier)
627 classType = enumClass;
628 else if(specifier.type == unionSpecifier)
629 classType = unionClass;
631 classType = structClass;
632 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev, declaration.declarators, declaration.declMode);
633 symbol.isStatic = declaration.declMode == staticAccess;
640 else if(external.type == importExternal)
642 //ImportModule(external._import);
647 // Update templated classes
649 for(external = ast->first; external; external = external.next)
651 if(external.type == classExternal)
653 ClassDefinition _class = external._class;
657 for(link = _class.symbol.templatedClasses.first; link; link = link.next)
659 Symbol symbol = link.data;
660 symbol.registered = eSystem_FindClass(privateModule, symbol.string);
664 else if(external.type == declarationExternal)
666 Declaration declaration = external.declaration;
667 if(declaration.type == initDeclaration)
669 if(declaration.specifiers)
672 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
674 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
675 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
677 Symbol type = FindType(globalContext, specifier.id.string);
678 Symbol symbol = FindClass(specifier.id.string);
685 for(link = symbol.templatedClasses.first; link; link = link.next)
687 Symbol tplSymbol = link.data;
688 tplSymbol.registered = eSystem_FindClass(privateModule, tplSymbol.string);
689 tplSymbol.module = symbol.module ? symbol.module : mainModule;