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...
252 if(propertyDef.isWatchable)
253 eProperty_Watchable(prop);
256 // TODO: What happens here?
260 // Testing this... wasn't found anywhere, seems to be useful
261 // (Determining if it's a conversion property in ProcessClassFunction)
262 propertyDef.symbol._property = prop;
264 if(propertyDef.symbol.type)
265 propertyDef.symbol.type.refCount++;
267 else if(def.type == classPropertyClassDef && def.propertyDef)
269 PropertyDef propertyDef = def.propertyDef;
272 // Register the property in the list
273 // MOVED THIS UP HERE BEFORE NEXT BLOCK BECAUSE WE NULL OUT SPECIFIERS/DECLARATORS... OK?
275 char * dataTypeString = StringFromSpecDecl(propertyDef.specifiers, propertyDef.declarator);
276 prop = eClass_AddClassProperty(regClass, propertyDef.id.string, dataTypeString,
277 inCompiler ? propertyDef.setStmt : null, inCompiler ? propertyDef.getStmt : null);
279 delete dataTypeString;
281 // Testing this... wasn't found anywhere, seems to be useful
282 // (Determining if it's a conversion property in ProcessClassFunction)
283 // propertyDef.symbol.property = prop;
285 if(propertyDef.symbol.type)
286 propertyDef.symbol.type.refCount++;
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 && param.defaultArgument.identifier._class.name)
505 if(param.defaultArgument.identifier._class.type == templateTypeSpecifier)
506 strcpy(memberString, param.defaultArgument.identifier._class.templateParameter.identifier.string);
508 strcpy(memberString, param.defaultArgument.identifier._class.name);
513 strcat(memberString, "::");
515 strcat(memberString, param.defaultArgument.identifier.string);
516 defaultArg.memberString = CopyString(memberString);
522 param.defaultArgument.expression.destType = ProcessType(param.dataType.specifiers, param.dataType.decl);
523 ProcessExpressionType(param.defaultArgument.expression);
524 ComputeExpression(param.defaultArgument.expression);
525 op = GetOperand(param.defaultArgument.expression);
526 defaultArg.expression.ui64 = op.ui64;
531 if(param.type == identifier)
533 eClass_AddTemplateParameter(regClass, param.identifier.string, identifier, (void *)param.memberType, defaultArg);
537 char * typeString = param.dataType ? StringFromSpecDecl(param.dataType.specifiers, param.dataType.decl) : null;
538 eClass_AddTemplateParameter(regClass, param.identifier.string, param.type, typeString, defaultArg);
541 if(param.type == type || param.type == identifier)
542 delete defaultArg.dataTypeString;
545 eClass_DoneAddingTemplateParameters(regClass);
549 extern External curExternal;
551 public void PrePreProcessClassDefinitions()
553 External external, next;
559 for(external = ast->first; external; external = next)
561 next = external.next;
562 curExternal = external;
563 if(external.type == classExternal)
565 ClassDefinition _class = external._class;
566 if(_class.definitions && !_class.symbol.registered)
568 ProcessClass(normalClass, _class.definitions, _class.symbol, _class.baseSpecs, null, _class.loc, ast, external.prev, null, _class.declMode);
569 _class.symbol.isStatic = _class.declMode == staticAccess;
572 else if(external.type == declarationExternal)
574 Declaration declaration = external.declaration;
575 if(declaration.type == initDeclaration)
577 if(declaration.specifiers)
580 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
582 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
583 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
585 Symbol type = FindType(globalContext, specifier.id.string);
586 Symbol symbol = FindClass(specifier.id.string);
589 declaration.declMode = defaultAccess;
592 globalContext.classes.Remove((BTNode)symbol);
593 excludedSymbols->Add(symbol);
596 else if(symbol && !symbol.registered)
600 if(specifier.type == enumSpecifier)
601 classType = enumClass;
602 else if(specifier.type == unionSpecifier)
603 classType = unionClass;
605 classType = structClass;
606 ProcessClass(classType, specifier.definitions, symbol, specifier.baseSpecs, specifier.list, specifier.loc, ast, external.prev, declaration.declarators, declaration.declMode);
607 symbol.isStatic = declaration.declMode == staticAccess;
614 else if(external.type == importExternal)
616 //ImportModule(external._import);
621 // Update templated classes
623 for(external = ast->first; external; external = external.next)
625 if(external.type == classExternal)
627 ClassDefinition _class = external._class;
631 for(link = _class.symbol.templatedClasses.first; link; link = link.next)
633 Symbol symbol = link.data;
634 symbol.registered = eSystem_FindClass(privateModule, symbol.string);
638 else if(external.type == declarationExternal)
640 Declaration declaration = external.declaration;
641 if(declaration.type == initDeclaration)
643 if(declaration.specifiers)
646 for(specifier = declaration.specifiers->first; specifier; specifier = specifier.next)
648 if((specifier.type == enumSpecifier || specifier.type == structSpecifier || specifier.type == unionSpecifier) && specifier.id && specifier.id.string &&
649 (declaration.declMode || specifier.baseSpecs || (specifier.type == enumSpecifier && specifier.definitions)))
651 Symbol type = FindType(globalContext, specifier.id.string);
652 Symbol symbol = FindClass(specifier.id.string);
659 for(link = symbol.templatedClasses.first; link; link = link.next)
661 Symbol tplSymbol = link.data;
662 tplSymbol.registered = eSystem_FindClass(privateModule, tplSymbol.string);
663 tplSymbol.module = symbol.module ? symbol.module : mainModule;