3 #define YYLTYPE Location
6 extern External curExternal;
7 static Statement curCompound;
9 static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
12 Expression memberExp = *memberExpPtr;
13 if(memberExp && memberExp.type == ExpressionType::memberExp &&
14 memberExp.member.exp && (memberExp.member.exp.type == bracketsExp || memberExp.member.exp.type == extensionExpressionExp))
16 Expression bracketExp = memberExp.member.exp;
17 Expression idExp = bracketExp.list->last;
19 if(idExp && idExp.type == identifierExp)
21 Expression newExp = null;
22 Expression exp = *expPtr;
24 // opExp ( memberExp ( bracketsExp ( identifierExp ) ) )
25 // bracketsExp ( opExp ( memberExp ( identifierExp ) ) )
28 newExp = CopyExpression(exp);
31 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
33 memberExp.member.exp = idExp;
35 exp.type = bracketsExp;
36 exp.list = bracketExp.list;
37 bracketExp.list = null;
39 exp.list->Remove(idExp);
40 exp.list->Add(newExp);
41 FreeExpression(bracketExp);
43 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
46 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
47 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
49 Expression newExp = null;
50 Expression exp = *expPtr;
53 newExp = CopyExpression(exp);
54 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
56 exp.type = bracketsExp;
57 exp.list = memberExp.list;
58 memberExp.list = null;
60 exp.list->Remove(exp.list->last);
61 exp.list->Add(newExp);
62 FreeExpression(memberExp);
64 *expPtr = newExp; //FixRefExp(newExp);
68 static Expression FixRefExp(Expression exp)
72 _FixRefExp(&exp, &exp.op.exp1);
73 _FixRefExp(&exp, &exp.op.exp2);
75 else if(exp.type == indexExp)
76 _FixRefExp(&exp, &exp.index.exp);
77 else if(exp.type == memberExp)
78 _FixRefExp(&exp, &exp.member.exp);
82 static Expression FixReference(Expression e, bool wantReference)
84 if(e.expType && e.type != constantExp)
86 Type type = e.expType;
87 bool isPointer = false;
89 if(type.kind == TypePointer && type.type && type.type.kind == classType)
96 if(type.kind == classType) // || type.kind == TypeInt)
98 Class _class = type._class ? type._class.registered : null;
99 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
100 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
101 if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
102 (_class.type == systemClass && _class.base &&
103 strcmp(_class.fullName, "uintptr") &&
104 strcmp(_class.fullName, "intptr") &&
105 strcmp(_class.fullName, "uintsize") &&
106 strcmp(_class.fullName, "intsize"))))
108 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
109 if(wantReference != (e.byReference || isPointer))
114 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
118 exp.byReference = wantReference;
119 exp = exp.list->last;
124 else if(exp.type == castExp)
126 exp.byReference = wantReference;
129 else if(exp.type == conditionExp)
131 if(exp.cond.exp->last)
132 FixReference(exp.cond.exp->last, wantReference);
133 FixReference(exp.cond.elseExp, wantReference);
138 if(wantReference != (exp.byReference || isPointer))
140 Expression newExp { };
143 if(exp.destType) exp.destType.refCount++;
144 if(exp.expType) exp.expType.refCount++;
148 exp.op.exp2 = newExp;
154 e.byReference = wantReference;
155 exp.byReference = wantReference;
168 static Expression GetInnerExp(Expression exp)
171 while(e && (e.type == bracketsExp || e.type == castExp))
173 if(e.type == bracketsExp)
174 e = e.list ? e.list->last : null;
175 else if(e.type == castExp)
181 Expression GetNonBracketsExp(Expression exp)
184 while(e && e.type == bracketsExp)
185 e = e.list ? e.list->last : null;
189 static bool FixMember(Expression exp)
191 bool byReference = false;
194 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
196 if(exp.list->count > 1)
198 exp = exp.list->last;
200 else if(exp.type == castExp)
207 FixReference(exp, true);
209 byReference = exp.byReference;
216 static void ProcessExpression(Expression exp)
218 Location oldyylloc = yylloc;
220 char debugExpString[1024] = "";
221 PrintExpression(exp, debugExpString);
231 if(exp.expType && exp.expType.kind == methodType)
233 Class _class = exp.expType.methodClass;
234 Method method = exp.expType.method;
235 if(method.type == virtualMethod)
240 OldList * specs = MkList();
241 strcpy(name, "__ecereVMethodID_");
242 FullClassNameCat(name, method._class.fullName, false);
244 strcat(name, method.name);
246 DeclareMethod(method, name);
248 // Cast function to its type
249 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
250 if(!method.dataType.staticMethod)
252 Declarator funcDecl = GetFuncDecl(decl);
254 if(!funcDecl.function.parameters)
255 funcDecl.function.parameters = MkList();
257 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
258 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
260 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
261 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
264 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
265 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
268 typeName = MkTypeName(specs, decl);
272 char className[1024];
273 // Need the class itself here...
274 strcpy(className, "__ecereClass_");
275 FullClassNameCat(className, _class.fullName, true);
276 //MangleClassName(className);
279 _class.symbol = FindClass(_class.fullName);
280 DeclareClass(_class.symbol, className);
283 FreeIdentifier(exp.identifier);
284 exp.type = bracketsExp;
285 exp.list = MkListOne(MkExpCast(typeName,
286 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
287 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
293 strcpy(name, "__ecereMethod_");
294 FullClassNameCat(name, method._class.fullName, false);
296 strcat(name, method.name);
298 delete exp.identifier.string;
299 FreeSpecifier(exp.identifier._class);
301 exp.identifier._class = null;
302 exp.identifier.string = CopyString(name);
303 DeclareMethod(method, name);
307 if(exp.usage & USAGE_MEMBER)
308 FixReference(exp, true);
321 OldList * args = MkList();
323 if(exp.type == renewExp || exp.type == renew0Exp)
324 ListAdd(args, exp._renew.exp);
326 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
330 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
331 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
332 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
333 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
335 exp.call.arguments = args;
338 ProcessExpression(exp);
343 Expression exp1 = exp.op.exp1;
344 Expression exp2 = exp.op.exp2;
348 // Assignment Operators
351 exp.op.exp2.usage.usageGet = true;
363 exp.op.exp2.usage.usageGet = true;
372 if(exp.op.exp1 && exp.op.exp2)
374 exp.op.exp1.usage.usageGet = true;
375 exp.op.exp2.usage.usageGet = true;
379 exp.op.exp2.usage.usageRef = true;
388 exp.op.exp1.usage.usageGet = true;
393 exp.op.exp2.usage.usageGet = true;
396 // Binary only operators
412 exp.op.exp1.usage.usageGet = true;
414 exp.op.exp2.usage.usageGet = true;
418 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
419 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
420 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
421 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
423 Expression memberExp;
424 Expression parentExp = null; // Where to take memberExp out from
426 // TOCHECK: See note below for this if
427 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
429 // Extra bit of code to access deep properties...
430 Expression testExp, topExp = null;
431 Expression lastExp = exp.op.exp1, parentExp = null;
432 Property lastProperty = null;
435 char setName[1024], getName[1024];
436 testExp = exp.op.exp1.member.exp;
439 // Is further fixing needed to address if statement above in the same way?
442 if(testExp.type == castExp)
443 testExp = testExp.cast.exp;
444 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
445 testExp = testExp.list->last;
446 else if(testExp.type == ExpressionType::memberExp)
453 if(testExp.member.memberType == propertyMember ||
454 testExp.member.memberType == reverseConversionMember)
456 Type type = testExp.member.exp.expType;
459 if(type.kind == classType)
461 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
462 Class convertTo = null;
463 if(testExp.member.memberType == reverseConversionMember)
466 _class = FindClass(testExp.member.member.string).registered;
467 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
468 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
472 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
474 if(lastProperty && lastProperty.Get && lastProperty.Set)
476 DeclareProperty(lastProperty, setName, getName);
477 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
478 propertyClass = convertTo ? _class :
479 ((((Symbol)lastProperty.symbol).type &&
480 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
481 // TODO: Handle this kind of things with bit classes?
482 if(propertyClass && propertyClass.type == structClass)
487 else if(propertyClass && propertyClass.type == bitClass)
499 testExp = testExp.member.exp;
503 if(propertyClass.type == structClass)
507 char className[1024];
510 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
511 tempExp = QMkExpId(className);
512 tempExp.expType = MkClassType(propertyClass.fullName);
514 parentExp.member.exp = tempExp;
516 value = MkExpBrackets(MkList());
518 copy = CopyExpression(topExp);
519 copy.usage.usageGet = true;
520 copy.usage.usageDeepGet = true;
522 ListAdd(value.list, copy);
523 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
524 ListAdd(value.list, CopyExpression(tempExp));
525 value.expType = tempExp.expType;
526 tempExp.expType.refCount++;
528 // Go on as usual with these new values:
529 exp.op.exp1 = topExp;
536 else if(propertyClass.type == bitClass)
540 char className[1024];
543 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
544 tempExp = QMkExpId(className);
545 tempExp.expType = MkClassType(propertyClass.fullName);
547 parentExp.member.exp = tempExp;
549 value = MkExpBrackets(MkList());
551 copy = CopyExpression(topExp);
552 copy.usage.usageGet = true;
553 copy.usage.usageDeepGet = true;
555 ListAdd(value.list, copy);
556 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
557 ListAdd(value.list, CopyExpression(tempExp));
558 value.expType = tempExp.expType;
559 value.expType.refCount++;
561 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
563 // Go on as usual with these new values:
564 exp.op.exp1 = topExp;
574 memberExp = exp.op.exp1;
576 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
577 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
579 parentExp = memberExp;
580 if(memberExp.type == extensionCompoundExp)
581 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
583 memberExp = memberExp.list->last;
586 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
587 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
588 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
590 Class c = memberExp.index.exp.expType._class.registered;
591 if(strcmp((c.templateClass ? c.templateClass : c).name, "Array"))
592 exp.op.exp2 = MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(exp.op.exp2)))));
594 ProcessExpression(memberExp);
596 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
597 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
599 parentExp = memberExp;
600 if(memberExp.type == extensionCompoundExp)
601 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
603 memberExp = memberExp.list->last;
606 if(memberExp && memberExp.type == extensionCompoundExp)
608 parentExp = memberExp;
609 if(memberExp.type == extensionCompoundExp)
611 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
612 if(stmt && stmt.type != expressionStmt) stmt = null;
613 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
616 stmt.expressions->Remove(memberExp);
617 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
618 exp.type = bracketsExp;
619 exp.list = MkListOne(parentExp);
620 ProcessExpression(exp);
625 memberExp = memberExp.list->last;
629 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
631 if(memberExp && memberExp.type == ExpressionType::memberExp && memberExp.member.member)
633 Type type = memberExp.member.exp.expType;
636 // Check if it's an instance
637 if(type.kind == classType || type.kind == subClassType)
639 // TODO: SOMETHING WRONG HERE...
640 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
642 if(memberExp == exp1)
646 if(parentExp.type == extensionCompoundExp)
647 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
649 parentExp.list->Remove(memberExp);
652 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
654 BitMember bitMember =
655 (BitMember)eClass_FindDataMember(_class,
656 memberExp.member.member.string, privateModule, null, null);
657 char mask[32], shift[10];
658 OldList * specs = MkList();
659 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
660 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
661 TypeName type = MkTypeName(specs, decl);
663 if(bitMember.mask > MAXDWORD)
664 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
666 sprintf(mask, FORMAT64HEX, bitMember.mask);
667 sprintf(shift, "%d", bitMember.pos);
669 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
670 exp.op.exp1 = memberExp.member.exp;
672 // TESTING THIS FOR: argb.color.r = 1;
673 //ProcessExpression(memberExp.member.exp);
675 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
676 if(exp.op.op == XOR_ASSIGN)
678 exp.op.exp2 = MkExpOp(MkExpBrackets(
679 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
683 exp.op.exp2 = MkExpOp(
684 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
685 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
686 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
687 MkListOne(MkExpCast(type, MkExpBrackets(MkListOne(exp.op.exp2))))), LEFT_OP, MkExpConstant(shift)))));
690 memberExp.member.exp = null;
691 FreeExpression(memberExp);
693 // TESTING THIS FOR: argb.color.r = 1;
694 ProcessExpression(exp);
697 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
700 else if(memberExp.member.memberType != dataMember)
703 Class convertTo = null;
704 ClassProperty classProperty = null;
706 if(memberExp.member.memberType == reverseConversionMember)
709 _class = FindClass(memberExp.member.member.string).registered;
710 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
711 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
714 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
716 if(memberExp.member.memberType == classPropertyMember)
717 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
719 exp.tempCount = memberExp.member.exp.tempCount;
723 // Only process Gets here, Set is processed in opExp's '='
724 if(classProperty.Set)
726 Identifier id = memberExp.member.member;
727 Expression classExp = memberExp.member.exp;
728 Expression value = exp.op.exp2;
730 memberExp.member.exp = null;
731 memberExp.member.member = null;
734 FreeExpContents(memberExp);
738 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
739 exp.call.arguments = MkList();
740 ListAdd(exp.call.arguments, classExp);
742 char * s = QMkString(id.string);
743 ListAdd(exp.call.arguments, MkExpString(s));
746 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
750 ProcessExpression(exp);
756 if((!convertTo && prop.Set) || (convertTo && prop.Get))
758 Expression value = exp.op.exp2;
759 char setName[1024], getName[1024];
760 char * setToUse = convertTo ? getName : setName;
761 char * getToUse = convertTo ? setName : getName;
762 bool needAddress = false;
763 int operator = exp.op.op;
766 case MUL_ASSIGN: operator = '*'; break;
767 case DIV_ASSIGN: operator = '/'; break;
768 case MOD_ASSIGN: operator = '%'; break;
769 case SUB_ASSIGN: operator = '-'; break;
770 case ADD_ASSIGN: operator = '+'; break;
771 case LEFT_ASSIGN: operator = LEFT_OP; break;
772 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
773 case AND_ASSIGN: operator = '&'; break;
774 case OR_ASSIGN: operator = '|'; break;
775 case XOR_ASSIGN: operator = '^'; break;
780 if(operator == INC_OP)
781 value = MkExpOp(CopyExpression(memberExp),
782 '+', MkExpConstant("1"));
783 else if(operator == DEC_OP)
784 value = MkExpOp(CopyExpression(memberExp),
785 '-', MkExpConstant("1"));
788 value = MkExpOp(CopyExpression(memberExp),
792 value.expType = memberExp.expType;
793 memberExp.expType.refCount++;
794 value.usage.usageArg = true;
798 // Dont free exp2, we're using it
803 value.usage.usageArg = true;
805 DeclareProperty(prop, setName, getName);
807 if(memberExp.member.exp)
808 ProcessExpression(memberExp.member.exp);
810 // If get flag present
811 if(exp.usage.usageGet &&
812 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
814 OldList * list = MkList();
817 Context context = PushContext();
820 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
821 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
823 curContext = context;
824 exp.type = extensionCompoundExp;
825 exp.compound = MkCompoundStmt(
826 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
827 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
828 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
835 ListAdd(args, value);
836 ListAdd(args, QMkExpId(ecereTemp));
837 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
841 ListAdd(args, QMkExpId(ecereTemp));
842 ListAdd(args, value);
843 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
849 ListAdd(args, QMkExpId(ecereTemp));
851 args->Insert(null, QMkExpId(ecereTemp));
852 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
854 exp.compound.compound.context = context;
856 curContext = context.parent;
860 Expression newExp = exp;
862 if(parentExp && parentExp.type == extensionCompoundExp)
864 newExp = Expression { };
865 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
866 FreeType(exp.expType);
867 FreeType(exp.destType);
870 parentExp.type = dummyExp;
871 parentExp.expType = null;
872 parentExp.destType = null;
875 newExp.type = callExp;
876 newExp.call.exp = QMkExpId(setToUse);
877 newExp.call.arguments = MkList();
880 ListAdd(newExp.call.arguments, value);
881 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
885 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
886 ListAdd(newExp.call.arguments, value);
891 // Take it out from there
892 memberExp.member.exp = null;
894 // Don't use the temporaries used by the left side...
897 value.tempCount = exp.tempCount;
898 ProcessExpression(value);
900 FixReference(value, true);
903 FreeExpression(memberExp);
907 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
910 memberExp.member.memberType = dataMember;
913 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
918 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
919 if(method && method.type == virtualMethod && type.kind != subClassType)
921 Expression value = exp.op.exp2;
922 // Don't use the temporaries used by the left side...
923 value.tempCount = exp.tempCount;
924 ProcessExpression(value);
926 if(memberExp.member.exp)
927 ProcessExpression(memberExp.member.exp);
929 if(exp.usage.usageGet)
931 OldList * list = MkList();
936 ListAdd(args, memberExp.member.exp);
938 char * string = QMkString(memberExp.member.member.string);
939 ListAdd(args, MkExpString(string));
942 ListAdd(args, value);
943 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
944 ListAdd(list, CopyExpression(value));
945 exp.type = bracketsExp;
952 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
953 exp.call.arguments = MkList();
954 ListAdd(exp.call.arguments, memberExp.member.exp);
956 char * string = QMkString(memberExp.member.member.string);
957 ListAdd(exp.call.arguments, MkExpString(string));
960 ListAdd(exp.call.arguments, value);
963 memberExp.member.exp = null;
966 FreeExpression(memberExp);
970 else if(memberExp.member.memberType == dataMember)
972 //if(exp.usage & USAGE_GET);
973 //FixReference(value, true);
974 if(FixMember(memberExp.member.exp))
976 // TESTING THIS HERE:
977 ProcessExpression(memberExp);
979 memberExp.type = pointerExp;
986 else if(exp.op.op == _INCREF)
988 Expression object = exp.op.exp2;
990 FreeExpContents(exp);
991 FreeType(exp.expType);
992 FreeType(exp.destType);
996 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
998 else if(exp.op.op == DELETE)
1000 Expression object = exp.op.exp2;
1001 OldList * args = MkList();
1003 exp.type = bracketsExp;
1004 exp.list = MkList();
1006 object.usage.usageDelete = true;
1008 ProcessExpression(object);
1010 ListAdd(args, object);
1012 // TOFIX: Same time as when we fix for = 0
1014 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
1015 exp.expType._class.registered.type == normalClass &&
1016 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
1018 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
1019 ProcessExpressionType(decRefExp);
1020 ListAdd(exp.list, decRefExp);
1022 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
1025 char className[1024];
1026 OldList * list = MkList();
1028 strcpy(className, "__ecereClass_");
1029 FullClassNameCat(className, exp.expType._class.string, true);
1030 //MangleClassName(className);
1032 DeclareClass(exp.expType._class, className);
1034 // Call the non virtual destructor
1035 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1036 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1038 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1040 MkExpBrackets(MkListOne(MkExpCondition(
1041 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1042 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1047 OldList * list = MkList();
1050 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1052 char className[1024];
1054 if(_class.templateClass) _class = _class.templateClass;
1055 strcpy(className, "__ecereClass_");
1056 FullClassNameCat(className, _class.fullName, false /*true*/);
1057 //MangleClassName(className);
1060 _class.symbol = FindClass(_class.fullName);
1061 DeclareClass(_class.symbol, className);
1063 // Call the non virtual destructor
1067 QMkExpId(className),
1068 MkIdentifier("Destructor")
1073 QMkExpId(className),
1074 MkIdentifier("Destructor")
1076 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), CopyExpression(args->first)))
1083 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1084 o = CopyExpression(object);
1085 ProcessExpressionType(o);
1086 o.usage.usageGet = true;
1087 ProcessExpression(o);
1103 else if(exp.expType && exp.expType.kind == templateType)
1105 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1108 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1110 OldList * qualifiers = MkList();
1111 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1113 typeName = MkTypeName(qualifiers, declarator);
1115 ProcessExpressionType(classExp);
1116 ProcessExpression(classExp);
1117 args->Insert(null, CopyExpression(classExp));
1118 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1119 ListAdd(exp.list, MkExpCall(
1120 MkExpBrackets(MkListOne(MkExpCast(typeName,
1121 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1122 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1123 //ProcessExpression(exp.list->last);
1127 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1129 //ProcessExpression(object);
1131 ListAdd(exp.list, MkExpOp(CopyExpression(GetInnerExp(object)), '=', MkExpConstant("0")));
1135 // TESTING THIS HERE...
1136 ProcessExpression(exp);
1139 if(exp.type == opExp)
1141 // Handle assigment of template structures
1142 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1143 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1145 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1148 // memcpy((byte *)array + (count * dataTypeClass.size), (dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1150 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1151 OldList * args = MkList();
1152 Expression derefExp = exp.op.exp1;
1155 ProcessExpressionType(classExp);
1156 ProcessExpression(classExp);
1158 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1160 if(exp.op.exp1.type == indexExp)
1162 Expression indexExp = derefExp.index.exp;
1163 OldList * indexExpIndex = derefExp.index.index;
1165 derefExp.index.index = null;
1166 derefExp.index.exp = null;
1167 FreeExpression(derefExp);
1169 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1170 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1174 Expression indexExp = derefExp.op.exp2;
1175 derefExp.op.exp2 = null;
1176 FreeExpression(derefExp);
1177 derefExp = indexExp;
1180 args->Add(derefExp);
1181 ProcessExpressionType(args->last);
1182 ProcessExpression(args->last);
1184 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1185 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1186 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2))))),
1187 MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1189 thisClass = curExternal.function ? curExternal.function._class : null;
1193 string = CopyString("this");
1194 type = MkClassType(thisClass.fullName);
1196 globalContext.symbols.Add((BTNode)thisSymbol);
1198 ProcessExpressionType(args->last);
1199 ProcessExpression(args->last);
1202 ProcessExpressionType(args->last);
1203 ProcessExpression(args->last);
1205 DeclareFunctionUtil("memcpy");
1207 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1208 exp.type = bracketsExp;
1210 //globalContext.symbols.Delete((BTNode)thisSymbol);
1211 globalContext.symbols.Remove((BTNode)thisSymbol);
1212 FreeSymbol(thisSymbol);
1218 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1219 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1221 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1224 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1227 ProcessExpressionType(classExp);
1228 ProcessExpression(classExp);
1230 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1232 exp.type = bracketsExp;
1233 exp.list = MkListOne(
1235 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1237 // ((class.type == structClass) ?
1238 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1241 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1243 // ((class.size == 1) ?
1244 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1246 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1247 CopyExpression(exp.op.exp2)))))),
1249 // ((class.size == 2) ?
1250 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1251 // *((uint16 *)array)
1252 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1253 CopyExpression(exp.op.exp2)))))),
1255 // ((class.size == 4) ?
1256 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1257 // *((uint32 *)array)
1258 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1259 CopyExpression(exp.op.exp2)))))),
1261 // *((uint64 *)array)
1262 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1263 exp.op.exp2))))))))))))))))))));
1265 // Add this to the context
1266 thisClass = curExternal.function ? curExternal.function._class : null;
1270 string = CopyString("this");
1271 type = MkClassType(thisClass.fullName);
1273 globalContext.symbols.Add((BTNode)thisSymbol);
1275 ProcessExpressionType(exp.list->first);
1276 ProcessExpression(exp.list->first);
1278 //globalContext.symbols.Delete((BTNode)thisSymbol);
1279 globalContext.symbols.Remove((BTNode)thisSymbol);
1280 FreeSymbol(thisSymbol);
1291 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1292 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1293 ProcessExpression(exp.op.exp1);
1296 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1297 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1298 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1299 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*/))
1300 FixReference(exp.op.exp1, false);
1301 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1305 // Don't use the temporaries used by the left side...
1307 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1308 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1309 ProcessExpression(exp.op.exp2);
1310 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1314 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1315 (exp.op.exp2.expType._class.registered.type != normalClass &&
1316 exp.op.exp2.expType._class.registered.type != structClass &&
1317 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1319 // TESTING THIS TEMPLATE TYPE CHECK HERE
1320 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1322 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1323 //FixReference(exp.op.exp2, false);
1326 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1329 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)
1331 // Preserve prev, next
1332 Expression next = exp.next, prev = exp.prev;
1333 Expression derefExp = exp.op.exp2;
1334 Expression refExp = exp.op.exp2.op.exp2;
1336 derefExp.op.exp2 = null;
1337 FreeExpression(derefExp);
1338 FreeType(exp.expType);
1339 FreeType(exp.destType);
1349 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)
1351 Expression exp2 = exp.op.exp2;
1352 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1355 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1358 ProcessExpressionType(classExp);
1359 ProcessExpression(classExp);
1361 exp.type = bracketsExp;
1362 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1363 MkExpOp(null, '&', exp2)), '+',
1364 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1365 MkListOne((e = MkExpMember(classExp, MkIdentifier("typeSize")))))));
1367 // Add this to the context
1368 thisClass = curExternal.function ? curExternal.function._class : null;
1372 string = CopyString("this");
1373 type = MkClassType(thisClass.fullName);
1375 //globalContext.symbols.Add((BTNode)thisSymbol);
1377 ProcessExpressionType(e);
1378 ProcessExpression(e);
1380 //globalContext.symbols.Remove((BTNode)thisSymbol);
1381 //FreeSymbol(thisSymbol);
1390 FreeExpression(exp1);
1392 FreeExpression(exp2);
1397 case extensionExpressionExp:
1402 for(e = exp.list->first; e; e = e.next)
1406 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1408 e.tempCount = exp.tempCount;
1409 ProcessExpression(e);
1411 exp.byReference = e.byReference;
1412 exp.tempCount = e.tempCount;
1416 exp.expType = e.expType;
1425 /*bool isBuiltin = exp && exp.index.exp &&
1426 (exp.index.exp.type == ExpressionType::arrayExp ||
1427 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1429 Expression checkedExp = exp.index.exp;
1430 bool isBuiltin = false;
1432 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1434 if(checkedExp.type == extensionCompoundExp)
1439 else if(checkedExp.type == bracketsExp)
1440 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1442 checkedExp = checkedExp.cast.exp;
1445 exp.index.exp.tempCount = exp.tempCount;
1447 exp.index.exp.usage.usageGet = true;
1448 ProcessExpression(exp.index.exp);
1450 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1451 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1453 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1456 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1459 ProcessExpressionType(classExp);
1460 ProcessExpression(classExp);
1462 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1464 exp.type = bracketsExp;
1465 exp.list = MkListOne(
1467 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1469 // ((class.type == structClass) ?
1470 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1471 // ((byte *)array) + (i) * class.size
1472 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1473 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1474 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1476 // ((class.size == 1) ?
1477 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1478 // ((byte *)array)[i]
1479 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1480 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1482 // ((class.size == 2) ?
1483 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1484 // ((uint16 *)array)[i]
1485 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1486 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1488 // ((class.size == 4) ?
1489 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1490 // ((uint32 *)array)[i]
1491 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1492 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1494 // ((uint64 *)array)[i]
1495 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1496 exp.index.exp))), exp.index.index)))))))))))))))));
1498 // Add this to the context
1499 thisClass = curExternal.function ? curExternal.function._class : null;
1503 string = CopyString("this");
1504 type = MkClassType(thisClass.fullName);
1506 globalContext.symbols.Add((BTNode)thisSymbol);
1508 ProcessExpressionType(exp.list->first);
1509 ProcessExpression(exp.list->first);
1511 //globalContext.symbols.Delete((BTNode)thisSymbol);
1512 globalContext.symbols.Remove((BTNode)thisSymbol);
1513 FreeSymbol(thisSymbol);
1521 for(e = exp.index.index->first; e; e = e.next)
1524 e.usage.usageGet = true;
1525 ProcessExpression(e);
1527 // Ignore temps in the index for now...
1528 exp.tempCount = exp.index.exp.tempCount;
1530 if(exp.index.exp.expType)
1532 Type source = exp.index.exp.expType;
1533 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1534 eClass_IsDerived(source._class.registered, containerClass))
1536 Class _class = source._class.registered;
1537 bool isArray = false;
1538 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1539 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1541 if(isArray && _class.templateArgs)
1543 OldList * specs = MkList();
1544 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1545 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1546 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1547 ProcessExpressionType(exp.index.exp);
1548 ProcessExpression(exp);
1550 else if(isBuiltin && _class.templateArgs)
1552 OldList * specs = MkList();
1553 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1554 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1555 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1556 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1557 ProcessExpressionType(exp.index.exp);
1558 ProcessExpression(exp);
1560 else if(_class.templateArgs)
1562 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1564 char iteratorType[1024];
1565 OldList * declarations = MkList();
1566 OldList * statements = MkList();
1567 OldList * args = MkList();
1568 OldList * instMembers = MkList();
1570 Context context = PushContext();
1572 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1574 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1576 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1577 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1579 ListAdd(args, MkExpBrackets(exp.index.index));
1580 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1582 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1583 MkIdentifier("Index")), args))));
1585 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1586 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1588 exp.type = bracketsExp;
1589 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1590 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1591 expExt.compound.compound.context = context;
1592 PopContext(context);
1593 expExt.usage = exp.usage;
1594 ProcessExpressionType(exp.list->first);
1595 ProcessExpressionInstPass(exp.list->first);
1596 ProcessExpression(exp.list->first);
1605 bool typedObject = false;
1606 Type ellipsisDestType = null;
1607 bool usedEllipsis = false;
1609 if(exp.call.arguments)
1611 for(e = exp.call.arguments->first; e; e = e.next)
1613 e.usage.usageGet = true;
1614 e.usage.usageArg = true;
1615 e.tempCount = Max(e.tempCount, exp.tempCount);
1616 ProcessExpression(e);
1617 exp.tempCount = Max(exp.tempCount, e.tempCount);
1620 exp.call.exp.usage.usageGet = true;
1621 exp.call.exp.usage.usageCall = true;
1622 exp.call.exp.tempCount = exp.tempCount;
1624 ProcessExpression(exp.call.exp);
1626 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1628 bool nullMemberExp = false;
1629 Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1631 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1632 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1633 Method method = exp.call.exp.expType.method;
1634 if(method.type == virtualMethod)
1640 OldList * specs = MkList();
1641 strcpy(name, "__ecereVMethodID_");
1642 FullClassNameCat(name, method._class.fullName, false);
1644 strcat(name, method.name);
1646 DeclareMethod(method, name);
1649 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1650 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1651 // Cast function to its type
1653 Context context = SetupTemplatesContext(method._class);
1655 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1657 FinishTemplatesContext(context);
1660 if(method.dataType && !method.dataType.staticMethod)
1662 Declarator funcDecl = GetFuncDecl(decl);
1664 if(!funcDecl.function.parameters)
1665 funcDecl.function.parameters = MkList();
1667 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1668 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1670 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1672 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1673 FreeTypeName(firstParam);
1677 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1682 param = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
1683 param.qualifiers->Insert(null, MkSpecifier(CONST));
1684 funcDecl.function.parameters->Insert(null, param);
1685 // Testing this for any_object::
1686 if(!method.dataType.extraParam)
1687 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1691 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1692 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1696 typeName = MkTypeName(specs, decl);
1698 // Added !exp.call.exp.expType.methodClass
1699 if(memberExp && memberExp.member.exp.expType)
1701 Type type = memberExp.member.exp.expType;
1703 if(type.kind == classType && type._class && type._class.registered)
1705 Class regClass = type._class.registered;
1706 ClassType classType = regClass.type;
1707 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1708 argClass = regClass;
1710 else if(type.kind == subClassType)
1712 argClass = FindClass("ecere::com::Class").registered;
1714 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1716 argClass = FindClass("char *").registered;
1718 else if(type.kind == pointerType)
1720 argClass = eSystem_FindClass(privateModule, "uintptr");
1721 FreeType(memberExp.member.exp.expType);
1722 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1723 memberExp.member.exp.byReference = true;
1727 char string[1024] = "";
1729 PrintTypeNoConst(type, string, false, true);
1730 classSym = FindClass(string);
1731 if(classSym) argClass = classSym.registered;
1735 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1741 Type type = memberExp ? memberExp.member.exp.expType : null;
1742 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1743 char className[1024];
1745 if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
1746 strcpy(className, "class");
1750 // TESTING: Moved this here...
1751 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1756 // TODO: Unhandled case here, what should happen?
1759 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1760 if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
1761 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1762 cl = cl.templateClass;
1764 // Need the class itself here...
1765 strcpy(className, "__ecereClass_");
1766 FullClassNameCat(className, cl.fullName, true);
1767 //MangleClassName(className);
1770 cl.symbol = FindClass(cl.fullName);
1772 DeclareClass(cl.symbol, className);
1775 if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
1777 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1778 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1779 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1781 else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
1782 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1785 FreeExpression(exp.call.exp);
1786 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1787 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1788 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1792 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1793 // as opposed to the File class vTbl one
1795 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1797 Context context = PushContext();
1799 c = MkExpExtensionCompound(MkCompoundStmt(
1800 MkListOne(MkDeclaration(
1801 (specs = MkListOne(MkSpecifierName("Instance"))),
1802 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1803 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
1804 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1805 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1806 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1807 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
1809 specs->Insert(null, MkSpecifier(CONST));
1811 c.compound.compound.context = context;
1812 PopContext(context);
1813 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1814 MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1821 strcpy(name, "__ecereMethod_");
1822 FullClassNameCat(name, method._class.fullName, false);
1824 strcat(name, method.name);
1827 FreeExpression(exp.call.exp);
1828 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1829 DeclareMethod(method, name);
1830 if(memberExp && memberExp.expType && method.dataType)
1832 exp.call.exp.expType = method.dataType;
1833 method.dataType.refCount++;
1836 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1838 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1840 if(!exp.call.arguments)
1841 exp.call.arguments = MkList();
1843 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1845 if(memberExp.member.exp.expType.kind != classType ||
1846 memberExp.member.exp.expType._class.registered.type == enumClass ||
1847 memberExp.member.exp.expType._class.registered.type == unitClass)
1849 char typeString[1024] = "";
1850 if(memberExp.member.exp.expType.kind != classType)
1851 PrintType(memberExp.member.exp.expType, typeString, false, true);
1853 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1856 // memberExp.member.exp.expType.kind = classType;
1857 // memberExp.member.exp.expType._class = FindClass(typeString);
1859 FreeType(memberExp.member.exp.expType);
1860 memberExp.member.exp.expType = Type
1863 _class = FindClass(typeString);
1867 // Default to an int instead
1868 if(!memberExp.member.exp.expType._class)
1870 // TODO: Shouldn't get here...
1871 memberExp.member.exp.expType.kind = TypeInt;
1876 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1878 bool changeReference = false;
1879 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1881 // Patched so that class isn't considered SYSTEM...
1882 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1883 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1884 changeReference = true;
1885 if(!memberExp.member.exp.expType.classObjectType &&
1887 (memberExp.member.exp.expType.kind != pointerType &&
1888 (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1889 !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1890 method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
1891 changeReference = true;
1892 if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
1893 changeReference = true;
1896 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1897 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1899 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1900 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1902 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1904 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1905 memberExp.member.exp.op.exp2 = null;
1907 else if(!memberExp.member.exp.byReference)
1909 // TESTING THIS... REUSE THIS CODE?
1910 Expression checkedExp = memberExp.member.exp;
1911 Expression parentExp = null;
1913 bool disconnected = false;
1914 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1916 parentExp = checkedExp;
1918 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1920 checkedExp = checkedExp.list->last;
1921 // Dissociate from memberExp which will get freed
1922 if(checkedExp && !disconnected)
1924 parentExp.list->Remove(checkedExp);
1925 disconnected = true;
1928 else if(checkedExp.type == castExp)
1930 checkedExp = checkedExp.cast.exp;
1931 // Dissociate from memberExp which will get freed
1932 if(checkedExp && !disconnected)
1934 checkedExp.cast.exp = null;
1935 disconnected = true;
1940 nullMemberExp = true;
1942 newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
1943 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1945 parentExp.list->Remove(checkedExp);
1946 parentExp.list->Add(newExp);
1948 else if(parentExp && parentExp.type == castExp)
1950 parentExp.cast.exp = newExp;
1951 // Add a dereference level here
1952 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1954 if(typedObject && !memberExp.member.exp.expType.classObjectType)
1956 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
1957 FreeType((parentExp ? parentExp : newExp).expType);
1958 FreeType((parentExp ? parentExp : newExp).destType);
1959 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
1960 (parentExp ? parentExp : newExp).destType = destType;
1961 if(checkedExp.expType) checkedExp.expType.refCount++;
1963 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1967 exp.call.arguments->Insert(null, memberExp.member.exp);
1968 nullMemberExp = true;
1973 exp.call.arguments->Insert(null, memberExp.member.exp);
1974 nullMemberExp = true;
1978 char className[1024];
1979 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
1980 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1981 Class cl = argClass ? argClass : regClass;
1984 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1985 strcpy(className, "class");
1988 // Need the class itself here...
1989 strcpy(className, "__ecereClass_");
1990 FullClassNameCat(className, cl.fullName, true);
1991 //MangleClassName(className);
1994 cl.symbol = FindClass(cl.fullName);
1995 DeclareClass(cl.symbol, className);
2000 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
2002 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2004 Context context = PushContext();
2007 c = MkExpExtensionCompound(MkCompoundStmt(
2008 MkListOne(MkDeclaration(
2009 (specs = MkListOne(MkSpecifierName("Instance"))),
2010 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2011 MkInitializerAssignment(memberExpMemberExp))))),
2012 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2013 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2014 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2015 MkExpIdentifier(MkIdentifier(className))))))));
2016 c.compound.compound.context = context;
2017 PopContext(context);
2020 specs->Insert(null, MkSpecifier(CONST));
2022 exp.call.arguments->Insert(null, c);
2024 memberExpMemberExp = null; // We used this
2027 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
2031 if(memberExpMemberExp)
2032 FreeExpression(memberExpMemberExp);
2036 exp.call.arguments->Insert(null, memberExp.member.exp);
2037 nullMemberExp = true;
2041 /*else if(method->dataType)
2047 memberExp.member.exp = null;
2048 FreeExpression(memberExp);
2052 if(exp.call.arguments)
2054 for(e = exp.call.arguments->first; e; e = e.next)
2056 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
2057 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
2058 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
2059 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
2061 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
2062 ellipsisDestType = destType;
2065 Type type = e.expType;
2066 Class _class = null;
2067 //Type destType = e.destType;
2069 if(type.kind == classType && type._class && type._class.registered)
2071 _class = type._class.registered;
2073 else if(type.kind == subClassType)
2075 _class = FindClass("ecere::com::Class").registered;
2077 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
2079 _class = FindClass("char *").registered;
2081 else if(type.kind == pointerType)
2083 _class = eSystem_FindClass(privateModule, "uintptr");
2084 FreeType(e.expType);
2085 e.expType = ProcessTypeString("uintptr", false);
2086 // Assume null pointers means 'no object' rather than an object holding a null pointer
2087 e.byReference = true;
2091 char string[1024] = "";
2093 PrintTypeNoConst(type, string, false, true);
2094 classSym = FindClass(string);
2095 if(classSym) _class = classSym.registered;
2096 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2099 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...
2100 (!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))) ||
2101 destType.byReference)))
2103 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2104 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2105 // TESTING WITHOUT THE ABOVE NOW!
2107 Expression checkedExp;
2108 Expression parentExp;
2113 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2115 parentExp = checkedExp;
2116 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2118 if(checkedExp.type == extensionCompoundExp)
2120 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2123 checkedExp = checkedExp.list->last;
2125 else if(checkedExp.type == castExp)
2126 checkedExp = checkedExp.cast.exp;
2129 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2132 Expression newExp = e.op.exp2;
2133 exp.call.arguments->Insert(e.prev, newExp);
2134 exp.call.arguments->Remove(e);
2139 newExp = checkedExp.op.exp2;
2140 checkedExp.op.exp2 = null;
2141 FreeExpContents(checkedExp);
2143 if(e.expType && e.expType.passAsTemplate)
2146 ComputeTypeSize(e.expType);
2147 sprintf(size, "%d", e.expType.size);
2148 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2149 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2150 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2153 if(parentExp.type == callExp)
2155 exp.call.arguments->Insert(e.prev, newExp);
2156 exp.call.arguments->Remove(e);
2159 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2161 parentExp.list->Remove(checkedExp);
2162 parentExp.list->Add(newExp);
2164 else if(parentExp.type == castExp)
2166 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2167 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2169 FreeTypeName(parentExp.cast.typeName);
2170 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2172 parentExp.cast.exp = newExp;
2174 else if(parentExp.type == extensionCompoundExp)
2176 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2177 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2179 e.byReference = true;
2181 FreeType(checkedExp.expType);
2182 FreeType(checkedExp.destType);
2185 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2187 Expression checkedExp;
2188 Expression parentExp;
2192 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2194 e.type == identifierExp ||
2195 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2196 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2197 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2200 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2202 Context context = PushContext();
2204 OldList * specs = MkList();
2205 char typeString[1024];
2206 Expression newExp { };
2208 typeString[0] = '\0';
2211 // TOCHECK: Should this read e.destType ???
2213 if(exp.destType) exp.destType.refCount++;
2214 // if(exp.expType) exp.expType.refCount++;
2217 newExp.expType = null;
2219 PrintTypeNoConst(e.expType, typeString, false, true);
2220 decl = SpecDeclFromString(typeString, specs, null);
2221 newExp.destType = ProcessType(specs, decl);
2223 curContext = context;
2224 e.type = extensionCompoundExp;
2226 // We need a current compound for this
2230 OldList * stmts = MkList();
2231 sprintf(name, "__internalValue%03X", internalValueCounter++);
2232 if(!curCompound.compound.declarations)
2233 curCompound.compound.declarations = MkList();
2234 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2235 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2236 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2237 e.compound = MkCompoundStmt(null, stmts);
2240 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2244 e.compound = MkCompoundStmt(
2245 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2246 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2249 e.compound.compound.context = context;
2250 PopContext(context);
2251 curContext = context.parent;
2255 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2258 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2260 parentExp = checkedExp;
2261 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2263 if(checkedExp.type == extensionCompoundExp)
2265 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2268 checkedExp = checkedExp.list->last;
2270 else if(checkedExp.type == castExp)
2271 checkedExp = checkedExp.cast.exp;
2273 newExp = MkExpOp(null, '&', checkedExp);
2274 newExp.byReference = true;
2275 if(parentExp.type == callExp)
2277 exp.call.arguments->Insert(e.prev, newExp);
2278 exp.call.arguments->Remove(e);
2281 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2283 parentExp.list->Remove(checkedExp);
2284 parentExp.list->Add(newExp);
2286 else if(parentExp.type == castExp)
2287 parentExp.cast.exp = newExp;
2288 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2290 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2291 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2297 if(destType.classObjectType == ClassObjectType::typedObject)
2299 char className[1024];
2300 // Need the class itself here...
2301 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2302 _class = eSystem_FindClass(privateModule, "String");
2303 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2305 if(!strcmp(_class.name, "class"))
2307 // Already inside a typed_object function, pass the class through
2308 strcpy(className, "class");
2312 strcpy(className, "__ecereClass_");
2313 FullClassNameCat(className, _class.fullName, true);
2314 //MangleClassName(className);
2317 _class.symbol = FindClass(_class.fullName);
2319 DeclareClass(_class.symbol, className);
2322 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2324 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2326 Context context = PushContext();
2328 // Work around to avoid repeating the BuiltInContainer just to get the type
2329 // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
2330 if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
2331 e.list && e.list->first &&
2332 ((Expression)e.list->first).type == castExp &&
2333 ((Expression)e.list->first).cast.exp &&
2334 ((Expression)e.list->first).cast.exp.type == opExp &&
2335 ((Expression)e.list->first).cast.exp.op.op == '&' &&
2336 ((Expression)e.list->first).cast.exp.op.exp2 &&
2337 ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
2339 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2344 c = MkExpExtensionCompound(MkCompoundStmt(
2345 MkListOne(MkDeclaration(
2346 (specs = MkListOne(MkSpecifierName("Instance"))),
2347 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2348 MkInitializerAssignment(CopyExpression(e)))))),
2349 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2350 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2351 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2352 MkExpIdentifier(MkIdentifier(className))))))));
2353 c.compound.compound.context = context;
2354 PopContext(context);
2357 specs->Insert(null, MkSpecifier(CONST));
2359 exp.call.arguments->Insert(e.prev, c);
2363 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2369 //char debugString[4096] = "";
2370 //PrintExpression(e, debugString);
2372 // If expression type is a simple class, make it an address
2373 FixReference(e, !destType || !destType.declaredWithStruct);
2376 if(ellipsisDestType)
2379 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2380 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2382 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2390 bool changeToPtr = false;
2391 bool noHead = false;
2392 Type type = exp.member.exp ? exp.member.exp.expType : null;
2393 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2394 if(exp.member.member) exp.member.member._class = null;
2396 if(type && type.kind == templateType)
2398 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2399 if(baseType) type = baseType;
2401 if(type && exp.member.member && !type.directClassAccess)
2403 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2404 Property prop = null;
2405 ClassProperty classProperty = null;
2406 Method method = null;
2407 Class convertTo = null;
2408 DataMember member = null;
2409 DataMember subMemberStack[256];
2410 int subMemberStackPos = 0;
2411 bool thisPtr = exp.member.thisPtr;
2412 if(type.kind == subClassType && exp.member.exp.type == classExp)
2413 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2415 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2419 // DANGER: Buffer overflow
2420 char string[2048] = "";
2422 PrintTypeNoConst(type, string, false, true);
2423 classSym = FindClass(string);
2424 _class = classSym ? classSym.registered : null;
2427 if(_class && exp.member.memberType == dataMember)
2429 if(!thisPtr && !exp.member.member.classSym)
2430 member = eClass_FindDataMember(_class, exp.member.member.string, null, subMemberStack, &subMemberStackPos);
2432 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2434 else if(_class && exp.member.memberType == propertyMember)
2436 if(!thisPtr && !exp.member.member.classSym)
2437 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2439 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2440 if(prop && (exp.usage.usageRef ||
2441 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2442 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2444 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2447 exp.member.memberType = dataMember;
2452 if(exp.usage.usageRef)
2453 Compiler_Error($"cannot obtain address of property\n");
2455 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2456 else if(exp.usage.usageDelete)
2457 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2461 else if(_class && exp.member.memberType == methodMember)
2464 method = eClass_FindMethod(_class, exp.member.member.string, null);
2466 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2468 else if(_class && exp.member.memberType == reverseConversionMember)
2471 _class = FindClass(exp.member.member.string).registered;
2472 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2473 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2475 else if(_class && exp.member.memberType == classPropertyMember)
2477 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2481 // Only process Gets here, Set is processed in opExp's '='
2482 if(exp.usage.usageGet)
2486 char getName[1024], setName[1024];
2487 Expression ptr = exp.member.exp;
2488 Class propertyClass;
2489 char * nameToUse = convertTo ? setName : getName;
2491 FreeIdentifier(exp.member.member);
2493 // Process this here since it won't be processed at the end...
2494 exp.member.exp.usage.usageGet = true;
2495 ProcessExpression(exp.member.exp);
2496 // TEST: exp.tempCount = exp.member.exp.tempCount;
2498 DeclareProperty(prop, setName, getName);
2499 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2500 propertyClass = convertTo ? _class :
2501 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2504 if(propertyClass && propertyClass.type == bitClass)
2506 // Bit classes shouldn't have properties except for conversions...
2507 OldList * args = MkList();
2508 if(exp.usage.usageDeepGet)
2510 char className[1024];
2512 Declarator declarator;
2513 OldList * specs = MkList(), * decls = MkList();
2516 // Make a declaration in the closest compound statement
2517 // (Do not reuse (since using address for function calls)...)
2518 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2520 SpecDeclFromString(propertyClass.dataTypeString, specs,
2521 MkDeclaratorIdentifier(MkIdentifier(className)));
2523 ListAdd(decls, MkInitDeclarator(declarator, null));
2525 decl = MkDeclaration(specs, decls);
2526 if(!curCompound.compound.declarations)
2527 curCompound.compound.declarations = MkList();
2528 curCompound.compound.declarations->Insert(null, decl);
2530 tempExp = QMkExpId(className);
2531 tempExp.expType = MkClassType(propertyClass.fullName);
2533 exp.op.exp1 = tempExp;
2534 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2541 exp.call.exp = QMkExpId(nameToUse);
2542 exp.call.arguments = args;
2544 ListAdd(args, FixReference(ptr, true));
2546 else if(propertyClass && propertyClass.type == unitClass)
2548 OldList * args = MkList();
2549 ListAdd(args, FixReference(ptr, true));
2551 exp.call.exp = QMkExpId(nameToUse);
2552 exp.call.arguments = args;
2554 else if(propertyClass && propertyClass.type == structClass)
2556 OldList * args = MkList();
2557 char className[1024];
2559 OldList * specs = MkList(), * decls = MkList();
2562 // Make a declaration in the closest compound statement
2563 // (Do not reuse (since using address for function calls)...)
2566 FullClassNameCat(className, propertyClass.fullName, false); //true);
2568 //ListAdd(specs, MkSpecifierName(className));
2569 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2571 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2573 ListAdd(decls, MkInitDeclarator(
2574 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2576 decl = MkDeclaration(specs, decls);
2579 if(!curCompound.compound.declarations)
2580 curCompound.compound.declarations = MkList();
2581 curCompound.compound.declarations->Insert(null, decl);
2584 tempExp = QMkExpId(className);
2585 tempExp.expType = MkClassType(propertyClass.fullName);
2589 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2590 ListAdd(args, FixReference(ptr, true));
2594 ListAdd(args, FixReference(ptr, true));
2595 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2598 if(exp.usage.usageDeepGet)
2601 exp.call.exp = QMkExpId(nameToUse);
2602 exp.call.arguments = args;
2604 FreeExpression(tempExp);
2608 exp.type = bracketsExp;
2609 exp.list = MkList();
2610 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2611 if(exp.usage.usageMember)
2613 ListAdd(exp.list, FixReference(tempExp, true));
2614 exp.byReference = true;
2617 ListAdd(exp.list, tempExp);
2623 exp.call.exp = QMkExpId(nameToUse);
2624 exp.call.arguments = MkList();
2625 ListAdd(exp.call.arguments, FixReference(ptr, true));
2628 else if(prop.conversion)
2630 void * prev = exp.prev, * next = exp.next;
2631 *exp = *exp.member.exp;
2637 else if(classProperty)
2639 // Only process Gets here, Set is processed in opExp's '='
2640 if(exp.usage.usageGet)
2642 if(classProperty.Get)
2644 Identifier id = exp.member.member;
2645 Expression classExp = exp.member.exp;
2646 OldList * args = MkList();
2652 char typeString[2048];
2653 OldList * specs = MkList();
2656 PrintType(exp.expType, typeString, false, false);
2657 decl = SpecDeclFromString(typeString, specs, null);
2658 exp.cast.typeName = MkTypeName(specs, decl);
2661 exp.cast.typeName = QMkType("uint64", null);
2662 exp.cast.exp = MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty")), args);
2664 ListAdd(args, classExp);
2666 char * s = QMkString(id.string);
2667 ListAdd(args, MkExpString(s));
2672 ProcessExpression(exp);
2679 // Get the function address if it's not called
2680 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2684 FreeIdentifier(exp.member.member);
2686 // Process this here since it won't be processed at the end...
2687 exp.member.exp.usage.usageGet = true;
2688 ProcessExpression(exp.member.exp);
2689 // TEST: exp.tempCount = exp.member.exp.tempCount;
2691 if(method.type == virtualMethod)
2693 strcpy(name, "__ecereVMethodID_");
2694 FullClassNameCat(name, method._class.fullName, false);
2696 strcat(name, method.name);
2697 exp.type = indexExp;
2698 if(memberClassSpecifier)
2700 char className[1024];
2701 // Need the class itself here...
2702 strcpy(className, "__ecereClass_");
2703 FullClassNameCat(className, _class.fullName, true);
2704 //MangleClassName(className);
2707 _class.symbol = FindClass(_class.fullName);
2708 DeclareClass(_class.symbol, className);
2710 FreeExpression(exp.member.exp);
2711 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2715 if(exp.thisPtr && _class.type != normalClass)
2717 FreeExpression(exp.member.exp);
2718 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2721 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2723 exp.index.index = MkListOne(QMkExpId(name));
2724 DeclareMethod(method, name);
2728 FreeExpression(exp.member.exp);
2729 exp.type = identifierExp;
2730 strcpy(name, "__ecereMethod_");
2731 FullClassNameCat(name, method._class.fullName, false);
2733 strcat(name, method.name);
2734 exp.identifier = MkIdentifier(name);
2735 DeclareMethod(method, name);
2741 if(subMemberStackPos)
2744 DataMember parentMember = null;
2745 String s, prefix = null;
2746 for(i = 0; i < subMemberStackPos; i++)
2748 DataMember curMember = subMemberStack[i];
2751 for(m = parentMember ? parentMember.members.first : _class.membersAndProperties.first; m; m = m.next)
2753 if(m && !m.isProperty && (m.type == unionMember || m.type == structMember) && !m.name)
2764 prefix = PrintString(prefix, ".__anon", anonID);
2768 prefix = PrintString("__anon", anonID);
2769 parentMember = curMember;
2772 s = exp.member.member.string;
2773 exp.member.member.string = PrintString(prefix, ".", s);
2777 // Process this here since it won't be processed at the end...
2778 if(exp.usage.usageGet)
2780 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2782 ProcessExpression(exp.member.exp);
2783 // TEST: exp.tempCount = exp.member.exp.tempCount;
2785 if(type.kind == classType && type._class && type._class.registered)
2786 DeclareStruct(type._class.registered.fullName, false);
2788 // TESTING THIS NOHEAD STUFF...
2789 if(_class.type == noHeadClass)
2793 else if(_class.type == structClass)
2797 else if(_class.type == bitClass)
2799 OldList * list = MkList();
2800 char mask[32], shift[10];
2801 OldList * specs = MkList();
2802 BitMember bitMember = (BitMember) member;
2803 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2804 TypeName type = MkTypeName(specs, decl);
2805 if(bitMember.mask > MAXDWORD)
2806 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2808 sprintf(mask, FORMAT64HEX, bitMember.mask);
2809 sprintf(shift, "%d", bitMember.pos);
2811 FreeIdentifier(exp.member.member);
2813 // ((type) ((color & mask) >> bitPos))
2814 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2815 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2816 MkExpConstant(shift))))));
2818 exp.type = bracketsExp;
2821 else if(_class.type == unitClass)
2826 // If it's a this pointer, replace by precomputed shortcut
2827 if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2829 char pointerName[1024];
2831 strcpy(pointerName, "__ecerePointer_");
2832 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2833 if(exp.member.exp.identifier)
2834 FreeIdentifier(exp.member.exp.identifier);
2835 exp.member.exp.identifier = MkIdentifier(pointerName);
2837 // Otherwise, access the data the hard way
2840 Expression bytePtr, e;
2841 Expression checkedExp;
2842 char structName[1024];
2843 char className[1024];
2844 strcpy(className, "__ecereClass_");
2845 FullClassNameCat(className, member._class.fullName, true);
2846 //MangleClassName(className);
2848 // classExp = QMkExpId(className);
2850 if(!member._class.symbol)
2851 member._class.symbol = FindClass(member._class.fullName);
2853 DeclareClass(member._class.symbol, className);
2854 DeclareStruct(member._class.fullName, false);
2857 FullClassNameCat(structName, member._class.fullName, false);
2859 checkedExp = exp.member.exp;
2860 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2861 checkedExp.type == castExp)
2863 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2864 checkedExp = checkedExp.list->last;
2865 else if(checkedExp.type == castExp)
2866 checkedExp = checkedExp.cast.exp;
2869 if(checkedExp.type != identifierExp &&
2870 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2871 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2873 char ecereTemp[100];
2875 Context context = PushContext();
2876 if(exp.member.exp.tempCount > exp.tempCount)
2877 exp.tempCount = exp.member.exp.tempCount;
2880 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2881 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2882 curContext = context;
2883 compound = MkCompoundStmt(
2884 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2885 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2886 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2887 if(member._class.fixed)
2889 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2892 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2893 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2896 e = QMkExpId(ecereTemp);
2900 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2901 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2904 compound.compound.context = context;
2905 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2906 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2907 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2909 exp.member.exp = MkExpExtensionCompound(compound);
2911 PopContext(context);
2912 curContext = context.parent;
2916 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2917 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2919 e = QBrackets(QMkExpCond(exp.member.exp,
2920 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2921 MkExpConstant("0")));
2925 if(member._class.fixed)
2927 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2930 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2931 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2937 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2939 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2940 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2943 exp.type = pointerExp;
2948 // Take Out Any Class Specifier (Should have been used by now)
2949 FreeSpecifier(memberClassSpecifier);
2951 // Just moved this at the end... How is it?
2952 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
2954 exp.member.exp.usage.usageGet = true;
2955 exp.member.exp.usage.usageMember = true;
2956 exp.member.exp.tempCount = exp.tempCount;
2957 ProcessExpression(exp.member.exp);
2958 exp.tempCount = exp.member.exp.tempCount;
2959 if((changeToPtr && exp.member.exp.byReference) || noHead)
2960 exp.type = pointerExp;
2964 case extensionCompoundExp:
2966 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
2968 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2970 ProcessStatement(exp.compound);
2972 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2973 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2978 exp.member.exp.usage.usageGet = true;
2979 ProcessExpression(exp.member.exp);
2984 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2985 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2987 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2990 Expression classExp;
2992 FreeTypeName(exp.typeName);
2994 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
2996 ProcessExpressionType(classExp);
2997 ProcessExpression(classExp);
2999 exp.type = bracketsExp;
3000 exp.list = MkListOne(MkExpMember(classExp, MkIdentifier("typeSize")));
3002 ProcessExpressionType(exp);
3003 ProcessExpression(exp);
3012 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
3013 ProcessExpression(exp.cast.exp);
3015 if(exp.cast.exp.byReference)
3016 exp.byReference = exp.cast.exp.byReference;
3017 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
3018 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
3019 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
3020 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
3021 exp.byReference = true;
3023 // Moved this to 1.5...
3024 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
3030 if(exp.usage.usageGet)
3031 exp.cond.cond.usage.usageGet = true;
3032 ProcessExpression(exp.cond.cond);
3033 for(e = exp.cond.exp->first; e; e = e.next)
3035 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
3036 ProcessExpression(e);
3038 if(exp.usage.usageGet)
3039 exp.cond.elseExp.usage.usageGet = true;
3040 ProcessExpression(exp.cond.elseExp);
3045 // Need the class itself here...
3046 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
3048 Specifier spec = exp._classExp.specifiers->first;
3049 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
3052 FreeList(exp._classExp.specifiers, FreeSpecifier);
3053 if(exp._classExp.decl)
3054 FreeDeclarator(exp._classExp.decl);
3056 exp.type = memberExp; //pointerExp;
3057 exp.member.exp = argExp;
3058 exp.member.member = MkIdentifier("dataTypeClass");
3059 exp.member.memberType = dataMember;
3061 ProcessExpressionType(argExp);
3062 ProcessExpressionType(exp);
3063 ProcessExpression(exp);
3068 char className[1024];
3069 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
3070 Symbol classSym = FindClass(string);
3072 strcpy(className, "__ecereClass_");
3073 FullClassNameCat(className, string, true); // TODO: Verify this
3074 //MangleClassName(className);
3075 DeclareClass(classSym, className);
3078 FreeList(exp._classExp.specifiers, FreeSpecifier);
3079 if(exp._classExp.decl)
3080 FreeDeclarator(exp._classExp.decl);
3082 exp.type = identifierExp;
3083 exp.identifier = MkIdentifier(className);
3089 ProcessExpression(exp.vaArg.exp);
3092 case extensionInitializerExp:
3094 ProcessInitializer(exp.initializer.initializer);
3100 if(exp.needTemplateCast != 2 && (exp.needTemplateCast == 1 || (exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate))))
3102 Expression nbExp = GetNonBracketsExp(exp);
3103 Expression inner = GetInnerExp(nbExp);
3105 if((!exp.expType || exp.expType.kind != templateType || nbExp.type != castExp) && !exp.usage.usageRef &&
3106 (!exp.destType || (!exp.destType.truth && (exp.destType.kind != templateType || (exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType))))) &&
3107 (exp.usage.usageDelete || exp.usage.usageGet || exp.usage.usageArg) &&
3108 (!exp.destType || (!exp.destType.passAsTemplate && exp.expType && (exp.expType.kind != pointerType || exp.destType.kind == pointerType) && (exp.destType.kind != pointerType || exp.expType.kind == pointerType))) &&
3109 !inner.needCast && inner.type != opExp)
3111 Expression e = CopyExpContents(exp);
3113 OldList * specs = MkList();
3114 char typeString[1024];
3116 typeString[0] = '\0';
3118 e.needTemplateCast = 2;
3119 inner.needTemplateCast = 2;
3120 nbExp.needTemplateCast = 2;
3121 if(exp.usage.usageDelete)
3122 strcpy(typeString, "void *");
3124 PrintType(exp.expType, typeString, false, false);
3126 decl = SpecDeclFromString(typeString, specs, null);
3128 if(specs && specs->first && ((Specifier)specs->first).type == templateTypeSpecifier &&
3129 exp.destType && !exp.destType.passAsTemplate && exp.destType.kind == templateType && exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType) && !exp.usage.usageArg)
3131 if(decl) FreeDeclarator(decl);
3132 FreeList(specs, FreeSpecifier);
3133 if(exp.destType.templateParameter.dataTypeString)
3136 strcpy(typeString, exp.destType.templateParameter.dataTypeString);
3137 decl = SpecDeclFromString(typeString, specs, null);
3141 specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
3142 decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
3146 e.destType = exp.destType;
3148 exp.destType.refCount++;
3150 exp.type = bracketsExp;
3151 exp.list = MkListOne(MkExpCast(MkTypeName(specs, decl), MkExpBrackets(MkListOne(e))));
3152 exp.needTemplateCast = 2;
3158 static void ProcessInitializer(Initializer init)
3162 case expInitializer:
3165 init.exp.usage.usageGet = true;
3166 ProcessExpression(init.exp);
3167 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
3168 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
3170 FixReference(init.exp, true);
3172 else if(init.exp.destType && init.exp.destType.kind == classType)
3173 FixReference(init.exp, false);
3176 case listInitializer:
3181 for(i = init.list->first; i; i = i.next)
3182 ProcessInitializer(i);
3189 static void ProcessDeclaration(Declaration decl)
3193 case initDeclaration:
3195 if(decl.declarators)
3199 for(d = decl.declarators->first; d; d = d.next)
3202 ProcessInitializer(d.initializer);
3210 static void ProcessStatement(Statement stmt)
3215 ProcessStatement(stmt.labeled.stmt);
3218 if(stmt.caseStmt.exp)
3220 stmt.caseStmt.exp.usage.usageGet = true;
3222 // This expression should be constant...
3223 ProcessExpression(stmt.caseStmt.exp);
3225 if(stmt.caseStmt.stmt)
3226 ProcessStatement(stmt.caseStmt.stmt);
3230 if(stmt.compound.context)
3234 Statement prevCompound = curCompound;
3235 Context prevContext = curContext;
3237 if(!stmt.compound.isSwitch)
3240 curContext = stmt.compound.context;
3243 if(stmt.compound.declarations)
3245 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3246 ProcessDeclaration(decl);
3248 if(stmt.compound.statements)
3250 for(s = stmt.compound.statements->first; s; s = s.next)
3251 ProcessStatement(s);
3253 curContext = prevContext;
3254 curCompound = prevCompound;
3258 case expressionStmt:
3261 if(stmt.expressions)
3263 for(exp = stmt.expressions->first; exp; exp = exp.next)
3265 ProcessExpression(exp);
3276 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3277 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3279 ProcessExpression(exp);
3282 if(stmt.ifStmt.stmt)
3283 ProcessStatement(stmt.ifStmt.stmt);
3284 if(stmt.ifStmt.elseStmt)
3285 ProcessStatement(stmt.ifStmt.elseStmt);
3291 if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
3293 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3294 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3296 ProcessExpression(exp);
3299 ProcessStatement(stmt.switchStmt.stmt);
3305 if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
3307 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3308 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3310 ProcessExpression(exp);
3313 ProcessStatement(stmt.whileStmt.stmt);
3319 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3321 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3322 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3324 ProcessExpression(exp);
3327 if(stmt.doWhile.stmt)
3328 ProcessStatement(stmt.doWhile.stmt);
3334 if(stmt.forStmt.init)
3335 ProcessStatement(stmt.forStmt.init);
3337 if(stmt.forStmt.check)
3339 if(stmt.forStmt.check.expressions)
3341 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3343 ProcessStatement(stmt.forStmt.check);
3345 if(stmt.forStmt.increment)
3347 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3349 ProcessExpression(exp);
3352 if(stmt.forStmt.stmt)
3353 ProcessStatement(stmt.forStmt.stmt);
3365 if(stmt.expressions)
3367 ((Expression)stmt.expressions->last).usage.usageGet = true;
3368 for(exp = stmt.expressions->first; exp; exp = exp.next)
3370 ProcessExpression(exp);
3371 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3372 if(!exp.next && exp.destType && exp.destType.byReference)
3373 FixReference(exp, true);
3378 case badDeclarationStmt:
3380 ProcessDeclaration(stmt.decl);
3386 if(stmt.asmStmt.inputFields)
3388 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3389 if(field.expression)
3390 ProcessExpression(field.expression);
3392 if(stmt.asmStmt.outputFields)
3394 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3395 if(field.expression)
3396 ProcessExpression(field.expression);
3398 if(stmt.asmStmt.clobberedFields)
3400 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3401 if(field.expression)
3402 ProcessExpression(field.expression);
3409 static void ProcessFunction(FunctionDefinition function)
3412 ProcessStatement(function.body);
3415 static void ProcessMemberInitData(MemberInit member)
3417 if(member.initializer)
3418 ProcessInitializer(member.initializer);
3421 static void ProcessInstantiation(Instantiation inst)
3425 MembersInit members;
3426 for(members = inst.members->first; members; members = members.next)
3428 if(members.type == dataMembersInit)
3430 if(members.dataMembers)
3433 for(member = members.dataMembers->first; member; member = member.next)
3434 ProcessMemberInitData(member);
3437 else if(members.type == methodMembersInit)
3439 ProcessFunction((FunctionDefinition)members.function);
3445 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3446 public void ProcessMemberAccess()
3449 for(external = ast->first; external; external = external.next)
3451 curExternal = external;
3452 // There shouldn't be any class member access here anyways...
3453 if(external.type == declarationExternal)
3455 if(external.declaration)
3456 ProcessDeclaration(external.declaration);
3460 for(external = ast->first; external; external = external.next)
3462 curExternal = external;
3463 if(external.type == functionExternal)
3465 ProcessFunction(external.function);
3467 else if(external.type == declarationExternal)
3469 if(external.declaration)
3470 ProcessDeclaration(external.declaration);
3472 else if(external.type == classExternal)
3474 ClassDefinition _class = external._class;
3475 if(_class.definitions)
3478 Class regClass = _class.symbol.registered;
3480 // Process all functions
3481 for(def = _class.definitions->first; def; def = def.next)
3483 if(def.type == functionClassDef)
3485 curExternal = def.function.declarator.symbol.pointerExternal;
3486 ProcessFunction((FunctionDefinition)def.function);
3488 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3490 ProcessInstantiation(def.decl.inst);
3492 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3494 MemberInit defProperty;
3496 // Add this to the context
3499 string = CopyString("this");
3500 type = MkClassType(regClass.fullName);
3502 globalContext.symbols.Add((BTNode)thisSymbol);
3504 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3506 //thisClass = regClass;
3507 ProcessMemberInitData(defProperty); //, regClass, &id);
3511 //globalContext.symbols.Delete((BTNode)thisSymbol);
3512 globalContext.symbols.Remove((BTNode)thisSymbol);
3513 FreeSymbol(thisSymbol);
3515 else if(def.type == propertyClassDef && def.propertyDef)
3517 PropertyDef prop = def.propertyDef;
3519 // Add this to the context
3522 string = CopyString("this");
3523 type = MkClassType(regClass.fullName);
3525 globalContext.symbols.Add((BTNode)thisSymbol);
3527 //thisClass = regClass;
3530 curExternal = prop.symbol.externalSet;
3531 ProcessStatement(prop.setStmt);
3535 curExternal = prop.symbol.externalGet;
3536 ProcessStatement(prop.getStmt);
3540 curExternal = prop.symbol.externalIsSet;
3541 ProcessStatement(prop.issetStmt);
3546 //globalContext.symbols.Delete((BTNode)thisSymbol);
3547 globalContext.symbols.Remove((BTNode)thisSymbol);
3548 FreeSymbol(thisSymbol);
3550 else if(def.type == classPropertyClassDef && def.propertyDef)
3552 PropertyDef prop = def.propertyDef;
3554 //thisClass = regClass;
3557 curExternal = prop.symbol.externalSet;
3558 ProcessStatement(prop.setStmt);
3562 curExternal = prop.symbol.externalGet;
3563 ProcessStatement(prop.getStmt);
3567 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3569 PropertyWatch propertyWatch = def.propertyWatch;
3571 // Add this to the context
3574 string = CopyString("this");
3575 type = MkClassType(regClass.fullName);
3577 globalContext.symbols.Add((BTNode)thisSymbol);
3579 //thisClass = regClass;
3580 if(propertyWatch.compound)
3584 string = CopyString("this");
3585 type = MkClassType(regClass.fullName);
3587 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3589 ProcessStatement(propertyWatch.compound);
3591 // thisClass = null;
3593 //globalContext.symbols.Delete((BTNode)thisSymbol);
3594 globalContext.symbols.Remove((BTNode)thisSymbol);
3595 FreeSymbol(thisSymbol);