3 #define YYLTYPE Location
6 extern External curExternal;
7 static Statement curCompound;
9 static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
12 Expression memberExp = *memberExpPtr;
13 if(memberExp && memberExp.type == ExpressionType::memberExp &&
14 memberExp.member.exp && (memberExp.member.exp.type == bracketsExp || memberExp.member.exp.type == extensionExpressionExp))
16 Expression bracketExp = memberExp.member.exp;
17 Expression idExp = bracketExp.list->last;
19 if(idExp && idExp.type == identifierExp)
21 Expression newExp = null;
22 Expression exp = *expPtr;
24 // opExp ( memberExp ( bracketsExp ( identifierExp ) ) )
25 // bracketsExp ( opExp ( memberExp ( identifierExp ) ) )
28 newExp = CopyExpression(exp);
31 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
33 memberExp.member.exp = idExp;
35 exp.type = bracketsExp;
36 exp.list = bracketExp.list;
37 bracketExp.list = null;
39 exp.list->Remove(idExp);
40 exp.list->Add(newExp);
41 FreeExpression(bracketExp);
43 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
46 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
47 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
49 Expression newExp = null;
50 Expression exp = *expPtr;
53 newExp = CopyExpression(exp);
54 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
56 exp.type = bracketsExp;
57 exp.list = memberExp.list;
58 memberExp.list = null;
60 exp.list->Remove(exp.list->last);
61 exp.list->Add(newExp);
62 FreeExpression(memberExp);
64 *expPtr = newExp; //FixRefExp(newExp);
68 static Expression FixRefExp(Expression exp)
72 _FixRefExp(&exp, &exp.op.exp1);
73 _FixRefExp(&exp, &exp.op.exp2);
75 else if(exp.type == indexExp)
76 _FixRefExp(&exp, &exp.index.exp);
77 else if(exp.type == memberExp)
78 _FixRefExp(&exp, &exp.member.exp);
82 static Expression FixReference(Expression e, bool wantReference)
84 if(e.expType && e.type != constantExp)
86 Type type = e.expType;
87 bool isPointer = false;
89 if(type.kind == TypePointer && type.type && type.type.kind == classType)
96 if(type.kind == classType) // || type.kind == TypeInt)
98 Class _class = type._class ? type._class.registered : null;
99 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
100 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
101 if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
102 (_class.type == systemClass && _class.base &&
103 strcmp(_class.fullName, "uintptr") &&
104 strcmp(_class.fullName, "intptr") &&
105 strcmp(_class.fullName, "uintsize") &&
106 strcmp(_class.fullName, "intsize"))))
108 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
109 if(wantReference != (e.byReference || isPointer))
114 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
118 exp.byReference = wantReference;
119 exp = exp.list->last;
124 else if(exp.type == castExp)
126 exp.byReference = wantReference;
129 else if(exp.type == conditionExp)
131 if(exp.cond.exp->last)
132 FixReference(exp.cond.exp->last, wantReference);
133 FixReference(exp.cond.elseExp, wantReference);
138 if(wantReference != (exp.byReference || isPointer))
140 Expression newExp { };
143 if(exp.destType) exp.destType.refCount++;
144 if(exp.expType) exp.expType.refCount++;
148 exp.op.exp2 = newExp;
154 e.byReference = wantReference;
155 exp.byReference = wantReference;
168 static Expression GetInnerExp(Expression exp)
171 while(e && (e.type == bracketsExp || e.type == castExp))
173 if(e.type == bracketsExp)
174 e = e.list ? e.list->last : null;
175 else if(e.type == castExp)
181 Expression GetNonBracketsExp(Expression exp)
184 while(e && e.type == bracketsExp)
185 e = e.list ? e.list->last : null;
189 static bool FixMember(Expression exp)
191 bool byReference = false;
194 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
196 if(exp.list->count > 1)
198 exp = exp.list->last;
200 else if(exp.type == castExp)
207 FixReference(exp, true);
209 byReference = exp.byReference;
216 static void ProcessExpression(Expression exp)
218 Location oldyylloc = yylloc;
220 char debugExpString[1024] = "";
221 PrintExpression(exp, debugExpString);
231 if(exp.expType && exp.expType.kind == methodType)
233 Class _class = exp.expType.methodClass;
234 Method method = exp.expType.method;
235 if(method.type == virtualMethod)
240 OldList * specs = MkList();
241 strcpy(name, "__ecereVMethodID_");
242 FullClassNameCat(name, method._class.fullName, false);
244 strcat(name, method.name);
246 DeclareMethod(method, name);
248 // Cast function to its type
249 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
250 if(!method.dataType.staticMethod)
252 Declarator funcDecl = GetFuncDecl(decl);
254 if(!funcDecl.function.parameters)
255 funcDecl.function.parameters = MkList();
257 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
258 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
260 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
261 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
264 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
265 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
268 typeName = MkTypeName(specs, decl);
272 char className[1024];
273 // Need the class itself here...
274 strcpy(className, "__ecereClass_");
275 FullClassNameCat(className, _class.fullName, true);
276 //MangleClassName(className);
279 _class.symbol = FindClass(_class.fullName);
280 DeclareClass(_class.symbol, className);
283 FreeIdentifier(exp.identifier);
284 exp.type = bracketsExp;
285 exp.list = MkListOne(MkExpCast(typeName,
286 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
287 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
293 strcpy(name, "__ecereMethod_");
294 FullClassNameCat(name, method._class.fullName, false);
296 strcat(name, method.name);
298 delete exp.identifier.string;
299 FreeSpecifier(exp.identifier._class);
301 exp.identifier._class = null;
302 exp.identifier.string = CopyString(name);
303 DeclareMethod(method, name);
307 if(exp.usage & USAGE_MEMBER)
308 FixReference(exp, true);
321 OldList * args = MkList();
323 if(exp.type == renewExp || exp.type == renew0Exp)
324 ListAdd(args, exp._renew.exp);
326 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
330 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
331 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
332 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
333 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
335 exp.call.arguments = args;
338 ProcessExpression(exp);
343 Expression exp1 = exp.op.exp1;
344 Expression exp2 = exp.op.exp2;
348 // Assignment Operators
351 exp.op.exp2.usage.usageGet = true;
363 exp.op.exp2.usage.usageGet = true;
372 if(exp.op.exp1 && exp.op.exp2)
374 exp.op.exp1.usage.usageGet = true;
375 exp.op.exp2.usage.usageGet = true;
379 exp.op.exp2.usage.usageRef = true;
388 exp.op.exp1.usage.usageGet = true;
393 exp.op.exp2.usage.usageGet = true;
396 // Binary only operators
412 exp.op.exp1.usage.usageGet = true;
414 exp.op.exp2.usage.usageGet = true;
418 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
419 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
420 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
421 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
423 Expression memberExp;
424 Expression parentExp = null; // Where to take memberExp out from
425 bool isIndexedContainerAssignment = false;
427 // TOCHECK: See note below for this if
428 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
430 // Extra bit of code to access deep properties...
431 Expression testExp, topExp = null;
432 Expression lastExp = exp.op.exp1, parentExp = null;
433 Property lastProperty = null;
436 char setName[1024], getName[1024];
437 testExp = exp.op.exp1.member.exp;
440 // Is further fixing needed to address if statement above in the same way?
443 if(testExp.type == castExp)
444 testExp = testExp.cast.exp;
445 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
446 testExp = testExp.list->last;
447 else if(testExp.type == ExpressionType::memberExp)
454 if(testExp.member.memberType == propertyMember ||
455 testExp.member.memberType == reverseConversionMember)
457 Type type = testExp.member.exp.expType;
460 if(type.kind == classType)
462 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
463 Class convertTo = null;
464 if(testExp.member.memberType == reverseConversionMember)
467 _class = FindClass(testExp.member.member.string).registered;
468 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
469 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
473 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
475 if(lastProperty && lastProperty.Get && lastProperty.Set)
477 DeclareProperty(lastProperty, setName, getName);
478 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
479 propertyClass = convertTo ? _class :
480 ((((Symbol)lastProperty.symbol).type &&
481 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
482 // TODO: Handle this kind of things with bit classes?
483 if(propertyClass && propertyClass.type == structClass)
488 else if(propertyClass && propertyClass.type == bitClass)
500 testExp = testExp.member.exp;
504 if(propertyClass.type == structClass)
508 char className[1024];
511 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
512 tempExp = QMkExpId(className);
513 tempExp.expType = MkClassType(propertyClass.fullName);
515 parentExp.member.exp = tempExp;
517 value = MkExpBrackets(MkList());
519 copy = CopyExpression(topExp);
520 copy.usage.usageGet = true;
521 copy.usage.usageDeepGet = true;
523 ListAdd(value.list, copy);
524 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
525 ListAdd(value.list, CopyExpression(tempExp));
526 value.expType = tempExp.expType;
527 tempExp.expType.refCount++;
529 // Go on as usual with these new values:
530 exp.op.exp1 = topExp;
537 else if(propertyClass.type == bitClass)
541 char className[1024];
544 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
545 tempExp = QMkExpId(className);
546 tempExp.expType = MkClassType(propertyClass.fullName);
548 parentExp.member.exp = tempExp;
550 value = MkExpBrackets(MkList());
552 copy = CopyExpression(topExp);
553 copy.usage.usageGet = true;
554 copy.usage.usageDeepGet = true;
556 ListAdd(value.list, copy);
557 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
558 ListAdd(value.list, CopyExpression(tempExp));
559 value.expType = tempExp.expType;
560 value.expType.refCount++;
562 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
564 // Go on as usual with these new values:
565 exp.op.exp1 = topExp;
575 memberExp = exp.op.exp1;
577 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
578 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
580 parentExp = memberExp;
581 if(memberExp.type == extensionCompoundExp)
582 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
584 memberExp = memberExp.list->last;
587 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
588 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
589 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
591 Class c = memberExp.index.exp.expType._class.registered;
592 if(strcmp((c.templateClass ? c.templateClass : c).name, "Array"))
594 exp.op.exp2 = MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(exp.op.exp2)))));
595 isIndexedContainerAssignment = true;
598 ProcessExpression(memberExp);
600 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
601 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
603 parentExp = memberExp;
604 if(memberExp.type == extensionCompoundExp)
605 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
607 memberExp = memberExp.list->last;
610 if(memberExp && memberExp.type == extensionCompoundExp)
612 parentExp = memberExp;
613 if(memberExp.type == extensionCompoundExp)
615 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
616 if(stmt && stmt.type != expressionStmt) stmt = null;
617 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
620 stmt.expressions->Remove(memberExp);
621 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
622 exp.type = bracketsExp;
623 exp.list = MkListOne(parentExp);
624 ProcessExpression(exp);
629 memberExp = memberExp.list->last;
633 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
635 if(memberExp && memberExp.type == ExpressionType::memberExp && memberExp.member.member)
637 Type type = memberExp.member.exp.expType;
640 // Check if it's an instance
641 if(type.kind == classType || type.kind == subClassType)
643 // TODO: SOMETHING WRONG HERE...
644 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
646 if(memberExp == exp1)
650 if(parentExp.type == extensionCompoundExp)
651 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
653 parentExp.list->Remove(memberExp);
656 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
658 BitMember bitMember =
659 (BitMember)eClass_FindDataMember(_class,
660 memberExp.member.member.string, privateModule, null, null);
661 char mask[32], shift[10];
662 OldList * specs = MkList();
663 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
664 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
665 TypeName type = MkTypeName(specs, decl);
667 if(bitMember.mask > MAXDWORD)
668 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
670 sprintf(mask, FORMAT64HEX, bitMember.mask);
671 sprintf(shift, "%d", bitMember.pos);
673 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
674 exp.op.exp1 = memberExp.member.exp;
676 // TESTING THIS FOR: argb.color.r = 1;
677 //ProcessExpression(memberExp.member.exp);
679 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
680 if(exp.op.op == XOR_ASSIGN)
682 exp.op.exp2 = MkExpOp(MkExpBrackets(
683 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
687 exp.op.exp2 = MkExpOp(
688 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
689 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
690 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
691 MkListOne(MkExpCast(type, MkExpBrackets(MkListOne(exp.op.exp2))))), LEFT_OP, MkExpConstant(shift)))));
694 memberExp.member.exp = null;
695 FreeExpression(memberExp);
697 // TESTING THIS FOR: argb.color.r = 1;
698 ProcessExpression(exp);
701 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
704 else if(memberExp.member.memberType != dataMember)
707 Class convertTo = null;
708 ClassProperty classProperty = null;
710 if(memberExp.member.memberType == reverseConversionMember)
713 _class = FindClass(memberExp.member.member.string).registered;
714 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
715 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
718 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
720 if(memberExp.member.memberType == classPropertyMember)
721 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
723 exp.tempCount = memberExp.member.exp.tempCount;
727 // Only process Gets here, Set is processed in opExp's '='
728 if(classProperty.Set)
730 Identifier id = memberExp.member.member;
731 Expression classExp = memberExp.member.exp;
732 Expression value = exp.op.exp2;
734 memberExp.member.exp = null;
735 memberExp.member.member = null;
738 FreeExpContents(memberExp);
742 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
743 exp.call.arguments = MkList();
744 ListAdd(exp.call.arguments, classExp);
746 char * s = QMkString(id.string);
747 ListAdd(exp.call.arguments, MkExpString(s));
750 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
754 ProcessExpression(exp);
760 if((!convertTo && prop.Set) || (convertTo && prop.Get))
762 Expression value = exp.op.exp2;
763 char setName[1024], getName[1024];
764 char * setToUse = convertTo ? getName : setName;
765 char * getToUse = convertTo ? setName : getName;
766 bool needAddress = false;
767 int operator = exp.op.op;
770 case MUL_ASSIGN: operator = '*'; break;
771 case DIV_ASSIGN: operator = '/'; break;
772 case MOD_ASSIGN: operator = '%'; break;
773 case SUB_ASSIGN: operator = '-'; break;
774 case ADD_ASSIGN: operator = '+'; break;
775 case LEFT_ASSIGN: operator = LEFT_OP; break;
776 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
777 case AND_ASSIGN: operator = '&'; break;
778 case OR_ASSIGN: operator = '|'; break;
779 case XOR_ASSIGN: operator = '^'; break;
784 if(operator == INC_OP)
785 value = MkExpOp(CopyExpression(memberExp),
786 '+', MkExpConstant("1"));
787 else if(operator == DEC_OP)
788 value = MkExpOp(CopyExpression(memberExp),
789 '-', MkExpConstant("1"));
792 value = MkExpOp(CopyExpression(memberExp),
796 value.expType = memberExp.expType;
797 memberExp.expType.refCount++;
798 value.usage.usageArg = true;
802 // Dont free exp2, we're using it
807 value.usage.usageArg = true;
809 DeclareProperty(prop, setName, getName);
811 if(memberExp.member.exp)
812 ProcessExpression(memberExp.member.exp);
814 // If get flag present
815 if(exp.usage.usageGet &&
816 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
818 OldList * list = MkList();
821 Context context = PushContext();
824 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
825 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
827 curContext = context;
828 exp.type = extensionCompoundExp;
829 exp.compound = MkCompoundStmt(
830 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
831 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
832 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
839 ListAdd(args, value);
840 ListAdd(args, QMkExpId(ecereTemp));
841 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
845 ListAdd(args, QMkExpId(ecereTemp));
846 ListAdd(args, value);
847 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
853 ListAdd(args, QMkExpId(ecereTemp));
855 args->Insert(null, QMkExpId(ecereTemp));
856 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
858 exp.compound.compound.context = context;
860 curContext = context.parent;
864 Expression newExp = exp;
866 if(parentExp && parentExp.type == extensionCompoundExp)
868 newExp = Expression { };
869 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
870 FreeType(exp.expType);
871 FreeType(exp.destType);
874 parentExp.type = dummyExp;
875 parentExp.expType = null;
876 parentExp.destType = null;
879 newExp.type = callExp;
880 newExp.call.exp = QMkExpId(setToUse);
881 newExp.call.arguments = MkList();
884 ListAdd(newExp.call.arguments, value);
885 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
889 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
890 ListAdd(newExp.call.arguments, value);
895 // Take it out from there
896 memberExp.member.exp = null;
898 // Don't use the temporaries used by the left side...
901 value.tempCount = exp.tempCount;
902 ProcessExpression(value);
904 FixReference(isIndexedContainerAssignment ? GetInnerExp(value) : value, true);
907 FreeExpression(memberExp);
911 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
914 memberExp.member.memberType = dataMember;
917 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
922 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
923 if(method && method.type == virtualMethod && type.kind != subClassType)
925 Expression value = exp.op.exp2;
926 // Don't use the temporaries used by the left side...
927 value.tempCount = exp.tempCount;
928 ProcessExpression(value);
930 if(memberExp.member.exp)
931 ProcessExpression(memberExp.member.exp);
933 if(exp.usage.usageGet)
935 OldList * list = MkList();
940 ListAdd(args, memberExp.member.exp);
942 char * string = QMkString(memberExp.member.member.string);
943 ListAdd(args, MkExpString(string));
946 ListAdd(args, value);
947 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
948 ListAdd(list, CopyExpression(value));
949 exp.type = bracketsExp;
956 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
957 exp.call.arguments = MkList();
958 ListAdd(exp.call.arguments, memberExp.member.exp);
960 char * string = QMkString(memberExp.member.member.string);
961 ListAdd(exp.call.arguments, MkExpString(string));
964 ListAdd(exp.call.arguments, value);
967 memberExp.member.exp = null;
970 FreeExpression(memberExp);
974 else if(memberExp.member.memberType == dataMember)
976 //if(exp.usage & USAGE_GET);
977 //FixReference(value, true);
978 if(FixMember(memberExp.member.exp))
980 // TESTING THIS HERE:
981 ProcessExpression(memberExp);
983 memberExp.type = pointerExp;
990 else if(exp.op.op == _INCREF)
992 Expression object = exp.op.exp2;
994 FreeExpContents(exp);
995 FreeType(exp.expType);
996 FreeType(exp.destType);
1000 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
1002 else if(exp.op.op == DELETE)
1004 Expression object = exp.op.exp2;
1005 OldList * args = MkList();
1007 exp.type = bracketsExp;
1008 exp.list = MkList();
1010 object.usage.usageDelete = true;
1012 ProcessExpression(object);
1014 ListAdd(args, object);
1016 // TOFIX: Same time as when we fix for = 0
1018 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
1019 exp.expType._class.registered.type == normalClass &&
1020 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
1022 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
1023 ProcessExpressionType(decRefExp);
1024 ListAdd(exp.list, decRefExp);
1026 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
1029 char className[1024];
1030 OldList * list = MkList();
1032 strcpy(className, "__ecereClass_");
1033 FullClassNameCat(className, exp.expType._class.string, true);
1034 //MangleClassName(className);
1036 DeclareClass(exp.expType._class, className);
1038 // Call the non virtual destructor
1039 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1040 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1042 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1044 MkExpBrackets(MkListOne(MkExpCondition(
1045 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1046 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1051 OldList * list = MkList();
1054 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1056 char className[1024];
1058 if(_class.templateClass) _class = _class.templateClass;
1059 strcpy(className, "__ecereClass_");
1060 FullClassNameCat(className, _class.fullName, false /*true*/);
1061 //MangleClassName(className);
1064 _class.symbol = FindClass(_class.fullName);
1065 DeclareClass(_class.symbol, className);
1067 // Call the non virtual destructor
1071 QMkExpId(className),
1072 MkIdentifier("Destructor")
1077 QMkExpId(className),
1078 MkIdentifier("Destructor")
1080 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), CopyExpression(args->first)))
1087 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1088 o = CopyExpression(object);
1089 ProcessExpressionType(o);
1090 o.usage.usageGet = true;
1091 ProcessExpression(o);
1107 else if(exp.expType && exp.expType.kind == templateType)
1109 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1112 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1114 OldList * qualifiers = MkList();
1115 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1117 typeName = MkTypeName(qualifiers, declarator);
1119 ProcessExpressionType(classExp);
1120 ProcessExpression(classExp);
1121 args->Insert(null, CopyExpression(classExp));
1122 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1123 ListAdd(exp.list, MkExpCall(
1124 MkExpBrackets(MkListOne(MkExpCast(typeName,
1125 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1126 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1127 //ProcessExpression(exp.list->last);
1131 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1133 //ProcessExpression(object);
1135 ListAdd(exp.list, MkExpOp(CopyExpression(GetInnerExp(object)), '=', MkExpConstant("0")));
1139 // TESTING THIS HERE...
1140 ProcessExpression(exp);
1143 if(exp.type == opExp)
1145 // Handle assigment of template structures
1146 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1147 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1149 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1152 // memcpy((byte *)array + (count * dataTypeClass.size), (dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1154 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1155 OldList * args = MkList();
1156 Expression derefExp = exp.op.exp1;
1159 ProcessExpressionType(classExp);
1160 ProcessExpression(classExp);
1162 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1164 if(exp.op.exp1.type == indexExp)
1166 Expression indexExp = derefExp.index.exp;
1167 OldList * indexExpIndex = derefExp.index.index;
1169 derefExp.index.index = null;
1170 derefExp.index.exp = null;
1171 FreeExpression(derefExp);
1173 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1174 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1178 Expression indexExp = derefExp.op.exp2;
1179 derefExp.op.exp2 = null;
1180 FreeExpression(derefExp);
1181 derefExp = indexExp;
1184 args->Add(derefExp);
1185 ProcessExpressionType(args->last);
1186 ProcessExpression(args->last);
1188 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1189 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1190 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2))))),
1191 MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1193 thisClass = curExternal.function ? curExternal.function._class : null;
1197 string = CopyString("this");
1198 type = MkClassType(thisClass.fullName);
1200 globalContext.symbols.Add((BTNode)thisSymbol);
1202 ProcessExpressionType(args->last);
1203 ProcessExpression(args->last);
1206 ProcessExpressionType(args->last);
1207 ProcessExpression(args->last);
1209 DeclareFunctionUtil("memcpy");
1211 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1212 exp.type = bracketsExp;
1214 //globalContext.symbols.Delete((BTNode)thisSymbol);
1215 globalContext.symbols.Remove((BTNode)thisSymbol);
1216 FreeSymbol(thisSymbol);
1222 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1223 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1225 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1228 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1231 ProcessExpressionType(classExp);
1232 ProcessExpression(classExp);
1234 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1236 exp.type = bracketsExp;
1237 exp.list = MkListOne(
1239 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1241 // ((class.type == structClass) ?
1242 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1245 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1247 // ((class.size == 1) ?
1248 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1250 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1251 CopyExpression(exp.op.exp2)))))),
1253 // ((class.size == 2) ?
1254 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1255 // *((uint16 *)array)
1256 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1257 CopyExpression(exp.op.exp2)))))),
1259 // ((class.size == 4) ?
1260 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1261 // *((uint32 *)array)
1262 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1263 CopyExpression(exp.op.exp2)))))),
1265 // *((uint64 *)array)
1266 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1267 exp.op.exp2))))))))))))))))))));
1269 // Add this to the context
1270 thisClass = curExternal.function ? curExternal.function._class : null;
1274 string = CopyString("this");
1275 type = MkClassType(thisClass.fullName);
1277 globalContext.symbols.Add((BTNode)thisSymbol);
1279 ProcessExpressionType(exp.list->first);
1280 ProcessExpression(exp.list->first);
1282 //globalContext.symbols.Delete((BTNode)thisSymbol);
1283 globalContext.symbols.Remove((BTNode)thisSymbol);
1284 FreeSymbol(thisSymbol);
1295 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1296 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1297 ProcessExpression(exp.op.exp1);
1300 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1301 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1302 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1303 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*/))
1304 FixReference(exp.op.exp1, false);
1305 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1309 // Don't use the temporaries used by the left side...
1311 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1312 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1313 ProcessExpression(exp.op.exp2);
1314 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1318 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1319 (exp.op.exp2.expType._class.registered.type != normalClass &&
1320 exp.op.exp2.expType._class.registered.type != structClass &&
1321 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1323 // TESTING THIS TEMPLATE TYPE CHECK HERE
1324 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1326 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1327 //FixReference(exp.op.exp2, false);
1330 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1333 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)
1335 // Preserve prev, next
1336 Expression next = exp.next, prev = exp.prev;
1337 Expression derefExp = exp.op.exp2;
1338 Expression refExp = exp.op.exp2.op.exp2;
1340 derefExp.op.exp2 = null;
1341 FreeExpression(derefExp);
1342 FreeType(exp.expType);
1343 FreeType(exp.destType);
1353 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)
1355 Expression exp2 = exp.op.exp2;
1356 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1359 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1362 ProcessExpressionType(classExp);
1363 ProcessExpression(classExp);
1365 exp.type = bracketsExp;
1366 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1367 MkExpOp(null, '&', exp2)), '+',
1368 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1369 MkListOne((e = MkExpMember(classExp, MkIdentifier("typeSize")))))));
1371 // Add this to the context
1372 thisClass = curExternal.function ? curExternal.function._class : null;
1376 string = CopyString("this");
1377 type = MkClassType(thisClass.fullName);
1379 //globalContext.symbols.Add((BTNode)thisSymbol);
1381 ProcessExpressionType(e);
1382 ProcessExpression(e);
1384 //globalContext.symbols.Remove((BTNode)thisSymbol);
1385 //FreeSymbol(thisSymbol);
1394 FreeExpression(exp1);
1396 FreeExpression(exp2);
1401 case extensionExpressionExp:
1406 for(e = exp.list->first; e; e = e.next)
1410 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1412 e.tempCount = exp.tempCount;
1413 ProcessExpression(e);
1415 exp.byReference = e.byReference;
1416 exp.tempCount = e.tempCount;
1420 exp.expType = e.expType;
1429 /*bool isBuiltin = exp && exp.index.exp &&
1430 (exp.index.exp.type == ExpressionType::arrayExp ||
1431 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1433 Expression checkedExp = exp.index.exp;
1434 bool isBuiltin = false;
1436 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1438 if(checkedExp.type == extensionCompoundExp)
1443 else if(checkedExp.type == bracketsExp)
1444 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1446 checkedExp = checkedExp.cast.exp;
1449 exp.index.exp.tempCount = exp.tempCount;
1451 exp.index.exp.usage.usageGet = true;
1452 ProcessExpression(exp.index.exp);
1454 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1455 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1457 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1460 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1463 ProcessExpressionType(classExp);
1464 ProcessExpression(classExp);
1466 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1468 exp.type = bracketsExp;
1469 exp.list = MkListOne(
1471 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1473 // ((class.type == structClass) ?
1474 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1475 // ((byte *)array) + (i) * class.size
1476 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1477 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1478 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1480 // ((class.size == 1) ?
1481 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1482 // ((byte *)array)[i]
1483 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1484 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1486 // ((class.size == 2) ?
1487 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1488 // ((uint16 *)array)[i]
1489 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1490 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1492 // ((class.size == 4) ?
1493 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1494 // ((uint32 *)array)[i]
1495 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1496 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1498 // ((uint64 *)array)[i]
1499 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1500 exp.index.exp))), exp.index.index)))))))))))))))));
1502 // Add this to the context
1503 thisClass = curExternal.function ? curExternal.function._class : null;
1507 string = CopyString("this");
1508 type = MkClassType(thisClass.fullName);
1510 globalContext.symbols.Add((BTNode)thisSymbol);
1512 ProcessExpressionType(exp.list->first);
1513 ProcessExpression(exp.list->first);
1515 //globalContext.symbols.Delete((BTNode)thisSymbol);
1516 globalContext.symbols.Remove((BTNode)thisSymbol);
1517 FreeSymbol(thisSymbol);
1525 for(e = exp.index.index->first; e; e = e.next)
1528 e.usage.usageGet = true;
1529 ProcessExpression(e);
1531 // Ignore temps in the index for now...
1532 exp.tempCount = exp.index.exp.tempCount;
1534 if(exp.index.exp.expType)
1536 Type source = exp.index.exp.expType;
1537 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1538 eClass_IsDerived(source._class.registered, containerClass))
1540 Class _class = source._class.registered;
1541 bool isArray = false;
1542 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1543 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1545 if(isArray && _class.templateArgs)
1547 OldList * specs = MkList();
1548 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1549 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1550 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1551 ProcessExpressionType(exp.index.exp);
1552 ProcessExpression(exp);
1554 else if(isBuiltin && _class.templateArgs)
1556 OldList * specs = MkList();
1557 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1558 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1559 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1560 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1561 ProcessExpressionType(exp.index.exp);
1562 ProcessExpression(exp);
1564 else if(_class.templateArgs)
1566 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1568 char iteratorType[1024];
1569 OldList * declarations = MkList();
1570 OldList * statements = MkList();
1571 OldList * args = MkList();
1572 OldList * instMembers = MkList();
1574 Context context = PushContext();
1576 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1578 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1580 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1581 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1583 ListAdd(args, MkExpBrackets(exp.index.index));
1584 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1586 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1587 MkIdentifier("Index")), args))));
1589 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1590 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1592 exp.type = bracketsExp;
1593 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1594 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1595 expExt.compound.compound.context = context;
1596 PopContext(context);
1597 expExt.usage = exp.usage;
1598 ProcessExpressionType(exp.list->first);
1599 ProcessExpressionInstPass(exp.list->first);
1600 ProcessExpression(exp.list->first);
1609 bool typedObject = false;
1610 Type ellipsisDestType = null;
1611 bool usedEllipsis = false;
1613 if(exp.call.arguments)
1615 for(e = exp.call.arguments->first; e; e = e.next)
1617 e.usage.usageGet = true;
1618 e.usage.usageArg = true;
1619 e.tempCount = Max(e.tempCount, exp.tempCount);
1620 ProcessExpression(e);
1621 exp.tempCount = Max(exp.tempCount, e.tempCount);
1624 exp.call.exp.usage.usageGet = true;
1625 exp.call.exp.usage.usageCall = true;
1626 exp.call.exp.tempCount = exp.tempCount;
1628 ProcessExpression(exp.call.exp);
1630 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1632 bool nullMemberExp = false;
1633 Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1635 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1636 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1637 Method method = exp.call.exp.expType.method;
1638 if(method.type == virtualMethod)
1644 OldList * specs = MkList();
1645 strcpy(name, "__ecereVMethodID_");
1646 FullClassNameCat(name, method._class.fullName, false);
1648 strcat(name, method.name);
1650 DeclareMethod(method, name);
1653 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1654 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1655 // Cast function to its type
1657 Context context = SetupTemplatesContext(method._class);
1659 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1661 FinishTemplatesContext(context);
1664 if(method.dataType && !method.dataType.staticMethod)
1666 Declarator funcDecl = GetFuncDecl(decl);
1668 if(!funcDecl.function.parameters)
1669 funcDecl.function.parameters = MkList();
1671 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1672 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1674 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1676 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1677 FreeTypeName(firstParam);
1681 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1686 param = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
1687 param.qualifiers->Insert(null, MkSpecifier(CONST));
1688 funcDecl.function.parameters->Insert(null, param);
1689 // Testing this for any_object::
1690 if(!method.dataType.extraParam)
1691 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1695 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1696 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1700 typeName = MkTypeName(specs, decl);
1702 // Added !exp.call.exp.expType.methodClass
1703 if(memberExp && memberExp.member.exp.expType)
1705 Type type = memberExp.member.exp.expType;
1707 if(type.kind == classType && type._class && type._class.registered)
1709 Class regClass = type._class.registered;
1710 ClassType classType = regClass.type;
1711 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1712 argClass = regClass;
1714 else if(type.kind == subClassType)
1716 argClass = FindClass("ecere::com::Class").registered;
1718 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1720 argClass = FindClass("char *").registered;
1722 else if(type.kind == pointerType)
1724 argClass = eSystem_FindClass(privateModule, "uintptr");
1725 FreeType(memberExp.member.exp.expType);
1726 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1727 memberExp.member.exp.byReference = true;
1731 char string[1024] = "";
1733 PrintTypeNoConst(type, string, false, true);
1734 classSym = FindClass(string);
1735 if(classSym) argClass = classSym.registered;
1739 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1745 Type type = memberExp ? memberExp.member.exp.expType : null;
1746 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1747 char className[1024];
1749 if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
1750 strcpy(className, "class");
1754 // TESTING: Moved this here...
1755 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1760 // TODO: Unhandled case here, what should happen?
1763 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1764 if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
1765 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1766 cl = cl.templateClass;
1768 // Need the class itself here...
1769 strcpy(className, "__ecereClass_");
1770 FullClassNameCat(className, cl.fullName, true);
1771 //MangleClassName(className);
1774 cl.symbol = FindClass(cl.fullName);
1776 DeclareClass(cl.symbol, className);
1779 if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
1781 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1782 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1783 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1785 else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
1786 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1789 FreeExpression(exp.call.exp);
1790 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1791 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1792 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1796 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1797 // as opposed to the File class vTbl one
1799 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1801 Context context = PushContext();
1803 c = MkExpExtensionCompound(MkCompoundStmt(
1804 MkListOne(MkDeclaration(
1805 (specs = MkListOne(MkSpecifierName("Instance"))),
1806 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1807 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
1808 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1809 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1810 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1811 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
1813 specs->Insert(null, MkSpecifier(CONST));
1815 c.compound.compound.context = context;
1816 PopContext(context);
1817 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1818 MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1825 strcpy(name, "__ecereMethod_");
1826 FullClassNameCat(name, method._class.fullName, false);
1828 strcat(name, method.name);
1831 FreeExpression(exp.call.exp);
1832 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1833 DeclareMethod(method, name);
1834 if(memberExp && memberExp.expType && method.dataType)
1836 exp.call.exp.expType = method.dataType;
1837 method.dataType.refCount++;
1840 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1842 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1844 if(!exp.call.arguments)
1845 exp.call.arguments = MkList();
1847 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1849 if(memberExp.member.exp.expType.kind != classType ||
1850 memberExp.member.exp.expType._class.registered.type == enumClass ||
1851 memberExp.member.exp.expType._class.registered.type == unitClass)
1853 char typeString[1024] = "";
1854 if(memberExp.member.exp.expType.kind != classType)
1855 PrintType(memberExp.member.exp.expType, typeString, false, true);
1857 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1860 // memberExp.member.exp.expType.kind = classType;
1861 // memberExp.member.exp.expType._class = FindClass(typeString);
1863 FreeType(memberExp.member.exp.expType);
1864 memberExp.member.exp.expType = Type
1867 _class = FindClass(typeString);
1871 // Default to an int instead
1872 if(!memberExp.member.exp.expType._class)
1874 // TODO: Shouldn't get here...
1875 memberExp.member.exp.expType.kind = TypeInt;
1880 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1882 bool changeReference = false;
1883 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1885 // Patched so that class isn't considered SYSTEM...
1886 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1887 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1888 changeReference = true;
1889 if(!memberExp.member.exp.expType.classObjectType &&
1891 (memberExp.member.exp.expType.kind != pointerType &&
1892 (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1893 !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1894 method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
1895 changeReference = true;
1896 if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
1897 changeReference = true;
1900 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1901 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1903 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1904 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1906 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1908 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1909 memberExp.member.exp.op.exp2 = null;
1911 else if(!memberExp.member.exp.byReference)
1913 // TESTING THIS... REUSE THIS CODE?
1914 Expression checkedExp = memberExp.member.exp;
1915 Expression parentExp = null;
1917 bool disconnected = false;
1918 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1920 parentExp = checkedExp;
1922 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1924 checkedExp = checkedExp.list->last;
1925 // Dissociate from memberExp which will get freed
1926 if(checkedExp && !disconnected)
1928 parentExp.list->Remove(checkedExp);
1929 disconnected = true;
1932 else if(checkedExp.type == castExp)
1934 checkedExp = checkedExp.cast.exp;
1935 // Dissociate from memberExp which will get freed
1936 if(checkedExp && !disconnected)
1938 checkedExp.cast.exp = null;
1939 disconnected = true;
1944 nullMemberExp = true;
1946 newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
1947 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1949 parentExp.list->Remove(checkedExp);
1950 parentExp.list->Add(newExp);
1952 else if(parentExp && parentExp.type == castExp)
1954 parentExp.cast.exp = newExp;
1955 // Add a dereference level here
1956 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1958 if(typedObject && !memberExp.member.exp.expType.classObjectType)
1960 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
1961 FreeType((parentExp ? parentExp : newExp).expType);
1962 FreeType((parentExp ? parentExp : newExp).destType);
1963 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
1964 (parentExp ? parentExp : newExp).destType = destType;
1965 if(checkedExp.expType) checkedExp.expType.refCount++;
1967 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1971 exp.call.arguments->Insert(null, memberExp.member.exp);
1972 nullMemberExp = true;
1977 exp.call.arguments->Insert(null, memberExp.member.exp);
1978 nullMemberExp = true;
1982 char className[1024];
1983 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
1984 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1985 Class cl = argClass ? argClass : regClass;
1988 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1989 strcpy(className, "class");
1992 // Need the class itself here...
1993 strcpy(className, "__ecereClass_");
1994 FullClassNameCat(className, cl.fullName, true);
1995 //MangleClassName(className);
1998 cl.symbol = FindClass(cl.fullName);
1999 DeclareClass(cl.symbol, className);
2004 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
2006 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2008 Context context = PushContext();
2011 c = MkExpExtensionCompound(MkCompoundStmt(
2012 MkListOne(MkDeclaration(
2013 (specs = MkListOne(MkSpecifierName("Instance"))),
2014 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2015 MkInitializerAssignment(memberExpMemberExp))))),
2016 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2017 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2018 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2019 MkExpIdentifier(MkIdentifier(className))))))));
2020 c.compound.compound.context = context;
2021 PopContext(context);
2024 specs->Insert(null, MkSpecifier(CONST));
2026 exp.call.arguments->Insert(null, c);
2028 memberExpMemberExp = null; // We used this
2031 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
2035 if(memberExpMemberExp)
2036 FreeExpression(memberExpMemberExp);
2040 exp.call.arguments->Insert(null, memberExp.member.exp);
2041 nullMemberExp = true;
2045 /*else if(method->dataType)
2051 memberExp.member.exp = null;
2052 FreeExpression(memberExp);
2056 if(exp.call.arguments)
2058 for(e = exp.call.arguments->first; e; e = e.next)
2060 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
2061 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
2062 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
2063 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
2065 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
2066 ellipsisDestType = destType;
2069 Type type = e.expType;
2070 Class _class = null;
2071 //Type destType = e.destType;
2073 if(type.kind == classType && type._class && type._class.registered)
2075 _class = type._class.registered;
2077 else if(type.kind == subClassType)
2079 _class = FindClass("ecere::com::Class").registered;
2081 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
2083 _class = FindClass("char *").registered;
2085 else if(type.kind == pointerType)
2087 _class = eSystem_FindClass(privateModule, "uintptr");
2088 FreeType(e.expType);
2089 e.expType = ProcessTypeString("uintptr", false);
2090 // Assume null pointers means 'no object' rather than an object holding a null pointer
2091 e.byReference = true;
2095 char string[1024] = "";
2097 PrintTypeNoConst(type, string, false, true);
2098 classSym = FindClass(string);
2099 if(classSym) _class = classSym.registered;
2100 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2103 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...
2104 (!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))) ||
2105 destType.byReference)))
2107 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2108 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2109 // TESTING WITHOUT THE ABOVE NOW!
2111 Expression checkedExp;
2112 Expression parentExp;
2117 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2119 parentExp = checkedExp;
2120 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2122 if(checkedExp.type == extensionCompoundExp)
2124 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2127 checkedExp = checkedExp.list->last;
2129 else if(checkedExp.type == castExp)
2130 checkedExp = checkedExp.cast.exp;
2133 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2136 Expression newExp = e.op.exp2;
2137 exp.call.arguments->Insert(e.prev, newExp);
2138 exp.call.arguments->Remove(e);
2143 newExp = checkedExp.op.exp2;
2144 checkedExp.op.exp2 = null;
2145 FreeExpContents(checkedExp);
2147 if(e.expType && e.expType.passAsTemplate)
2150 ComputeTypeSize(e.expType);
2151 sprintf(size, "%d", e.expType.size);
2152 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2153 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2154 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2157 if(parentExp.type == callExp)
2159 exp.call.arguments->Insert(e.prev, newExp);
2160 exp.call.arguments->Remove(e);
2163 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2165 parentExp.list->Remove(checkedExp);
2166 parentExp.list->Add(newExp);
2168 else if(parentExp.type == castExp)
2170 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2171 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2173 FreeTypeName(parentExp.cast.typeName);
2174 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2176 parentExp.cast.exp = newExp;
2178 else if(parentExp.type == extensionCompoundExp)
2180 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2181 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2183 e.byReference = true;
2185 FreeType(checkedExp.expType);
2186 FreeType(checkedExp.destType);
2189 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2191 Expression checkedExp;
2192 Expression parentExp;
2196 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2198 e.type == identifierExp ||
2199 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2200 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2201 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2204 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2206 Context context = PushContext();
2208 OldList * specs = MkList();
2209 char typeString[1024];
2210 Expression newExp { };
2212 typeString[0] = '\0';
2215 // TOCHECK: Should this read e.destType ???
2217 if(exp.destType) exp.destType.refCount++;
2218 // if(exp.expType) exp.expType.refCount++;
2221 newExp.expType = null;
2223 PrintTypeNoConst(e.expType, typeString, false, true);
2224 decl = SpecDeclFromString(typeString, specs, null);
2225 newExp.destType = ProcessType(specs, decl);
2227 curContext = context;
2228 e.type = extensionCompoundExp;
2230 // We need a current compound for this
2234 OldList * stmts = MkList();
2235 sprintf(name, "__internalValue%03X", internalValueCounter++);
2236 if(!curCompound.compound.declarations)
2237 curCompound.compound.declarations = MkList();
2238 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2239 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2240 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2241 e.compound = MkCompoundStmt(null, stmts);
2244 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2248 e.compound = MkCompoundStmt(
2249 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2250 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2253 e.compound.compound.context = context;
2254 PopContext(context);
2255 curContext = context.parent;
2259 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2262 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2264 parentExp = checkedExp;
2265 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2267 if(checkedExp.type == extensionCompoundExp)
2269 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2272 checkedExp = checkedExp.list->last;
2274 else if(checkedExp.type == castExp)
2275 checkedExp = checkedExp.cast.exp;
2277 newExp = MkExpOp(null, '&', checkedExp);
2278 newExp.byReference = true;
2279 if(parentExp.type == callExp)
2281 exp.call.arguments->Insert(e.prev, newExp);
2282 exp.call.arguments->Remove(e);
2285 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2287 parentExp.list->Remove(checkedExp);
2288 parentExp.list->Add(newExp);
2290 else if(parentExp.type == castExp)
2291 parentExp.cast.exp = newExp;
2292 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2294 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2295 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2301 if(destType.classObjectType == ClassObjectType::typedObject)
2303 char className[1024];
2304 // Need the class itself here...
2305 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2306 _class = eSystem_FindClass(privateModule, "String");
2307 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2309 if(!strcmp(_class.name, "class"))
2311 // Already inside a typed_object function, pass the class through
2312 strcpy(className, "class");
2316 strcpy(className, "__ecereClass_");
2317 FullClassNameCat(className, _class.fullName, true);
2318 //MangleClassName(className);
2321 _class.symbol = FindClass(_class.fullName);
2323 DeclareClass(_class.symbol, className);
2326 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2328 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2330 Context context = PushContext();
2332 // Work around to avoid repeating the BuiltInContainer just to get the type
2333 // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
2334 if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
2335 e.list && e.list->first &&
2336 ((Expression)e.list->first).type == castExp &&
2337 ((Expression)e.list->first).cast.exp &&
2338 ((Expression)e.list->first).cast.exp.type == opExp &&
2339 ((Expression)e.list->first).cast.exp.op.op == '&' &&
2340 ((Expression)e.list->first).cast.exp.op.exp2 &&
2341 ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
2343 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2348 c = MkExpExtensionCompound(MkCompoundStmt(
2349 MkListOne(MkDeclaration(
2350 (specs = MkListOne(MkSpecifierName("Instance"))),
2351 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2352 MkInitializerAssignment(CopyExpression(e)))))),
2353 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2354 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2355 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2356 MkExpIdentifier(MkIdentifier(className))))))));
2357 c.compound.compound.context = context;
2358 PopContext(context);
2361 specs->Insert(null, MkSpecifier(CONST));
2363 exp.call.arguments->Insert(e.prev, c);
2367 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2373 //char debugString[4096] = "";
2374 //PrintExpression(e, debugString);
2376 // If expression type is a simple class, make it an address
2377 FixReference(e, !destType || !destType.declaredWithStruct);
2380 if(ellipsisDestType)
2383 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2384 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2386 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2394 bool changeToPtr = false;
2395 bool noHead = false;
2396 Type type = exp.member.exp ? exp.member.exp.expType : null;
2397 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2398 if(exp.member.member) exp.member.member._class = null;
2400 if(type && type.kind == templateType)
2402 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2403 if(baseType) type = baseType;
2405 if(type && exp.member.member && !type.directClassAccess)
2407 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2408 Property prop = null;
2409 ClassProperty classProperty = null;
2410 Method method = null;
2411 Class convertTo = null;
2412 DataMember member = null;
2413 DataMember subMemberStack[256];
2414 int subMemberStackPos = 0;
2415 bool thisPtr = exp.member.thisPtr;
2416 if(type.kind == subClassType && exp.member.exp.type == classExp)
2417 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2419 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2423 // DANGER: Buffer overflow
2424 char string[2048] = "";
2426 PrintTypeNoConst(type, string, false, true);
2427 classSym = FindClass(string);
2428 _class = classSym ? classSym.registered : null;
2431 if(_class && exp.member.memberType == dataMember)
2433 if(!thisPtr && !exp.member.member.classSym)
2434 member = eClass_FindDataMember(_class, exp.member.member.string, null, subMemberStack, &subMemberStackPos);
2436 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2438 else if(_class && exp.member.memberType == propertyMember)
2440 if(!thisPtr && !exp.member.member.classSym)
2441 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2443 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2444 if(prop && (exp.usage.usageRef ||
2445 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2446 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2448 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2451 exp.member.memberType = dataMember;
2456 if(exp.usage.usageRef)
2457 Compiler_Error($"cannot obtain address of property\n");
2459 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2460 else if(exp.usage.usageDelete)
2461 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2465 else if(_class && exp.member.memberType == methodMember)
2468 method = eClass_FindMethod(_class, exp.member.member.string, null);
2470 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2472 else if(_class && exp.member.memberType == reverseConversionMember)
2475 _class = FindClass(exp.member.member.string).registered;
2476 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2477 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2479 else if(_class && exp.member.memberType == classPropertyMember)
2481 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2485 // Only process Gets here, Set is processed in opExp's '='
2486 if(exp.usage.usageGet)
2490 char getName[1024], setName[1024];
2491 Expression ptr = exp.member.exp;
2492 Class propertyClass;
2493 char * nameToUse = convertTo ? setName : getName;
2495 FreeIdentifier(exp.member.member);
2497 // Process this here since it won't be processed at the end...
2498 exp.member.exp.usage.usageGet = true;
2499 ProcessExpression(exp.member.exp);
2500 // TEST: exp.tempCount = exp.member.exp.tempCount;
2502 DeclareProperty(prop, setName, getName);
2503 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2504 propertyClass = convertTo ? _class :
2505 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2508 if(propertyClass && propertyClass.type == bitClass)
2510 // Bit classes shouldn't have properties except for conversions...
2511 OldList * args = MkList();
2512 if(exp.usage.usageDeepGet)
2514 char className[1024];
2516 Declarator declarator;
2517 OldList * specs = MkList(), * decls = MkList();
2520 // Make a declaration in the closest compound statement
2521 // (Do not reuse (since using address for function calls)...)
2522 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2524 SpecDeclFromString(propertyClass.dataTypeString, specs,
2525 MkDeclaratorIdentifier(MkIdentifier(className)));
2527 ListAdd(decls, MkInitDeclarator(declarator, null));
2529 decl = MkDeclaration(specs, decls);
2530 if(!curCompound.compound.declarations)
2531 curCompound.compound.declarations = MkList();
2532 curCompound.compound.declarations->Insert(null, decl);
2534 tempExp = QMkExpId(className);
2535 tempExp.expType = MkClassType(propertyClass.fullName);
2537 exp.op.exp1 = tempExp;
2538 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2545 exp.call.exp = QMkExpId(nameToUse);
2546 exp.call.arguments = args;
2548 ListAdd(args, FixReference(ptr, true));
2550 else if(propertyClass && propertyClass.type == unitClass)
2552 OldList * args = MkList();
2553 ListAdd(args, FixReference(ptr, true));
2555 exp.call.exp = QMkExpId(nameToUse);
2556 exp.call.arguments = args;
2558 else if(propertyClass && propertyClass.type == structClass)
2560 OldList * args = MkList();
2561 char className[1024];
2563 OldList * specs = MkList(), * decls = MkList();
2566 // Make a declaration in the closest compound statement
2567 // (Do not reuse (since using address for function calls)...)
2570 FullClassNameCat(className, propertyClass.fullName, false); //true);
2572 //ListAdd(specs, MkSpecifierName(className));
2573 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2575 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2577 ListAdd(decls, MkInitDeclarator(
2578 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2580 decl = MkDeclaration(specs, decls);
2583 if(!curCompound.compound.declarations)
2584 curCompound.compound.declarations = MkList();
2585 curCompound.compound.declarations->Insert(null, decl);
2588 tempExp = QMkExpId(className);
2589 tempExp.expType = MkClassType(propertyClass.fullName);
2593 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2594 ListAdd(args, FixReference(ptr, true));
2598 ListAdd(args, FixReference(ptr, true));
2599 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2602 if(exp.usage.usageDeepGet)
2605 exp.call.exp = QMkExpId(nameToUse);
2606 exp.call.arguments = args;
2608 FreeExpression(tempExp);
2612 exp.type = bracketsExp;
2613 exp.list = MkList();
2614 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2615 if(exp.usage.usageMember)
2617 ListAdd(exp.list, FixReference(tempExp, true));
2618 exp.byReference = true;
2621 ListAdd(exp.list, tempExp);
2627 exp.call.exp = QMkExpId(nameToUse);
2628 exp.call.arguments = MkList();
2629 ListAdd(exp.call.arguments, FixReference(ptr, true));
2632 else if(prop.conversion)
2634 void * prev = exp.prev, * next = exp.next;
2635 *exp = *exp.member.exp;
2641 else if(classProperty)
2643 // Only process Gets here, Set is processed in opExp's '='
2644 if(exp.usage.usageGet)
2646 if(classProperty.Get)
2648 Identifier id = exp.member.member;
2649 Expression classExp = exp.member.exp;
2650 OldList * args = MkList();
2656 char typeString[2048];
2657 OldList * specs = MkList();
2660 PrintType(exp.expType, typeString, false, false);
2661 decl = SpecDeclFromString(typeString, specs, null);
2662 exp.cast.typeName = MkTypeName(specs, decl);
2665 exp.cast.typeName = QMkType("uint64", null);
2666 exp.cast.exp = MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty")), args);
2668 ListAdd(args, classExp);
2670 char * s = QMkString(id.string);
2671 ListAdd(args, MkExpString(s));
2676 ProcessExpression(exp);
2683 // Get the function address if it's not called
2684 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2688 FreeIdentifier(exp.member.member);
2690 // Process this here since it won't be processed at the end...
2691 exp.member.exp.usage.usageGet = true;
2692 ProcessExpression(exp.member.exp);
2693 // TEST: exp.tempCount = exp.member.exp.tempCount;
2695 if(method.type == virtualMethod)
2697 strcpy(name, "__ecereVMethodID_");
2698 FullClassNameCat(name, method._class.fullName, false);
2700 strcat(name, method.name);
2701 exp.type = indexExp;
2702 if(memberClassSpecifier)
2704 char className[1024];
2705 // Need the class itself here...
2706 strcpy(className, "__ecereClass_");
2707 FullClassNameCat(className, _class.fullName, true);
2708 //MangleClassName(className);
2711 _class.symbol = FindClass(_class.fullName);
2712 DeclareClass(_class.symbol, className);
2714 FreeExpression(exp.member.exp);
2715 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2719 if(exp.thisPtr && _class.type != normalClass)
2721 FreeExpression(exp.member.exp);
2722 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2725 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2727 exp.index.index = MkListOne(QMkExpId(name));
2728 DeclareMethod(method, name);
2732 FreeExpression(exp.member.exp);
2733 exp.type = identifierExp;
2734 strcpy(name, "__ecereMethod_");
2735 FullClassNameCat(name, method._class.fullName, false);
2737 strcat(name, method.name);
2738 exp.identifier = MkIdentifier(name);
2739 DeclareMethod(method, name);
2745 if(subMemberStackPos)
2748 DataMember parentMember = null;
2749 String s, prefix = null;
2750 for(i = 0; i < subMemberStackPos; i++)
2752 DataMember curMember = subMemberStack[i];
2755 for(m = parentMember ? parentMember.members.first : _class.membersAndProperties.first; m; m = m.next)
2757 if(m && !m.isProperty && (m.type == unionMember || m.type == structMember) && !m.name)
2768 prefix = PrintString(prefix, ".__anon", anonID);
2772 prefix = PrintString("__anon", anonID);
2773 parentMember = curMember;
2776 s = exp.member.member.string;
2777 exp.member.member.string = PrintString(prefix, ".", s);
2781 // Process this here since it won't be processed at the end...
2782 if(exp.usage.usageGet)
2784 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2786 ProcessExpression(exp.member.exp);
2787 // TEST: exp.tempCount = exp.member.exp.tempCount;
2789 if(type.kind == classType && type._class && type._class.registered)
2790 DeclareStruct(type._class.registered.fullName, false);
2792 // TESTING THIS NOHEAD STUFF...
2793 if(_class.type == noHeadClass)
2797 else if(_class.type == structClass)
2801 else if(_class.type == bitClass)
2803 OldList * list = MkList();
2804 char mask[32], shift[10];
2805 OldList * specs = MkList();
2806 BitMember bitMember = (BitMember) member;
2807 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2808 TypeName type = MkTypeName(specs, decl);
2809 if(bitMember.mask > MAXDWORD)
2810 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2812 sprintf(mask, FORMAT64HEX, bitMember.mask);
2813 sprintf(shift, "%d", bitMember.pos);
2815 FreeIdentifier(exp.member.member);
2817 // ((type) ((color & mask) >> bitPos))
2818 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2819 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2820 MkExpConstant(shift))))));
2822 exp.type = bracketsExp;
2825 else if(_class.type == unitClass)
2830 // If it's a this pointer, replace by precomputed shortcut
2831 if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2833 char pointerName[1024];
2835 strcpy(pointerName, "__ecerePointer_");
2836 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2837 if(exp.member.exp.identifier)
2838 FreeIdentifier(exp.member.exp.identifier);
2839 exp.member.exp.identifier = MkIdentifier(pointerName);
2841 // Otherwise, access the data the hard way
2844 Expression bytePtr, e;
2845 Expression checkedExp;
2846 char structName[1024];
2847 char className[1024];
2848 strcpy(className, "__ecereClass_");
2849 FullClassNameCat(className, member._class.fullName, true);
2850 //MangleClassName(className);
2852 // classExp = QMkExpId(className);
2854 if(!member._class.symbol)
2855 member._class.symbol = FindClass(member._class.fullName);
2857 DeclareClass(member._class.symbol, className);
2858 DeclareStruct(member._class.fullName, false);
2861 FullClassNameCat(structName, member._class.fullName, false);
2863 checkedExp = exp.member.exp;
2864 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2865 checkedExp.type == castExp)
2867 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2868 checkedExp = checkedExp.list->last;
2869 else if(checkedExp.type == castExp)
2870 checkedExp = checkedExp.cast.exp;
2873 if(checkedExp.type != identifierExp &&
2874 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2875 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2877 char ecereTemp[100];
2879 Context context = PushContext();
2880 if(exp.member.exp.tempCount > exp.tempCount)
2881 exp.tempCount = exp.member.exp.tempCount;
2884 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2885 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2886 curContext = context;
2887 compound = MkCompoundStmt(
2888 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2889 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2890 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2891 if(member._class.fixed)
2893 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2896 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2897 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2900 e = QMkExpId(ecereTemp);
2904 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2905 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2908 compound.compound.context = context;
2909 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2910 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2911 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2913 exp.member.exp = MkExpExtensionCompound(compound);
2915 PopContext(context);
2916 curContext = context.parent;
2920 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2921 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2923 e = QBrackets(QMkExpCond(exp.member.exp,
2924 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2925 MkExpConstant("0")));
2929 if(member._class.fixed)
2931 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2934 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2935 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2941 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2943 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2944 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2947 exp.type = pointerExp;
2952 // Take Out Any Class Specifier (Should have been used by now)
2953 FreeSpecifier(memberClassSpecifier);
2955 // Just moved this at the end... How is it?
2956 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
2958 exp.member.exp.usage.usageGet = true;
2959 exp.member.exp.usage.usageMember = true;
2960 exp.member.exp.tempCount = exp.tempCount;
2961 ProcessExpression(exp.member.exp);
2962 exp.tempCount = exp.member.exp.tempCount;
2963 if((changeToPtr && exp.member.exp.byReference) || noHead)
2964 exp.type = pointerExp;
2968 case extensionCompoundExp:
2970 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
2972 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2974 ProcessStatement(exp.compound);
2976 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2977 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2982 exp.member.exp.usage.usageGet = true;
2983 ProcessExpression(exp.member.exp);
2988 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2989 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2991 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2994 Expression classExp;
2996 FreeTypeName(exp.typeName);
2998 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
3000 ProcessExpressionType(classExp);
3001 ProcessExpression(classExp);
3003 exp.type = bracketsExp;
3004 exp.list = MkListOne(MkExpMember(classExp, MkIdentifier("typeSize")));
3006 ProcessExpressionType(exp);
3007 ProcessExpression(exp);
3016 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
3017 ProcessExpression(exp.cast.exp);
3019 if(exp.cast.exp.byReference)
3020 exp.byReference = exp.cast.exp.byReference;
3021 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
3022 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
3023 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
3024 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
3025 exp.byReference = true;
3027 // Moved this to 1.5...
3028 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
3034 if(exp.usage.usageGet)
3035 exp.cond.cond.usage.usageGet = true;
3036 ProcessExpression(exp.cond.cond);
3037 for(e = exp.cond.exp->first; e; e = e.next)
3039 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
3040 ProcessExpression(e);
3042 if(exp.usage.usageGet)
3043 exp.cond.elseExp.usage.usageGet = true;
3044 ProcessExpression(exp.cond.elseExp);
3049 // Need the class itself here...
3050 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
3052 Specifier spec = exp._classExp.specifiers->first;
3053 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
3056 FreeList(exp._classExp.specifiers, FreeSpecifier);
3057 if(exp._classExp.decl)
3058 FreeDeclarator(exp._classExp.decl);
3060 exp.type = memberExp; //pointerExp;
3061 exp.member.exp = argExp;
3062 exp.member.member = MkIdentifier("dataTypeClass");
3063 exp.member.memberType = dataMember;
3065 ProcessExpressionType(argExp);
3066 ProcessExpressionType(exp);
3067 ProcessExpression(exp);
3072 char className[1024];
3073 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
3074 Symbol classSym = FindClass(string);
3076 strcpy(className, "__ecereClass_");
3077 FullClassNameCat(className, string, true); // TODO: Verify this
3078 //MangleClassName(className);
3079 DeclareClass(classSym, className);
3082 FreeList(exp._classExp.specifiers, FreeSpecifier);
3083 if(exp._classExp.decl)
3084 FreeDeclarator(exp._classExp.decl);
3086 exp.type = identifierExp;
3087 exp.identifier = MkIdentifier(className);
3093 ProcessExpression(exp.vaArg.exp);
3096 case extensionInitializerExp:
3098 ProcessInitializer(exp.initializer.initializer);
3104 if(exp.needTemplateCast != 2 && (exp.needTemplateCast == 1 || (exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate))))
3106 Expression nbExp = GetNonBracketsExp(exp);
3107 Expression inner = GetInnerExp(nbExp);
3109 if((!exp.expType || exp.expType.kind != templateType || nbExp.type != castExp) && !exp.usage.usageRef &&
3110 (!exp.destType || (!exp.destType.truth && (exp.destType.kind != templateType || (exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType))))) &&
3111 (exp.usage.usageDelete || exp.usage.usageGet || exp.usage.usageArg) &&
3112 (!exp.destType || (!exp.destType.passAsTemplate && exp.expType && (exp.expType.kind != pointerType || exp.destType.kind == pointerType) && (exp.destType.kind != pointerType || exp.expType.kind == pointerType))) &&
3113 !inner.needCast && inner.type != opExp)
3115 Expression e = CopyExpContents(exp);
3117 OldList * specs = MkList();
3118 char typeString[1024];
3120 typeString[0] = '\0';
3122 e.needTemplateCast = 2;
3123 inner.needTemplateCast = 2;
3124 nbExp.needTemplateCast = 2;
3125 if(exp.usage.usageDelete)
3126 strcpy(typeString, "void *");
3128 PrintType(exp.expType, typeString, false, false);
3130 decl = SpecDeclFromString(typeString, specs, null);
3132 if(specs && specs->first && ((Specifier)specs->first).type == templateTypeSpecifier &&
3133 exp.destType && !exp.destType.passAsTemplate && exp.destType.kind == templateType && exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType) && !exp.usage.usageArg)
3135 if(decl) FreeDeclarator(decl);
3136 FreeList(specs, FreeSpecifier);
3137 if(exp.destType.templateParameter.dataTypeString)
3140 strcpy(typeString, exp.destType.templateParameter.dataTypeString);
3141 decl = SpecDeclFromString(typeString, specs, null);
3145 specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
3146 decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
3150 e.destType = exp.destType;
3152 exp.destType.refCount++;
3154 exp.type = bracketsExp;
3155 exp.list = MkListOne(MkExpCast(MkTypeName(specs, decl), MkExpBrackets(MkListOne(e))));
3156 exp.needTemplateCast = 2;
3162 static void ProcessInitializer(Initializer init)
3166 case expInitializer:
3169 init.exp.usage.usageGet = true;
3170 ProcessExpression(init.exp);
3171 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
3172 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
3174 FixReference(init.exp, true);
3176 else if(init.exp.destType && init.exp.destType.kind == classType)
3177 FixReference(init.exp, false);
3180 case listInitializer:
3185 for(i = init.list->first; i; i = i.next)
3186 ProcessInitializer(i);
3193 static void ProcessDeclaration(Declaration decl)
3197 case initDeclaration:
3199 if(decl.declarators)
3203 for(d = decl.declarators->first; d; d = d.next)
3206 ProcessInitializer(d.initializer);
3214 static void ProcessStatement(Statement stmt)
3219 ProcessStatement(stmt.labeled.stmt);
3222 if(stmt.caseStmt.exp)
3224 stmt.caseStmt.exp.usage.usageGet = true;
3226 // This expression should be constant...
3227 ProcessExpression(stmt.caseStmt.exp);
3229 if(stmt.caseStmt.stmt)
3230 ProcessStatement(stmt.caseStmt.stmt);
3234 if(stmt.compound.context)
3238 Statement prevCompound = curCompound;
3239 Context prevContext = curContext;
3241 if(!stmt.compound.isSwitch)
3244 curContext = stmt.compound.context;
3247 if(stmt.compound.declarations)
3249 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3250 ProcessDeclaration(decl);
3252 if(stmt.compound.statements)
3254 for(s = stmt.compound.statements->first; s; s = s.next)
3255 ProcessStatement(s);
3257 curContext = prevContext;
3258 curCompound = prevCompound;
3262 case expressionStmt:
3265 if(stmt.expressions)
3267 for(exp = stmt.expressions->first; exp; exp = exp.next)
3269 ProcessExpression(exp);
3280 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3281 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3283 ProcessExpression(exp);
3286 if(stmt.ifStmt.stmt)
3287 ProcessStatement(stmt.ifStmt.stmt);
3288 if(stmt.ifStmt.elseStmt)
3289 ProcessStatement(stmt.ifStmt.elseStmt);
3295 if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
3297 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3298 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3300 ProcessExpression(exp);
3303 ProcessStatement(stmt.switchStmt.stmt);
3309 if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
3311 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3312 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3314 ProcessExpression(exp);
3317 ProcessStatement(stmt.whileStmt.stmt);
3323 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3325 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3326 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3328 ProcessExpression(exp);
3331 if(stmt.doWhile.stmt)
3332 ProcessStatement(stmt.doWhile.stmt);
3338 if(stmt.forStmt.init)
3339 ProcessStatement(stmt.forStmt.init);
3341 if(stmt.forStmt.check)
3343 if(stmt.forStmt.check.expressions)
3345 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3347 ProcessStatement(stmt.forStmt.check);
3349 if(stmt.forStmt.increment)
3351 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3353 ProcessExpression(exp);
3356 if(stmt.forStmt.stmt)
3357 ProcessStatement(stmt.forStmt.stmt);
3369 if(stmt.expressions)
3371 ((Expression)stmt.expressions->last).usage.usageGet = true;
3372 for(exp = stmt.expressions->first; exp; exp = exp.next)
3374 ProcessExpression(exp);
3375 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3376 if(!exp.next && exp.destType && exp.destType.byReference)
3377 FixReference(exp, true);
3382 case badDeclarationStmt:
3384 ProcessDeclaration(stmt.decl);
3390 if(stmt.asmStmt.inputFields)
3392 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3393 if(field.expression)
3394 ProcessExpression(field.expression);
3396 if(stmt.asmStmt.outputFields)
3398 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3399 if(field.expression)
3400 ProcessExpression(field.expression);
3402 if(stmt.asmStmt.clobberedFields)
3404 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3405 if(field.expression)
3406 ProcessExpression(field.expression);
3413 static void ProcessFunction(FunctionDefinition function)
3416 ProcessStatement(function.body);
3419 static void ProcessMemberInitData(MemberInit member)
3421 if(member.initializer)
3422 ProcessInitializer(member.initializer);
3425 static void ProcessInstantiation(Instantiation inst)
3429 MembersInit members;
3430 for(members = inst.members->first; members; members = members.next)
3432 if(members.type == dataMembersInit)
3434 if(members.dataMembers)
3437 for(member = members.dataMembers->first; member; member = member.next)
3438 ProcessMemberInitData(member);
3441 else if(members.type == methodMembersInit)
3443 ProcessFunction((FunctionDefinition)members.function);
3449 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3450 public void ProcessMemberAccess()
3453 for(external = ast->first; external; external = external.next)
3455 curExternal = external;
3456 // There shouldn't be any class member access here anyways...
3457 if(external.type == declarationExternal)
3459 if(external.declaration)
3460 ProcessDeclaration(external.declaration);
3464 for(external = ast->first; external; external = external.next)
3466 curExternal = external;
3467 if(external.type == functionExternal)
3469 ProcessFunction(external.function);
3471 else if(external.type == declarationExternal)
3473 if(external.declaration)
3474 ProcessDeclaration(external.declaration);
3476 else if(external.type == classExternal)
3478 ClassDefinition _class = external._class;
3479 if(_class.definitions)
3482 Class regClass = _class.symbol.registered;
3484 // Process all functions
3485 for(def = _class.definitions->first; def; def = def.next)
3487 if(def.type == functionClassDef)
3489 curExternal = def.function.declarator.symbol.pointerExternal;
3490 ProcessFunction((FunctionDefinition)def.function);
3492 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3494 ProcessInstantiation(def.decl.inst);
3496 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3498 MemberInit defProperty;
3500 // Add this to the context
3503 string = CopyString("this");
3504 type = MkClassType(regClass.fullName);
3506 globalContext.symbols.Add((BTNode)thisSymbol);
3508 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3510 //thisClass = regClass;
3511 ProcessMemberInitData(defProperty); //, regClass, &id);
3515 //globalContext.symbols.Delete((BTNode)thisSymbol);
3516 globalContext.symbols.Remove((BTNode)thisSymbol);
3517 FreeSymbol(thisSymbol);
3519 else if(def.type == propertyClassDef && def.propertyDef)
3521 PropertyDef prop = def.propertyDef;
3523 // Add this to the context
3526 string = CopyString("this");
3527 type = MkClassType(regClass.fullName);
3529 globalContext.symbols.Add((BTNode)thisSymbol);
3531 //thisClass = regClass;
3534 curExternal = prop.symbol.externalSet;
3535 ProcessStatement(prop.setStmt);
3539 curExternal = prop.symbol.externalGet;
3540 ProcessStatement(prop.getStmt);
3544 curExternal = prop.symbol.externalIsSet;
3545 ProcessStatement(prop.issetStmt);
3550 //globalContext.symbols.Delete((BTNode)thisSymbol);
3551 globalContext.symbols.Remove((BTNode)thisSymbol);
3552 FreeSymbol(thisSymbol);
3554 else if(def.type == classPropertyClassDef && def.propertyDef)
3556 PropertyDef prop = def.propertyDef;
3558 //thisClass = regClass;
3561 curExternal = prop.symbol.externalSet;
3562 ProcessStatement(prop.setStmt);
3566 curExternal = prop.symbol.externalGet;
3567 ProcessStatement(prop.getStmt);
3571 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3573 PropertyWatch propertyWatch = def.propertyWatch;
3575 // Add this to the context
3578 string = CopyString("this");
3579 type = MkClassType(regClass.fullName);
3581 globalContext.symbols.Add((BTNode)thisSymbol);
3583 //thisClass = regClass;
3584 if(propertyWatch.compound)
3588 string = CopyString("this");
3589 type = MkClassType(regClass.fullName);
3591 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3593 ProcessStatement(propertyWatch.compound);
3595 // thisClass = null;
3597 //globalContext.symbols.Delete((BTNode)thisSymbol);
3598 globalContext.symbols.Remove((BTNode)thisSymbol);
3599 FreeSymbol(thisSymbol);