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 bool FixMember(Expression exp)
170 bool byReference = false;
173 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
175 if(exp.list->count > 1)
177 exp = exp.list->last;
179 else if(exp.type == castExp)
186 FixReference(exp, true);
188 byReference = exp.byReference;
195 static void ProcessExpression(Expression exp)
197 Location oldyylloc = yylloc;
199 char debugExpString[1024] = "";
200 PrintExpression(exp, debugExpString);
210 if(exp.expType && exp.expType.kind == methodType)
212 Class _class = exp.expType.methodClass;
213 Method method = exp.expType.method;
214 if(method.type == virtualMethod)
219 OldList * specs = MkList();
220 strcpy(name, "__ecereVMethodID_");
221 FullClassNameCat(name, method._class.fullName, false);
223 strcat(name, method.name);
225 DeclareMethod(method, name);
227 // Cast function to its type
228 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
229 if(!method.dataType.staticMethod)
231 Declarator funcDecl = GetFuncDecl(decl);
233 if(!funcDecl.function.parameters)
234 funcDecl.function.parameters = MkList();
236 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
237 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
239 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
240 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
243 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
244 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
247 typeName = MkTypeName(specs, decl);
251 char className[1024];
252 // Need the class itself here...
253 strcpy(className, "__ecereClass_");
254 FullClassNameCat(className, _class.fullName, true);
255 MangleClassName(className);
258 _class.symbol = FindClass(_class.fullName);
259 DeclareClass(_class.symbol, className);
262 FreeIdentifier(exp.identifier);
263 exp.type = bracketsExp;
264 exp.list = MkListOne(MkExpCast(typeName,
265 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
266 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
272 strcpy(name, "__ecereMethod_");
273 FullClassNameCat(name, method._class.fullName, false);
275 strcat(name, method.name);
277 delete exp.identifier.string;
278 FreeSpecifier(exp.identifier._class);
280 exp.identifier._class = null;
281 exp.identifier.string = CopyString(name);
282 DeclareMethod(method, name);
286 if(exp.usage & USAGE_MEMBER)
287 FixReference(exp, true);
300 OldList * args = MkList();
302 if(exp.type == renewExp || exp.type == renew0Exp)
303 ListAdd(args, exp._renew.exp);
305 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
309 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
310 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
311 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
312 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
314 exp.call.arguments = args;
317 ProcessExpression(exp);
322 Expression exp1 = exp.op.exp1;
323 Expression exp2 = exp.op.exp2;
327 // Assignment Operators
330 exp.op.exp2.usage.usageGet = true;
342 exp.op.exp2.usage.usageGet = true;
351 if(exp.op.exp1 && exp.op.exp2)
353 exp.op.exp1.usage.usageGet = true;
354 exp.op.exp2.usage.usageGet = true;
358 exp.op.exp2.usage.usageRef = true;
367 exp.op.exp1.usage.usageGet = true;
372 exp.op.exp2.usage.usageGet = true;
375 // Binary only operators
391 exp.op.exp1.usage.usageGet = true;
393 exp.op.exp2.usage.usageGet = true;
397 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
398 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
399 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
400 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
402 Expression memberExp;
403 Expression parentExp = null; // Where to take memberExp out from
405 // TOCHECK: See note below for this if
406 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
408 // Extra bit of code to access deep properties...
409 Expression testExp, topExp = null;
410 Expression lastExp = exp.op.exp1, parentExp = null;
411 Property lastProperty = null;
414 char setName[1024], getName[1024];
415 testExp = exp.op.exp1.member.exp;
418 // Is further fixing needed to address if statement above in the same way?
421 if(testExp.type == castExp)
422 testExp = testExp.cast.exp;
423 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
424 testExp = testExp.list->last;
425 else if(testExp.type == ExpressionType::memberExp)
432 if(testExp.member.memberType == propertyMember ||
433 testExp.member.memberType == reverseConversionMember)
435 Type type = testExp.member.exp.expType;
438 if(type.kind == classType)
440 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
441 Class convertTo = null;
442 if(testExp.member.memberType == reverseConversionMember)
445 _class = FindClass(testExp.member.member.string).registered;
446 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
447 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
451 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
453 if(lastProperty && lastProperty.Get && lastProperty.Set)
455 DeclareProperty(lastProperty, setName, getName);
456 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
457 propertyClass = convertTo ? _class :
458 ((((Symbol)lastProperty.symbol).type &&
459 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
460 // TODO: Handle this kind of things with bit classes?
461 if(propertyClass && propertyClass.type == structClass)
466 else if(propertyClass && propertyClass.type == bitClass)
478 testExp = testExp.member.exp;
482 if(propertyClass.type == structClass)
486 char className[1024];
489 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
490 tempExp = QMkExpId(className);
491 tempExp.expType = MkClassType(propertyClass.fullName);
493 parentExp.member.exp = tempExp;
495 value = MkExpBrackets(MkList());
497 copy = CopyExpression(topExp);
498 copy.usage.usageGet = true;
499 copy.usage.usageDeepGet = true;
501 ListAdd(value.list, copy);
502 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
503 ListAdd(value.list, CopyExpression(tempExp));
504 value.expType = tempExp.expType;
505 tempExp.expType.refCount++;
507 // Go on as usual with these new values:
508 exp.op.exp1 = topExp;
515 else if(propertyClass.type == bitClass)
519 char className[1024];
522 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
523 tempExp = QMkExpId(className);
524 tempExp.expType = MkClassType(propertyClass.fullName);
526 parentExp.member.exp = tempExp;
528 value = MkExpBrackets(MkList());
530 copy = CopyExpression(topExp);
531 copy.usage.usageGet = true;
532 copy.usage.usageDeepGet = true;
534 ListAdd(value.list, copy);
535 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
536 ListAdd(value.list, CopyExpression(tempExp));
537 value.expType = tempExp.expType;
538 value.expType.refCount++;
540 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
542 // Go on as usual with these new values:
543 exp.op.exp1 = topExp;
553 memberExp = exp.op.exp1;
555 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
556 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
558 parentExp = memberExp;
559 if(memberExp.type == extensionCompoundExp)
560 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
562 memberExp = memberExp.list->last;
565 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
566 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
567 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
569 ProcessExpression(memberExp);
571 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
572 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
574 parentExp = memberExp;
575 if(memberExp.type == extensionCompoundExp)
576 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
578 memberExp = memberExp.list->last;
581 if(memberExp && memberExp.type == extensionCompoundExp)
583 parentExp = memberExp;
584 if(memberExp.type == extensionCompoundExp)
586 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
587 if(stmt && stmt.type != expressionStmt) stmt = null;
588 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
591 stmt.expressions->Remove(memberExp);
592 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
593 exp.type = bracketsExp;
594 exp.list = MkListOne(parentExp);
595 ProcessExpression(exp);
600 memberExp = memberExp.list->last;
604 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
606 if(memberExp && memberExp.type == ExpressionType::memberExp)
608 Type type = memberExp.member.exp.expType;
611 // Check if it's an instance
612 if(type.kind == classType || type.kind == subClassType)
614 // TODO: SOMETHING WRONG HERE...
615 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
617 if(memberExp == exp1)
621 if(parentExp.type == extensionCompoundExp)
622 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
624 parentExp.list->Remove(memberExp);
627 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
629 BitMember bitMember =
630 (BitMember)eClass_FindDataMember(_class,
631 memberExp.member.member.string, privateModule, null, null);
632 char mask[32], shift[10];
633 OldList * specs = MkList();
634 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
635 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
636 TypeName type = MkTypeName(specs, decl);
638 if(bitMember.mask > MAXDWORD)
639 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
641 sprintf(mask, FORMAT64HEX, bitMember.mask);
642 sprintf(shift, "%d", bitMember.pos);
644 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
645 exp.op.exp1 = memberExp.member.exp;
647 // TESTING THIS FOR: argb.color.r = 1;
648 //ProcessExpression(memberExp.member.exp);
650 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
651 if(exp.op.op == XOR_ASSIGN)
653 exp.op.exp2 = MkExpOp(MkExpBrackets(
654 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
658 exp.op.exp2 = MkExpOp(
659 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
660 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
661 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
662 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift)))));
665 memberExp.member.exp = null;
666 FreeExpression(memberExp);
668 // TESTING THIS FOR: argb.color.r = 1;
669 ProcessExpression(exp);
672 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
675 else if(memberExp.member.memberType != dataMember)
678 Class convertTo = null;
679 ClassProperty classProperty = null;
681 if(memberExp.member.memberType == reverseConversionMember)
684 _class = FindClass(memberExp.member.member.string).registered;
685 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
686 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
689 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
691 if(memberExp.member.memberType == classPropertyMember)
692 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
694 exp.tempCount = memberExp.member.exp.tempCount;
698 // Only process Gets here, Set is processed in opExp's '='
699 if(classProperty.Set)
701 Identifier id = memberExp.member.member;
702 Expression classExp = memberExp.member.exp;
703 Expression value = exp.op.exp2;
705 memberExp.member.exp = null;
706 memberExp.member.member = null;
709 FreeExpContents(memberExp);
713 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
714 exp.call.arguments = MkList();
715 ListAdd(exp.call.arguments, classExp);
717 char * s = QMkString(id.string);
718 ListAdd(exp.call.arguments, MkExpString(s));
721 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
725 ProcessExpression(exp);
731 if((!convertTo && prop.Set) || (convertTo && prop.Get))
733 Expression value = exp.op.exp2;
734 char setName[1024], getName[1024];
735 char * setToUse = convertTo ? getName : setName;
736 char * getToUse = convertTo ? setName : getName;
737 bool needAddress = false;
738 int operator = exp.op.op;
741 case MUL_ASSIGN: operator = '*'; break;
742 case DIV_ASSIGN: operator = '/'; break;
743 case MOD_ASSIGN: operator = '%'; break;
744 case SUB_ASSIGN: operator = '-'; break;
745 case ADD_ASSIGN: operator = '+'; break;
746 case LEFT_ASSIGN: operator = LEFT_OP; break;
747 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
748 case AND_ASSIGN: operator = '&'; break;
749 case OR_ASSIGN: operator = '|'; break;
750 case XOR_ASSIGN: operator = '^'; break;
755 if(operator == INC_OP)
756 value = MkExpOp(CopyExpression(memberExp),
757 '+', MkExpConstant("1"));
758 else if(operator == DEC_OP)
759 value = MkExpOp(CopyExpression(memberExp),
760 '-', MkExpConstant("1"));
763 value = MkExpOp(CopyExpression(memberExp),
767 value.expType = memberExp.expType;
768 memberExp.expType.refCount++;
769 value.usage.usageArg = true;
773 // Dont free exp2, we're using it
778 value.usage.usageArg = true;
780 DeclareProperty(prop, setName, getName);
782 if(memberExp.member.exp)
783 ProcessExpression(memberExp.member.exp);
785 // If get flag present
786 if(exp.usage.usageGet &&
787 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
789 OldList * list = MkList();
792 Context context = PushContext();
795 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
796 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
798 curContext = context;
799 exp.type = extensionCompoundExp;
800 exp.compound = MkCompoundStmt(
801 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
802 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
803 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
810 ListAdd(args, value);
811 ListAdd(args, QMkExpId(ecereTemp));
812 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
816 ListAdd(args, QMkExpId(ecereTemp));
817 ListAdd(args, value);
818 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
824 ListAdd(args, QMkExpId(ecereTemp));
826 args->Insert(null, QMkExpId(ecereTemp));
827 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
829 exp.compound.compound.context = context;
831 curContext = context.parent;
835 Expression newExp = exp;
837 if(parentExp && parentExp.type == extensionCompoundExp)
839 newExp = Expression { };
840 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
841 FreeType(exp.expType);
842 FreeType(exp.destType);
845 parentExp.type = dummyExp;
846 parentExp.expType = null;
847 parentExp.destType = null;
850 newExp.type = callExp;
851 newExp.call.exp = QMkExpId(setToUse);
852 newExp.call.arguments = MkList();
855 ListAdd(newExp.call.arguments, value);
856 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
860 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
861 ListAdd(newExp.call.arguments, value);
866 // Take it out from there
867 memberExp.member.exp = null;
869 // Don't use the temporaries used by the left side...
872 value.tempCount = exp.tempCount;
873 ProcessExpression(value);
875 FixReference(value, true);
878 FreeExpression(memberExp);
882 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
885 memberExp.member.memberType = dataMember;
888 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
893 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
894 if(method && method.type == virtualMethod && type.kind != subClassType)
896 Expression value = exp.op.exp2;
897 // Don't use the temporaries used by the left side...
898 value.tempCount = exp.tempCount;
899 ProcessExpression(value);
901 if(memberExp.member.exp)
902 ProcessExpression(memberExp.member.exp);
904 if(exp.usage.usageGet)
906 OldList * list = MkList();
911 ListAdd(args, memberExp.member.exp);
913 char * string = QMkString(memberExp.member.member.string);
914 ListAdd(args, MkExpString(string));
917 ListAdd(args, value);
918 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
919 ListAdd(list, CopyExpression(value));
920 exp.type = bracketsExp;
927 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
928 exp.call.arguments = MkList();
929 ListAdd(exp.call.arguments, memberExp.member.exp);
931 char * string = QMkString(memberExp.member.member.string);
932 ListAdd(exp.call.arguments, MkExpString(string));
935 ListAdd(exp.call.arguments, value);
938 memberExp.member.exp = null;
941 FreeExpression(memberExp);
945 else if(memberExp.member.memberType == dataMember)
947 //if(exp.usage & USAGE_GET);
948 //FixReference(value, true);
949 if(FixMember(memberExp.member.exp))
951 // TESTING THIS HERE:
952 ProcessExpression(memberExp);
954 memberExp.type = pointerExp;
961 else if(exp.op.op == _INCREF)
963 Expression object = exp.op.exp2;
965 FreeExpContents(exp);
966 FreeType(exp.expType);
967 FreeType(exp.destType);
971 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
973 else if(exp.op.op == DELETE)
975 Expression object = exp.op.exp2;
976 OldList * args = MkList();
978 exp.type = bracketsExp;
981 object.usage.usageDelete = true;
983 ProcessExpression(object);
985 ListAdd(args, object);
987 // TOFIX: Same time as when we fix for = 0
989 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
990 exp.expType._class.registered.type == normalClass &&
991 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
993 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
994 ProcessExpressionType(decRefExp);
995 ListAdd(exp.list, decRefExp);
997 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
1000 char className[1024];
1001 OldList * list = MkList();
1003 strcpy(className, "__ecereClass_");
1004 FullClassNameCat(className, exp.expType._class.string, true);
1005 MangleClassName(className);
1007 DeclareClass(exp.expType._class, className);
1009 // Call the non virtual destructor
1010 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1011 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1013 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1015 MkExpBrackets(MkListOne(MkExpCondition(
1016 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1017 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1022 OldList * list = MkList();
1024 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1026 char className[1024];
1028 if(_class.templateClass) _class = _class.templateClass;
1029 strcpy(className, "__ecereClass_");
1030 FullClassNameCat(className, _class.fullName, false /*true*/);
1031 MangleClassName(className);
1034 _class.symbol = FindClass(_class.fullName);
1035 DeclareClass(_class.symbol, className);
1037 // Call the non virtual destructor
1041 QMkExpId(className),
1042 MkIdentifier("Destructor")
1047 QMkExpId(className),
1048 MkIdentifier("Destructor")
1050 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), CopyExpression(args->first)))
1057 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1062 CopyExpression(object),
1072 else if(exp.expType && exp.expType.kind == templateType)
1074 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1077 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1079 OldList * qualifiers = MkList();
1080 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1082 typeName = MkTypeName(qualifiers, declarator);
1084 ProcessExpressionType(classExp);
1085 args->Insert(null, CopyExpression(classExp));
1086 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1087 ListAdd(exp.list, MkExpCall(
1088 MkExpBrackets(MkListOne(MkExpCast(typeName,
1089 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1090 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1091 //ProcessExpression(exp.list->last);
1095 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1097 //ProcessExpression(object);
1099 ListAdd(exp.list, MkExpOp(CopyExpression(object.type == castExp ? object.cast.exp : object), '=', MkExpConstant("0")));
1103 // TESTING THIS HERE...
1104 ProcessExpression(exp);
1107 if(exp.type == opExp)
1109 // Handle assigment of template structures
1110 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1111 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1113 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1116 // memcpy((byte *)array + (count * dataTypeClass.size), dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1118 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1119 OldList * args = MkList();
1120 Expression derefExp = exp.op.exp1;
1121 Expression sizeExp = MkExpCondition(MkExpBrackets(MkListOne(
1123 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1125 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1126 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1127 MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize")));
1129 if(exp.op.exp1.type == indexExp)
1131 Expression indexExp = derefExp.index.exp;
1132 OldList * indexExpIndex = derefExp.index.index;
1134 derefExp.index.index = null;
1135 derefExp.index.exp = null;
1136 FreeExpression(derefExp);
1138 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1139 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1143 Expression indexExp = derefExp.op.exp2;
1144 derefExp.op.exp2 = null;
1145 FreeExpression(derefExp);
1146 derefExp = indexExp;
1149 args->Add(derefExp);
1150 ProcessExpressionType(args->last);
1151 ProcessExpression(args->last);
1153 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1154 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1155 MkListOne(exp.op.exp2), MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1157 thisClass = curExternal.function ? curExternal.function._class : null;
1161 string = CopyString("this");
1162 type = MkClassType(thisClass.fullName);
1164 globalContext.symbols.Add((BTNode)thisSymbol);
1166 ProcessExpressionType(args->last);
1167 ProcessExpression(args->last);
1170 ProcessExpressionType(args->last);
1171 ProcessExpression(args->last);
1173 DeclareFunctionUtil("memcpy");
1175 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1176 exp.type = bracketsExp;
1178 //globalContext.symbols.Delete((BTNode)thisSymbol);
1179 globalContext.symbols.Remove((BTNode)thisSymbol);
1180 FreeSymbol(thisSymbol);
1186 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1187 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1189 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1192 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1193 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1195 exp.type = bracketsExp;
1196 exp.list = MkListOne(
1198 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1200 // ((class.type == structClass) ?
1201 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1204 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1206 // ((class.type == normalClass || class.type == noHeadClass) ?
1207 MkExpCondition(MkExpBrackets(MkListOne(
1209 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1211 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1212 // *((void **)array)
1213 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1214 CopyExpression(exp.op.exp2))))))),
1216 // ((class.size == 1) ?
1217 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1219 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1220 CopyExpression(exp.op.exp2)))))),
1222 // ((class.size == 2) ?
1223 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1224 // *((uint16 *)array)
1225 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1226 CopyExpression(exp.op.exp2)))))),
1228 // ((class.size == 4) ?
1229 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1230 // *((uint32 *)array)
1231 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1232 CopyExpression(exp.op.exp2)))))),
1234 // *((uint64 *)array)
1235 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1236 exp.op.exp2)))))))))))))))))))));
1238 // Add this to the context
1239 thisClass = curExternal.function ? curExternal.function._class : null;
1243 string = CopyString("this");
1244 type = MkClassType(thisClass.fullName);
1246 globalContext.symbols.Add((BTNode)thisSymbol);
1248 ProcessExpressionType(exp.list->first);
1249 ProcessExpression(exp.list->first);
1251 //globalContext.symbols.Delete((BTNode)thisSymbol);
1252 globalContext.symbols.Remove((BTNode)thisSymbol);
1253 FreeSymbol(thisSymbol);
1264 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1265 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1266 ProcessExpression(exp.op.exp1);
1269 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1270 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1271 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1272 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*/))
1273 FixReference(exp.op.exp1, false);
1274 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1278 // Don't use the temporaries used by the left side...
1280 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1281 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1282 ProcessExpression(exp.op.exp2);
1283 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1287 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1288 (exp.op.exp2.expType._class.registered.type != normalClass &&
1289 exp.op.exp2.expType._class.registered.type != structClass &&
1290 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1292 // TESTING THIS TEMPLATE TYPE CHECK HERE
1293 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1295 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1296 //FixReference(exp.op.exp2, false);
1299 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1302 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)
1304 // Preserve prev, next
1305 Expression next = exp.next, prev = exp.prev;
1306 Expression derefExp = exp.op.exp2;
1307 Expression refExp = exp.op.exp2.op.exp2;
1308 Type expType = exp.expType, destType = exp.destType;
1310 derefExp.op.exp2 = null;
1311 FreeExpression(derefExp);
1312 FreeType(exp.expType);
1313 FreeType(exp.destType);
1323 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)
1325 Expression exp2 = exp.op.exp2;
1326 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1329 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1331 exp.type = bracketsExp;
1332 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1333 MkExpOp(null, '&', exp2)), '+',
1334 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1335 MkListOne((e = MkExpCondition(MkExpBrackets(MkListOne(
1339 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))),
1341 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))),
1343 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))))
1345 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1346 MkExpMember(classExp, MkIdentifier("typeSize"))))))));
1348 // Add this to the context
1349 thisClass = curExternal.function ? curExternal.function._class : null;
1353 string = CopyString("this");
1354 type = MkClassType(thisClass.fullName);
1356 //globalContext.symbols.Add((BTNode)thisSymbol);
1358 ProcessExpressionType(e);
1359 ProcessExpression(e);
1361 //globalContext.symbols.Remove((BTNode)thisSymbol);
1362 //FreeSymbol(thisSymbol);
1371 FreeExpression(exp1);
1373 FreeExpression(exp2);
1378 case extensionExpressionExp:
1383 for(e = exp.list->first; e; e = e.next)
1387 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1389 e.tempCount = exp.tempCount;
1390 ProcessExpression(e);
1392 exp.byReference = e.byReference;
1393 exp.tempCount = e.tempCount;
1397 exp.expType = e.expType;
1406 /*bool isBuiltin = exp && exp.index.exp &&
1407 (exp.index.exp.type == ExpressionType::arrayExp ||
1408 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1410 Expression checkedExp = exp.index.exp;
1411 bool isBuiltin = false;
1413 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1415 if(checkedExp.type == extensionCompoundExp)
1420 else if(checkedExp.type == bracketsExp)
1421 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1423 checkedExp = checkedExp.cast.exp;
1426 exp.index.exp.tempCount = exp.tempCount;
1428 exp.index.exp.usage.usageGet = true;
1429 ProcessExpression(exp.index.exp);
1431 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1432 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1434 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1437 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1438 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1440 exp.type = bracketsExp;
1441 exp.list = MkListOne(
1443 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1445 // ((class.type == structClass) ?
1446 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1447 // ((byte *)array) + (i) * class.size
1448 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1449 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1450 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1452 // ((class.type == normalClass || class.type == noHeadClass) ?
1453 MkExpCondition(MkExpBrackets(MkListOne(
1455 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1457 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1458 // ((void **)array)[i]
1459 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1460 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression)))),
1462 // ((class.size == 1) ?
1463 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1464 // ((byte *)array)[i]
1465 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1466 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1468 // ((class.size == 2) ?
1469 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1470 // ((uint16 *)array)[i]
1471 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1472 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1474 // ((class.size == 4) ?
1475 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1476 // ((uint32 *)array)[i]
1477 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1478 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1480 // ((uint64 *)array)[i]
1481 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1482 exp.index.exp))), exp.index.index))))))))))))))))));
1484 // Add this to the context
1485 thisClass = curExternal.function ? curExternal.function._class : null;
1489 string = CopyString("this");
1490 type = MkClassType(thisClass.fullName);
1492 globalContext.symbols.Add((BTNode)thisSymbol);
1494 ProcessExpressionType(exp.list->first);
1495 ProcessExpression(exp.list->first);
1497 //globalContext.symbols.Delete((BTNode)thisSymbol);
1498 globalContext.symbols.Remove((BTNode)thisSymbol);
1499 FreeSymbol(thisSymbol);
1507 for(e = exp.index.index->first; e; e = e.next)
1510 e.usage.usageGet = true;
1511 ProcessExpression(e);
1513 // Ignore temps in the index for now...
1514 exp.tempCount = exp.index.exp.tempCount;
1516 if(exp.index.exp.expType)
1518 Type source = exp.index.exp.expType;
1519 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1520 eClass_IsDerived(source._class.registered, containerClass))
1522 Class _class = source._class.registered;
1523 bool isArray = false;
1524 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1525 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1527 if(isArray && _class.templateArgs)
1529 OldList * specs = MkList();
1530 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1531 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1532 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1533 ProcessExpressionType(exp.index.exp);
1534 ProcessExpression(exp);
1536 else if(isBuiltin && _class.templateArgs)
1538 OldList * specs = MkList();
1539 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1540 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1541 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1542 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1543 ProcessExpressionType(exp.index.exp);
1544 ProcessExpression(exp);
1546 else if(_class.templateArgs)
1548 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1550 char iteratorType[1024];
1551 OldList * declarations = MkList();
1552 OldList * statements = MkList();
1553 OldList * args = MkList();
1554 OldList * instMembers = MkList();
1556 Context context = PushContext();
1558 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1560 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1562 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1563 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1565 ListAdd(args, MkExpBrackets(exp.index.index));
1566 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1568 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1569 MkIdentifier("Index")), args))));
1571 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1572 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1574 exp.type = bracketsExp;
1575 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1576 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1577 expExt.compound.compound.context = context;
1578 PopContext(context);
1579 expExt.usage = exp.usage;
1580 ProcessExpressionType(exp.list->first);
1581 ProcessExpressionInstPass(exp.list->first);
1582 ProcessExpression(exp.list->first);
1591 bool typedObject = false;
1592 Type ellipsisDestType = null;
1593 bool usedEllipsis = false;
1595 if(exp.call.arguments)
1597 for(e = exp.call.arguments->first; e; e = e.next)
1599 e.usage.usageGet = true;
1600 e.usage.usageArg = true;
1601 e.tempCount = Max(e.tempCount, exp.tempCount);
1602 ProcessExpression(e);
1603 exp.tempCount = Max(exp.tempCount, e.tempCount);
1606 exp.call.exp.usage.usageGet = true;
1607 exp.call.exp.usage.usageCall = true;
1608 exp.call.exp.tempCount = exp.tempCount;
1610 ProcessExpression(exp.call.exp);
1612 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1614 bool nullMemberExp = false;
1615 Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1617 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1618 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1619 Method method = exp.call.exp.expType.method;
1620 if(method.type == virtualMethod)
1626 OldList * specs = MkList();
1627 strcpy(name, "__ecereVMethodID_");
1628 FullClassNameCat(name, method._class.fullName, false);
1630 strcat(name, method.name);
1632 DeclareMethod(method, name);
1635 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1636 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1637 // Cast function to its type
1639 Context context = SetupTemplatesContext(method._class);
1641 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1643 FinishTemplatesContext(context);
1646 if(method.dataType && !method.dataType.staticMethod)
1648 Declarator funcDecl = GetFuncDecl(decl);
1650 if(!funcDecl.function.parameters)
1651 funcDecl.function.parameters = MkList();
1653 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1654 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1656 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1658 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1659 FreeTypeName(firstParam);
1663 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1668 param = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
1669 param.qualifiers->Insert(null, MkSpecifier(CONST));
1670 funcDecl.function.parameters->Insert(null, param);
1671 // Testing this for any_object::
1672 if(!method.dataType.extraParam)
1673 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1677 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1678 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1682 typeName = MkTypeName(specs, decl);
1684 // Added !exp.call.exp.expType.methodClass
1685 if(memberExp && memberExp.member.exp.expType)
1687 Type type = memberExp.member.exp.expType;
1689 if(type.kind == classType && type._class && type._class.registered)
1691 Class regClass = type._class.registered;
1692 ClassType classType = regClass.type;
1693 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1694 argClass = regClass;
1696 else if(type.kind == subClassType)
1698 argClass = FindClass("ecere::com::Class").registered;
1700 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1702 argClass = FindClass("char *").registered;
1704 else if(type.kind == pointerType)
1706 argClass = eSystem_FindClass(privateModule, "uintptr");
1707 FreeType(memberExp.member.exp.expType);
1708 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1709 memberExp.member.exp.byReference = true;
1713 char string[1024] = "";
1715 PrintTypeNoConst(type, string, false, true);
1716 classSym = FindClass(string);
1717 if(classSym) argClass = classSym.registered;
1721 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1727 Type type = memberExp ? memberExp.member.exp.expType : null;
1728 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1729 char className[1024];
1730 bool useInstance = false;
1732 if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
1733 strcpy(className, "class");
1737 // TESTING: Moved this here...
1738 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1743 // TODO: Unhandled case here, what should happen?
1746 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1747 if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
1748 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1749 cl = cl.templateClass;
1751 // Need the class itself here...
1752 strcpy(className, "__ecereClass_");
1753 FullClassNameCat(className, cl.fullName, true);
1754 MangleClassName(className);
1757 cl.symbol = FindClass(cl.fullName);
1759 DeclareClass(cl.symbol, className);
1762 if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
1764 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1765 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1766 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1768 else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
1769 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1772 FreeExpression(exp.call.exp);
1773 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1774 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1775 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1779 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1780 // as opposed to the File class vTbl one
1782 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1784 Context context = PushContext();
1786 c = MkExpExtensionCompound(MkCompoundStmt(
1787 MkListOne(MkDeclaration(
1788 (specs = MkListOne(MkSpecifierName("Instance"))),
1789 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1790 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
1791 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1792 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1793 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1794 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
1796 specs->Insert(null, MkSpecifier(CONST));
1798 c.compound.compound.context = context;
1799 PopContext(context);
1800 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1801 MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1808 strcpy(name, "__ecereMethod_");
1809 FullClassNameCat(name, method._class.fullName, false);
1811 strcat(name, method.name);
1814 FreeExpression(exp.call.exp);
1815 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1816 DeclareMethod(method, name);
1817 if(memberExp && memberExp.expType && method.dataType)
1819 exp.call.exp.expType = method.dataType;
1820 method.dataType.refCount++;
1823 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1825 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1827 if(!exp.call.arguments)
1828 exp.call.arguments = MkList();
1830 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1832 if(memberExp.member.exp.expType.kind != classType ||
1833 memberExp.member.exp.expType._class.registered.type == enumClass ||
1834 memberExp.member.exp.expType._class.registered.type == unitClass)
1836 char typeString[1024] = "";
1837 if(memberExp.member.exp.expType.kind != classType)
1838 PrintType(memberExp.member.exp.expType, typeString, false, true);
1840 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1843 // memberExp.member.exp.expType.kind = classType;
1844 // memberExp.member.exp.expType._class = FindClass(typeString);
1846 FreeType(memberExp.member.exp.expType);
1847 memberExp.member.exp.expType = Type
1850 _class = FindClass(typeString);
1854 // Default to an int instead
1855 if(!memberExp.member.exp.expType._class)
1857 // TODO: Shouldn't get here...
1858 memberExp.member.exp.expType.kind = TypeInt;
1863 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1865 bool changeReference = false;
1866 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1868 // Patched so that class isn't considered SYSTEM...
1869 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1870 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1871 changeReference = true;
1872 if(!memberExp.member.exp.expType.classObjectType &&
1874 (memberExp.member.exp.expType.kind != pointerType &&
1875 (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1876 !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1877 method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
1878 changeReference = true;
1879 if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
1880 changeReference = true;
1883 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1884 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1886 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1887 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1889 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1891 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1892 memberExp.member.exp.op.exp2 = null;
1894 else if(!memberExp.member.exp.byReference)
1896 // TESTING THIS... REUSE THIS CODE?
1897 Expression checkedExp = memberExp.member.exp;
1898 Expression parentExp = null;
1900 bool disconnected = false;
1901 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1903 parentExp = checkedExp;
1905 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1907 checkedExp = checkedExp.list->last;
1908 // Dissociate from memberExp which will get freed
1909 if(checkedExp && !disconnected)
1911 parentExp.list->Remove(checkedExp);
1912 disconnected = true;
1915 else if(checkedExp.type == castExp)
1917 checkedExp = checkedExp.cast.exp;
1918 // Dissociate from memberExp which will get freed
1919 if(checkedExp && !disconnected)
1921 checkedExp.cast.exp = null;
1922 disconnected = true;
1927 nullMemberExp = true;
1929 newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
1930 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1932 parentExp.list->Remove(checkedExp);
1933 parentExp.list->Add(newExp);
1935 else if(parentExp && parentExp.type == castExp)
1937 parentExp.cast.exp = newExp;
1938 // Add a dereference level here
1939 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1941 if(typedObject && !memberExp.member.exp.expType.classObjectType)
1943 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
1944 FreeType((parentExp ? parentExp : newExp).expType);
1945 FreeType((parentExp ? parentExp : newExp).destType);
1946 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
1947 (parentExp ? parentExp : newExp).destType = destType;
1948 if(checkedExp.expType) checkedExp.expType.refCount++;
1950 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1954 exp.call.arguments->Insert(null, memberExp.member.exp);
1955 nullMemberExp = true;
1960 exp.call.arguments->Insert(null, memberExp.member.exp);
1961 nullMemberExp = true;
1965 char className[1024];
1966 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
1967 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1968 Class cl = argClass ? argClass : regClass;
1971 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1972 strcpy(className, "class");
1975 // Need the class itself here...
1976 strcpy(className, "__ecereClass_");
1977 FullClassNameCat(className, cl.fullName, true);
1978 MangleClassName(className);
1981 cl.symbol = FindClass(cl.fullName);
1982 DeclareClass(cl.symbol, className);
1987 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
1989 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
1991 Context context = PushContext();
1994 c = MkExpExtensionCompound(MkCompoundStmt(
1995 MkListOne(MkDeclaration(
1996 (specs = MkListOne(MkSpecifierName("Instance"))),
1997 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1998 MkInitializerAssignment(memberExpMemberExp))))),
1999 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2000 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2001 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2002 MkExpIdentifier(MkIdentifier(className))))))));
2003 c.compound.compound.context = context;
2004 PopContext(context);
2007 specs->Insert(null, MkSpecifier(CONST));
2009 exp.call.arguments->Insert(null, c);
2011 memberExpMemberExp = null; // We used this
2014 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
2018 if(memberExpMemberExp)
2019 FreeExpression(memberExpMemberExp);
2023 exp.call.arguments->Insert(null, memberExp.member.exp);
2024 nullMemberExp = true;
2028 /*else if(method->dataType)
2034 memberExp.member.exp = null;
2035 FreeExpression(memberExp);
2039 if(exp.call.arguments)
2041 for(e = exp.call.arguments->first; e; e = e.next)
2043 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
2044 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
2045 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
2046 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
2048 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
2049 ellipsisDestType = destType;
2052 Type type = e.expType;
2053 Class _class = null;
2054 //Type destType = e.destType;
2056 if(type.kind == classType && type._class && type._class.registered)
2058 _class = type._class.registered;
2060 else if(type.kind == subClassType)
2062 _class = FindClass("ecere::com::Class").registered;
2064 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
2066 _class = FindClass("char *").registered;
2068 else if(type.kind == pointerType)
2070 _class = eSystem_FindClass(privateModule, "uintptr");
2071 FreeType(e.expType);
2072 e.expType = ProcessTypeString("uintptr", false);
2073 // Assume null pointers means 'no object' rather than an object holding a null pointer
2074 e.byReference = true;
2078 char string[1024] = "";
2080 PrintTypeNoConst(type, string, false, true);
2081 classSym = FindClass(string);
2082 if(classSym) _class = classSym.registered;
2083 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2086 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...
2087 (!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))) ||
2088 destType.byReference)))
2090 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2091 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2092 // TESTING WITHOUT THE ABOVE NOW!
2094 Expression checkedExp;
2095 Expression parentExp;
2100 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2102 parentExp = checkedExp;
2103 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2105 if(checkedExp.type == extensionCompoundExp)
2107 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2110 checkedExp = checkedExp.list->last;
2112 else if(checkedExp.type == castExp)
2113 checkedExp = checkedExp.cast.exp;
2116 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2119 Expression newExp = e.op.exp2;
2120 exp.call.arguments->Insert(e.prev, newExp);
2121 exp.call.arguments->Remove(e);
2126 newExp = checkedExp.op.exp2;
2127 checkedExp.op.exp2 = null;
2128 FreeExpContents(checkedExp);
2130 if(e.expType && e.expType.passAsTemplate)
2133 ComputeTypeSize(e.expType);
2134 sprintf(size, "%d", e.expType.size);
2135 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2136 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2137 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2140 if(parentExp.type == callExp)
2142 exp.call.arguments->Insert(e.prev, newExp);
2143 exp.call.arguments->Remove(e);
2146 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2148 parentExp.list->Remove(checkedExp);
2149 parentExp.list->Add(newExp);
2151 else if(parentExp.type == castExp)
2153 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2154 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2156 FreeTypeName(parentExp.cast.typeName);
2157 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2159 parentExp.cast.exp = newExp;
2161 else if(parentExp.type == extensionCompoundExp)
2163 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2164 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2166 e.byReference = true;
2168 FreeType(checkedExp.expType);
2169 FreeType(checkedExp.destType);
2172 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2174 Expression checkedExp;
2175 Expression parentExp;
2179 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2181 e.type == identifierExp ||
2182 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2183 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2184 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2187 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2189 Context context = PushContext();
2191 OldList * specs = MkList();
2192 char typeString[1024];
2193 Expression newExp { };
2195 typeString[0] = '\0';
2198 // TOCHECK: Should this read e.destType ???
2200 if(exp.destType) exp.destType.refCount++;
2201 // if(exp.expType) exp.expType.refCount++;
2204 newExp.expType = null;
2206 PrintTypeNoConst(e.expType, typeString, false, true);
2207 decl = SpecDeclFromString(typeString, specs, null);
2208 newExp.destType = ProcessType(specs, decl);
2210 curContext = context;
2211 e.type = extensionCompoundExp;
2213 // We need a current compound for this
2217 OldList * stmts = MkList();
2218 sprintf(name, "__internalValue%03X", internalValueCounter++);
2219 if(!curCompound.compound.declarations)
2220 curCompound.compound.declarations = MkList();
2221 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2222 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2223 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2224 e.compound = MkCompoundStmt(null, stmts);
2227 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2231 e.compound = MkCompoundStmt(
2232 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2233 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2236 e.compound.compound.context = context;
2237 PopContext(context);
2238 curContext = context.parent;
2242 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2245 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2247 parentExp = checkedExp;
2248 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2250 if(checkedExp.type == extensionCompoundExp)
2252 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2255 checkedExp = checkedExp.list->last;
2257 else if(checkedExp.type == castExp)
2258 checkedExp = checkedExp.cast.exp;
2260 newExp = MkExpOp(null, '&', checkedExp);
2261 newExp.byReference = true;
2262 if(parentExp.type == callExp)
2264 exp.call.arguments->Insert(e.prev, newExp);
2265 exp.call.arguments->Remove(e);
2268 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2270 parentExp.list->Remove(checkedExp);
2271 parentExp.list->Add(newExp);
2273 else if(parentExp.type == castExp)
2274 parentExp.cast.exp = newExp;
2275 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2277 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2278 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2284 if(destType.classObjectType == ClassObjectType::typedObject)
2286 char className[1024];
2287 // Need the class itself here...
2288 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2289 _class = eSystem_FindClass(privateModule, "String");
2290 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2292 if(!strcmp(_class.name, "class"))
2294 // Already inside a typed_object function, pass the class through
2295 strcpy(className, "class");
2299 strcpy(className, "__ecereClass_");
2300 FullClassNameCat(className, _class.fullName, true);
2301 MangleClassName(className);
2304 _class.symbol = FindClass(_class.fullName);
2306 DeclareClass(_class.symbol, className);
2309 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2311 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2313 Context context = PushContext();
2315 // Work around to avoid repeating the BuiltInContainer just to get the type
2316 // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
2317 if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
2318 e.list && e.list->first &&
2319 ((Expression)e.list->first).type == castExp &&
2320 ((Expression)e.list->first).cast.exp &&
2321 ((Expression)e.list->first).cast.exp.type == opExp &&
2322 ((Expression)e.list->first).cast.exp.op.op == '&' &&
2323 ((Expression)e.list->first).cast.exp.op.exp2 &&
2324 ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
2326 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2331 c = MkExpExtensionCompound(MkCompoundStmt(
2332 MkListOne(MkDeclaration(
2333 (specs = MkListOne(MkSpecifierName("Instance"))),
2334 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2335 MkInitializerAssignment(CopyExpression(e)))))),
2336 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2337 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2338 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2339 MkExpIdentifier(MkIdentifier(className))))))));
2340 c.compound.compound.context = context;
2341 PopContext(context);
2344 specs->Insert(null, MkSpecifier(CONST));
2346 exp.call.arguments->Insert(e.prev, c);
2350 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2356 //char debugString[4096] = "";
2357 //PrintExpression(e, debugString);
2359 // If expression type is a simple class, make it an address
2360 FixReference(e, !destType || !destType.declaredWithStruct);
2363 if(ellipsisDestType)
2366 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2367 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2369 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2377 bool changeToPtr = false;
2378 bool noHead = false;
2379 Type type = exp.member.exp ? exp.member.exp.expType : null;
2380 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2381 if(exp.member.member) exp.member.member._class = null;
2383 if(type && type.kind == templateType)
2385 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2386 if(baseType) type = baseType;
2388 if(type && exp.member.member && !type.directClassAccess)
2390 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2391 Property prop = null;
2392 ClassProperty classProperty = null;
2393 Method method = null;
2394 Class convertTo = null;
2395 DataMember member = null;
2396 bool thisPtr = exp.member.thisPtr;
2397 if(type.kind == subClassType && exp.member.exp.type == classExp)
2398 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2400 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2404 // DANGER: Buffer overflow
2405 char string[2048] = "";
2407 PrintTypeNoConst(type, string, false, true);
2408 classSym = FindClass(string);
2409 _class = classSym ? classSym.registered : null;
2412 if(_class && exp.member.memberType == dataMember)
2414 if(!thisPtr && !exp.member.member.classSym)
2415 member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
2417 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2419 else if(_class && exp.member.memberType == propertyMember)
2421 if(!thisPtr && !exp.member.member.classSym)
2422 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2424 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2425 if(prop && (exp.usage.usageRef ||
2426 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2427 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2429 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2432 exp.member.memberType = dataMember;
2437 if(exp.usage.usageRef)
2438 Compiler_Error($"cannot obtain address of property\n");
2440 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2441 else if(exp.usage.usageDelete)
2442 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2446 else if(_class && exp.member.memberType == methodMember)
2449 method = eClass_FindMethod(_class, exp.member.member.string, null);
2451 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2453 else if(_class && exp.member.memberType == reverseConversionMember)
2456 _class = FindClass(exp.member.member.string).registered;
2457 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2458 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2460 else if(_class && exp.member.memberType == classPropertyMember)
2462 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2466 // Only process Gets here, Set is processed in opExp's '='
2467 if(exp.usage.usageGet)
2471 char getName[1024], setName[1024];
2472 Expression ptr = exp.member.exp;
2473 Class propertyClass;
2474 char * nameToUse = convertTo ? setName : getName;
2476 FreeIdentifier(exp.member.member);
2478 // Process this here since it won't be processed at the end...
2479 exp.member.exp.usage.usageGet = true;
2480 ProcessExpression(exp.member.exp);
2481 // TEST: exp.tempCount = exp.member.exp.tempCount;
2483 DeclareProperty(prop, setName, getName);
2484 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2485 propertyClass = convertTo ? _class :
2486 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2489 if(propertyClass && propertyClass.type == bitClass)
2491 // Bit classes shouldn't have properties except for conversions...
2492 OldList * args = MkList();
2493 if(exp.usage.usageDeepGet)
2495 char className[1024];
2497 Declarator declarator;
2498 OldList * specs = MkList(), * decls = MkList();
2501 // Make a declaration in the closest compound statement
2502 // (Do not reuse (since using address for function calls)...)
2503 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2505 SpecDeclFromString(propertyClass.dataTypeString, specs,
2506 MkDeclaratorIdentifier(MkIdentifier(className)));
2508 ListAdd(decls, MkInitDeclarator(declarator, null));
2510 decl = MkDeclaration(specs, decls);
2511 if(!curCompound.compound.declarations)
2512 curCompound.compound.declarations = MkList();
2513 curCompound.compound.declarations->Insert(null, decl);
2515 tempExp = QMkExpId(className);
2516 tempExp.expType = MkClassType(propertyClass.fullName);
2518 exp.op.exp1 = tempExp;
2519 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2526 exp.call.exp = QMkExpId(nameToUse);
2527 exp.call.arguments = args;
2529 ListAdd(args, FixReference(ptr, true));
2531 else if(propertyClass && propertyClass.type == unitClass)
2533 OldList * args = MkList();
2534 ListAdd(args, FixReference(ptr, true));
2536 exp.call.exp = QMkExpId(nameToUse);
2537 exp.call.arguments = args;
2539 else if(propertyClass && propertyClass.type == structClass)
2541 OldList * args = MkList();
2542 char className[1024];
2544 OldList * specs = MkList(), * decls = MkList();
2547 // Make a declaration in the closest compound statement
2548 // (Do not reuse (since using address for function calls)...)
2551 FullClassNameCat(className, propertyClass.fullName, false); //true);
2553 //ListAdd(specs, MkSpecifierName(className));
2554 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2556 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2558 ListAdd(decls, MkInitDeclarator(
2559 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2561 decl = MkDeclaration(specs, decls);
2564 if(!curCompound.compound.declarations)
2565 curCompound.compound.declarations = MkList();
2566 curCompound.compound.declarations->Insert(null, decl);
2569 tempExp = QMkExpId(className);
2570 tempExp.expType = MkClassType(propertyClass.fullName);
2574 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2575 ListAdd(args, FixReference(ptr, true));
2579 ListAdd(args, FixReference(ptr, true));
2580 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2583 if(exp.usage.usageDeepGet)
2586 exp.call.exp = QMkExpId(nameToUse);
2587 exp.call.arguments = args;
2589 FreeExpression(tempExp);
2593 exp.type = bracketsExp;
2594 exp.list = MkList();
2595 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2596 if(exp.usage.usageMember)
2598 ListAdd(exp.list, FixReference(tempExp, true));
2599 exp.byReference = true;
2602 ListAdd(exp.list, tempExp);
2608 exp.call.exp = QMkExpId(nameToUse);
2609 exp.call.arguments = MkList();
2610 ListAdd(exp.call.arguments, FixReference(ptr, true));
2613 else if(prop.conversion)
2615 void * prev = exp.prev, * next = exp.next;
2616 *exp = *exp.member.exp;
2622 else if(classProperty)
2624 // Only process Gets here, Set is processed in opExp's '='
2625 if(exp.usage.usageGet)
2627 if(classProperty.Get)
2629 Identifier id = exp.member.member;
2630 Expression classExp = exp.member.exp;
2634 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty"));
2635 exp.call.arguments = MkList();
2636 ListAdd(exp.call.arguments, classExp);
2638 char * s = QMkString(id.string);
2639 ListAdd(exp.call.arguments, MkExpString(s));
2644 ProcessExpression(exp);
2651 // Get the function address if it's not called
2652 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2656 FreeIdentifier(exp.member.member);
2658 // Process this here since it won't be processed at the end...
2659 exp.member.exp.usage.usageGet = true;
2660 ProcessExpression(exp.member.exp);
2661 // TEST: exp.tempCount = exp.member.exp.tempCount;
2663 if(method.type == virtualMethod)
2665 strcpy(name, "__ecereVMethodID_");
2666 FullClassNameCat(name, method._class.fullName, false);
2668 strcat(name, method.name);
2669 exp.type = indexExp;
2670 if(memberClassSpecifier)
2672 char className[1024];
2673 // Need the class itself here...
2674 strcpy(className, "__ecereClass_");
2675 FullClassNameCat(className, _class.fullName, true);
2676 MangleClassName(className);
2679 _class.symbol = FindClass(_class.fullName);
2680 DeclareClass(_class.symbol, className);
2682 FreeExpression(exp.member.exp);
2683 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2687 if(exp.thisPtr && _class.type != normalClass)
2689 FreeExpression(exp.member.exp);
2690 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2693 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2695 exp.index.index = MkListOne(QMkExpId(name));
2696 DeclareMethod(method, name);
2700 FreeExpression(exp.member.exp);
2701 exp.type = identifierExp;
2702 strcpy(name, "__ecereMethod_");
2703 FullClassNameCat(name, method._class.fullName, false);
2705 strcat(name, method.name);
2706 exp.identifier = MkIdentifier(name);
2707 DeclareMethod(method, name);
2713 // Process this here since it won't be processed at the end...
2714 if(exp.usage.usageGet)
2716 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2718 ProcessExpression(exp.member.exp);
2719 // TEST: exp.tempCount = exp.member.exp.tempCount;
2721 if(type.kind == classType && type._class && type._class.registered)
2722 DeclareStruct(type._class.registered.fullName, false);
2724 // TESTING THIS NOHEAD STUFF...
2725 if(_class.type == noHeadClass)
2729 else if(_class.type == structClass)
2733 else if(_class.type == bitClass)
2735 OldList * list = MkList();
2736 char mask[32], shift[10];
2737 OldList * specs = MkList();
2738 BitMember bitMember = (BitMember) member;
2739 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2740 TypeName type = MkTypeName(specs, decl);
2741 if(bitMember.mask > MAXDWORD)
2742 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2744 sprintf(mask, FORMAT64HEX, bitMember.mask);
2745 sprintf(shift, "%d", bitMember.pos);
2747 FreeIdentifier(exp.member.member);
2749 // ((type) ((color & mask) >> bitPos))
2750 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2751 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2752 MkExpConstant(shift))))));
2754 exp.type = bracketsExp;
2757 else if(_class.type == unitClass)
2762 // If it's a this pointer, replace by precomputed shortcut
2763 if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2765 char pointerName[1024];
2767 strcpy(pointerName, "__ecerePointer_");
2768 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2769 if(exp.member.exp.identifier)
2770 FreeIdentifier(exp.member.exp.identifier);
2771 exp.member.exp.identifier = MkIdentifier(pointerName);
2773 // Otherwise, access the data the hard way
2776 Expression bytePtr, e;
2777 Expression classExp;
2778 Expression checkedExp;
2779 char structName[1024];
2780 char className[1024];
2781 strcpy(className, "__ecereClass_");
2782 FullClassNameCat(className, member._class.fullName, true);
2783 MangleClassName(className);
2785 // classExp = QMkExpId(className);
2787 if(!member._class.symbol)
2788 member._class.symbol = FindClass(member._class.fullName);
2790 DeclareClass(member._class.symbol, className);
2791 DeclareStruct(member._class.fullName, false);
2794 FullClassNameCat(structName, member._class.fullName, false);
2796 checkedExp = exp.member.exp;
2797 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2798 checkedExp.type == castExp)
2800 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2801 checkedExp = checkedExp.list->last;
2802 else if(checkedExp.type == castExp)
2803 checkedExp = checkedExp.cast.exp;
2806 if(checkedExp.type != identifierExp &&
2807 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2808 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2810 char ecereTemp[100];
2812 Context context = PushContext();
2813 if(exp.member.exp.tempCount > exp.tempCount)
2814 exp.tempCount = exp.member.exp.tempCount;
2817 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2818 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2819 curContext = context;
2820 compound = MkCompoundStmt(
2821 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2822 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2823 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2824 if(member._class.fixed)
2826 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2829 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2830 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2833 e = QMkExpId(ecereTemp);
2837 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2838 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2841 compound.compound.context = context;
2842 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2843 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2844 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2846 exp.member.exp = MkExpExtensionCompound(compound);
2848 PopContext(context);
2849 curContext = context.parent;
2853 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2854 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2856 e = QBrackets(QMkExpCond(exp.member.exp,
2857 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2858 MkExpConstant("0")));
2862 if(member._class.fixed)
2864 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2867 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2868 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2874 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2876 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2877 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2880 exp.type = pointerExp;
2885 // Take Out Any Class Specifier (Should have been used by now)
2886 FreeSpecifier(memberClassSpecifier);
2888 // Just moved this at the end... How is it?
2889 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
2891 exp.member.exp.usage.usageGet = true;
2892 exp.member.exp.usage.usageMember = true;
2893 exp.member.exp.tempCount = exp.tempCount;
2894 ProcessExpression(exp.member.exp);
2895 exp.tempCount = exp.member.exp.tempCount;
2896 if((changeToPtr && exp.member.exp.byReference) || noHead)
2897 exp.type = pointerExp;
2901 case extensionCompoundExp:
2903 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
2905 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2907 ProcessStatement(exp.compound);
2909 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2910 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2915 exp.member.exp.usage.usageGet = true;
2916 ProcessExpression(exp.member.exp);
2921 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2922 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2924 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2927 Expression classExp;
2929 FreeTypeName(exp.typeName);
2931 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
2933 exp.type = bracketsExp;
2934 exp.list = MkListOne(
2935 MkExpCondition(MkExpBrackets(MkListOne(
2938 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2939 MkExpIdentifier(MkIdentifier("normalClass"))),
2942 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2943 MkExpIdentifier(MkIdentifier("noHeadClass"))
2945 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
2946 MkExpMember(classExp, MkIdentifier("typeSize")))
2949 ProcessExpressionType(exp);
2950 ProcessExpression(exp);
2959 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
2960 ProcessExpression(exp.cast.exp);
2962 if(exp.cast.exp.byReference)
2963 exp.byReference = exp.cast.exp.byReference;
2964 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
2965 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
2966 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
2967 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
2968 exp.byReference = true;
2970 // Moved this to 1.5...
2971 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
2977 if(exp.usage.usageGet)
2978 exp.cond.cond.usage.usageGet = true;
2979 ProcessExpression(exp.cond.cond);
2980 for(e = exp.cond.exp->first; e; e = e.next)
2982 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
2983 ProcessExpression(e);
2985 if(exp.usage.usageGet)
2986 exp.cond.elseExp.usage.usageGet = true;
2987 ProcessExpression(exp.cond.elseExp);
2992 // Need the class itself here...
2993 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
2995 Specifier spec = exp._classExp.specifiers->first;
2996 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
2999 FreeList(exp._classExp.specifiers, FreeSpecifier);
3000 if(exp._classExp.decl)
3001 FreeDeclarator(exp._classExp.decl);
3003 exp.type = memberExp; //pointerExp;
3004 exp.member.exp = argExp;
3005 exp.member.member = MkIdentifier("dataTypeClass");
3007 ProcessExpressionType(argExp);
3008 ProcessExpression(exp);
3013 char className[1024];
3014 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
3015 Symbol classSym = FindClass(string);
3017 strcpy(className, "__ecereClass_");
3018 FullClassNameCat(className, string, true); // TODO: Verify this
3019 MangleClassName(className);
3020 DeclareClass(classSym, className);
3023 FreeList(exp._classExp.specifiers, FreeSpecifier);
3024 if(exp._classExp.decl)
3025 FreeDeclarator(exp._classExp.decl);
3027 exp.type = identifierExp;
3028 exp.identifier = MkIdentifier(className);
3034 ProcessExpression(exp.vaArg.exp);
3037 case extensionInitializerExp:
3039 ProcessInitializer(exp.initializer.initializer);
3047 static void ProcessInitializer(Initializer init)
3051 case expInitializer:
3054 init.exp.usage.usageGet = true;
3055 ProcessExpression(init.exp);
3056 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
3057 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
3059 FixReference(init.exp, true);
3061 else if(init.exp.destType && init.exp.destType.kind == classType)
3062 FixReference(init.exp, false);
3065 case listInitializer:
3070 for(i = init.list->first; i; i = i.next)
3071 ProcessInitializer(i);
3078 static void ProcessDeclaration(Declaration decl)
3082 case initDeclaration:
3084 if(decl.declarators)
3088 for(d = decl.declarators->first; d; d = d.next)
3091 ProcessInitializer(d.initializer);
3099 static void ProcessStatement(Statement stmt)
3104 ProcessStatement(stmt.labeled.stmt);
3107 if(stmt.caseStmt.exp)
3109 stmt.caseStmt.exp.usage.usageGet = true;
3111 // This expression should be constant...
3112 ProcessExpression(stmt.caseStmt.exp);
3114 if(stmt.caseStmt.stmt)
3115 ProcessStatement(stmt.caseStmt.stmt);
3119 if(stmt.compound.context)
3123 Statement prevCompound = curCompound;
3124 Context prevContext = curContext;
3126 if(!stmt.compound.isSwitch)
3129 curContext = stmt.compound.context;
3132 if(stmt.compound.declarations)
3134 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3135 ProcessDeclaration(decl);
3137 if(stmt.compound.statements)
3139 for(s = stmt.compound.statements->first; s; s = s.next)
3140 ProcessStatement(s);
3142 curContext = prevContext;
3143 curCompound = prevCompound;
3147 case expressionStmt:
3150 if(stmt.expressions)
3152 for(exp = stmt.expressions->first; exp; exp = exp.next)
3154 ProcessExpression(exp);
3165 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3166 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3168 ProcessExpression(exp);
3171 if(stmt.ifStmt.stmt)
3172 ProcessStatement(stmt.ifStmt.stmt);
3173 if(stmt.ifStmt.elseStmt)
3174 ProcessStatement(stmt.ifStmt.elseStmt);
3180 if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
3182 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3183 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3185 ProcessExpression(exp);
3188 ProcessStatement(stmt.switchStmt.stmt);
3194 if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
3196 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3197 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3199 ProcessExpression(exp);
3202 ProcessStatement(stmt.whileStmt.stmt);
3208 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3210 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3211 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3213 ProcessExpression(exp);
3216 if(stmt.doWhile.stmt)
3217 ProcessStatement(stmt.doWhile.stmt);
3223 if(stmt.forStmt.init)
3224 ProcessStatement(stmt.forStmt.init);
3226 if(stmt.forStmt.check)
3228 if(stmt.forStmt.check.expressions)
3230 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3232 ProcessStatement(stmt.forStmt.check);
3234 if(stmt.forStmt.increment)
3236 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3238 ProcessExpression(exp);
3241 if(stmt.forStmt.stmt)
3242 ProcessStatement(stmt.forStmt.stmt);
3254 if(stmt.expressions)
3256 ((Expression)stmt.expressions->last).usage.usageGet = true;
3257 for(exp = stmt.expressions->first; exp; exp = exp.next)
3259 ProcessExpression(exp);
3260 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3261 if(!exp.next && exp.destType && exp.destType.byReference)
3262 FixReference(exp, true);
3267 case badDeclarationStmt:
3269 ProcessDeclaration(stmt.decl);
3275 if(stmt.asmStmt.inputFields)
3277 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3278 if(field.expression)
3279 ProcessExpression(field.expression);
3281 if(stmt.asmStmt.outputFields)
3283 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3284 if(field.expression)
3285 ProcessExpression(field.expression);
3287 if(stmt.asmStmt.clobberedFields)
3289 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3290 if(field.expression)
3291 ProcessExpression(field.expression);
3298 static void ProcessFunction(FunctionDefinition function)
3301 ProcessStatement(function.body);
3304 static void ProcessMemberInitData(MemberInit member)
3306 if(member.initializer)
3307 ProcessInitializer(member.initializer);
3310 static void ProcessInstantiation(Instantiation inst)
3314 MembersInit members;
3315 for(members = inst.members->first; members; members = members.next)
3317 if(members.type == dataMembersInit)
3319 if(members.dataMembers)
3322 for(member = members.dataMembers->first; member; member = member.next)
3323 ProcessMemberInitData(member);
3326 else if(members.type == methodMembersInit)
3328 ProcessFunction((FunctionDefinition)members.function);
3334 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3335 public void ProcessMemberAccess()
3338 for(external = ast->first; external; external = external.next)
3340 curExternal = external;
3341 // There shouldn't be any class member access here anyways...
3342 if(external.type == declarationExternal)
3344 if(external.declaration)
3345 ProcessDeclaration(external.declaration);
3349 for(external = ast->first; external; external = external.next)
3351 curExternal = external;
3352 if(external.type == functionExternal)
3354 ProcessFunction(external.function);
3356 else if(external.type == declarationExternal)
3358 //currentClass = external.function._class;
3359 if(external.declaration)
3360 ProcessDeclaration(external.declaration);
3362 else if(external.type == classExternal)
3364 ClassDefinition _class = external._class;
3365 //currentClass = external.symbol.registered;
3366 if(_class.definitions)
3369 Class regClass = _class.symbol.registered;
3371 // Process all functions
3372 for(def = _class.definitions->first; def; def = def.next)
3374 if(def.type == functionClassDef)
3376 curExternal = def.function.declarator.symbol.pointerExternal;
3377 ProcessFunction((FunctionDefinition)def.function);
3379 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3381 ProcessInstantiation(def.decl.inst);
3383 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3385 MemberInit defProperty;
3387 // Add this to the context
3390 string = CopyString("this");
3391 type = MkClassType(regClass.fullName);
3393 globalContext.symbols.Add((BTNode)thisSymbol);
3395 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3397 //thisClass = regClass;
3398 ProcessMemberInitData(defProperty); //, regClass, &id);
3402 //globalContext.symbols.Delete((BTNode)thisSymbol);
3403 globalContext.symbols.Remove((BTNode)thisSymbol);
3404 FreeSymbol(thisSymbol);
3406 else if(def.type == propertyClassDef && def.propertyDef)
3408 PropertyDef prop = def.propertyDef;
3410 // Add this to the context
3413 string = CopyString("this");
3414 type = MkClassType(regClass.fullName);
3416 globalContext.symbols.Add((BTNode)thisSymbol);
3418 //thisClass = regClass;
3421 curExternal = prop.symbol.externalSet;
3422 ProcessStatement(prop.setStmt);
3426 curExternal = prop.symbol.externalGet;
3427 ProcessStatement(prop.getStmt);
3431 curExternal = prop.symbol.externalIsSet;
3432 ProcessStatement(prop.issetStmt);
3437 //globalContext.symbols.Delete((BTNode)thisSymbol);
3438 globalContext.symbols.Remove((BTNode)thisSymbol);
3439 FreeSymbol(thisSymbol);
3441 else if(def.type == classPropertyClassDef && def.propertyDef)
3443 PropertyDef prop = def.propertyDef;
3445 //thisClass = regClass;
3448 curExternal = prop.symbol.externalSet;
3449 ProcessStatement(prop.setStmt);
3453 curExternal = prop.symbol.externalGet;
3454 ProcessStatement(prop.getStmt);
3458 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3460 PropertyWatch propertyWatch = def.propertyWatch;
3462 // Add this to the context
3465 string = CopyString("this");
3466 type = MkClassType(regClass.fullName);
3468 globalContext.symbols.Add((BTNode)thisSymbol);
3470 //thisClass = regClass;
3471 if(propertyWatch.compound)
3475 string = CopyString("this");
3476 type = MkClassType(regClass.fullName);
3478 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3480 ProcessStatement(propertyWatch.compound);
3482 // thisClass = null;
3484 //globalContext.symbols.Delete((BTNode)thisSymbol);
3485 globalContext.symbols.Remove((BTNode)thisSymbol);
3486 FreeSymbol(thisSymbol);