3 #define YYLTYPE Location
6 extern External curExternal;
7 static Statement curCompound;
9 static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
12 Expression memberExp = *memberExpPtr;
13 if(memberExp && memberExp.type == ExpressionType::memberExp &&
14 memberExp.member.exp && (memberExp.member.exp.type == bracketsExp || memberExp.member.exp.type == extensionExpressionExp))
16 Expression bracketExp = memberExp.member.exp;
17 Expression idExp = bracketExp.list->last;
19 if(idExp && idExp.type == identifierExp)
21 Expression newExp = null;
22 Expression exp = *expPtr;
24 // opExp ( memberExp ( bracketsExp ( identifierExp ) ) )
25 // bracketsExp ( opExp ( memberExp ( identifierExp ) ) )
28 newExp = CopyExpression(exp);
31 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
33 memberExp.member.exp = idExp;
35 exp.type = bracketsExp;
36 exp.list = bracketExp.list;
37 bracketExp.list = null;
39 exp.list->Remove(idExp);
40 exp.list->Add(newExp);
41 FreeExpression(bracketExp);
43 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
46 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
47 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
49 Expression newExp = null;
50 Expression exp = *expPtr;
53 newExp = CopyExpression(exp);
54 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
56 exp.type = bracketsExp;
57 exp.list = memberExp.list;
58 memberExp.list = null;
60 exp.list->Remove(exp.list->last);
61 exp.list->Add(newExp);
62 FreeExpression(memberExp);
64 *expPtr = newExp; //FixRefExp(newExp);
68 static Expression FixRefExp(Expression exp)
72 _FixRefExp(&exp, &exp.op.exp1);
73 _FixRefExp(&exp, &exp.op.exp2);
75 else if(exp.type == indexExp)
76 _FixRefExp(&exp, &exp.index.exp);
77 else if(exp.type == memberExp)
78 _FixRefExp(&exp, &exp.member.exp);
82 static Expression FixReference(Expression e, bool wantReference)
84 if(e.expType && e.type != constantExp)
86 Type type = e.expType;
87 bool isPointer = false;
89 if(type.kind == TypePointer && type.type && type.type.kind == classType)
96 if(type.kind == classType) // || type.kind == TypeInt)
98 Class _class = type._class ? type._class.registered : null;
99 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
100 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
101 if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
102 (_class.type == systemClass && _class.base &&
103 strcmp(_class.fullName, "uintptr") &&
104 strcmp(_class.fullName, "intptr") &&
105 strcmp(_class.fullName, "uintsize") &&
106 strcmp(_class.fullName, "intsize"))))
108 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
109 if(wantReference != (e.byReference || isPointer))
114 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
118 exp.byReference = wantReference;
119 exp = exp.list->last;
124 else if(exp.type == castExp)
126 exp.byReference = wantReference;
129 else if(exp.type == conditionExp)
131 if(exp.cond.exp->last)
132 FixReference(exp.cond.exp->last, wantReference);
133 FixReference(exp.cond.elseExp, wantReference);
138 if(wantReference != (exp.byReference || isPointer))
140 Expression newExp { };
145 if(exp.destType) exp.destType.refCount++;
146 if(exp.expType) exp.expType.refCount++;
150 exp.op.exp2 = newExp;
156 e.byReference = wantReference;
157 exp.byReference = wantReference;
170 static Expression GetInnerExp(Expression exp)
173 while(e && (e.type == bracketsExp || e.type == castExp))
175 if(e.type == bracketsExp)
176 e = e.list ? e.list->last : null;
177 else if(e.type == castExp)
183 Expression GetNonBracketsExp(Expression exp)
186 while(e && e.type == bracketsExp)
187 e = e.list ? e.list->last : null;
191 static bool FixMember(Expression exp)
193 bool byReference = false;
196 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
198 if(exp.list->count > 1)
200 exp = exp.list->last;
202 else if(exp.type == castExp)
209 FixReference(exp, true);
211 byReference = exp.byReference;
218 static void ProcessExpression(Expression exp)
220 Location oldyylloc = yylloc;
222 char debugExpString[1024] = "";
223 PrintExpression(exp, debugExpString);
233 if(exp.expType && exp.expType.kind == methodType)
235 Class _class = exp.expType.methodClass;
236 Method method = exp.expType.method;
237 if(method.type == virtualMethod)
242 OldList * specs = MkList();
243 strcpy(name, "__ecereVMethodID_");
244 FullClassNameCat(name, method._class.fullName, false);
246 strcat(name, method.name);
248 DeclareMethod(method, name);
250 // Cast function to its type
251 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
252 if(!method.dataType.staticMethod)
254 Declarator funcDecl = GetFuncDecl(decl);
256 if(!funcDecl.function.parameters)
257 funcDecl.function.parameters = MkList();
259 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
260 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
262 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
263 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
266 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
267 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
270 typeName = MkTypeName(specs, decl);
274 char className[1024];
275 // Need the class itself here...
276 strcpy(className, "__ecereClass_");
277 FullClassNameCat(className, _class.fullName, true);
278 //MangleClassName(className);
281 _class.symbol = FindClass(_class.fullName);
282 DeclareClass(_class.symbol, className);
285 FreeIdentifier(exp.identifier);
286 exp.type = bracketsExp;
287 exp.list = MkListOne(MkExpCast(typeName,
288 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
289 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
295 strcpy(name, "__ecereMethod_");
296 FullClassNameCat(name, method._class.fullName, false);
298 strcat(name, method.name);
300 delete exp.identifier.string;
301 FreeSpecifier(exp.identifier._class);
303 exp.identifier._class = null;
304 exp.identifier.string = CopyString(name);
305 DeclareMethod(method, name);
309 if(exp.usage & USAGE_MEMBER)
310 FixReference(exp, true);
323 OldList * args = MkList();
325 if(exp.type == renewExp || exp.type == renew0Exp)
326 ListAdd(args, exp._renew.exp);
328 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
332 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
333 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
334 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
335 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
337 exp.call.arguments = args;
340 ProcessExpression(exp);
345 Expression exp1 = exp.op.exp1;
346 Expression exp2 = exp.op.exp2;
350 // Assignment Operators
353 exp.op.exp2.usage.usageGet = true;
365 exp.op.exp2.usage.usageGet = true;
374 if(exp.op.exp1 && exp.op.exp2)
376 exp.op.exp1.usage.usageGet = true;
377 exp.op.exp2.usage.usageGet = true;
381 exp.op.exp2.usage.usageRef = true;
390 exp.op.exp1.usage.usageGet = true;
395 exp.op.exp2.usage.usageGet = true;
398 // Binary only operators
414 exp.op.exp1.usage.usageGet = true;
416 exp.op.exp2.usage.usageGet = true;
420 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
421 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
422 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
423 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
425 Expression memberExp;
426 Expression parentExp = null; // Where to take memberExp out from
427 bool isIndexedContainerAssignment = false;
429 // TOCHECK: See note below for this if
430 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
432 // Extra bit of code to access deep properties...
433 Expression testExp, topExp = null;
434 Expression lastExp = exp.op.exp1, parentExp = null;
435 Property lastProperty = null;
438 char setName[1024], getName[1024];
439 testExp = exp.op.exp1.member.exp;
442 // Is further fixing needed to address if statement above in the same way?
445 if(testExp.type == castExp)
446 testExp = testExp.cast.exp;
447 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
448 testExp = testExp.list->last;
449 else if(testExp.type == ExpressionType::memberExp)
456 if(testExp.member.memberType == propertyMember ||
457 testExp.member.memberType == reverseConversionMember)
459 Type type = testExp.member.exp.expType;
462 if(type.kind == classType)
464 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
465 Class convertTo = null;
466 if(testExp.member.memberType == reverseConversionMember)
469 _class = FindClass(testExp.member.member.string).registered;
470 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
471 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
475 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
477 if(lastProperty && lastProperty.Get && lastProperty.Set)
479 DeclareProperty(lastProperty, setName, getName);
480 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
481 propertyClass = convertTo ? _class :
482 ((((Symbol)lastProperty.symbol).type &&
483 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
484 // TODO: Handle this kind of things with bit classes?
485 if(propertyClass && propertyClass.type == structClass)
490 else if(propertyClass && propertyClass.type == bitClass)
502 testExp = testExp.member.exp;
506 if(propertyClass.type == structClass)
510 char className[1024];
513 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
514 tempExp = QMkExpId(className);
515 tempExp.expType = MkClassType(propertyClass.fullName);
517 parentExp.member.exp = tempExp;
519 value = MkExpBrackets(MkList());
521 copy = CopyExpression(topExp);
522 copy.usage.usageGet = true;
523 copy.usage.usageDeepGet = true;
525 ListAdd(value.list, copy);
526 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
527 ListAdd(value.list, CopyExpression(tempExp));
528 value.expType = tempExp.expType;
529 tempExp.expType.refCount++;
531 // Go on as usual with these new values:
532 exp.op.exp1 = topExp;
539 else if(propertyClass.type == bitClass)
543 char className[1024];
546 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
547 tempExp = QMkExpId(className);
548 tempExp.expType = MkClassType(propertyClass.fullName);
550 parentExp.member.exp = tempExp;
552 value = MkExpBrackets(MkList());
554 copy = CopyExpression(topExp);
555 copy.usage.usageGet = true;
556 copy.usage.usageDeepGet = true;
558 ListAdd(value.list, copy);
559 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
560 ListAdd(value.list, CopyExpression(tempExp));
561 value.expType = tempExp.expType;
562 value.expType.refCount++;
564 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
566 // Go on as usual with these new values:
567 exp.op.exp1 = topExp;
577 memberExp = exp.op.exp1;
579 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
580 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
582 parentExp = memberExp;
583 if(memberExp.type == extensionCompoundExp)
584 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
586 memberExp = memberExp.list->last;
589 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
590 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
591 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
593 Class c = memberExp.index.exp.expType._class.registered;
594 if(strcmp((c.templateClass ? c.templateClass : c).name, "Array"))
596 exp.op.exp2 = MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(exp.op.exp2)))));
597 isIndexedContainerAssignment = true;
600 ProcessExpression(memberExp);
602 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
603 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
605 parentExp = memberExp;
606 if(memberExp.type == extensionCompoundExp)
607 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
609 memberExp = memberExp.list->last;
612 if(memberExp && memberExp.type == extensionCompoundExp)
614 parentExp = memberExp;
615 if(memberExp.type == extensionCompoundExp)
617 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
618 if(stmt && stmt.type != expressionStmt) stmt = null;
619 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
622 stmt.expressions->Remove(memberExp);
623 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
624 exp.type = bracketsExp;
625 exp.list = MkListOne(parentExp);
626 ProcessExpression(exp);
631 memberExp = memberExp.list->last;
635 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
637 if(memberExp && memberExp.type == ExpressionType::memberExp && memberExp.member.member)
639 Type type = memberExp.member.exp.expType;
642 // Check if it's an instance
643 if(type.kind == classType || type.kind == subClassType)
645 // TODO: SOMETHING WRONG HERE...
646 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
648 if(memberExp == exp1)
652 if(parentExp.type == extensionCompoundExp)
653 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
655 parentExp.list->Remove(memberExp);
658 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
660 BitMember bitMember =
661 (BitMember)eClass_FindDataMember(_class,
662 memberExp.member.member.string, privateModule, null, null);
663 char mask[32], shift[10];
664 OldList * specs = MkList();
665 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
666 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
667 TypeName type = MkTypeName(specs, decl);
669 if(bitMember.mask > MAXDWORD)
670 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
672 sprintf(mask, FORMAT64HEX, bitMember.mask);
673 sprintf(shift, "%d", bitMember.pos);
675 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
676 exp.op.exp1 = memberExp.member.exp;
678 // TESTING THIS FOR: argb.color.r = 1;
679 //ProcessExpression(memberExp.member.exp);
681 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
682 if(exp.op.op == XOR_ASSIGN)
684 exp.op.exp2 = MkExpOp(MkExpBrackets(
685 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
689 exp.op.exp2 = MkExpOp(
690 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
691 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
692 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
693 MkListOne(MkExpCast(type, MkExpBrackets(MkListOne(exp.op.exp2))))), LEFT_OP, MkExpConstant(shift)))));
696 memberExp.member.exp = null;
697 FreeExpression(memberExp);
699 // TESTING THIS FOR: argb.color.r = 1;
700 ProcessExpression(exp);
703 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
706 else if(memberExp.member.memberType != dataMember)
709 Class convertTo = null;
710 ClassProperty classProperty = null;
712 if(memberExp.member.memberType == reverseConversionMember)
715 _class = FindClass(memberExp.member.member.string).registered;
716 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
717 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
720 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
722 if(memberExp.member.memberType == classPropertyMember)
723 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
725 exp.tempCount = memberExp.member.exp.tempCount;
729 // Only process Gets here, Set is processed in opExp's '='
730 if(classProperty.Set)
732 Identifier id = memberExp.member.member;
733 Expression classExp = memberExp.member.exp;
734 Expression value = exp.op.exp2;
736 memberExp.member.exp = null;
737 memberExp.member.member = null;
740 FreeExpContents(memberExp);
744 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
745 exp.call.arguments = MkList();
746 ListAdd(exp.call.arguments, classExp);
748 char * s = QMkString(id.string);
749 ListAdd(exp.call.arguments, MkExpString(s));
752 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
756 ProcessExpression(exp);
762 if((!convertTo && prop.Set) || (convertTo && prop.Get))
764 Expression value = exp.op.exp2;
765 char setName[1024], getName[1024];
766 char * setToUse = convertTo ? getName : setName;
767 char * getToUse = convertTo ? setName : getName;
768 bool needAddress = false;
769 int operator = exp.op.op;
772 case MUL_ASSIGN: operator = '*'; break;
773 case DIV_ASSIGN: operator = '/'; break;
774 case MOD_ASSIGN: operator = '%'; break;
775 case SUB_ASSIGN: operator = '-'; break;
776 case ADD_ASSIGN: operator = '+'; break;
777 case LEFT_ASSIGN: operator = LEFT_OP; break;
778 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
779 case AND_ASSIGN: operator = '&'; break;
780 case OR_ASSIGN: operator = '|'; break;
781 case XOR_ASSIGN: operator = '^'; break;
786 if(operator == INC_OP)
787 value = MkExpOp(CopyExpression(memberExp),
788 '+', MkExpConstant("1"));
789 else if(operator == DEC_OP)
790 value = MkExpOp(CopyExpression(memberExp),
791 '-', MkExpConstant("1"));
794 value = MkExpOp(CopyExpression(memberExp),
798 value.expType = memberExp.expType;
799 memberExp.expType.refCount++;
800 value.usage.usageArg = true;
804 // Dont free exp2, we're using it
809 value.usage.usageArg = true;
811 DeclareProperty(prop, setName, getName);
813 if(memberExp.member.exp)
814 ProcessExpression(memberExp.member.exp);
816 // If get flag present
817 if(exp.usage.usageGet &&
818 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
820 OldList * list = MkList();
823 Context context = PushContext();
826 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
827 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
829 curContext = context;
830 exp.type = extensionCompoundExp;
831 exp.compound = MkCompoundStmt(
832 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
833 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
834 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
841 ListAdd(args, value);
842 ListAdd(args, QMkExpId(ecereTemp));
843 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
847 ListAdd(args, QMkExpId(ecereTemp));
848 ListAdd(args, value);
849 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
855 ListAdd(args, QMkExpId(ecereTemp));
857 args->Insert(null, QMkExpId(ecereTemp));
858 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
860 exp.compound.compound.context = context;
862 curContext = context.parent;
866 Expression newExp = exp;
868 if(parentExp && parentExp.type == extensionCompoundExp)
870 newExp = Expression { };
871 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
872 FreeType(exp.expType);
873 FreeType(exp.destType);
876 parentExp.type = dummyExp;
877 parentExp.expType = null;
878 parentExp.destType = null;
881 newExp.type = callExp;
882 newExp.call.exp = QMkExpId(setToUse);
883 newExp.call.arguments = MkList();
886 ListAdd(newExp.call.arguments, value);
887 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
891 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
892 ListAdd(newExp.call.arguments, value);
897 // Take it out from there
898 memberExp.member.exp = null;
900 // Don't use the temporaries used by the left side...
903 value.tempCount = exp.tempCount;
904 ProcessExpression(value);
906 FixReference(isIndexedContainerAssignment ? GetInnerExp(value) : value, true);
909 FreeExpression(memberExp);
913 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
916 memberExp.member.memberType = dataMember;
919 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
924 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
925 if(method && method.type == virtualMethod && type.kind != subClassType)
927 Expression value = exp.op.exp2;
928 // Don't use the temporaries used by the left side...
929 value.tempCount = exp.tempCount;
930 ProcessExpression(value);
932 if(memberExp.member.exp)
933 ProcessExpression(memberExp.member.exp);
935 if(exp.usage.usageGet)
937 OldList * list = MkList();
942 ListAdd(args, memberExp.member.exp);
944 char * string = QMkString(memberExp.member.member.string);
945 ListAdd(args, MkExpString(string));
948 ListAdd(args, value);
949 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
950 ListAdd(list, CopyExpression(value));
951 exp.type = bracketsExp;
958 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
959 exp.call.arguments = MkList();
960 ListAdd(exp.call.arguments, memberExp.member.exp);
962 char * string = QMkString(memberExp.member.member.string);
963 ListAdd(exp.call.arguments, MkExpString(string));
966 ListAdd(exp.call.arguments, value);
969 memberExp.member.exp = null;
972 FreeExpression(memberExp);
976 else if(memberExp.member.memberType == dataMember)
978 //if(exp.usage & USAGE_GET);
979 //FixReference(value, true);
980 if(FixMember(memberExp.member.exp))
982 // TESTING THIS HERE:
983 ProcessExpression(memberExp);
985 memberExp.type = pointerExp;
992 else if(exp.op.op == _INCREF)
994 Expression object = exp.op.exp2;
996 FreeExpContents(exp);
997 FreeType(exp.expType);
998 FreeType(exp.destType);
1000 exp.destType = null;
1002 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
1004 else if(exp.op.op == DELETE)
1006 Expression object = exp.op.exp2;
1007 OldList * args = MkList();
1009 exp.type = bracketsExp;
1010 exp.list = MkList();
1012 object.usage.usageDelete = true;
1014 ProcessExpression(object);
1016 ListAdd(args, object);
1018 // TOFIX: Same time as when we fix for = 0
1020 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
1021 exp.expType._class.registered.type == normalClass &&
1022 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
1024 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
1025 ProcessExpressionType(decRefExp);
1026 ListAdd(exp.list, decRefExp);
1028 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
1031 char className[1024];
1032 OldList * list = MkList();
1034 strcpy(className, "__ecereClass_");
1035 FullClassNameCat(className, exp.expType._class.string, true);
1036 //MangleClassName(className);
1038 DeclareClass(exp.expType._class, className);
1040 // Call the non virtual destructor
1041 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1042 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1044 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1046 MkExpBrackets(MkListOne(MkExpCondition(
1047 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1048 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1053 OldList * list = MkList();
1056 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1058 char className[1024];
1060 if(_class.templateClass) _class = _class.templateClass;
1061 strcpy(className, "__ecereClass_");
1062 FullClassNameCat(className, _class.fullName, false /*true*/);
1063 //MangleClassName(className);
1066 _class.symbol = FindClass(_class.fullName);
1067 DeclareClass(_class.symbol, className);
1069 // Call the non virtual destructor
1073 QMkExpId(className),
1074 MkIdentifier("Destructor")
1079 QMkExpId(className),
1080 MkIdentifier("Destructor")
1082 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), CopyExpression(args->first)))
1089 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1090 o = CopyExpression(object);
1091 ProcessExpressionType(o);
1092 o.usage.usageGet = true;
1093 ProcessExpression(o);
1109 else if(exp.expType && exp.expType.kind == templateType)
1111 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1114 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1116 OldList * qualifiers = MkList();
1117 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1119 typeName = MkTypeName(qualifiers, declarator);
1121 ProcessExpressionType(classExp);
1122 ProcessExpression(classExp);
1123 args->Insert(null, CopyExpression(classExp));
1124 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1125 ListAdd(exp.list, MkExpCall(
1126 MkExpBrackets(MkListOne(MkExpCast(typeName,
1127 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1128 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1129 //ProcessExpression(exp.list->last);
1133 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1135 //ProcessExpression(object);
1137 ListAdd(exp.list, MkExpOp(CopyExpression(GetInnerExp(object)), '=', MkExpConstant("0")));
1141 // TESTING THIS HERE...
1142 ProcessExpression(exp);
1145 if(exp.type == opExp)
1147 // Handle assigment of template structures
1148 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1149 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1151 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1154 // memcpy((byte *)array + (count * dataTypeClass.size), (dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1156 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1157 OldList * args = MkList();
1158 Expression derefExp = exp.op.exp1;
1161 ProcessExpressionType(classExp);
1162 ProcessExpression(classExp);
1164 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1166 if(exp.op.exp1.type == indexExp)
1168 Expression indexExp = derefExp.index.exp;
1169 OldList * indexExpIndex = derefExp.index.index;
1171 derefExp.index.index = null;
1172 derefExp.index.exp = null;
1173 FreeExpression(derefExp);
1175 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1176 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1180 Expression indexExp = derefExp.op.exp2;
1181 derefExp.op.exp2 = null;
1182 FreeExpression(derefExp);
1183 derefExp = indexExp;
1186 args->Add(derefExp);
1187 ProcessExpressionType(args->last);
1188 ProcessExpression(args->last);
1190 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1191 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1192 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2))))),
1193 MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1195 thisClass = curExternal.function ? curExternal.function._class : null;
1199 string = CopyString("this");
1200 type = MkClassType(thisClass.fullName);
1202 globalContext.symbols.Add((BTNode)thisSymbol);
1204 ProcessExpressionType(args->last);
1205 ProcessExpression(args->last);
1208 ProcessExpressionType(args->last);
1209 ProcessExpression(args->last);
1211 DeclareFunctionUtil("memcpy");
1213 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1214 exp.type = bracketsExp;
1216 //globalContext.symbols.Delete((BTNode)thisSymbol);
1217 globalContext.symbols.Remove((BTNode)thisSymbol);
1218 FreeSymbol(thisSymbol);
1224 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1225 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1227 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1230 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1233 ProcessExpressionType(classExp);
1234 ProcessExpression(classExp);
1236 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1238 exp.type = bracketsExp;
1239 exp.list = MkListOne(
1241 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1243 // ((class.type == structClass) ?
1244 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1247 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1249 // ((class.size == 1) ?
1250 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1252 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1253 CopyExpression(exp.op.exp2)))))),
1255 // ((class.size == 2) ?
1256 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1257 // *((uint16 *)array)
1258 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1259 CopyExpression(exp.op.exp2)))))),
1261 // ((class.size == 4) ?
1262 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1263 // *((uint32 *)array)
1264 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1265 CopyExpression(exp.op.exp2)))))),
1267 // *((uint64 *)array)
1268 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1269 exp.op.exp2))))))))))))))))))));
1271 // Add this to the context
1272 thisClass = curExternal.function ? curExternal.function._class : null;
1276 string = CopyString("this");
1277 type = MkClassType(thisClass.fullName);
1279 globalContext.symbols.Add((BTNode)thisSymbol);
1281 ProcessExpressionType(exp.list->first);
1282 ProcessExpression(exp.list->first);
1284 //globalContext.symbols.Delete((BTNode)thisSymbol);
1285 globalContext.symbols.Remove((BTNode)thisSymbol);
1286 FreeSymbol(thisSymbol);
1297 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1298 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1299 ProcessExpression(exp.op.exp1);
1302 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1303 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1304 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1305 exp.op.exp2.expType && (exp.op.exp2.expType.kind != pointerType && exp.op.exp2.expType.kind != templateType /*|| !exp.op.exp2.expType.type || exp.op.exp2.expType.type.kind != voidType*/))
1306 FixReference(exp.op.exp1, false);
1307 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1311 // Don't use the temporaries used by the left side...
1313 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1314 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1315 ProcessExpression(exp.op.exp2);
1316 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1320 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1321 (exp.op.exp2.expType._class.registered.type != normalClass &&
1322 exp.op.exp2.expType._class.registered.type != structClass &&
1323 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1325 // TESTING THIS TEMPLATE TYPE CHECK HERE
1326 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1328 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1329 //FixReference(exp.op.exp2, false);
1332 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1335 if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.type == opExp && exp.op.exp2.op.op == '&' && !exp.op.exp2.op.exp1)
1337 // Preserve prev, next
1338 Expression next = exp.next, prev = exp.prev;
1339 Expression derefExp = exp.op.exp2;
1340 Expression refExp = exp.op.exp2.op.exp2;
1342 derefExp.op.exp2 = null;
1343 FreeExpression(derefExp);
1344 FreeType(exp.expType);
1345 FreeType(exp.destType);
1355 if(exp.op.op == '&' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == templateType && !exp.op.exp2.expType.passAsTemplate)
1357 Expression exp2 = exp.op.exp2;
1358 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1361 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1364 ProcessExpressionType(classExp);
1365 ProcessExpression(classExp);
1367 exp.type = bracketsExp;
1368 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1369 MkExpOp(null, '&', exp2)), '+',
1370 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1371 MkListOne((e = MkExpMember(classExp, MkIdentifier("typeSize")))))));
1373 // Add this to the context
1374 thisClass = curExternal.function ? curExternal.function._class : null;
1378 string = CopyString("this");
1379 type = MkClassType(thisClass.fullName);
1381 //globalContext.symbols.Add((BTNode)thisSymbol);
1383 ProcessExpressionType(e);
1384 ProcessExpression(e);
1386 //globalContext.symbols.Remove((BTNode)thisSymbol);
1387 //FreeSymbol(thisSymbol);
1396 FreeExpression(exp1);
1398 FreeExpression(exp2);
1403 case extensionExpressionExp:
1408 for(e = exp.list->first; e; e = e.next)
1412 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1414 e.tempCount = exp.tempCount;
1415 ProcessExpression(e);
1417 exp.byReference = e.byReference;
1418 exp.tempCount = e.tempCount;
1422 exp.expType = e.expType;
1431 /*bool isBuiltin = exp && exp.index.exp &&
1432 (exp.index.exp.type == ExpressionType::arrayExp ||
1433 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1435 Expression checkedExp = exp.index.exp;
1436 bool isBuiltin = false;
1438 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1440 if(checkedExp.type == extensionCompoundExp)
1445 else if(checkedExp.type == bracketsExp)
1446 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1448 checkedExp = checkedExp.cast.exp;
1451 exp.index.exp.tempCount = exp.tempCount;
1453 exp.index.exp.usage.usageGet = true;
1454 ProcessExpression(exp.index.exp);
1456 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1457 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1459 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1462 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1465 ProcessExpressionType(classExp);
1466 ProcessExpression(classExp);
1468 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1470 exp.type = bracketsExp;
1471 exp.list = MkListOne(
1473 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1475 // ((class.type == structClass) ?
1476 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1477 // ((byte *)array) + (i) * class.size
1478 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1479 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1480 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1482 // ((class.size == 1) ?
1483 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1484 // ((byte *)array)[i]
1485 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1486 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1488 // ((class.size == 2) ?
1489 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1490 // ((uint16 *)array)[i]
1491 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1492 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1494 // ((class.size == 4) ?
1495 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1496 // ((uint32 *)array)[i]
1497 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1498 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1500 // ((uint64 *)array)[i]
1501 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1502 exp.index.exp))), exp.index.index)))))))))))))))));
1504 // Add this to the context
1505 thisClass = curExternal.function ? curExternal.function._class : null;
1509 string = CopyString("this");
1510 type = MkClassType(thisClass.fullName);
1512 globalContext.symbols.Add((BTNode)thisSymbol);
1514 ProcessExpressionType(exp.list->first);
1515 ProcessExpression(exp.list->first);
1517 //globalContext.symbols.Delete((BTNode)thisSymbol);
1518 globalContext.symbols.Remove((BTNode)thisSymbol);
1519 FreeSymbol(thisSymbol);
1527 for(e = exp.index.index->first; e; e = e.next)
1530 e.usage.usageGet = true;
1531 ProcessExpression(e);
1533 // Ignore temps in the index for now...
1534 exp.tempCount = exp.index.exp.tempCount;
1536 if(exp.index.exp.expType)
1538 Type source = exp.index.exp.expType;
1539 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1540 eClass_IsDerived(source._class.registered, containerClass))
1542 Class _class = source._class.registered;
1543 bool isArray = false;
1544 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1545 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1547 if(isArray && _class.templateArgs)
1549 OldList * specs = MkList();
1550 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1551 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1552 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1553 ProcessExpressionType(exp.index.exp);
1554 ProcessExpression(exp);
1556 else if(isBuiltin && _class.templateArgs)
1558 OldList * specs = MkList();
1559 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1560 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1561 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1562 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1563 ProcessExpressionType(exp.index.exp);
1564 ProcessExpression(exp);
1566 else if(_class.templateArgs)
1568 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1570 char iteratorType[1024];
1571 OldList * declarations = MkList();
1572 OldList * statements = MkList();
1573 OldList * args = MkList();
1574 OldList * instMembers = MkList();
1576 Context context = PushContext();
1578 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1580 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1582 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1583 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1585 ListAdd(args, MkExpBrackets(exp.index.index));
1586 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1588 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1589 MkIdentifier("Index")), args))));
1591 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1592 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1594 exp.type = bracketsExp;
1595 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1596 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1597 expExt.compound.compound.context = context;
1598 PopContext(context);
1599 expExt.usage = exp.usage;
1600 ProcessExpressionType(exp.list->first);
1601 ProcessExpressionInstPass(exp.list->first);
1602 ProcessExpression(exp.list->first);
1611 bool typedObject = false;
1612 Type ellipsisDestType = null;
1613 bool usedEllipsis = false;
1615 if(exp.call.arguments)
1617 for(e = exp.call.arguments->first; e; e = e.next)
1619 e.usage.usageGet = true;
1620 e.usage.usageArg = true;
1621 e.tempCount = Max(e.tempCount, exp.tempCount);
1622 ProcessExpression(e);
1623 exp.tempCount = Max(exp.tempCount, e.tempCount);
1626 exp.call.exp.usage.usageGet = true;
1627 exp.call.exp.usage.usageCall = true;
1628 exp.call.exp.tempCount = exp.tempCount;
1630 ProcessExpression(exp.call.exp);
1632 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1634 bool nullMemberExp = false;
1635 Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1637 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1638 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1639 Method method = exp.call.exp.expType.method;
1640 if(method.type == virtualMethod)
1646 OldList * specs = MkList();
1647 strcpy(name, "__ecereVMethodID_");
1648 FullClassNameCat(name, method._class.fullName, false);
1650 strcat(name, method.name);
1652 DeclareMethod(method, name);
1655 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1656 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1657 // Cast function to its type
1659 Context context = SetupTemplatesContext(method._class);
1661 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1663 FinishTemplatesContext(context);
1666 if(method.dataType && !method.dataType.staticMethod)
1668 Declarator funcDecl = GetFuncDecl(decl);
1670 if(!funcDecl.function.parameters)
1671 funcDecl.function.parameters = MkList();
1673 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1674 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1676 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1678 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1679 FreeTypeName(firstParam);
1683 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1688 param = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
1689 param.qualifiers->Insert(null, MkSpecifier(CONST));
1690 funcDecl.function.parameters->Insert(null, param);
1691 // Testing this for any_object::
1692 if(!method.dataType.extraParam)
1693 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1697 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1698 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1702 typeName = MkTypeName(specs, decl);
1704 // Added !exp.call.exp.expType.methodClass
1705 if(memberExp && memberExp.member.exp.expType)
1707 Type type = memberExp.member.exp.expType;
1709 if(type.kind == classType && type._class && type._class.registered)
1711 Class regClass = type._class.registered;
1712 ClassType classType = regClass.type;
1713 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1714 argClass = regClass;
1716 else if(type.kind == subClassType)
1718 argClass = FindClass("ecere::com::Class").registered;
1720 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1722 argClass = FindClass("char *").registered;
1724 else if(type.kind == pointerType)
1726 argClass = eSystem_FindClass(privateModule, "uintptr");
1727 FreeType(memberExp.member.exp.expType);
1728 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1729 memberExp.member.exp.byReference = true;
1733 char string[1024] = "";
1735 PrintTypeNoConst(type, string, false, true);
1736 classSym = FindClass(string);
1737 if(classSym) argClass = classSym.registered;
1741 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1747 Type type = memberExp ? memberExp.member.exp.expType : null;
1748 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1749 char className[1024];
1751 if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
1752 strcpy(className, "class");
1756 // TESTING: Moved this here...
1757 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1762 // TODO: Unhandled case here, what should happen?
1765 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1766 if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
1767 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1768 cl = cl.templateClass;
1770 // Need the class itself here...
1771 strcpy(className, "__ecereClass_");
1772 FullClassNameCat(className, cl.fullName, true);
1773 //MangleClassName(className);
1776 cl.symbol = FindClass(cl.fullName);
1778 DeclareClass(cl.symbol, className);
1781 if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
1783 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1784 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1785 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1787 else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
1788 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1791 FreeExpression(exp.call.exp);
1792 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1793 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1794 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1798 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1799 // as opposed to the File class vTbl one
1801 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1803 Context context = PushContext();
1805 c = MkExpExtensionCompound(MkCompoundStmt(
1806 MkListOne(MkDeclaration(
1807 (specs = MkListOne(MkSpecifierName("Instance"))),
1808 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1809 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
1810 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1811 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1812 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1813 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
1815 specs->Insert(null, MkSpecifier(CONST));
1817 c.compound.compound.context = context;
1818 PopContext(context);
1819 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1820 MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1827 strcpy(name, "__ecereMethod_");
1828 FullClassNameCat(name, method._class.fullName, false);
1830 strcat(name, method.name);
1833 FreeExpression(exp.call.exp);
1834 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1835 DeclareMethod(method, name);
1836 if(memberExp && memberExp.expType && method.dataType)
1838 exp.call.exp.expType = method.dataType;
1839 method.dataType.refCount++;
1842 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1844 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1846 if(!exp.call.arguments)
1847 exp.call.arguments = MkList();
1849 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1851 if(memberExp.member.exp.expType.kind != classType ||
1852 memberExp.member.exp.expType._class.registered.type == enumClass ||
1853 memberExp.member.exp.expType._class.registered.type == unitClass)
1855 char typeString[1024] = "";
1856 if(memberExp.member.exp.expType.kind != classType)
1857 PrintType(memberExp.member.exp.expType, typeString, false, true);
1859 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1862 // memberExp.member.exp.expType.kind = classType;
1863 // memberExp.member.exp.expType._class = FindClass(typeString);
1865 FreeType(memberExp.member.exp.expType);
1866 memberExp.member.exp.expType = Type
1869 _class = FindClass(typeString);
1873 // Default to an int instead
1874 if(!memberExp.member.exp.expType._class)
1876 // TODO: Shouldn't get here...
1877 memberExp.member.exp.expType.kind = TypeInt;
1882 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1884 bool changeReference = false;
1885 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1887 // Patched so that class isn't considered SYSTEM...
1888 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1889 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1890 changeReference = true;
1891 if(!memberExp.member.exp.expType.classObjectType &&
1893 (memberExp.member.exp.expType.kind != pointerType &&
1894 (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1895 !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1896 method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
1897 changeReference = true;
1898 if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
1899 changeReference = true;
1902 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1903 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1905 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1906 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1908 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1910 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1911 memberExp.member.exp.op.exp2 = null;
1913 else if(!memberExp.member.exp.byReference)
1915 // TESTING THIS... REUSE THIS CODE?
1916 Expression checkedExp = memberExp.member.exp;
1917 Expression parentExp = null;
1919 bool disconnected = false;
1920 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1922 parentExp = checkedExp;
1924 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1926 checkedExp = checkedExp.list->last;
1927 // Dissociate from memberExp which will get freed
1928 if(checkedExp && !disconnected)
1930 parentExp.list->Remove(checkedExp);
1931 disconnected = true;
1934 else if(checkedExp.type == castExp)
1936 checkedExp = checkedExp.cast.exp;
1937 // Dissociate from memberExp which will get freed
1938 if(checkedExp && !disconnected)
1940 checkedExp.cast.exp = null;
1941 disconnected = true;
1946 nullMemberExp = true;
1948 newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
1949 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1951 parentExp.list->Remove(checkedExp);
1952 parentExp.list->Add(newExp);
1954 else if(parentExp && parentExp.type == castExp)
1956 parentExp.cast.exp = newExp;
1957 // Add a dereference level here
1958 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1960 if(typedObject && !memberExp.member.exp.expType.classObjectType)
1962 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
1963 FreeType((parentExp ? parentExp : newExp).expType);
1964 FreeType((parentExp ? parentExp : newExp).destType);
1965 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
1966 (parentExp ? parentExp : newExp).destType = destType;
1967 if(checkedExp.expType) checkedExp.expType.refCount++;
1969 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1973 exp.call.arguments->Insert(null, memberExp.member.exp);
1974 nullMemberExp = true;
1979 exp.call.arguments->Insert(null, memberExp.member.exp);
1980 nullMemberExp = true;
1984 char className[1024];
1985 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
1986 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1987 Class cl = argClass ? argClass : regClass;
1990 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1991 strcpy(className, "class");
1994 // Need the class itself here...
1995 strcpy(className, "__ecereClass_");
1996 FullClassNameCat(className, cl.fullName, true);
1997 //MangleClassName(className);
2000 cl.symbol = FindClass(cl.fullName);
2001 DeclareClass(cl.symbol, className);
2006 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
2008 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2010 Context context = PushContext();
2013 c = MkExpExtensionCompound(MkCompoundStmt(
2014 MkListOne(MkDeclaration(
2015 (specs = MkListOne(MkSpecifierName("Instance"))),
2016 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2017 MkInitializerAssignment(memberExpMemberExp))))),
2018 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2019 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2020 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2021 MkExpIdentifier(MkIdentifier(className))))))));
2022 c.compound.compound.context = context;
2023 PopContext(context);
2026 specs->Insert(null, MkSpecifier(CONST));
2028 exp.call.arguments->Insert(null, c);
2030 memberExpMemberExp = null; // We used this
2033 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
2037 if(memberExpMemberExp)
2038 FreeExpression(memberExpMemberExp);
2042 exp.call.arguments->Insert(null, memberExp.member.exp);
2043 nullMemberExp = true;
2047 /*else if(method->dataType)
2053 memberExp.member.exp = null;
2054 FreeExpression(memberExp);
2058 if(exp.call.arguments)
2060 for(e = exp.call.arguments->first; e; e = e.next)
2062 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
2063 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
2064 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
2065 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
2067 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
2068 ellipsisDestType = destType;
2071 Type type = e.expType;
2072 Class _class = null;
2073 //Type destType = e.destType;
2075 if(type.kind == classType && type._class && type._class.registered)
2077 _class = type._class.registered;
2079 else if(type.kind == subClassType)
2081 _class = FindClass("ecere::com::Class").registered;
2083 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
2085 _class = FindClass("char *").registered;
2087 else if(type.kind == pointerType)
2089 _class = eSystem_FindClass(privateModule, "uintptr");
2090 FreeType(e.expType);
2091 e.expType = ProcessTypeString("uintptr", false);
2092 // Assume null pointers means 'no object' rather than an object holding a null pointer
2093 e.byReference = true;
2097 char string[1024] = "";
2099 PrintTypeNoConst(type, string, false, true);
2100 classSym = FindClass(string);
2101 if(classSym) _class = classSym.registered;
2102 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2105 if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "uintptr") && strcmp(_class.fullName, "intptr")) || // Patched so that class isn't considered SYSTEM...
2106 (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != intPtrType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
2107 destType.byReference)))
2109 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2110 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2111 // TESTING WITHOUT THE ABOVE NOW!
2113 Expression checkedExp;
2114 Expression parentExp;
2119 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2121 parentExp = checkedExp;
2122 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2124 if(checkedExp.type == extensionCompoundExp)
2126 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2129 checkedExp = checkedExp.list->last;
2131 else if(checkedExp.type == castExp)
2132 checkedExp = checkedExp.cast.exp;
2135 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2138 Expression newExp = e.op.exp2;
2139 exp.call.arguments->Insert(e.prev, newExp);
2140 exp.call.arguments->Remove(e);
2145 newExp = checkedExp.op.exp2;
2146 checkedExp.op.exp2 = null;
2147 FreeExpContents(checkedExp);
2149 if(e.expType && e.expType.passAsTemplate)
2152 ComputeTypeSize(e.expType);
2153 sprintf(size, "%d", e.expType.size);
2154 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2155 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2156 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2159 if(parentExp.type == callExp)
2161 exp.call.arguments->Insert(e.prev, newExp);
2162 exp.call.arguments->Remove(e);
2165 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2167 parentExp.list->Remove(checkedExp);
2168 parentExp.list->Add(newExp);
2170 else if(parentExp.type == castExp)
2172 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2173 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2175 FreeTypeName(parentExp.cast.typeName);
2176 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2178 parentExp.cast.exp = newExp;
2180 else if(parentExp.type == extensionCompoundExp)
2182 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2183 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2185 e.byReference = true;
2187 FreeType(checkedExp.expType);
2188 FreeType(checkedExp.destType);
2191 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2193 Expression checkedExp;
2194 Expression parentExp;
2198 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2200 e.type == identifierExp ||
2201 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2202 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2203 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2206 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2208 Context context = PushContext();
2210 OldList * specs = MkList();
2211 char typeString[1024];
2212 Expression newExp { };
2214 typeString[0] = '\0';
2217 // TOCHECK: Should this read e.destType ???
2219 if(exp.destType) exp.destType.refCount++;
2220 // if(exp.expType) exp.expType.refCount++;
2223 newExp.expType = null;
2225 PrintTypeNoConst(e.expType, typeString, false, true);
2226 decl = SpecDeclFromString(typeString, specs, null);
2227 newExp.destType = ProcessType(specs, decl);
2229 curContext = context;
2230 e.type = extensionCompoundExp;
2232 // We need a current compound for this
2236 OldList * stmts = MkList();
2237 sprintf(name, "__internalValue%03X", internalValueCounter++);
2238 if(!curCompound.compound.declarations)
2239 curCompound.compound.declarations = MkList();
2240 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2241 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2242 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2243 e.compound = MkCompoundStmt(null, stmts);
2246 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2250 e.compound = MkCompoundStmt(
2251 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2252 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2255 e.compound.compound.context = context;
2256 PopContext(context);
2257 curContext = context.parent;
2261 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2264 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2266 parentExp = checkedExp;
2267 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2269 if(checkedExp.type == extensionCompoundExp)
2271 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2274 checkedExp = checkedExp.list->last;
2276 else if(checkedExp.type == castExp)
2277 checkedExp = checkedExp.cast.exp;
2279 newExp = MkExpOp(null, '&', checkedExp);
2280 newExp.byReference = true;
2281 if(parentExp.type == callExp)
2283 exp.call.arguments->Insert(e.prev, newExp);
2284 exp.call.arguments->Remove(e);
2287 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2289 parentExp.list->Remove(checkedExp);
2290 parentExp.list->Add(newExp);
2292 else if(parentExp.type == castExp)
2293 parentExp.cast.exp = newExp;
2294 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2296 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2297 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2303 if(destType.classObjectType == ClassObjectType::typedObject)
2305 char className[1024];
2306 // Need the class itself here...
2307 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2308 _class = eSystem_FindClass(privateModule, "String");
2309 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2311 if(!strcmp(_class.name, "class"))
2313 // Already inside a typed_object function, pass the class through
2314 strcpy(className, "class");
2318 strcpy(className, "__ecereClass_");
2319 FullClassNameCat(className, _class.fullName, true);
2320 //MangleClassName(className);
2323 _class.symbol = FindClass(_class.fullName);
2325 DeclareClass(_class.symbol, className);
2328 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2330 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2332 Context context = PushContext();
2334 // Work around to avoid repeating the BuiltInContainer just to get the type
2335 // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
2336 if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
2337 e.list && e.list->first &&
2338 ((Expression)e.list->first).type == castExp &&
2339 ((Expression)e.list->first).cast.exp &&
2340 ((Expression)e.list->first).cast.exp.type == opExp &&
2341 ((Expression)e.list->first).cast.exp.op.op == '&' &&
2342 ((Expression)e.list->first).cast.exp.op.exp2 &&
2343 ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
2345 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2350 c = MkExpExtensionCompound(MkCompoundStmt(
2351 MkListOne(MkDeclaration(
2352 (specs = MkListOne(MkSpecifierName("Instance"))),
2353 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2354 MkInitializerAssignment(CopyExpression(e)))))),
2355 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2356 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2357 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2358 MkExpIdentifier(MkIdentifier(className))))))));
2359 c.compound.compound.context = context;
2360 PopContext(context);
2363 specs->Insert(null, MkSpecifier(CONST));
2365 exp.call.arguments->Insert(e.prev, c);
2369 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2375 //char debugString[4096] = "";
2376 //PrintExpression(e, debugString);
2378 // If expression type is a simple class, make it an address
2379 FixReference(e, !destType || !destType.declaredWithStruct);
2382 if(ellipsisDestType)
2385 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2386 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2388 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2396 bool changeToPtr = false;
2397 bool noHead = false;
2398 Type type = exp.member.exp ? exp.member.exp.expType : null;
2399 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2400 if(exp.member.member) exp.member.member._class = null;
2402 if(type && type.kind == templateType)
2404 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2405 if(baseType) type = baseType;
2407 if(type && exp.member.member && !type.directClassAccess)
2409 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2410 Property prop = null;
2411 ClassProperty classProperty = null;
2412 Method method = null;
2413 Class convertTo = null;
2414 DataMember member = null;
2415 DataMember subMemberStack[256];
2416 int subMemberStackPos = 0;
2417 bool thisPtr = exp.member.thisPtr;
2418 if(type.kind == subClassType && exp.member.exp.type == classExp)
2419 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2421 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2425 // DANGER: Buffer overflow
2426 char string[2048] = "";
2428 PrintTypeNoConst(type, string, false, true);
2429 classSym = FindClass(string);
2430 _class = classSym ? classSym.registered : null;
2433 if(_class && exp.member.memberType == dataMember)
2435 if(!thisPtr && !exp.member.member.classSym)
2436 member = eClass_FindDataMember(_class, exp.member.member.string, null, subMemberStack, &subMemberStackPos);
2438 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2440 else if(_class && exp.member.memberType == propertyMember)
2442 if(!thisPtr && !exp.member.member.classSym)
2443 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2445 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2446 if(prop && (exp.usage.usageRef ||
2447 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2448 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2450 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2453 exp.member.memberType = dataMember;
2458 if(exp.usage.usageRef)
2459 Compiler_Error($"cannot obtain address of property\n");
2461 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2462 else if(exp.usage.usageDelete)
2463 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2467 else if(_class && exp.member.memberType == methodMember)
2470 method = eClass_FindMethod(_class, exp.member.member.string, null);
2472 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2474 else if(_class && exp.member.memberType == reverseConversionMember)
2477 _class = FindClass(exp.member.member.string).registered;
2478 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2479 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2481 else if(_class && exp.member.memberType == classPropertyMember)
2483 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2487 // Only process Gets here, Set is processed in opExp's '='
2488 if(exp.usage.usageGet)
2492 char getName[1024], setName[1024];
2493 Expression ptr = exp.member.exp;
2494 Class propertyClass;
2495 char * nameToUse = convertTo ? setName : getName;
2497 FreeIdentifier(exp.member.member);
2499 // Process this here since it won't be processed at the end...
2500 exp.member.exp.usage.usageGet = true;
2501 ProcessExpression(exp.member.exp);
2502 // TEST: exp.tempCount = exp.member.exp.tempCount;
2504 DeclareProperty(prop, setName, getName);
2505 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2506 propertyClass = convertTo ? _class :
2507 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2510 if(propertyClass && propertyClass.type == bitClass)
2512 // Bit classes shouldn't have properties except for conversions...
2513 OldList * args = MkList();
2514 if(exp.usage.usageDeepGet)
2516 char className[1024];
2518 Declarator declarator;
2519 OldList * specs = MkList(), * decls = MkList();
2522 // Make a declaration in the closest compound statement
2523 // (Do not reuse (since using address for function calls)...)
2524 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2526 SpecDeclFromString(propertyClass.dataTypeString, specs,
2527 MkDeclaratorIdentifier(MkIdentifier(className)));
2529 ListAdd(decls, MkInitDeclarator(declarator, null));
2531 decl = MkDeclaration(specs, decls);
2532 if(!curCompound.compound.declarations)
2533 curCompound.compound.declarations = MkList();
2534 curCompound.compound.declarations->Insert(null, decl);
2536 tempExp = QMkExpId(className);
2537 tempExp.expType = MkClassType(propertyClass.fullName);
2539 exp.op.exp1 = tempExp;
2540 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2547 exp.call.exp = QMkExpId(nameToUse);
2548 exp.call.arguments = args;
2550 ListAdd(args, FixReference(ptr, true));
2552 else if(propertyClass && propertyClass.type == unitClass)
2554 OldList * args = MkList();
2555 ListAdd(args, FixReference(ptr, true));
2557 exp.call.exp = QMkExpId(nameToUse);
2558 exp.call.arguments = args;
2560 else if(propertyClass && propertyClass.type == structClass)
2562 OldList * args = MkList();
2563 char className[1024];
2565 OldList * specs = MkList(), * decls = MkList();
2568 // Make a declaration in the closest compound statement
2569 // (Do not reuse (since using address for function calls)...)
2572 FullClassNameCat(className, propertyClass.fullName, false); //true);
2574 //ListAdd(specs, MkSpecifierName(className));
2575 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2577 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2579 ListAdd(decls, MkInitDeclarator(
2580 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2582 decl = MkDeclaration(specs, decls);
2585 if(!curCompound.compound.declarations)
2586 curCompound.compound.declarations = MkList();
2587 curCompound.compound.declarations->Insert(null, decl);
2590 tempExp = QMkExpId(className);
2591 tempExp.expType = MkClassType(propertyClass.fullName);
2595 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2596 ListAdd(args, FixReference(ptr, true));
2600 ListAdd(args, FixReference(ptr, true));
2601 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2604 if(exp.usage.usageDeepGet)
2607 exp.call.exp = QMkExpId(nameToUse);
2608 exp.call.arguments = args;
2610 FreeExpression(tempExp);
2614 exp.type = bracketsExp;
2615 exp.list = MkList();
2616 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2617 if(exp.usage.usageMember)
2619 ListAdd(exp.list, FixReference(tempExp, true));
2620 exp.byReference = true;
2623 ListAdd(exp.list, tempExp);
2629 exp.call.exp = QMkExpId(nameToUse);
2630 exp.call.arguments = MkList();
2631 ListAdd(exp.call.arguments, FixReference(ptr, true));
2634 else if(prop.conversion)
2636 void * prev = exp.prev, * next = exp.next;
2637 *exp = *exp.member.exp;
2643 else if(classProperty)
2645 // Only process Gets here, Set is processed in opExp's '='
2646 if(exp.usage.usageGet)
2648 if(classProperty.Get)
2650 Identifier id = exp.member.member;
2651 Expression classExp = exp.member.exp;
2652 OldList * args = MkList();
2658 char typeString[2048];
2659 OldList * specs = MkList();
2662 PrintType(exp.expType, typeString, false, false);
2663 decl = SpecDeclFromString(typeString, specs, null);
2664 exp.cast.typeName = MkTypeName(specs, decl);
2667 exp.cast.typeName = QMkType("uint64", null);
2668 exp.cast.exp = MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty")), args);
2670 ListAdd(args, classExp);
2672 char * s = QMkString(id.string);
2673 ListAdd(args, MkExpString(s));
2678 ProcessExpression(exp);
2685 // Get the function address if it's not called
2686 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2690 FreeIdentifier(exp.member.member);
2692 // Process this here since it won't be processed at the end...
2693 exp.member.exp.usage.usageGet = true;
2694 ProcessExpression(exp.member.exp);
2695 // TEST: exp.tempCount = exp.member.exp.tempCount;
2697 if(method.type == virtualMethod)
2699 strcpy(name, "__ecereVMethodID_");
2700 FullClassNameCat(name, method._class.fullName, false);
2702 strcat(name, method.name);
2703 exp.type = indexExp;
2704 if(memberClassSpecifier)
2706 char className[1024];
2707 // Need the class itself here...
2708 strcpy(className, "__ecereClass_");
2709 FullClassNameCat(className, _class.fullName, true);
2710 //MangleClassName(className);
2713 _class.symbol = FindClass(_class.fullName);
2714 DeclareClass(_class.symbol, className);
2716 FreeExpression(exp.member.exp);
2717 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2721 if(exp.thisPtr && _class.type != normalClass)
2723 FreeExpression(exp.member.exp);
2724 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2727 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2729 exp.index.index = MkListOne(QMkExpId(name));
2730 DeclareMethod(method, name);
2734 FreeExpression(exp.member.exp);
2735 exp.type = identifierExp;
2736 strcpy(name, "__ecereMethod_");
2737 FullClassNameCat(name, method._class.fullName, false);
2739 strcat(name, method.name);
2740 exp.identifier = MkIdentifier(name);
2741 DeclareMethod(method, name);
2747 if(subMemberStackPos)
2750 DataMember parentMember = null;
2751 String s, prefix = null;
2752 for(i = 0; i < subMemberStackPos; i++)
2754 DataMember curMember = subMemberStack[i];
2757 for(m = parentMember ? parentMember.members.first : _class.membersAndProperties.first; m; m = m.next)
2759 if(m && !m.isProperty && (m.type == unionMember || m.type == structMember) && !m.name)
2770 prefix = PrintString(prefix, ".__anon", anonID);
2774 prefix = PrintString("__anon", anonID);
2775 parentMember = curMember;
2778 s = exp.member.member.string;
2779 exp.member.member.string = PrintString(prefix, ".", s);
2783 // Process this here since it won't be processed at the end...
2784 if(exp.usage.usageGet)
2786 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2788 ProcessExpression(exp.member.exp);
2789 // TEST: exp.tempCount = exp.member.exp.tempCount;
2791 if(type.kind == classType && type._class && type._class.registered)
2792 DeclareStruct(type._class.registered.fullName, false);
2794 // TESTING THIS NOHEAD STUFF...
2795 if(_class.type == noHeadClass)
2799 else if(_class.type == structClass)
2803 else if(_class.type == bitClass)
2805 OldList * list = MkList();
2806 char mask[32], shift[10];
2807 OldList * specs = MkList();
2808 BitMember bitMember = (BitMember) member;
2809 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2810 TypeName type = MkTypeName(specs, decl);
2811 if(bitMember.mask > MAXDWORD)
2812 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2814 sprintf(mask, FORMAT64HEX, bitMember.mask);
2815 sprintf(shift, "%d", bitMember.pos);
2817 FreeIdentifier(exp.member.member);
2819 // ((type) ((color & mask) >> bitPos))
2820 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2821 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2822 MkExpConstant(shift))))));
2824 exp.type = bracketsExp;
2827 else if(_class.type == unitClass)
2832 // If it's a this pointer, replace by precomputed shortcut
2833 if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2835 char pointerName[1024];
2837 strcpy(pointerName, "__ecerePointer_");
2838 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2839 if(exp.member.exp.identifier)
2840 FreeIdentifier(exp.member.exp.identifier);
2841 exp.member.exp.identifier = MkIdentifier(pointerName);
2843 // Otherwise, access the data the hard way
2846 Expression bytePtr, e;
2847 Expression checkedExp;
2848 char structName[1024];
2849 char className[1024];
2850 strcpy(className, "__ecereClass_");
2851 FullClassNameCat(className, member._class.fullName, true);
2852 //MangleClassName(className);
2854 // classExp = QMkExpId(className);
2856 if(!member._class.symbol)
2857 member._class.symbol = FindClass(member._class.fullName);
2859 DeclareClass(member._class.symbol, className);
2860 DeclareStruct(member._class.fullName, false);
2863 FullClassNameCat(structName, member._class.fullName, false);
2865 checkedExp = exp.member.exp;
2866 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2867 checkedExp.type == castExp)
2869 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2870 checkedExp = checkedExp.list->last;
2871 else if(checkedExp.type == castExp)
2872 checkedExp = checkedExp.cast.exp;
2875 if(checkedExp.type != identifierExp &&
2876 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2877 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2879 char ecereTemp[100];
2881 Context context = PushContext();
2882 if(exp.member.exp.tempCount > exp.tempCount)
2883 exp.tempCount = exp.member.exp.tempCount;
2886 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2887 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2888 curContext = context;
2889 compound = MkCompoundStmt(
2890 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2891 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2892 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2893 if(member._class.fixed)
2895 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2898 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2899 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2902 e = QMkExpId(ecereTemp);
2906 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2907 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2910 compound.compound.context = context;
2911 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2912 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2913 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2915 exp.member.exp = MkExpExtensionCompound(compound);
2917 PopContext(context);
2918 curContext = context.parent;
2922 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2923 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2925 e = QBrackets(QMkExpCond(exp.member.exp,
2926 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2927 MkExpConstant("0")));
2931 if(member._class.fixed)
2933 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2936 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2937 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2943 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2945 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2946 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2949 exp.type = pointerExp;
2954 // Take Out Any Class Specifier (Should have been used by now)
2955 FreeSpecifier(memberClassSpecifier);
2957 // Just moved this at the end... How is it?
2958 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
2960 exp.member.exp.usage.usageGet = true;
2961 exp.member.exp.usage.usageMember = true;
2962 exp.member.exp.tempCount = exp.tempCount;
2963 ProcessExpression(exp.member.exp);
2964 exp.tempCount = exp.member.exp.tempCount;
2965 if((changeToPtr && exp.member.exp.byReference) || noHead)
2966 exp.type = pointerExp;
2970 case extensionCompoundExp:
2972 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
2974 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2976 ProcessStatement(exp.compound);
2978 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2979 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2984 exp.member.exp.usage.usageGet = true;
2985 ProcessExpression(exp.member.exp);
2990 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2991 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2993 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2996 Expression classExp;
2998 FreeTypeName(exp.typeName);
3000 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
3002 ProcessExpressionType(classExp);
3003 ProcessExpression(classExp);
3005 exp.type = bracketsExp;
3006 exp.list = MkListOne(MkExpMember(classExp, MkIdentifier("typeSize")));
3008 ProcessExpressionType(exp);
3009 ProcessExpression(exp);
3018 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
3019 ProcessExpression(exp.cast.exp);
3021 if(exp.cast.exp.byReference)
3022 exp.byReference = exp.cast.exp.byReference;
3023 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
3024 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
3025 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
3026 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
3027 exp.byReference = true;
3029 // Moved this to 1.5...
3030 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
3036 if(exp.usage.usageGet)
3037 exp.cond.cond.usage.usageGet = true;
3038 ProcessExpression(exp.cond.cond);
3039 for(e = exp.cond.exp->first; e; e = e.next)
3041 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
3042 ProcessExpression(e);
3044 if(exp.usage.usageGet)
3045 exp.cond.elseExp.usage.usageGet = true;
3046 ProcessExpression(exp.cond.elseExp);
3051 // Need the class itself here...
3052 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
3054 Specifier spec = exp._classExp.specifiers->first;
3055 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
3058 FreeList(exp._classExp.specifiers, FreeSpecifier);
3059 if(exp._classExp.decl)
3060 FreeDeclarator(exp._classExp.decl);
3062 exp.type = memberExp; //pointerExp;
3063 exp.member.exp = argExp;
3064 exp.member.member = MkIdentifier("dataTypeClass");
3065 exp.member.memberType = dataMember;
3067 ProcessExpressionType(argExp);
3068 ProcessExpressionType(exp);
3069 ProcessExpression(exp);
3074 char className[1024];
3075 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
3076 Symbol classSym = FindClass(string);
3078 strcpy(className, "__ecereClass_");
3079 FullClassNameCat(className, string, true); // TODO: Verify this
3080 //MangleClassName(className);
3081 DeclareClass(classSym, className);
3084 FreeList(exp._classExp.specifiers, FreeSpecifier);
3085 if(exp._classExp.decl)
3086 FreeDeclarator(exp._classExp.decl);
3088 exp.type = identifierExp;
3089 exp.identifier = MkIdentifier(className);
3095 ProcessExpression(exp.vaArg.exp);
3098 case extensionInitializerExp:
3100 ProcessInitializer(exp.initializer.initializer);
3106 if(exp.needTemplateCast != 2 && (exp.needTemplateCast == 1 || (exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate))))
3108 Expression nbExp = GetNonBracketsExp(exp);
3109 Expression inner = GetInnerExp(nbExp);
3111 if((!exp.expType || exp.expType.kind != templateType || nbExp.type != castExp) && !exp.usage.usageRef &&
3112 (!exp.destType || (!exp.destType.truth && (exp.destType.kind != templateType || (exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType))))) &&
3113 (exp.usage.usageDelete || exp.usage.usageGet || exp.usage.usageArg) &&
3114 (!exp.destType || (!exp.destType.passAsTemplate && exp.expType && (exp.expType.kind != pointerType || exp.destType.kind == pointerType) && (exp.destType.kind != pointerType || exp.expType.kind == pointerType))) &&
3115 !inner.needCast && inner.type != opExp)
3117 Expression e = CopyExpContents(exp);
3119 OldList * specs = MkList();
3120 char typeString[1024];
3122 typeString[0] = '\0';
3124 e.needTemplateCast = 2;
3125 inner.needTemplateCast = 2;
3126 nbExp.needTemplateCast = 2;
3127 if(exp.usage.usageDelete)
3128 strcpy(typeString, "void *");
3130 PrintType(exp.expType, typeString, false, false);
3132 decl = SpecDeclFromString(typeString, specs, null);
3134 if(specs && specs->first && ((Specifier)specs->first).type == templateTypeSpecifier &&
3135 exp.destType && !exp.destType.passAsTemplate && exp.destType.kind == templateType && exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType) && !exp.usage.usageArg)
3137 if(decl) FreeDeclarator(decl);
3138 FreeList(specs, FreeSpecifier);
3139 if(exp.destType.templateParameter.dataTypeString)
3142 strcpy(typeString, exp.destType.templateParameter.dataTypeString);
3143 decl = SpecDeclFromString(typeString, specs, null);
3147 specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
3148 decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
3152 e.destType = exp.destType;
3154 exp.destType.refCount++;
3156 exp.type = bracketsExp;
3157 exp.list = MkListOne(MkExpCast(MkTypeName(specs, decl), MkExpBrackets(MkListOne(e))));
3158 exp.needTemplateCast = 2;
3164 static void ProcessInitializer(Initializer init)
3168 case expInitializer:
3171 init.exp.usage.usageGet = true;
3172 ProcessExpression(init.exp);
3173 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
3174 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
3176 FixReference(init.exp, true);
3178 else if(init.exp.destType && init.exp.destType.kind == classType)
3179 FixReference(init.exp, false);
3182 case listInitializer:
3187 for(i = init.list->first; i; i = i.next)
3188 ProcessInitializer(i);
3195 static void ProcessDeclaration(Declaration decl)
3199 case initDeclaration:
3201 if(decl.declarators)
3205 for(d = decl.declarators->first; d; d = d.next)
3208 ProcessInitializer(d.initializer);
3216 static void ProcessStatement(Statement stmt)
3221 ProcessStatement(stmt.labeled.stmt);
3224 if(stmt.caseStmt.exp)
3226 stmt.caseStmt.exp.usage.usageGet = true;
3228 // This expression should be constant...
3229 ProcessExpression(stmt.caseStmt.exp);
3231 if(stmt.caseStmt.stmt)
3232 ProcessStatement(stmt.caseStmt.stmt);
3236 if(stmt.compound.context)
3240 Statement prevCompound = curCompound;
3241 Context prevContext = curContext;
3243 if(!stmt.compound.isSwitch)
3246 curContext = stmt.compound.context;
3249 if(stmt.compound.declarations)
3251 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3252 ProcessDeclaration(decl);
3254 if(stmt.compound.statements)
3256 for(s = stmt.compound.statements->first; s; s = s.next)
3257 ProcessStatement(s);
3259 curContext = prevContext;
3260 curCompound = prevCompound;
3264 case expressionStmt:
3267 if(stmt.expressions)
3269 for(exp = stmt.expressions->first; exp; exp = exp.next)
3271 ProcessExpression(exp);
3282 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3283 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3285 ProcessExpression(exp);
3288 if(stmt.ifStmt.stmt)
3289 ProcessStatement(stmt.ifStmt.stmt);
3290 if(stmt.ifStmt.elseStmt)
3291 ProcessStatement(stmt.ifStmt.elseStmt);
3297 if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
3299 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3300 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3302 ProcessExpression(exp);
3305 ProcessStatement(stmt.switchStmt.stmt);
3311 if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
3313 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3314 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3316 ProcessExpression(exp);
3319 ProcessStatement(stmt.whileStmt.stmt);
3325 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3327 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3328 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3330 ProcessExpression(exp);
3333 if(stmt.doWhile.stmt)
3334 ProcessStatement(stmt.doWhile.stmt);
3340 if(stmt.forStmt.init)
3341 ProcessStatement(stmt.forStmt.init);
3343 if(stmt.forStmt.check)
3345 if(stmt.forStmt.check.expressions)
3347 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3349 ProcessStatement(stmt.forStmt.check);
3351 if(stmt.forStmt.increment)
3353 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3355 ProcessExpression(exp);
3358 if(stmt.forStmt.stmt)
3359 ProcessStatement(stmt.forStmt.stmt);
3371 if(stmt.expressions)
3373 ((Expression)stmt.expressions->last).usage.usageGet = true;
3374 for(exp = stmt.expressions->first; exp; exp = exp.next)
3376 ProcessExpression(exp);
3377 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3378 if(!exp.next && exp.destType && exp.destType.byReference)
3379 FixReference(exp, true);
3384 case badDeclarationStmt:
3386 ProcessDeclaration(stmt.decl);
3392 if(stmt.asmStmt.inputFields)
3394 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3395 if(field.expression)
3396 ProcessExpression(field.expression);
3398 if(stmt.asmStmt.outputFields)
3400 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3401 if(field.expression)
3402 ProcessExpression(field.expression);
3404 if(stmt.asmStmt.clobberedFields)
3406 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3407 if(field.expression)
3408 ProcessExpression(field.expression);
3415 static void ProcessFunction(FunctionDefinition function)
3418 ProcessStatement(function.body);
3421 static void ProcessMemberInitData(MemberInit member)
3423 if(member.initializer)
3424 ProcessInitializer(member.initializer);
3427 static void ProcessInstantiation(Instantiation inst)
3431 MembersInit members;
3432 for(members = inst.members->first; members; members = members.next)
3434 if(members.type == dataMembersInit)
3436 if(members.dataMembers)
3439 for(member = members.dataMembers->first; member; member = member.next)
3440 ProcessMemberInitData(member);
3443 else if(members.type == methodMembersInit)
3445 ProcessFunction((FunctionDefinition)members.function);
3451 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3452 public void ProcessMemberAccess()
3455 for(external = ast->first; external; external = external.next)
3457 curExternal = external;
3458 // There shouldn't be any class member access here anyways...
3459 if(external.type == declarationExternal)
3461 if(external.declaration)
3462 ProcessDeclaration(external.declaration);
3466 for(external = ast->first; external; external = external.next)
3468 curExternal = external;
3469 if(external.type == functionExternal)
3471 ProcessFunction(external.function);
3473 else if(external.type == declarationExternal)
3475 if(external.declaration)
3476 ProcessDeclaration(external.declaration);
3478 else if(external.type == classExternal)
3480 ClassDefinition _class = external._class;
3481 if(_class.definitions)
3484 Class regClass = _class.symbol.registered;
3486 // Process all functions
3487 for(def = _class.definitions->first; def; def = def.next)
3489 if(def.type == functionClassDef)
3491 curExternal = def.function.declarator.symbol.pointerExternal;
3492 ProcessFunction((FunctionDefinition)def.function);
3494 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3496 ProcessInstantiation(def.decl.inst);
3498 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3500 MemberInit defProperty;
3502 // Add this to the context
3505 string = CopyString("this");
3506 type = MkClassType(regClass.fullName);
3508 globalContext.symbols.Add((BTNode)thisSymbol);
3510 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3512 //thisClass = regClass;
3513 ProcessMemberInitData(defProperty); //, regClass, &id);
3517 //globalContext.symbols.Delete((BTNode)thisSymbol);
3518 globalContext.symbols.Remove((BTNode)thisSymbol);
3519 FreeSymbol(thisSymbol);
3521 else if(def.type == propertyClassDef && def.propertyDef)
3523 PropertyDef prop = def.propertyDef;
3525 // Add this to the context
3528 string = CopyString("this");
3529 type = MkClassType(regClass.fullName);
3531 globalContext.symbols.Add((BTNode)thisSymbol);
3533 //thisClass = regClass;
3536 curExternal = prop.symbol.externalSet;
3537 ProcessStatement(prop.setStmt);
3541 curExternal = prop.symbol.externalGet;
3542 ProcessStatement(prop.getStmt);
3546 curExternal = prop.symbol.externalIsSet;
3547 ProcessStatement(prop.issetStmt);
3552 //globalContext.symbols.Delete((BTNode)thisSymbol);
3553 globalContext.symbols.Remove((BTNode)thisSymbol);
3554 FreeSymbol(thisSymbol);
3556 else if(def.type == classPropertyClassDef && def.propertyDef)
3558 PropertyDef prop = def.propertyDef;
3560 //thisClass = regClass;
3563 curExternal = prop.symbol.externalSet;
3564 ProcessStatement(prop.setStmt);
3568 curExternal = prop.symbol.externalGet;
3569 ProcessStatement(prop.getStmt);
3573 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3575 PropertyWatch propertyWatch = def.propertyWatch;
3577 // Add this to the context
3580 string = CopyString("this");
3581 type = MkClassType(regClass.fullName);
3583 globalContext.symbols.Add((BTNode)thisSymbol);
3585 //thisClass = regClass;
3586 if(propertyWatch.compound)
3590 string = CopyString("this");
3591 type = MkClassType(regClass.fullName);
3593 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3595 ProcessStatement(propertyWatch.compound);
3597 // thisClass = null;
3599 //globalContext.symbols.Delete((BTNode)thisSymbol);
3600 globalContext.symbols.Remove((BTNode)thisSymbol);
3601 FreeSymbol(thisSymbol);