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);
29 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
31 memberExp.member.exp = idExp;
33 exp.type = bracketsExp;
34 exp.list = bracketExp.list;
35 bracketExp.list = null;
37 exp.list->Remove(idExp);
38 exp.list->Add(newExp);
39 FreeExpression(bracketExp);
41 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
44 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
45 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
47 Expression newExp = null;
48 Expression exp = *expPtr;
51 newExp = CopyExpression(exp);
52 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
54 exp.type = bracketsExp;
55 exp.list = memberExp.list;
56 memberExp.list = null;
58 exp.list->Remove(exp.list->last);
59 exp.list->Add(newExp);
60 FreeExpression(memberExp);
62 *expPtr = newExp; //FixRefExp(newExp);
66 static Expression FixRefExp(Expression exp)
70 _FixRefExp(&exp, &exp.op.exp1);
71 _FixRefExp(&exp, &exp.op.exp2);
73 else if(exp.type == indexExp)
74 _FixRefExp(&exp, &exp.index.exp);
75 else if(exp.type == memberExp)
76 _FixRefExp(&exp, &exp.member.exp);
80 static Expression FixReference(Expression e, bool wantReference)
82 if(e.expType && e.type != constantExp)
84 Type type = e.expType;
85 bool isPointer = false;
87 if(type.kind == TypePointer && type.type && type.type.kind == classType)
94 if(type.kind == classType) // || type.kind == TypeInt)
96 Class _class = type._class ? type._class.registered : null;
97 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
98 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
99 if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
100 (_class.type == systemClass && _class.base &&
101 strcmp(_class.fullName, "uintptr") &&
102 strcmp(_class.fullName, "intptr") &&
103 strcmp(_class.fullName, "uintsize") &&
104 strcmp(_class.fullName, "intsize"))))
106 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
107 if(wantReference != (e.byReference || isPointer))
112 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
116 exp.byReference = wantReference;
117 exp = exp.list->last;
122 else if(exp.type == castExp)
124 exp.byReference = wantReference;
127 else if(exp.type == conditionExp)
129 if(exp.cond.exp->last)
130 FixReference(exp.cond.exp->last, wantReference);
131 FixReference(exp.cond.elseExp, wantReference);
136 if(wantReference != (exp.byReference || isPointer))
138 Expression newExp { };
141 if(exp.destType) exp.destType.refCount++;
142 if(exp.expType) exp.expType.refCount++;
146 exp.op.exp2 = newExp;
152 e.byReference = wantReference;
153 exp.byReference = wantReference;
166 static bool FixMember(Expression exp)
168 bool byReference = false;
171 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
173 if(exp.list->count > 1)
175 exp = exp.list->last;
177 else if(exp.type == castExp)
184 FixReference(exp, true);
186 byReference = exp.byReference;
193 static void ProcessExpression(Expression exp)
195 Location oldyylloc = yylloc;
197 char debugExpString[1024] = "";
198 PrintExpression(exp, debugExpString);
208 if(exp.expType && exp.expType.kind == methodType)
210 Class _class = exp.expType.methodClass;
211 Method method = exp.expType.method;
212 if(method.type == virtualMethod)
217 OldList * specs = MkList();
218 strcpy(name, "__ecereVMethodID_");
219 FullClassNameCat(name, method._class.fullName, false);
221 strcat(name, method.name);
223 DeclareMethod(method, name);
225 // Cast function to its type
226 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
227 if(!method.dataType.staticMethod)
229 Declarator funcDecl = GetFuncDecl(decl);
231 if(!funcDecl.function.parameters)
232 funcDecl.function.parameters = MkList();
234 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
235 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
237 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
238 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
241 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
242 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
245 typeName = MkTypeName(specs, decl);
249 char className[1024];
250 // Need the class itself here...
251 strcpy(className, "__ecereClass_");
252 FullClassNameCat(className, _class.fullName, true);
253 MangleClassName(className);
256 _class.symbol = FindClass(_class.fullName);
257 DeclareClass(_class.symbol, className);
259 exp.type = bracketsExp;
260 exp.list = MkListOne(MkExpCast(typeName,
261 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
262 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
268 strcpy(name, "__ecereMethod_");
269 FullClassNameCat(name, method._class.fullName, false);
271 strcat(name, method.name);
273 delete exp.identifier.string;
275 exp.identifier._class = null;
276 exp.identifier.string = CopyString(name);
277 DeclareMethod(method, name);
281 if(exp.usage & USAGE_MEMBER)
282 FixReference(exp, true);
295 OldList * args = MkList();
297 if(exp.type == renewExp || exp.type == renew0Exp)
298 ListAdd(args, exp._renew.exp);
300 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
304 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
305 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
306 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
307 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
309 exp.call.arguments = args;
312 ProcessExpression(exp);
317 Expression exp1 = exp.op.exp1;
318 Expression exp2 = exp.op.exp2;
322 // Assignment Operators
325 exp.op.exp2.usage.usageGet = true;
337 exp.op.exp2.usage.usageGet = true;
346 if(exp.op.exp1 && exp.op.exp2)
348 exp.op.exp1.usage.usageGet = true;
349 exp.op.exp2.usage.usageGet = true;
353 exp.op.exp2.usage.usageRef = true;
362 exp.op.exp1.usage.usageGet = true;
367 exp.op.exp2.usage.usageGet = true;
370 // Binary only operators
386 exp.op.exp1.usage.usageGet = true;
388 exp.op.exp2.usage.usageGet = true;
392 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
393 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
394 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
395 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
397 Expression memberExp;
398 Expression parentExp = null; // Where to take memberExp out from
400 // TOCHECK: See note below for this if
401 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
403 // Extra bit of code to access deep properties...
404 Expression testExp, topExp = null;
405 Expression lastExp = exp.op.exp1, parentExp = null;
406 Property lastProperty = null;
409 char setName[1024], getName[1024];
410 testExp = exp.op.exp1.member.exp;
413 // Is further fixing needed to address if statement above in the same way?
416 if(testExp.type == castExp)
417 testExp = testExp.cast.exp;
418 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
419 testExp = testExp.list->last;
420 else if(testExp.type == ExpressionType::memberExp)
427 if(testExp.member.memberType == propertyMember ||
428 testExp.member.memberType == reverseConversionMember)
430 Type type = testExp.member.exp.expType;
433 if(type.kind == classType)
435 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
436 Class convertTo = null;
437 if(testExp.member.memberType == reverseConversionMember)
440 _class = FindClass(testExp.member.member.string).registered;
441 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
442 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
446 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
448 if(lastProperty && lastProperty.Get && lastProperty.Set)
450 DeclareProperty(lastProperty, setName, getName);
451 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
452 propertyClass = convertTo ? _class :
453 ((((Symbol)lastProperty.symbol).type &&
454 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
455 // TODO: Handle this kind of things with bit classes?
456 if(propertyClass && propertyClass.type == structClass)
461 else if(propertyClass && propertyClass.type == bitClass)
473 testExp = testExp.member.exp;
477 if(propertyClass.type == structClass)
481 char className[1024];
484 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
485 tempExp = QMkExpId(className);
486 tempExp.expType = MkClassType(propertyClass.fullName);
488 parentExp.member.exp = tempExp;
490 value = MkExpBrackets(MkList());
492 copy = CopyExpression(topExp);
493 copy.usage.usageGet = true;
494 copy.usage.usageDeepGet = true;
496 ListAdd(value.list, copy);
497 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
498 ListAdd(value.list, CopyExpression(tempExp));
499 value.expType = tempExp.expType;
500 tempExp.expType.refCount++;
502 // Go on as usual with these new values:
503 exp.op.exp1 = topExp;
510 else if(propertyClass.type == bitClass)
514 char className[1024];
517 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
518 tempExp = QMkExpId(className);
519 tempExp.expType = MkClassType(propertyClass.fullName);
521 parentExp.member.exp = tempExp;
523 value = MkExpBrackets(MkList());
525 copy = CopyExpression(topExp);
526 copy.usage.usageGet = true;
527 copy.usage.usageDeepGet = true;
529 ListAdd(value.list, copy);
530 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
531 ListAdd(value.list, CopyExpression(tempExp));
532 value.expType = tempExp.expType;
533 value.expType.refCount++;
535 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
537 // Go on as usual with these new values:
538 exp.op.exp1 = topExp;
548 memberExp = exp.op.exp1;
550 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
551 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
553 parentExp = memberExp;
554 if(memberExp.type == extensionCompoundExp)
555 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
557 memberExp = memberExp.list->last;
560 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
561 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
562 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
564 ProcessExpression(memberExp);
566 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
567 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
569 parentExp = memberExp;
570 if(memberExp.type == extensionCompoundExp)
571 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
573 memberExp = memberExp.list->last;
576 if(memberExp && memberExp.type == extensionCompoundExp)
578 parentExp = memberExp;
579 if(memberExp.type == extensionCompoundExp)
581 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
582 if(stmt && stmt.type != expressionStmt) stmt = null;
583 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
586 stmt.expressions->Remove(memberExp);
587 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
588 exp.type = bracketsExp;
589 exp.list = MkListOne(parentExp);
590 ProcessExpression(exp);
595 memberExp = memberExp.list->last;
599 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
601 if(memberExp && memberExp.type == ExpressionType::memberExp)
603 Type type = memberExp.member.exp.expType;
606 // Check if it's an instance
607 if(type.kind == classType || type.kind == subClassType)
609 // TODO: SOMETHING WRONG HERE...
610 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
612 if(memberExp == exp1)
616 if(parentExp.type == extensionCompoundExp)
617 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
619 parentExp.list->Remove(memberExp);
622 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
624 BitMember bitMember =
625 (BitMember)eClass_FindDataMember(_class,
626 memberExp.member.member.string, privateModule, null, null);
627 char mask[32], shift[10];
628 OldList * specs = MkList();
629 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
630 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
631 TypeName type = MkTypeName(specs, decl);
633 if(bitMember.mask > MAXDWORD)
634 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
636 sprintf(mask, FORMAT64HEX, bitMember.mask);
637 sprintf(shift, "%d", bitMember.pos);
639 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
640 exp.op.exp1 = memberExp.member.exp;
642 // TESTING THIS FOR: argb.color.r = 1;
643 //ProcessExpression(memberExp.member.exp);
645 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
646 if(exp.op.op == XOR_ASSIGN)
648 exp.op.exp2 = MkExpOp(MkExpBrackets(
649 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
653 exp.op.exp2 = MkExpOp(
654 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
655 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
656 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
657 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift)))));
660 memberExp.member.exp = null;
661 FreeExpression(memberExp);
663 // TESTING THIS FOR: argb.color.r = 1;
664 ProcessExpression(exp);
667 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
670 else if(memberExp.member.memberType != dataMember)
673 Class convertTo = null;
674 ClassProperty classProperty = null;
676 if(memberExp.member.memberType == reverseConversionMember)
679 _class = FindClass(memberExp.member.member.string).registered;
680 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
681 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
684 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
686 if(memberExp.member.memberType == classPropertyMember)
687 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
689 exp.tempCount = memberExp.member.exp.tempCount;
693 // Only process Gets here, Set is processed in opExp's '='
694 if(classProperty.Set)
696 Identifier id = memberExp.member.member;
697 Expression classExp = memberExp.member.exp;
698 Expression value = exp.op.exp2;
700 memberExp.member.exp = null;
701 memberExp.member.member = null;
704 FreeExpContents(memberExp);
708 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
709 exp.call.arguments = MkList();
710 ListAdd(exp.call.arguments, classExp);
711 ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
712 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
716 ProcessExpression(exp);
722 if((!convertTo && prop.Set) || (convertTo && prop.Get))
724 Expression value = exp.op.exp2;
725 char setName[1024], getName[1024];
726 char * setToUse = convertTo ? getName : setName;
727 char * getToUse = convertTo ? setName : getName;
728 bool needAddress = false;
729 int operator = exp.op.op;
732 case MUL_ASSIGN: operator = '*'; break;
733 case DIV_ASSIGN: operator = '/'; break;
734 case MOD_ASSIGN: operator = '%'; break;
735 case SUB_ASSIGN: operator = '-'; break;
736 case ADD_ASSIGN: operator = '+'; break;
737 case LEFT_ASSIGN: operator = LEFT_OP; break;
738 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
739 case AND_ASSIGN: operator = '&'; break;
740 case OR_ASSIGN: operator = '|'; break;
741 case XOR_ASSIGN: operator = '^'; break;
746 if(operator == INC_OP)
747 value = MkExpOp(CopyExpression(memberExp),
748 '+', MkExpConstant("1"));
749 else if(operator == DEC_OP)
750 value = MkExpOp(CopyExpression(memberExp),
751 '-', MkExpConstant("1"));
754 value = MkExpOp(CopyExpression(memberExp),
758 value.expType = memberExp.expType;
759 memberExp.expType.refCount++;
760 value.usage.usageArg = true;
764 // Dont free exp2, we're using it
769 value.usage.usageArg = true;
771 DeclareProperty(prop, setName, getName);
773 if(memberExp.member.exp)
774 ProcessExpression(memberExp.member.exp);
776 // If get flag present
777 if(exp.usage.usageGet &&
778 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
780 OldList * list = MkList();
783 Context context = PushContext();
786 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
787 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
789 curContext = context;
790 exp.type = extensionCompoundExp;
791 exp.compound = MkCompoundStmt(
792 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
793 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
794 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
801 ListAdd(args, value);
802 ListAdd(args, QMkExpId(ecereTemp));
803 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
807 ListAdd(args, QMkExpId(ecereTemp));
808 ListAdd(args, value);
809 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
815 ListAdd(args, QMkExpId(ecereTemp));
817 args->Insert(null, QMkExpId(ecereTemp));
818 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
820 exp.compound.compound.context = context;
822 curContext = context.parent;
826 Expression newExp = exp;
828 if(parentExp && parentExp.type == extensionCompoundExp)
830 newExp = Expression { };
831 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
832 FreeType(exp.expType);
833 FreeType(exp.destType);
836 parentExp.type = dummyExp;
837 parentExp.expType = null;
838 parentExp.destType = null;
841 newExp.type = callExp;
842 newExp.call.exp = QMkExpId(setToUse);
843 newExp.call.arguments = MkList();
846 ListAdd(newExp.call.arguments, value);
847 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
851 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
852 ListAdd(newExp.call.arguments, value);
857 // Take it out from there
858 memberExp.member.exp = null;
860 // Don't use the temporaries used by the left side...
863 value.tempCount = exp.tempCount;
864 ProcessExpression(value);
866 FixReference(value, true);
869 FreeExpression(memberExp);
873 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
876 memberExp.member.memberType = dataMember;
879 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
884 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
885 if(method && method.type == virtualMethod && type.kind != subClassType)
887 Expression value = exp.op.exp2;
888 // Don't use the temporaries used by the left side...
889 value.tempCount = exp.tempCount;
890 ProcessExpression(value);
892 if(memberExp.member.exp)
893 ProcessExpression(memberExp.member.exp);
895 if(exp.usage.usageGet)
897 OldList * list = MkList();
902 ListAdd(args, memberExp.member.exp);
904 char * string = QMkString(memberExp.member.member.string);
905 ListAdd(args, MkExpString(string));
908 ListAdd(args, value);
909 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
910 ListAdd(list, CopyExpression(value));
911 exp.type = bracketsExp;
918 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
919 exp.call.arguments = MkList();
920 ListAdd(exp.call.arguments, memberExp.member.exp);
922 char * string = QMkString(memberExp.member.member.string);
923 ListAdd(exp.call.arguments, MkExpString(string));
926 ListAdd(exp.call.arguments, value);
929 memberExp.member.exp = null;
932 FreeExpression(memberExp);
936 else if(memberExp.member.memberType == dataMember)
938 //if(exp.usage & USAGE_GET);
939 //FixReference(value, true);
940 if(FixMember(memberExp.member.exp))
942 // TESTING THIS HERE:
943 ProcessExpression(memberExp);
945 memberExp.type = pointerExp;
952 else if(exp.op.op == _INCREF)
954 Expression object = exp.op.exp2;
956 FreeExpContents(exp);
960 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
962 else if(exp.op.op == DELETE)
964 Expression object = exp.op.exp2;
965 OldList * args = MkList();
967 exp.type = bracketsExp;
970 object.usage.usageDelete = true;
972 ProcessExpression(object);
974 ListAdd(args, object);
976 // TOFIX: Same time as when we fix for = 0
978 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
979 exp.expType._class.registered.type == normalClass &&
980 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
982 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
983 ProcessExpressionType(decRefExp);
984 ListAdd(exp.list, decRefExp);
986 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
989 char className[1024];
990 OldList * list = MkList();
992 strcpy(className, "__ecereClass_");
993 FullClassNameCat(className, exp.expType._class.string, true);
994 MangleClassName(className);
996 DeclareClass(exp.expType._class, className);
998 // Call the non virtual destructor
999 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1000 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1002 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1004 MkExpBrackets(MkListOne(MkExpCondition(
1005 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1006 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1011 OldList * list = MkList();
1013 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1015 char className[1024];
1017 if(_class.templateClass) _class = _class.templateClass;
1018 strcpy(className, "__ecereClass_");
1019 FullClassNameCat(className, _class.fullName, false /*true*/);
1020 MangleClassName(className);
1023 _class.symbol = FindClass(_class.fullName);
1024 DeclareClass(_class.symbol, className);
1026 // Call the non virtual destructor
1030 QMkExpId(className),
1031 MkIdentifier("Destructor")
1036 QMkExpId(className),
1037 MkIdentifier("Destructor")
1039 CopyList(args, CopyExpression)
1046 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1051 CopyExpression(object),
1061 else if(exp.expType && exp.expType.kind == templateType)
1063 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1066 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1068 OldList * qualifiers = MkList();
1069 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1071 typeName = MkTypeName(qualifiers, declarator);
1073 ProcessExpressionType(classExp);
1074 args->Insert(null, CopyExpression(classExp));
1075 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1076 ListAdd(exp.list, MkExpCall(
1077 MkExpBrackets(MkListOne(MkExpCast(typeName,
1078 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1079 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1080 //ProcessExpression(exp.list->last);
1084 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1086 //ProcessExpression(object);
1088 ListAdd(exp.list, MkExpOp(CopyExpression(object), '=', MkExpConstant("0")));
1092 // TESTING THIS HERE...
1093 ProcessExpression(exp);
1096 if(exp.type == opExp)
1098 // Handle assigment of template structures
1099 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1100 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1102 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1105 // memcpy((byte *)array + (count * dataTypeClass.size), dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1107 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1108 OldList * args = MkList();
1109 Expression derefExp = exp.op.exp1;
1110 Expression sizeExp = MkExpCondition(MkExpBrackets(MkListOne(
1112 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1114 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1115 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1116 MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize")));
1118 if(exp.op.exp1.type == indexExp)
1120 Expression indexExp = derefExp.index.exp;
1121 OldList * indexExpIndex = derefExp.index.index;
1123 derefExp.index.index = null;
1124 derefExp.index.exp = null;
1125 FreeExpression(derefExp);
1127 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1128 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1132 Expression indexExp = derefExp.op.exp2;
1133 derefExp.op.exp2 = null;
1134 FreeExpression(derefExp);
1135 derefExp = indexExp;
1138 args->Add(derefExp);
1139 ProcessExpressionType(args->last);
1140 ProcessExpression(args->last);
1142 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1143 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1144 MkListOne(exp.op.exp2), MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1146 thisClass = curExternal.function ? curExternal.function._class : null;
1150 string = CopyString("this");
1151 type = MkClassType(thisClass.fullName);
1153 globalContext.symbols.Add((BTNode)thisSymbol);
1155 ProcessExpressionType(args->last);
1156 ProcessExpression(args->last);
1159 ProcessExpressionType(args->last);
1160 ProcessExpression(args->last);
1162 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1163 exp.type = bracketsExp;
1165 //globalContext.symbols.Delete((BTNode)thisSymbol);
1166 globalContext.symbols.Remove((BTNode)thisSymbol);
1167 FreeSymbol(thisSymbol);
1173 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1174 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1176 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1179 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1180 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1182 exp.type = bracketsExp;
1183 exp.list = MkListOne(
1185 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1187 // ((class.type == structClass) ?
1188 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1191 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1193 // ((class.type == normalClass || class.type == noHeadClass) ?
1194 MkExpCondition(MkExpBrackets(MkListOne(
1196 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1198 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1199 // *((void **)array)
1200 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1201 CopyExpression(exp.op.exp2))))))),
1203 // ((class.size == 1) ?
1204 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1206 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1207 CopyExpression(exp.op.exp2)))))),
1209 // ((class.size == 2) ?
1210 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1211 // *((uint16 *)array)
1212 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1213 CopyExpression(exp.op.exp2)))))),
1215 // ((class.size == 4) ?
1216 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1217 // *((uint32 *)array)
1218 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1219 CopyExpression(exp.op.exp2)))))),
1221 // *((uint64 *)array)
1222 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1223 exp.op.exp2)))))))))))))))))))));
1225 // Add this to the context
1226 thisClass = curExternal.function ? curExternal.function._class : null;
1230 string = CopyString("this");
1231 type = MkClassType(thisClass.fullName);
1233 globalContext.symbols.Add((BTNode)thisSymbol);
1235 ProcessExpressionType(exp.list->first);
1236 ProcessExpression(exp.list->first);
1238 //globalContext.symbols.Delete((BTNode)thisSymbol);
1239 globalContext.symbols.Remove((BTNode)thisSymbol);
1240 FreeSymbol(thisSymbol);
1251 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1252 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1253 ProcessExpression(exp.op.exp1);
1256 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1257 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1258 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1259 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*/))
1260 FixReference(exp.op.exp1, false);
1261 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1265 // Don't use the temporaries used by the left side...
1267 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1268 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1269 ProcessExpression(exp.op.exp2);
1270 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1274 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1275 (exp.op.exp2.expType._class.registered.type != normalClass &&
1276 exp.op.exp2.expType._class.registered.type != structClass &&
1277 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1279 // TESTING THIS TEMPLATE TYPE CHECK HERE
1280 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1282 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1283 //FixReference(exp.op.exp2, false);
1286 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1289 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)
1291 // Preserve prev, next
1292 Expression next = exp.next, prev = exp.prev;
1293 Expression derefExp = exp.op.exp2;
1294 Expression refExp = exp.op.exp2.op.exp2;
1295 Type expType = exp.expType, destType = exp.destType;
1297 derefExp.op.exp2 = null;
1298 FreeExpression(derefExp);
1299 FreeType(exp.expType);
1300 FreeType(exp.destType);
1310 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)
1312 Expression exp2 = exp.op.exp2;
1313 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1316 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1318 exp.type = bracketsExp;
1319 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1320 MkExpOp(null, '&', exp2)), '+',
1321 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1322 MkListOne((e = MkExpCondition(MkExpBrackets(MkListOne(
1326 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))),
1328 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))),
1330 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))))
1332 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1333 MkExpMember(classExp, MkIdentifier("typeSize"))))))));
1335 // Add this to the context
1336 thisClass = curExternal.function ? curExternal.function._class : null;
1340 string = CopyString("this");
1341 type = MkClassType(thisClass.fullName);
1343 //globalContext.symbols.Add((BTNode)thisSymbol);
1345 ProcessExpressionType(e);
1346 ProcessExpression(e);
1348 //globalContext.symbols.Remove((BTNode)thisSymbol);
1349 //FreeSymbol(thisSymbol);
1358 FreeExpression(exp1);
1360 FreeExpression(exp2);
1365 case extensionExpressionExp:
1370 for(e = exp.list->first; e; e = e.next)
1374 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1376 e.tempCount = exp.tempCount;
1377 ProcessExpression(e);
1379 exp.byReference = e.byReference;
1380 exp.tempCount = e.tempCount;
1384 exp.expType = e.expType;
1393 /*bool isBuiltin = exp && exp.index.exp &&
1394 (exp.index.exp.type == ExpressionType::arrayExp ||
1395 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1397 Expression checkedExp = exp.index.exp;
1398 bool isBuiltin = false;
1400 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1402 if(checkedExp.type == extensionCompoundExp)
1407 else if(checkedExp.type == bracketsExp)
1408 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1410 checkedExp = checkedExp.cast.exp;
1413 exp.index.exp.tempCount = exp.tempCount;
1415 exp.index.exp.usage.usageGet = true;
1416 ProcessExpression(exp.index.exp);
1418 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1419 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1421 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1424 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1425 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1427 exp.type = bracketsExp;
1428 exp.list = MkListOne(
1430 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1432 // ((class.type == structClass) ?
1433 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1434 // ((byte *)array) + (i) * class.size
1435 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1436 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1437 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1439 // ((class.type == normalClass || class.type == noHeadClass) ?
1440 MkExpCondition(MkExpBrackets(MkListOne(
1442 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1444 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1445 // ((void **)array)[i]
1446 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1447 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression)))),
1449 // ((class.size == 1) ?
1450 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1451 // ((byte *)array)[i]
1452 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1453 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1455 // ((class.size == 2) ?
1456 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1457 // ((uint16 *)array)[i]
1458 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1459 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1461 // ((class.size == 4) ?
1462 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1463 // ((uint32 *)array)[i]
1464 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1465 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1467 // ((uint64 *)array)[i]
1468 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1469 exp.index.exp))), exp.index.index))))))))))))))))));
1471 // Add this to the context
1472 thisClass = curExternal.function ? curExternal.function._class : null;
1476 string = CopyString("this");
1477 type = MkClassType(thisClass.fullName);
1479 globalContext.symbols.Add((BTNode)thisSymbol);
1481 ProcessExpressionType(exp.list->first);
1482 ProcessExpression(exp.list->first);
1484 //globalContext.symbols.Delete((BTNode)thisSymbol);
1485 globalContext.symbols.Remove((BTNode)thisSymbol);
1486 FreeSymbol(thisSymbol);
1494 for(e = exp.index.index->first; e; e = e.next)
1497 e.usage.usageGet = true;
1498 ProcessExpression(e);
1500 // Ignore temps in the index for now...
1501 exp.tempCount = exp.index.exp.tempCount;
1503 if(exp.index.exp.expType)
1505 Type source = exp.index.exp.expType;
1506 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1507 eClass_IsDerived(source._class.registered, containerClass))
1509 Class _class = source._class.registered;
1510 bool isArray = false;
1511 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1512 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1514 if(isArray && _class.templateArgs)
1516 OldList * specs = MkList();
1517 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1518 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
1519 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1520 ProcessExpressionType(exp.index.exp);
1521 ProcessExpression(exp);
1523 else if(isBuiltin && _class.templateArgs)
1525 OldList * specs = MkList();
1526 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1527 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
1528 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1529 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1530 ProcessExpressionType(exp.index.exp);
1531 ProcessExpression(exp);
1533 else if(_class.templateArgs)
1535 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1537 char iteratorType[1024];
1538 OldList * declarations = MkList();
1539 OldList * statements = MkList();
1540 OldList * args = MkList();
1541 OldList * instMembers = MkList();
1543 Context context = PushContext();
1545 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1547 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1549 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1550 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1552 ListAdd(args, MkExpBrackets(exp.index.index));
1553 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1555 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1556 MkIdentifier("Index")), args))));
1558 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1559 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1561 exp.type = bracketsExp;
1562 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1563 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1564 expExt.compound.compound.context = context;
1565 PopContext(context);
1566 expExt.usage = exp.usage;
1567 ProcessExpressionType(exp.list->first);
1568 ProcessExpressionInstPass(exp.list->first);
1569 ProcessExpression(exp.list->first);
1578 Expression memberExp;
1579 bool typedObject = false;
1580 Type ellipsisDestType = null;
1581 bool usedEllipsis = false;
1583 if(exp.call.arguments)
1585 for(e = exp.call.arguments->first; e; e = e.next)
1587 e.usage.usageGet = true;
1588 e.usage.usageArg = true;
1589 e.tempCount = Max(e.tempCount, exp.tempCount);
1590 ProcessExpression(e);
1591 exp.tempCount = Max(exp.tempCount, e.tempCount);
1594 exp.call.exp.usage.usageGet = true;
1595 exp.call.exp.usage.usageCall = true;
1596 exp.call.exp.tempCount = exp.tempCount;
1597 ProcessExpression(exp.call.exp);
1598 memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1600 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1602 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1603 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1604 Method method = exp.call.exp.expType.method;
1605 if(method.type == virtualMethod)
1611 OldList * specs = MkList();
1612 strcpy(name, "__ecereVMethodID_");
1613 FullClassNameCat(name, method._class.fullName, false);
1615 strcat(name, method.name);
1617 DeclareMethod(method, name);
1620 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1621 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1622 // Cast function to its type
1624 Context context = SetupTemplatesContext(method._class);
1626 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1628 FinishTemplatesContext(context);
1631 if(method.dataType && !method.dataType.staticMethod)
1633 Declarator funcDecl = GetFuncDecl(decl);
1635 if(!funcDecl.function.parameters)
1636 funcDecl.function.parameters = MkList();
1638 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1639 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1641 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1642 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1645 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1649 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)));
1650 // Testing this for any_object::
1651 if(!method.dataType.extraParam)
1652 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1656 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1657 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1661 typeName = MkTypeName(specs, decl);
1663 // Added !exp.call.exp.expType.methodClass
1664 if(memberExp && memberExp.member.exp.expType)
1666 Type type = memberExp.member.exp.expType;
1668 if(type.kind == classType && type._class && type._class.registered)
1670 Class regClass = type._class.registered;
1671 ClassType classType = regClass.type;
1672 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1673 argClass = regClass;
1675 else if(type.kind == subClassType)
1677 argClass = FindClass("ecere::com::Class").registered;
1679 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1681 argClass = FindClass("char *").registered;
1683 else if(type.kind == pointerType)
1685 argClass = eSystem_FindClass(privateModule, "uintptr");
1686 FreeType(memberExp.member.exp.expType);
1687 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1688 memberExp.member.exp.byReference = true;
1692 char string[1024] = "";
1694 PrintTypeNoConst(type, string, false, true);
1695 classSym = FindClass(string);
1696 if(classSym) argClass = classSym.registered;
1700 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1706 Type type = memberExp ? memberExp.member.exp.expType : null;
1707 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1708 char className[1024];
1709 bool useInstance = false;
1711 if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
1712 strcpy(className, "class");
1716 // TESTING: Moved this here...
1717 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1722 // TODO: Unhandled case here, what should happen?
1725 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1726 if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
1727 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1728 cl = cl.templateClass;
1730 // Need the class itself here...
1731 strcpy(className, "__ecereClass_");
1732 FullClassNameCat(className, cl.fullName, true);
1733 MangleClassName(className);
1736 cl.symbol = FindClass(cl.fullName);
1738 DeclareClass(cl.symbol, className);
1741 if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
1743 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1744 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1745 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1747 else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
1748 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1750 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1751 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1752 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1756 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1757 // as opposed to the File class vTbl one
1759 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1761 Context context = PushContext();
1762 c = MkExpExtensionCompound(MkCompoundStmt(
1763 MkListOne(MkDeclaration(
1764 MkListOne(MkSpecifierName("Instance")),
1765 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1766 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
1767 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1768 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1769 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1770 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
1771 c.compound.compound.context = context;
1772 PopContext(context);
1773 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1774 MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1781 strcpy(name, "__ecereMethod_");
1782 FullClassNameCat(name, method._class.fullName, false);
1784 strcat(name, method.name);
1786 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1787 DeclareMethod(method, name);
1788 if(memberExp && memberExp.expType && method.dataType)
1790 exp.call.exp.expType = method.dataType;
1791 method.dataType.refCount++;
1794 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1796 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1798 if(!exp.call.arguments)
1799 exp.call.arguments = MkList();
1801 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1803 if(memberExp.member.exp.expType.kind != classType ||
1804 memberExp.member.exp.expType._class.registered.type == enumClass ||
1805 memberExp.member.exp.expType._class.registered.type == unitClass)
1807 char typeString[1024] = "";
1808 if(memberExp.member.exp.expType.kind != classType)
1809 PrintType(memberExp.member.exp.expType, typeString, false, true);
1811 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1814 // memberExp.member.exp.expType.kind = classType;
1815 // memberExp.member.exp.expType._class = FindClass(typeString);
1817 FreeType(memberExp.member.exp.expType);
1818 memberExp.member.exp.expType = Type
1821 _class = FindClass(typeString);
1825 // Default to an int instead
1826 if(!memberExp.member.exp.expType._class)
1828 // TODO: Shouldn't get here...
1829 memberExp.member.exp.expType.kind = TypeInt;
1834 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1836 bool changeReference = false;
1837 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1839 // Patched so that class isn't considered SYSTEM...
1840 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1841 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1842 changeReference = true;
1843 if(!memberExp.member.exp.expType.classObjectType &&
1845 (memberExp.member.exp.expType.kind != pointerType &&
1846 (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1847 !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1848 method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
1849 changeReference = true;
1850 if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
1851 changeReference = true;
1854 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1855 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1857 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1858 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1860 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1862 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1863 memberExp.member.exp.op.exp2 = null;
1865 else if(!memberExp.member.exp.byReference)
1867 // TESTING THIS... REUSE THIS CODE?
1868 Expression checkedExp = memberExp.member.exp;
1869 Expression parentExp = null;
1871 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1873 parentExp = checkedExp;
1874 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1875 checkedExp = checkedExp.list->last;
1876 else if(checkedExp.type == castExp)
1877 checkedExp = checkedExp.cast.exp;
1879 newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
1880 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1882 parentExp.list->Remove(checkedExp);
1883 parentExp.list->Add(newExp);
1885 else if(parentExp && parentExp.type == castExp)
1887 parentExp.cast.exp = newExp;
1888 // Add a dereference level here
1889 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1891 if(typedObject && !memberExp.member.exp.expType.classObjectType)
1893 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
1894 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
1895 (parentExp ? parentExp : newExp).destType = destType;
1896 if(checkedExp.expType) checkedExp.expType.refCount++;
1898 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1901 exp.call.arguments->Insert(null, memberExp.member.exp);
1904 exp.call.arguments->Insert(null, memberExp.member.exp);
1907 char className[1024];
1908 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
1909 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1910 Class cl = argClass ? argClass : regClass;
1913 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1914 strcpy(className, "class");
1917 // Need the class itself here...
1918 strcpy(className, "__ecereClass_");
1919 FullClassNameCat(className, cl.fullName, true);
1920 MangleClassName(className);
1923 cl.symbol = FindClass(cl.fullName);
1924 DeclareClass(cl.symbol, className);
1929 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
1931 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
1933 Context context = PushContext();
1934 c = MkExpExtensionCompound(MkCompoundStmt(
1935 MkListOne(MkDeclaration(
1936 MkListOne(MkSpecifierName("Instance")),
1937 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1938 MkInitializerAssignment(memberExpMemberExp))))),
1939 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1940 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1941 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
1942 MkExpIdentifier(MkIdentifier(className))))))));
1943 c.compound.compound.context = context;
1944 PopContext(context);
1946 exp.call.arguments->Insert(null, c);
1948 memberExpMemberExp = null; // We used this
1951 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
1955 if(memberExpMemberExp)
1956 FreeExpression(memberExpMemberExp);
1959 exp.call.arguments->Insert(null, memberExp.member.exp);
1960 memberExp.member.exp = null;
1962 FreeExpression(memberExp);
1964 /*else if(method->dataType)
1968 if(exp.call.arguments)
1970 for(e = exp.call.arguments->first; e; e = e.next)
1972 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
1973 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
1974 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
1975 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
1977 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
1978 ellipsisDestType = destType;
1981 Type type = e.expType;
1982 Class _class = null;
1983 //Type destType = e.destType;
1985 if(type.kind == classType && type._class && type._class.registered)
1987 _class = type._class.registered;
1989 else if(type.kind == subClassType)
1991 _class = FindClass("ecere::com::Class").registered;
1993 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1995 _class = FindClass("char *").registered;
1997 else if(type.kind == pointerType)
1999 _class = eSystem_FindClass(privateModule, "uintptr");
2000 FreeType(e.expType);
2001 e.expType = ProcessTypeString("uintptr", false);
2002 // Assume null pointers means 'no object' rather than an object holding a null pointer
2003 e.byReference = true;
2007 char string[1024] = "";
2009 PrintTypeNoConst(type, string, false, true);
2010 classSym = FindClass(string);
2011 if(classSym) _class = classSym.registered;
2012 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2015 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...
2016 (!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))) ||
2017 destType.byReference)))
2019 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2020 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2021 // TESTING WITHOUT THE ABOVE NOW!
2023 Expression checkedExp;
2024 Expression parentExp;
2029 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2031 parentExp = checkedExp;
2032 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2034 if(checkedExp.type == extensionCompoundExp)
2036 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2039 checkedExp = checkedExp.list->last;
2041 else if(checkedExp.type == castExp)
2042 checkedExp = checkedExp.cast.exp;
2045 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2048 Expression newExp = e.op.exp2;
2049 exp.call.arguments->Insert(e.prev, newExp);
2050 exp.call.arguments->Remove(e);
2055 newExp = checkedExp.op.exp2;
2056 checkedExp.op.exp2 = null;
2057 FreeExpContents(checkedExp);
2059 if(e.expType && e.expType.passAsTemplate)
2062 ComputeTypeSize(e.expType);
2063 sprintf(size, "%d", e.expType.size);
2064 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2065 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2066 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2069 if(parentExp.type == callExp)
2071 exp.call.arguments->Insert(e.prev, newExp);
2072 exp.call.arguments->Remove(e);
2075 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2077 parentExp.list->Remove(checkedExp);
2078 parentExp.list->Add(newExp);
2080 else if(parentExp.type == castExp)
2082 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2083 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2085 FreeTypeName(parentExp.cast.typeName);
2086 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2088 parentExp.cast.exp = newExp;
2090 else if(parentExp.type == extensionCompoundExp)
2092 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2093 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2095 e.byReference = true;
2097 FreeType(checkedExp.expType);
2098 FreeType(checkedExp.destType);
2101 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2103 Expression checkedExp;
2104 Expression parentExp;
2108 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2110 e.type == identifierExp ||
2111 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2112 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2113 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2116 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2118 Context context = PushContext();
2120 OldList * specs = MkList();
2121 char typeString[1024];
2122 Expression newExp { };
2124 typeString[0] = '\0';
2127 // TOCHECK: Should this read e.destType ???
2129 if(exp.destType) exp.destType.refCount++;
2130 // if(exp.expType) exp.expType.refCount++;
2133 newExp.expType = null;
2135 PrintTypeNoConst(e.expType, typeString, false, true);
2136 decl = SpecDeclFromString(typeString, specs, null);
2137 newExp.destType = ProcessType(specs, decl);
2139 curContext = context;
2140 e.type = extensionCompoundExp;
2142 // We need a current compound for this
2146 OldList * stmts = MkList();
2147 sprintf(name, "__internalValue%03X", internalValueCounter++);
2148 if(!curCompound.compound.declarations)
2149 curCompound.compound.declarations = MkList();
2150 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2151 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2152 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2153 e.compound = MkCompoundStmt(null, stmts);
2156 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2160 e.compound = MkCompoundStmt(
2161 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2162 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2165 e.compound.compound.context = context;
2166 PopContext(context);
2167 curContext = context.parent;
2171 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2174 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2176 parentExp = checkedExp;
2177 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2179 if(checkedExp.type == extensionCompoundExp)
2181 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2184 checkedExp = checkedExp.list->last;
2186 else if(checkedExp.type == castExp)
2187 checkedExp = checkedExp.cast.exp;
2189 newExp = MkExpOp(null, '&', checkedExp);
2190 newExp.byReference = true;
2191 if(parentExp.type == callExp)
2193 exp.call.arguments->Insert(e.prev, newExp);
2194 exp.call.arguments->Remove(e);
2197 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2199 parentExp.list->Remove(checkedExp);
2200 parentExp.list->Add(newExp);
2202 else if(parentExp.type == castExp)
2203 parentExp.cast.exp = newExp;
2204 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2206 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2207 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2213 if(destType.classObjectType == ClassObjectType::typedObject)
2215 char className[1024];
2216 // Need the class itself here...
2217 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2218 _class = eSystem_FindClass(privateModule, "String");
2219 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2221 if(!strcmp(_class.name, "class"))
2223 // Already inside a typed_object function, pass the class through
2224 strcpy(className, "class");
2228 strcpy(className, "__ecereClass_");
2229 FullClassNameCat(className, _class.fullName, true);
2230 MangleClassName(className);
2233 _class.symbol = FindClass(_class.fullName);
2235 DeclareClass(_class.symbol, className);
2238 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2240 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2242 Context context = PushContext();
2243 c = MkExpExtensionCompound(MkCompoundStmt(
2244 MkListOne(MkDeclaration(
2245 MkListOne(MkSpecifierName("Instance")),
2246 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2247 MkInitializerAssignment(CopyExpression(e)))))),
2248 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2249 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2250 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2251 MkExpIdentifier(MkIdentifier(className))))))));
2252 c.compound.compound.context = context;
2253 PopContext(context);
2255 exp.call.arguments->Insert(e.prev, c);
2258 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2264 //char debugString[4096] = "";
2265 //PrintExpression(e, debugString);
2267 // If expression type is a simple class, make it an address
2268 FixReference(e, !destType || !destType.declaredWithStruct);
2271 if(ellipsisDestType)
2274 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2275 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2277 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2285 bool changeToPtr = false;
2286 bool noHead = false;
2287 Type type = exp.member.exp ? exp.member.exp.expType : null;
2288 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2289 if(exp.member.member) exp.member.member._class = null;
2291 if(type && type.kind == templateType)
2293 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2294 if(baseType) type = baseType;
2296 if(type && exp.member.member && !type.directClassAccess)
2298 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2299 Property prop = null;
2300 ClassProperty classProperty = null;
2301 Method method = null;
2302 Class convertTo = null;
2303 DataMember member = null;
2304 bool thisPtr = exp.member.thisPtr;
2305 if(type.kind == subClassType && exp.member.exp.type == classExp)
2306 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2308 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2312 // DANGER: Buffer overflow
2313 char string[2048] = "";
2315 PrintTypeNoConst(type, string, false, true);
2316 classSym = FindClass(string);
2317 _class = classSym ? classSym.registered : null;
2320 if(_class && exp.member.memberType == dataMember)
2322 if(!thisPtr && !exp.member.member.classSym)
2323 member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
2325 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2327 else if(_class && exp.member.memberType == propertyMember)
2329 if(!thisPtr && !exp.member.member.classSym)
2330 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2332 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2333 if(prop && (exp.usage.usageRef ||
2334 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2335 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2337 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2340 exp.member.memberType = dataMember;
2345 if(exp.usage.usageRef)
2346 Compiler_Error($"cannot obtain address of property\n");
2348 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2349 else if(exp.usage.usageDelete)
2350 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2354 else if(_class && exp.member.memberType == methodMember)
2357 method = eClass_FindMethod(_class, exp.member.member.string, null);
2359 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2361 else if(_class && exp.member.memberType == reverseConversionMember)
2364 _class = FindClass(exp.member.member.string).registered;
2365 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2366 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2368 else if(_class && exp.member.memberType == classPropertyMember)
2370 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2374 // Only process Gets here, Set is processed in opExp's '='
2375 if(exp.usage.usageGet)
2379 char getName[1024], setName[1024];
2380 Expression ptr = exp.member.exp;
2381 Class propertyClass;
2382 char * nameToUse = convertTo ? setName : getName;
2384 FreeIdentifier(exp.member.member);
2386 // Process this here since it won't be processed at the end...
2387 exp.member.exp.usage.usageGet = true;
2388 ProcessExpression(exp.member.exp);
2389 // TEST: exp.tempCount = exp.member.exp.tempCount;
2391 DeclareProperty(prop, setName, getName);
2392 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2393 propertyClass = convertTo ? _class :
2394 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2397 if(propertyClass && propertyClass.type == bitClass)
2399 // Bit classes shouldn't have properties except for conversions...
2400 OldList * args = MkList();
2401 if(exp.usage.usageDeepGet)
2403 char className[1024];
2405 Declarator declarator;
2406 OldList * specs = MkList(), * decls = MkList();
2409 // Make a declaration in the closest compound statement
2410 // (Do not reuse (since using address for function calls)...)
2411 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2413 SpecDeclFromString(propertyClass.dataTypeString, specs,
2414 MkDeclaratorIdentifier(MkIdentifier(className)));
2416 ListAdd(decls, MkInitDeclarator(declarator, null));
2418 decl = MkDeclaration(specs, decls);
2419 if(!curCompound.compound.declarations)
2420 curCompound.compound.declarations = MkList();
2421 curCompound.compound.declarations->Insert(null, decl);
2423 tempExp = QMkExpId(className);
2424 tempExp.expType = MkClassType(propertyClass.fullName);
2426 exp.op.exp1 = tempExp;
2427 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2434 exp.call.exp = QMkExpId(nameToUse);
2435 exp.call.arguments = args;
2437 ListAdd(args, FixReference(ptr, true));
2439 else if(propertyClass && propertyClass.type == unitClass)
2441 OldList * args = MkList();
2442 ListAdd(args, FixReference(ptr, true));
2444 exp.call.exp = QMkExpId(nameToUse);
2445 exp.call.arguments = args;
2447 else if(propertyClass && propertyClass.type == structClass)
2449 OldList * args = MkList();
2450 char className[1024];
2452 OldList * specs = MkList(), * decls = MkList();
2455 // Make a declaration in the closest compound statement
2456 // (Do not reuse (since using address for function calls)...)
2459 FullClassNameCat(className, propertyClass.fullName, false); //true);
2461 //ListAdd(specs, MkSpecifierName(className));
2462 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2464 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2466 ListAdd(decls, MkInitDeclarator(
2467 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2469 decl = MkDeclaration(specs, decls);
2472 if(!curCompound.compound.declarations)
2473 curCompound.compound.declarations = MkList();
2474 curCompound.compound.declarations->Insert(null, decl);
2477 tempExp = QMkExpId(className);
2478 tempExp.expType = MkClassType(propertyClass.fullName);
2482 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2483 ListAdd(args, FixReference(ptr, true));
2487 ListAdd(args, FixReference(ptr, true));
2488 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2491 if(exp.usage.usageDeepGet)
2494 exp.call.exp = QMkExpId(nameToUse);
2495 exp.call.arguments = args;
2497 FreeExpression(tempExp);
2501 exp.type = bracketsExp;
2502 exp.list = MkList();
2503 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2504 if(exp.usage.usageMember)
2506 ListAdd(exp.list, FixReference(tempExp, true));
2507 exp.byReference = true;
2510 ListAdd(exp.list, tempExp);
2516 exp.call.exp = QMkExpId(nameToUse);
2517 exp.call.arguments = MkList();
2518 ListAdd(exp.call.arguments, FixReference(ptr, true));
2521 else if(prop.conversion)
2523 void * prev = exp.prev, * next = exp.next;
2524 *exp = *exp.member.exp;
2530 else if(classProperty)
2532 // Only process Gets here, Set is processed in opExp's '='
2533 if(exp.usage.usageGet)
2535 if(classProperty.Get)
2537 Identifier id = exp.member.member;
2538 Expression classExp = exp.member.exp;
2542 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty"));
2543 exp.call.arguments = MkList();
2544 ListAdd(exp.call.arguments, classExp);
2545 ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
2548 ProcessExpression(exp);
2555 // Get the function address if it's not called
2556 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2560 FreeIdentifier(exp.member.member);
2562 // Process this here since it won't be processed at the end...
2563 exp.member.exp.usage.usageGet = true;
2564 ProcessExpression(exp.member.exp);
2565 // TEST: exp.tempCount = exp.member.exp.tempCount;
2567 if(method.type == virtualMethod)
2569 strcpy(name, "__ecereVMethodID_");
2570 FullClassNameCat(name, method._class.fullName, false);
2572 strcat(name, method.name);
2573 exp.type = indexExp;
2574 if(memberClassSpecifier)
2576 char className[1024];
2577 // Need the class itself here...
2578 strcpy(className, "__ecereClass_");
2579 FullClassNameCat(className, _class.fullName, true);
2580 MangleClassName(className);
2583 _class.symbol = FindClass(_class.fullName);
2584 DeclareClass(_class.symbol, className);
2585 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2587 // WHAT HAPPENS TO exp.member.exp ?
2591 if(exp.thisPtr && _class.type != normalClass)
2593 FreeExpression(exp.member.exp);
2594 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2597 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2599 exp.index.index = MkListOne(QMkExpId(name));
2600 DeclareMethod(method, name);
2604 FreeExpression(exp.member.exp);
2605 exp.type = identifierExp;
2606 strcpy(name, "__ecereMethod_");
2607 FullClassNameCat(name, method._class.fullName, false);
2609 strcat(name, method.name);
2610 exp.identifier = MkIdentifier(name);
2611 DeclareMethod(method, name);
2617 // Process this here since it won't be processed at the end...
2618 if(exp.usage.usageGet)
2620 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2622 ProcessExpression(exp.member.exp);
2623 // TEST: exp.tempCount = exp.member.exp.tempCount;
2625 if(type.kind == classType)
2626 DeclareStruct(type._class.registered.fullName, false);
2628 // TESTING THIS NOHEAD STUFF...
2629 if(_class.type == noHeadClass)
2633 else if(_class.type == structClass)
2637 else if(_class.type == bitClass)
2639 OldList * list = MkList();
2640 char mask[32], shift[10];
2641 OldList * specs = MkList();
2642 BitMember bitMember = (BitMember) member;
2643 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2644 TypeName type = MkTypeName(specs, decl);
2645 if(bitMember.mask > MAXDWORD)
2646 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2648 sprintf(mask, FORMAT64HEX, bitMember.mask);
2649 sprintf(shift, "%d", bitMember.pos);
2651 FreeIdentifier(exp.member.member);
2653 // ((type) ((color & mask) >> bitPos))
2654 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2655 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2656 MkExpConstant(shift))))));
2658 exp.type = bracketsExp;
2661 else if(_class.type == unitClass)
2666 // If it's a this pointer, replace by precomputed shortcut
2667 if(exp.member.exp.type == identifierExp && thisPtr && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2669 char pointerName[1024];
2671 strcpy(pointerName, "__ecerePointer_");
2672 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2673 if(exp.member.exp.identifier)
2674 FreeIdentifier(exp.member.exp.identifier);
2675 exp.member.exp.identifier = MkIdentifier(pointerName);
2677 // Otherwise, access the data the hard way
2680 Expression bytePtr, e;
2681 Expression classExp;
2682 Expression checkedExp;
2683 char structName[1024];
2684 char className[1024];
2685 strcpy(className, "__ecereClass_");
2686 FullClassNameCat(className, member._class.fullName, true);
2687 MangleClassName(className);
2689 // classExp = QMkExpId(className);
2691 if(!member._class.symbol)
2692 member._class.symbol = FindClass(member._class.fullName);
2694 DeclareClass(member._class.symbol, className);
2695 DeclareStruct(member._class.fullName, false);
2698 FullClassNameCat(structName, member._class.fullName, false);
2700 checkedExp = exp.member.exp;
2701 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2702 checkedExp.type == castExp)
2704 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2705 checkedExp = checkedExp.list->last;
2706 else if(checkedExp.type == castExp)
2707 checkedExp = checkedExp.cast.exp;
2710 if(checkedExp.type != identifierExp &&
2711 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2712 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2714 char ecereTemp[100];
2716 OldList * list = MkList();
2717 Context context = PushContext();
2718 if(exp.member.exp.tempCount > exp.tempCount)
2719 exp.tempCount = exp.member.exp.tempCount;
2722 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2723 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2724 curContext = context;
2725 compound = MkCompoundStmt(
2726 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2727 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2728 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2729 if(member._class.fixed)
2731 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2734 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2735 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2738 e = QMkExpId(ecereTemp);
2742 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2743 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2746 compound.compound.context = context;
2747 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2748 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2749 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2751 exp.member.exp = MkExpExtensionCompound(compound);
2753 PopContext(context);
2754 curContext = context.parent;
2758 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2759 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2761 e = QBrackets(QMkExpCond(exp.member.exp,
2762 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2763 MkExpConstant("0")));
2767 if(member._class.fixed)
2769 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2772 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2773 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2779 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2781 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2782 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2785 exp.type = pointerExp;
2790 // Take Out Any Class Specifier (Should have been used by now)
2791 FreeSpecifier(memberClassSpecifier);
2793 // Just moved this at the end... How is it?
2794 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
2796 exp.member.exp.usage.usageGet = true;
2797 exp.member.exp.usage.usageMember = true;
2798 exp.member.exp.tempCount = exp.tempCount;
2799 ProcessExpression(exp.member.exp);
2800 exp.tempCount = exp.member.exp.tempCount;
2801 if((changeToPtr && exp.member.exp.byReference) || noHead)
2802 exp.type = pointerExp;
2806 case extensionCompoundExp:
2808 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
2810 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2812 ProcessStatement(exp.compound);
2814 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2815 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2820 exp.member.exp.usage.usageGet = true;
2821 ProcessExpression(exp.member.exp);
2826 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2827 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2829 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2832 Expression classExp;
2834 FreeTypeName(exp.typeName);
2836 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
2838 exp.type = bracketsExp;
2839 exp.list = MkListOne(
2840 MkExpCondition(MkExpBrackets(MkListOne(
2843 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2844 MkExpIdentifier(MkIdentifier("normalClass"))),
2847 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2848 MkExpIdentifier(MkIdentifier("noHeadClass"))
2850 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
2851 MkExpMember(classExp, MkIdentifier("typeSize")))
2854 ProcessExpressionType(exp);
2855 ProcessExpression(exp);
2864 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
2865 ProcessExpression(exp.cast.exp);
2867 if(exp.cast.exp.byReference)
2868 exp.byReference = exp.cast.exp.byReference;
2869 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
2870 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
2871 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
2872 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
2873 exp.byReference = true;
2875 // Moved this to 1.5...
2876 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
2882 if(exp.usage.usageGet)
2883 exp.cond.cond.usage.usageGet = true;
2884 ProcessExpression(exp.cond.cond);
2885 for(e = exp.cond.exp->first; e; e = e.next)
2887 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
2888 ProcessExpression(e);
2890 if(exp.usage.usageGet)
2891 exp.cond.elseExp.usage.usageGet = true;
2892 ProcessExpression(exp.cond.elseExp);
2897 // Need the class itself here...
2898 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
2900 Specifier spec = exp._classExp.specifiers->first;
2901 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
2904 FreeList(exp._classExp.specifiers, FreeSpecifier);
2905 if(exp._classExp.decl)
2906 FreeDeclarator(exp._classExp.decl);
2908 exp.type = memberExp; //pointerExp;
2909 exp.member.exp = argExp;
2910 exp.member.member = MkIdentifier("dataTypeClass");
2912 ProcessExpressionType(argExp);
2913 ProcessExpression(exp);
2918 char className[1024];
2919 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
2920 Symbol classSym = FindClass(string);
2922 strcpy(className, "__ecereClass_");
2923 FullClassNameCat(className, string, true); // TODO: Verify this
2924 MangleClassName(className);
2925 DeclareClass(classSym, className);
2928 FreeList(exp._classExp.specifiers, FreeSpecifier);
2929 if(exp._classExp.decl)
2930 FreeDeclarator(exp._classExp.decl);
2932 exp.type = identifierExp;
2933 exp.identifier = MkIdentifier(className);
2939 ProcessExpression(exp.vaArg.exp);
2942 case extensionInitializerExp:
2944 ProcessInitializer(exp.initializer.initializer);
2952 static void ProcessInitializer(Initializer init)
2956 case expInitializer:
2957 init.exp.usage.usageGet = true;
2958 ProcessExpression(init.exp);
2959 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
2960 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
2962 FixReference(init.exp, true);
2964 else if(init.exp.destType && init.exp.destType.kind == classType)
2965 FixReference(init.exp, false);
2967 case listInitializer:
2970 for(i = init.list->first; i; i = i.next)
2971 ProcessInitializer(i);
2977 static void ProcessDeclaration(Declaration decl)
2981 case initDeclaration:
2983 if(decl.declarators)
2987 for(d = decl.declarators->first; d; d = d.next)
2990 ProcessInitializer(d.initializer);
2998 static void ProcessStatement(Statement stmt)
3003 ProcessStatement(stmt.labeled.stmt);
3006 if(stmt.caseStmt.exp)
3008 stmt.caseStmt.exp.usage.usageGet = true;
3010 // This expression should be constant...
3011 ProcessExpression(stmt.caseStmt.exp);
3013 if(stmt.caseStmt.stmt)
3014 ProcessStatement(stmt.caseStmt.stmt);
3018 if(stmt.compound.context)
3022 Statement prevCompound = curCompound;
3023 Context prevContext = curContext;
3025 if(!stmt.compound.isSwitch)
3028 curContext = stmt.compound.context;
3031 if(stmt.compound.declarations)
3033 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3034 ProcessDeclaration(decl);
3036 if(stmt.compound.statements)
3038 for(s = stmt.compound.statements->first; s; s = s.next)
3039 ProcessStatement(s);
3041 curContext = prevContext;
3042 curCompound = prevCompound;
3046 case expressionStmt:
3049 if(stmt.expressions)
3051 for(exp = stmt.expressions->first; exp; exp = exp.next)
3053 ProcessExpression(exp);
3064 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3065 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3067 ProcessExpression(exp);
3070 if(stmt.ifStmt.stmt)
3071 ProcessStatement(stmt.ifStmt.stmt);
3072 if(stmt.ifStmt.elseStmt)
3073 ProcessStatement(stmt.ifStmt.elseStmt);
3079 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3080 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3082 ProcessExpression(exp);
3084 ProcessStatement(stmt.switchStmt.stmt);
3090 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3091 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3093 ProcessExpression(exp);
3095 ProcessStatement(stmt.whileStmt.stmt);
3101 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3103 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3104 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3106 ProcessExpression(exp);
3109 if(stmt.doWhile.stmt)
3110 ProcessStatement(stmt.doWhile.stmt);
3116 if(stmt.forStmt.init)
3117 ProcessStatement(stmt.forStmt.init);
3119 if(stmt.forStmt.check)
3121 if(stmt.forStmt.check.expressions)
3123 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3125 ProcessStatement(stmt.forStmt.check);
3127 if(stmt.forStmt.increment)
3129 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3131 ProcessExpression(exp);
3134 if(stmt.forStmt.stmt)
3135 ProcessStatement(stmt.forStmt.stmt);
3147 if(stmt.expressions)
3149 ((Expression)stmt.expressions->last).usage.usageGet = true;
3150 for(exp = stmt.expressions->first; exp; exp = exp.next)
3152 ProcessExpression(exp);
3153 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3154 if(!exp.next && exp.destType && exp.destType.byReference)
3155 FixReference(exp, true);
3160 case badDeclarationStmt:
3162 ProcessDeclaration(stmt.decl);
3168 if(stmt.asmStmt.inputFields)
3170 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3171 if(field.expression)
3172 ProcessExpression(field.expression);
3174 if(stmt.asmStmt.outputFields)
3176 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3177 if(field.expression)
3178 ProcessExpression(field.expression);
3180 if(stmt.asmStmt.clobberedFields)
3182 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3183 if(field.expression)
3184 ProcessExpression(field.expression);
3191 static void ProcessFunction(FunctionDefinition function)
3194 ProcessStatement(function.body);
3197 static void ProcessMemberInitData(MemberInit member)
3199 if(member.initializer)
3200 ProcessInitializer(member.initializer);
3203 static void ProcessInstantiation(Instantiation inst)
3207 MembersInit members;
3208 for(members = inst.members->first; members; members = members.next)
3210 if(members.type == dataMembersInit)
3212 if(members.dataMembers)
3215 for(member = members.dataMembers->first; member; member = member.next)
3216 ProcessMemberInitData(member);
3219 else if(members.type == methodMembersInit)
3221 ProcessFunction((FunctionDefinition)members.function);
3227 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3228 public void ProcessMemberAccess()
3231 for(external = ast->first; external; external = external.next)
3233 curExternal = external;
3234 // There shouldn't be any class member access here anyways...
3235 if(external.type == declarationExternal)
3237 if(external.declaration)
3238 ProcessDeclaration(external.declaration);
3242 for(external = ast->first; external; external = external.next)
3244 curExternal = external;
3245 if(external.type == functionExternal)
3247 ProcessFunction(external.function);
3249 else if(external.type == declarationExternal)
3251 //currentClass = external.function._class;
3252 if(external.declaration)
3253 ProcessDeclaration(external.declaration);
3255 else if(external.type == classExternal)
3257 ClassDefinition _class = external._class;
3258 //currentClass = external.symbol.registered;
3259 if(_class.definitions)
3262 Class regClass = _class.symbol.registered;
3264 // Process all functions
3265 for(def = _class.definitions->first; def; def = def.next)
3267 if(def.type == functionClassDef)
3269 curExternal = def.function.declarator.symbol.pointerExternal;
3270 ProcessFunction((FunctionDefinition)def.function);
3272 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3274 ProcessInstantiation(def.decl.inst);
3276 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3278 MemberInit defProperty;
3280 // Add this to the context
3283 string = CopyString("this");
3284 type = MkClassType(regClass.fullName);
3286 globalContext.symbols.Add((BTNode)thisSymbol);
3288 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3290 //thisClass = regClass;
3291 ProcessMemberInitData(defProperty); //, regClass, &id);
3295 //globalContext.symbols.Delete((BTNode)thisSymbol);
3296 globalContext.symbols.Remove((BTNode)thisSymbol);
3297 FreeSymbol(thisSymbol);
3299 else if(def.type == propertyClassDef && def.propertyDef)
3301 PropertyDef prop = def.propertyDef;
3303 // Add this to the context
3306 string = CopyString("this");
3307 type = MkClassType(regClass.fullName);
3309 globalContext.symbols.Add((BTNode)thisSymbol);
3311 //thisClass = regClass;
3314 curExternal = prop.symbol.externalSet;
3315 ProcessStatement(prop.setStmt);
3319 curExternal = prop.symbol.externalGet;
3320 ProcessStatement(prop.getStmt);
3324 curExternal = prop.symbol.externalIsSet;
3325 ProcessStatement(prop.issetStmt);
3330 //globalContext.symbols.Delete((BTNode)thisSymbol);
3331 globalContext.symbols.Remove((BTNode)thisSymbol);
3332 FreeSymbol(thisSymbol);
3334 else if(def.type == classPropertyClassDef && def.propertyDef)
3336 PropertyDef prop = def.propertyDef;
3338 //thisClass = regClass;
3341 curExternal = prop.symbol.externalSet;
3342 ProcessStatement(prop.setStmt);
3346 curExternal = prop.symbol.externalGet;
3347 ProcessStatement(prop.getStmt);
3351 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3353 PropertyWatch propertyWatch = def.propertyWatch;
3355 // Add this to the context
3358 string = CopyString("this");
3359 type = MkClassType(regClass.fullName);
3361 globalContext.symbols.Add((BTNode)thisSymbol);
3363 //thisClass = regClass;
3364 if(propertyWatch.compound)
3368 string = CopyString("this");
3369 type = MkClassType(regClass.fullName);
3371 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3373 ProcessStatement(propertyWatch.compound);
3375 // thisClass = null;
3377 //globalContext.symbols.Delete((BTNode)thisSymbol);
3378 globalContext.symbols.Remove((BTNode)thisSymbol);
3379 FreeSymbol(thisSymbol);