3 #define YYLTYPE Location
6 extern External curExternal;
7 static Statement curCompound;
9 static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
12 Expression memberExp = *memberExpPtr;
13 if(memberExp && memberExp.type == ExpressionType::memberExp &&
14 memberExp.member.exp && (memberExp.member.exp.type == bracketsExp || memberExp.member.exp.type == extensionExpressionExp))
16 Expression bracketExp = memberExp.member.exp;
17 Expression idExp = bracketExp.list->last;
19 if(idExp && idExp.type == identifierExp)
21 Expression newExp = null;
22 Expression exp = *expPtr;
24 // opExp ( memberExp ( bracketsExp ( identifierExp ) ) )
25 // bracketsExp ( opExp ( memberExp ( identifierExp ) ) )
28 newExp = CopyExpression(exp);
31 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
33 memberExp.member.exp = idExp;
35 exp.type = bracketsExp;
36 exp.list = bracketExp.list;
37 bracketExp.list = null;
39 exp.list->Remove(idExp);
40 exp.list->Add(newExp);
41 FreeExpression(bracketExp);
43 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
46 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
47 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
49 Expression newExp = null;
50 Expression exp = *expPtr;
53 newExp = CopyExpression(exp);
54 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
56 exp.type = bracketsExp;
57 exp.list = memberExp.list;
58 memberExp.list = null;
60 exp.list->Remove(exp.list->last);
61 exp.list->Add(newExp);
62 FreeExpression(memberExp);
64 *expPtr = newExp; //FixRefExp(newExp);
68 static Expression FixRefExp(Expression exp)
72 _FixRefExp(&exp, &exp.op.exp1);
73 _FixRefExp(&exp, &exp.op.exp2);
75 else if(exp.type == indexExp)
76 _FixRefExp(&exp, &exp.index.exp);
77 else if(exp.type == memberExp)
78 _FixRefExp(&exp, &exp.member.exp);
82 static Expression FixReference(Expression e, bool wantReference)
84 if(e.expType && e.type != constantExp)
86 Type type = e.expType;
87 bool isPointer = false;
89 if(type.kind == TypePointer && type.type && type.type.kind == classType)
96 if(type.kind == classType) // || type.kind == TypeInt)
98 Class _class = type._class ? type._class.registered : null;
99 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
100 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
101 if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
102 (_class.type == systemClass && _class.base &&
103 strcmp(_class.fullName, "uintptr") &&
104 strcmp(_class.fullName, "intptr") &&
105 strcmp(_class.fullName, "uintsize") &&
106 strcmp(_class.fullName, "intsize"))))
108 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
109 if(wantReference != (e.byReference || isPointer))
114 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
118 exp.byReference = wantReference;
119 exp = exp.list->last;
124 else if(exp.type == castExp)
126 exp.byReference = wantReference;
129 else if(exp.type == conditionExp)
131 if(exp.cond.exp->last)
132 FixReference(exp.cond.exp->last, wantReference);
133 FixReference(exp.cond.elseExp, wantReference);
138 if(wantReference != (exp.byReference || isPointer))
140 Expression newExp { };
145 if(exp.destType) exp.destType.refCount++;
146 if(exp.expType) exp.expType.refCount++;
150 exp.op.exp2 = newExp;
156 e.byReference = wantReference;
157 exp.byReference = wantReference;
170 static Expression GetInnerExp(Expression exp)
173 while(e && (e.type == bracketsExp || e.type == castExp))
175 if(e.type == bracketsExp)
176 e = e.list ? e.list->last : null;
177 else if(e.type == castExp)
183 Expression GetNonBracketsExp(Expression exp)
186 while(e && e.type == bracketsExp)
187 e = e.list ? e.list->last : null;
191 static bool FixMember(Expression exp)
193 bool byReference = false;
196 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
198 if(exp.list->count > 1)
200 exp = exp.list->last;
202 else if(exp.type == castExp)
209 FixReference(exp, true);
211 byReference = exp.byReference;
218 static void ProcessExpression(Expression exp)
220 Location oldyylloc = yylloc;
222 char debugExpString[1024] = "";
223 PrintExpression(exp, debugExpString);
233 if(exp.expType && exp.expType.kind == methodType)
235 Class _class = exp.expType.methodClass;
236 Method method = exp.expType.method;
237 if(method.type == virtualMethod)
242 OldList * specs = MkList();
243 strcpy(name, "__ecereVMethodID_");
244 FullClassNameCat(name, method._class.fullName, false);
246 strcat(name, method.name);
248 DeclareMethod(curExternal, method, name);
250 // Cast function to its type
251 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
252 if(!method.dataType.staticMethod)
254 Declarator funcDecl = GetFuncDecl(decl);
256 if(!funcDecl.function.parameters)
257 funcDecl.function.parameters = MkList();
259 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
260 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
262 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
263 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
266 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
267 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
270 typeName = MkTypeName(specs, decl);
274 char className[1024];
275 // Need the class itself here...
276 strcpy(className, "__ecereClass_");
277 FullClassNameCat(className, _class.fullName, true);
280 _class.symbol = FindClass(_class.fullName);
281 DeclareClass(curExternal, _class.symbol, className);
284 FreeIdentifier(exp.identifier);
285 exp.type = bracketsExp;
286 exp.list = MkListOne(MkExpCast(typeName,
287 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
288 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
294 strcpy(name, "__ecereMethod_");
295 FullClassNameCat(name, method._class.fullName, false);
297 strcat(name, method.name);
299 delete exp.identifier.string;
300 FreeSpecifier(exp.identifier._class);
302 exp.identifier._class = null;
303 exp.identifier.string = CopyString(name);
304 DeclareMethod(curExternal, method, name);
308 if(exp.usage & USAGE_MEMBER)
309 FixReference(exp, true);
322 OldList * args = MkList();
324 if(exp.type == renewExp || exp.type == renew0Exp)
325 ListAdd(args, exp._renew.exp);
327 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
331 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); DeclareFunctionUtil(curExternal, "eSystem_New"); break;
332 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); DeclareFunctionUtil(curExternal, "eSystem_New0"); break;
333 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); DeclareFunctionUtil(curExternal, "eSystem_Renew"); break;
334 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); DeclareFunctionUtil(curExternal, "eSystem_Renew0"); break;
336 exp.call.arguments = args;
339 ProcessExpression(exp);
344 Expression exp1 = exp.op.exp1;
345 Expression exp2 = exp.op.exp2;
349 // Assignment Operators
352 exp.op.exp2.usage.usageGet = true;
364 exp.op.exp2.usage.usageGet = true;
373 if(exp.op.exp1 && exp.op.exp2)
375 exp.op.exp1.usage.usageGet = true;
376 exp.op.exp2.usage.usageGet = true;
380 exp.op.exp2.usage.usageRef = true;
389 exp.op.exp1.usage.usageGet = true;
394 exp.op.exp2.usage.usageGet = true;
397 // Binary only operators
413 exp.op.exp1.usage.usageGet = true;
415 exp.op.exp2.usage.usageGet = true;
419 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
420 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
421 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
422 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
424 Expression memberExp;
425 Expression parentExp = null; // Where to take memberExp out from
426 bool isIndexedContainerAssignment = false;
428 // TOCHECK: See note below for this if
429 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
431 // Extra bit of code to access deep properties...
432 Expression testExp, topExp = null;
433 Expression lastExp = exp.op.exp1, parentExp = null;
434 Property lastProperty = null;
437 char setName[1024], getName[1024];
438 testExp = exp.op.exp1.member.exp;
441 // Is further fixing needed to address if statement above in the same way?
444 if(testExp.type == castExp)
445 testExp = testExp.cast.exp;
446 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
447 testExp = testExp.list->last;
448 else if(testExp.type == ExpressionType::memberExp)
455 if(testExp.member.memberType == propertyMember ||
456 testExp.member.memberType == reverseConversionMember)
458 Type type = testExp.member.exp.expType;
461 if(type.kind == classType)
463 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
464 Class convertTo = null;
465 if(testExp.member.memberType == reverseConversionMember)
468 _class = FindClass(testExp.member.member.string).registered;
469 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
470 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
474 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
476 if(lastProperty && lastProperty.Get && lastProperty.Set)
478 DeclareProperty(curExternal, lastProperty, setName, getName);
479 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
480 propertyClass = convertTo ? _class :
481 ((((Symbol)lastProperty.symbol).type &&
482 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
483 // TODO: Handle this kind of things with bit classes?
484 if(propertyClass && propertyClass.type == structClass)
489 else if(propertyClass && propertyClass.type == bitClass)
501 testExp = testExp.member.exp;
505 if(propertyClass.type == structClass)
509 char className[1024];
512 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
513 tempExp = QMkExpId(className);
514 tempExp.expType = MkClassType(propertyClass.fullName);
516 parentExp.member.exp = tempExp;
518 value = MkExpBrackets(MkList());
520 copy = CopyExpression(topExp);
521 copy.usage.usageGet = true;
522 copy.usage.usageDeepGet = true;
524 ListAdd(value.list, copy);
525 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
526 ListAdd(value.list, CopyExpression(tempExp));
527 value.expType = tempExp.expType;
528 tempExp.expType.refCount++;
530 // Go on as usual with these new values:
531 exp.op.exp1 = topExp;
538 else if(propertyClass.type == bitClass)
542 char className[1024];
545 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
546 tempExp = QMkExpId(className);
547 tempExp.expType = MkClassType(propertyClass.fullName);
549 parentExp.member.exp = tempExp;
551 value = MkExpBrackets(MkList());
553 copy = CopyExpression(topExp);
554 copy.usage.usageGet = true;
555 copy.usage.usageDeepGet = true;
557 ListAdd(value.list, copy);
558 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
559 ListAdd(value.list, CopyExpression(tempExp));
560 value.expType = tempExp.expType;
561 value.expType.refCount++;
563 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
565 // Go on as usual with these new values:
566 exp.op.exp1 = topExp;
576 memberExp = exp.op.exp1;
578 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
579 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
581 parentExp = memberExp;
582 if(memberExp.type == extensionCompoundExp)
583 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
585 memberExp = memberExp.list->last;
588 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
589 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
590 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
592 Class c = memberExp.index.exp.expType._class.registered;
593 if(strcmp((c.templateClass ? c.templateClass : c).name, "Array"))
595 exp.op.exp2 = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2)));
596 exp.op.exp2 = MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(exp.op.exp2)))));
597 isIndexedContainerAssignment = true;
600 ProcessExpression(memberExp);
602 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
603 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
605 parentExp = memberExp;
606 if(memberExp.type == extensionCompoundExp)
607 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
609 memberExp = memberExp.list->last;
612 if(memberExp && memberExp.type == extensionCompoundExp)
614 parentExp = memberExp;
615 if(memberExp.type == extensionCompoundExp)
617 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
618 if(stmt && stmt.type != expressionStmt) stmt = null;
619 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
622 stmt.expressions->Remove(memberExp);
623 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
624 exp.type = bracketsExp;
625 exp.list = MkListOne(parentExp);
626 ProcessExpression(exp);
631 memberExp = memberExp.list->last;
635 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
637 if(memberExp && memberExp.type == ExpressionType::memberExp && memberExp.member.member)
639 Type type = memberExp.member.exp.expType;
642 // Check if it's an instance
643 if(type.kind == classType || type.kind == subClassType)
645 // TODO: SOMETHING WRONG HERE...
646 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
648 if(memberExp == exp1)
652 if(parentExp.type == extensionCompoundExp)
653 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
655 parentExp.list->Remove(memberExp);
658 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
660 BitMember bitMember =
661 (BitMember)eClass_FindDataMember(_class,
662 memberExp.member.member.string, privateModule, null, null);
663 char mask[32], shift[10];
664 OldList * specs = MkList();
665 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
666 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
667 TypeName type = MkTypeName(specs, decl);
669 if(bitMember.mask > MAXDWORD)
670 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
672 sprintf(mask, FORMAT64HEX, bitMember.mask);
673 sprintf(shift, "%d", bitMember.pos);
675 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
676 exp.op.exp1 = memberExp.member.exp;
678 // TESTING THIS FOR: argb.color.r = 1;
679 //ProcessExpression(memberExp.member.exp);
681 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
682 if(exp.op.op == XOR_ASSIGN)
684 exp.op.exp2 = MkExpOp(MkExpBrackets(
685 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
689 exp.op.exp2 = MkExpOp(
690 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
691 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
692 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
693 MkListOne(MkExpCast(type, MkExpBrackets(MkListOne(exp.op.exp2))))), LEFT_OP, MkExpConstant(shift)))));
696 memberExp.member.exp = null;
697 FreeExpression(memberExp);
699 // TESTING THIS FOR: argb.color.r = 1;
700 ProcessExpression(exp);
703 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
706 else if(memberExp.member.memberType != dataMember)
709 Class convertTo = null;
710 ClassProperty classProperty = null;
712 if(memberExp.member.memberType == reverseConversionMember)
715 _class = FindClass(memberExp.member.member.string).registered;
716 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
717 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
720 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
722 if(memberExp.member.memberType == classPropertyMember)
723 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
725 exp.tempCount = memberExp.member.exp.tempCount;
729 // Only process Gets here, Set is processed in opExp's '='
730 if(classProperty.Set)
732 Identifier id = memberExp.member.member;
733 Expression classExp = memberExp.member.exp;
734 Expression value = exp.op.exp2;
736 memberExp.member.exp = null;
737 memberExp.member.member = null;
740 FreeExpContents(memberExp);
744 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
745 exp.call.arguments = MkList();
746 ListAdd(exp.call.arguments, classExp);
748 char * s = QMkString(id.string);
749 ListAdd(exp.call.arguments, MkExpString(s));
752 if(value.expType.isPointerType)
753 value = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("intptr")), null), value);
754 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
758 ProcessExpression(exp);
764 if((!convertTo && prop.Set) || (convertTo && prop.Get))
766 Expression value = exp.op.exp2;
767 char setName[1024], getName[1024];
768 char * setToUse = convertTo ? getName : setName;
769 char * getToUse = convertTo ? setName : getName;
770 bool needAddress = false;
771 int operator = exp.op.op;
774 case MUL_ASSIGN: operator = '*'; break;
775 case DIV_ASSIGN: operator = '/'; break;
776 case MOD_ASSIGN: operator = '%'; break;
777 case SUB_ASSIGN: operator = '-'; break;
778 case ADD_ASSIGN: operator = '+'; break;
779 case LEFT_ASSIGN: operator = LEFT_OP; break;
780 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
781 case AND_ASSIGN: operator = '&'; break;
782 case OR_ASSIGN: operator = '|'; break;
783 case XOR_ASSIGN: operator = '^'; break;
788 if(operator == INC_OP)
789 value = MkExpOp(CopyExpression(memberExp),
790 '+', MkExpConstant("1"));
791 else if(operator == DEC_OP)
792 value = MkExpOp(CopyExpression(memberExp),
793 '-', MkExpConstant("1"));
796 value = MkExpOp(CopyExpression(memberExp),
800 value.expType = memberExp.expType;
801 memberExp.expType.refCount++;
802 value.usage.usageArg = true;
806 // Dont free exp2, we're using it
811 value.usage.usageArg = true;
813 DeclareProperty(curExternal, prop, setName, getName);
815 if(memberExp.member.exp)
816 ProcessExpression(memberExp.member.exp);
818 // If get flag present
819 if(exp.usage.usageGet &&
820 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
822 OldList * list = MkList();
825 Context context = PushContext();
828 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
829 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
831 curContext = context;
832 exp.type = extensionCompoundExp;
833 exp.compound = MkCompoundStmt(
834 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
835 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
836 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
843 ListAdd(args, value);
844 ListAdd(args, QMkExpId(ecereTemp));
845 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
849 ListAdd(args, QMkExpId(ecereTemp));
850 ListAdd(args, value);
851 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
857 ListAdd(args, QMkExpId(ecereTemp));
859 args->Insert(null, QMkExpId(ecereTemp));
860 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
862 exp.compound.compound.context = context;
864 curContext = context.parent;
868 Expression newExp = exp;
870 if(parentExp && parentExp.type == extensionCompoundExp)
872 newExp = Expression { };
873 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
874 FreeType(exp.expType);
875 FreeType(exp.destType);
878 parentExp.type = dummyExp;
879 parentExp.expType = null;
880 parentExp.destType = null;
883 newExp.type = callExp;
884 newExp.call.exp = QMkExpId(setToUse);
885 newExp.call.arguments = MkList();
888 ListAdd(newExp.call.arguments, value);
889 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
893 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
894 ListAdd(newExp.call.arguments, value);
899 // Take it out from there
900 memberExp.member.exp = null;
902 // Don't use the temporaries used by the left side...
905 value.tempCount = exp.tempCount;
906 ProcessExpression(value);
908 FixReference(isIndexedContainerAssignment ? GetInnerExp(value) : value, true);
911 FreeExpression(memberExp);
915 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
918 memberExp.member.memberType = dataMember;
921 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
926 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
927 if(method && method.type == virtualMethod && type.kind != subClassType)
929 Expression value = exp.op.exp2;
930 // Don't use the temporaries used by the left side...
931 value.tempCount = exp.tempCount;
932 ProcessExpression(value);
934 if(memberExp.member.exp)
935 ProcessExpression(memberExp.member.exp);
937 if(exp.usage.usageGet)
939 OldList * list = MkList();
944 ListAdd(args, memberExp.member.exp);
946 char * string = QMkString(memberExp.member.member.string);
947 ListAdd(args, MkExpString(string));
950 ListAdd(args, value);
951 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
952 ListAdd(list, CopyExpression(value));
953 exp.type = bracketsExp;
960 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
961 exp.call.arguments = MkList();
962 ListAdd(exp.call.arguments, memberExp.member.exp);
964 char * string = QMkString(memberExp.member.member.string);
965 ListAdd(exp.call.arguments, MkExpString(string));
968 ListAdd(exp.call.arguments, value);
971 memberExp.member.exp = null;
974 FreeExpression(memberExp);
978 else if(memberExp.member.memberType == dataMember)
980 //if(exp.usage & USAGE_GET);
981 //FixReference(value, true);
982 if(FixMember(memberExp.member.exp))
984 // TESTING THIS HERE:
985 ProcessExpression(memberExp);
987 memberExp.type = pointerExp;
994 else if(exp.op.op == _INCREF)
996 Expression object = exp.op.exp2;
998 FreeExpContents(exp);
999 FreeType(exp.expType);
1000 FreeType(exp.destType);
1002 exp.destType = null;
1004 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
1006 else if(exp.op.op == DELETE)
1008 Expression object = exp.op.exp2;
1009 OldList * args = MkList();
1011 exp.type = bracketsExp;
1012 exp.list = MkList();
1014 object.usage.usageDelete = true;
1016 ProcessExpression(object);
1018 ListAdd(args, object);
1020 // TOFIX: Same time as when we fix for = 0
1022 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
1023 exp.expType._class.registered.type == normalClass &&
1024 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
1026 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
1027 ProcessExpressionType(decRefExp);
1028 ListAdd(exp.list, decRefExp);
1030 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
1033 char className[1024];
1034 OldList * list = MkList();
1036 strcpy(className, "__ecereClass_");
1037 FullClassNameCat(className, exp.expType._class.string, true);
1039 DeclareClass(exp.expType._class, className);
1041 // Call the non virtual destructor
1042 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1043 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1045 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1047 MkExpBrackets(MkListOne(MkExpCondition(
1048 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1049 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1054 OldList * list = MkList();
1058 Statement compound = MkCompoundStmt(MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("__ecerePtrToDelete"))),
1059 MkInitializerAssignment(MkExpBrackets(args)))))), MkListOne(stmt = MkExpressionStmt(list)));
1060 Expression stmtExp = MkExpExtensionCompound(compound);
1061 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1063 char className[1024];
1065 if(_class.templateClass) _class = _class.templateClass;
1066 strcpy(className, "__ecereClass_");
1067 FullClassNameCat(className, _class.fullName, false /*true*/);
1070 _class.symbol = FindClass(_class.fullName);
1071 DeclareClass(curExternal, _class.symbol, className);
1073 // Call the non virtual destructor
1077 QMkExpId(className),
1078 MkIdentifier("Destructor")
1083 QMkExpId(className),
1084 MkIdentifier("Destructor")
1086 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), MkExpIdentifier(MkIdentifier("__ecerePtrToDelete")) /*CopyExpression(args->first)*/))
1093 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), MkListOne(MkExpIdentifier(MkIdentifier("__ecerePtrToDelete"))) /*args*/));
1094 DeclareFunctionUtil(curExternal, "eSystem_Delete");
1095 o = CopyExpression(object);
1096 ProcessExpressionType(o);
1097 o.usage.usageGet = true;
1098 ProcessExpression(o);
1106 //MkExpBrackets(list)
1115 else if(exp.expType && exp.expType.kind == templateType)
1117 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1120 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1122 OldList * qualifiers = MkList();
1123 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1125 typeName = MkTypeName(qualifiers, declarator);
1127 ProcessExpressionType(classExp);
1128 ProcessExpression(classExp);
1129 args->Insert(null, CopyExpression(classExp));
1130 DeclareMethod(curExternal, eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1131 ListAdd(exp.list, MkExpCall(
1132 MkExpBrackets(MkListOne(MkExpCast(typeName,
1133 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1134 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1135 //ProcessExpression(exp.list->last);
1140 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1141 DeclareFunctionUtil(curExternal, "eSystem_Delete");
1144 //ProcessExpression(object);
1146 ListAdd(exp.list, MkExpOp(CopyExpression(GetInnerExp(object)), '=', MkExpConstant("0")));
1150 // TESTING THIS HERE...
1151 ProcessExpression(exp);
1154 if(exp.type == opExp)
1156 // Handle assigment of template structures
1157 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1158 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1160 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1163 // memcpy((byte *)array + (count * dataTypeClass.size), (dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1165 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1166 OldList * args = MkList();
1167 Expression derefExp = exp.op.exp1;
1170 ProcessExpressionType(classExp);
1171 ProcessExpression(classExp);
1173 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1175 if(exp.op.exp1.type == indexExp)
1177 Expression indexExp = derefExp.index.exp;
1178 OldList * indexExpIndex = derefExp.index.index;
1180 derefExp.index.index = null;
1181 derefExp.index.exp = null;
1182 FreeExpression(derefExp);
1185 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1186 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1190 Expression indexExp = derefExp.op.exp2;
1191 derefExp.op.exp2 = null;
1192 FreeExpression(derefExp);
1193 derefExp = indexExp;
1196 args->Add(derefExp);
1197 ProcessExpressionType(args->last);
1198 ProcessExpression(args->last);
1200 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1201 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1202 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2))))),
1203 MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1205 thisClass = curExternal.function ? curExternal.function._class : null;
1209 string = CopyString("this");
1210 type = MkClassType(thisClass.fullName);
1212 globalContext.symbols.Add((BTNode)thisSymbol);
1214 ProcessExpressionType(args->last);
1215 ProcessExpression(args->last);
1218 ProcessExpressionType(args->last);
1219 ProcessExpression(args->last);
1221 DeclareFunctionUtil(curExternal, "memcpy");
1223 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1224 exp.type = bracketsExp;
1226 //globalContext.symbols.Delete((BTNode)thisSymbol);
1227 globalContext.symbols.Remove((BTNode)thisSymbol);
1228 FreeSymbol(thisSymbol);
1234 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1235 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1237 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1240 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1243 ProcessExpressionType(classExp);
1244 ProcessExpression(classExp);
1246 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1248 exp.type = bracketsExp;
1249 exp.list = MkListOne(
1251 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1253 // ((class.type == structClass) ?
1254 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1257 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), CopyExpression(exp.op.exp2)))))),
1259 // ((class.size == 1) ?
1260 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1262 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1263 CopyExpression(exp.op.exp2)))))),
1265 // ((class.size == 2) ?
1266 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1267 // *((uint16 *)array)
1268 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1269 CopyExpression(exp.op.exp2)))))),
1271 // ((class.size == 4) ?
1272 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1273 // *((uint32 *)array)
1274 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1275 CopyExpression(exp.op.exp2)))))),
1277 // *((uint64 *)array)
1278 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1279 exp.op.exp2))))))))))))))))))));
1281 // Add this to the context
1282 thisClass = curExternal.function ? curExternal.function._class : null;
1286 string = CopyString("this");
1287 type = MkClassType(thisClass.fullName);
1289 globalContext.symbols.Add((BTNode)thisSymbol);
1291 ProcessExpressionType(exp.list->first);
1292 ProcessExpression(exp.list->first);
1294 //globalContext.symbols.Delete((BTNode)thisSymbol);
1295 globalContext.symbols.Remove((BTNode)thisSymbol);
1296 FreeSymbol(thisSymbol);
1307 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1308 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1309 ProcessExpression(exp.op.exp1);
1312 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1313 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1314 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1315 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*/))
1316 FixReference(exp.op.exp1, false);
1317 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1321 // Don't use the temporaries used by the left side...
1323 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1324 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1325 ProcessExpression(exp.op.exp2);
1326 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1330 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1331 (exp.op.exp2.expType._class.registered.type != normalClass &&
1332 exp.op.exp2.expType._class.registered.type != structClass &&
1333 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1335 // TESTING THIS TEMPLATE TYPE CHECK HERE
1336 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1338 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1339 //FixReference(exp.op.exp2, false);
1342 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1345 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)
1347 // Preserve prev, next
1348 Expression next = exp.next, prev = exp.prev;
1349 Expression derefExp = exp.op.exp2;
1350 Expression refExp = exp.op.exp2.op.exp2;
1352 derefExp.op.exp2 = null;
1353 FreeExpression(derefExp);
1354 FreeType(exp.expType);
1355 FreeType(exp.destType);
1365 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)
1367 Expression exp2 = exp.op.exp2;
1368 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1371 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1374 ProcessExpressionType(classExp);
1375 ProcessExpression(classExp);
1377 exp.type = bracketsExp;
1378 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1379 MkExpOp(null, '&', exp2)), '+',
1380 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1381 MkListOne((e = MkExpMember(classExp, MkIdentifier("typeSize")))))));
1383 // Add this to the context
1384 thisClass = curExternal.function ? curExternal.function._class : null;
1388 string = CopyString("this");
1389 type = MkClassType(thisClass.fullName);
1391 //globalContext.symbols.Add((BTNode)thisSymbol);
1393 ProcessExpressionType(e);
1394 ProcessExpression(e);
1396 //globalContext.symbols.Remove((BTNode)thisSymbol);
1397 //FreeSymbol(thisSymbol);
1406 FreeExpression(exp1);
1408 FreeExpression(exp2);
1413 case extensionExpressionExp:
1418 for(e = exp.list->first; e; e = e.next)
1422 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1424 e.tempCount = exp.tempCount;
1425 ProcessExpression(e);
1427 exp.byReference = e.byReference;
1428 exp.tempCount = e.tempCount;
1432 exp.expType = e.expType;
1441 /*bool isBuiltin = exp && exp.index.exp &&
1442 (exp.index.exp.type == ExpressionType::arrayExp ||
1443 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1445 Expression checkedExp = exp.index.exp;
1446 bool isBuiltin = false;
1448 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1450 if(checkedExp.type == extensionCompoundExp)
1455 else if(checkedExp.type == bracketsExp)
1456 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1458 checkedExp = checkedExp.cast.exp;
1461 exp.index.exp.tempCount = exp.tempCount;
1463 exp.index.exp.usage.usageGet = true;
1464 ProcessExpression(exp.index.exp);
1466 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1467 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1469 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1472 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1475 ProcessExpressionType(classExp);
1476 ProcessExpression(classExp);
1478 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1480 exp.type = bracketsExp;
1481 exp.list = MkListOne(
1483 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1485 // ((class.type == structClass) ?
1486 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1487 // ((byte *)array) + (i) * class.size
1488 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(MkExpOp(
1489 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1490 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp)))))))),
1492 // ((class.size == 1) ?
1493 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1494 // ((byte *)array)[i]
1495 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1496 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1498 // ((class.size == 2) ?
1499 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1500 // ((uint16 *)array)[i]
1501 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1502 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1504 // ((class.size == 4) ?
1505 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1506 // ((uint32 *)array)[i]
1507 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1508 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1510 // ((uint64 *)array)[i]
1511 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1512 exp.index.exp))), exp.index.index)))))))))))))))));
1514 // Add this to the context
1515 thisClass = curExternal.function ? curExternal.function._class : null;
1519 string = CopyString("this");
1520 type = MkClassType(thisClass.fullName);
1522 globalContext.symbols.Add((BTNode)thisSymbol);
1524 ProcessExpressionType(exp.list->first);
1525 ProcessExpression(exp.list->first);
1527 //globalContext.symbols.Delete((BTNode)thisSymbol);
1528 globalContext.symbols.Remove((BTNode)thisSymbol);
1529 FreeSymbol(thisSymbol);
1537 for(e = exp.index.index->first; e; e = e.next)
1540 e.usage.usageGet = true;
1541 ProcessExpression(e);
1543 // Ignore temps in the index for now...
1544 exp.tempCount = exp.index.exp.tempCount;
1546 if(exp.index.exp.expType)
1548 Type source = exp.index.exp.expType;
1549 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1550 eClass_IsDerived(source._class.registered, containerClass))
1552 Class _class = source._class.registered;
1553 bool isArray = false;
1554 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1555 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1557 if(isArray && _class.templateArgs)
1559 OldList * specs = MkList();
1560 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1561 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1562 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1563 ProcessExpressionType(exp.index.exp);
1564 ProcessExpression(exp);
1566 else if(isBuiltin && _class.templateArgs)
1568 OldList * specs = MkList();
1569 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1570 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1571 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1572 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1573 ProcessExpressionType(exp.index.exp);
1574 ProcessExpression(exp);
1576 else if(_class.templateArgs)
1578 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1580 char iteratorType[1024];
1581 OldList * declarations = MkList();
1582 OldList * statements = MkList();
1583 OldList * args = MkList();
1584 OldList * instMembers = MkList();
1586 Context context = PushContext();
1588 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1590 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1592 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1593 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1595 ListAdd(args, MkExpBrackets(exp.index.index));
1596 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1598 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1599 MkIdentifier("Index")), args))));
1601 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1602 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1604 exp.type = bracketsExp;
1605 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1606 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1607 expExt.compound.compound.context = context;
1608 PopContext(context);
1609 expExt.usage = exp.usage;
1610 ProcessExpressionType(exp.list->first);
1611 ProcessExpressionInstPass(exp.list->first);
1612 ProcessExpression(exp.list->first);
1621 bool typedObject = false;
1622 Type ellipsisDestType = null;
1623 bool usedEllipsis = false;
1625 if(exp.call.arguments)
1627 for(e = exp.call.arguments->first; e; e = e.next)
1629 e.usage.usageGet = true;
1630 e.usage.usageArg = true;
1631 e.tempCount = Max(e.tempCount, exp.tempCount);
1632 ProcessExpression(e);
1633 exp.tempCount = Max(exp.tempCount, e.tempCount);
1636 exp.call.exp.usage.usageGet = true;
1637 exp.call.exp.usage.usageCall = true;
1638 exp.call.exp.tempCount = exp.tempCount;
1640 ProcessExpression(exp.call.exp);
1642 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1644 bool nullMemberExp = false;
1645 Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1647 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1648 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1649 Method method = exp.call.exp.expType.method;
1650 if(method.type == virtualMethod)
1656 OldList * specs = MkList();
1657 strcpy(name, "__ecereVMethodID_");
1658 FullClassNameCat(name, method._class.fullName, false);
1660 strcat(name, method.name);
1662 DeclareMethod(curExternal, method, name);
1665 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1666 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1667 // Cast function to its type
1669 Context context = SetupTemplatesContext(method._class);
1671 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1673 FinishTemplatesContext(context);
1676 if(method.dataType && !method.dataType.staticMethod)
1678 Declarator funcDecl = GetFuncDecl(decl);
1680 if(!funcDecl.function.parameters)
1681 funcDecl.function.parameters = MkList();
1683 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1684 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1686 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1688 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1689 FreeTypeName(firstParam);
1693 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1698 param = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
1699 param.qualifiers->Insert(null, MkSpecifier(CONST));
1700 funcDecl.function.parameters->Insert(null, param);
1701 // Testing this for any_object::
1702 if(!method.dataType.extraParam)
1704 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1705 DeclareStruct(curExternal, "ecere::com::Class", false, true);
1710 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1711 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1715 typeName = MkTypeName(specs, decl);
1717 // Added !exp.call.exp.expType.methodClass
1718 if(memberExp && memberExp.member.exp.expType)
1720 Type type = memberExp.member.exp.expType;
1722 if(type.kind == classType && type._class && type._class.registered)
1724 Class regClass = type._class.registered;
1725 ClassType classType = regClass.type;
1726 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1727 argClass = regClass;
1729 else if(type.kind == subClassType)
1731 argClass = FindClass("ecere::com::Class").registered;
1733 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1735 argClass = FindClass("char *").registered;
1737 else if(type.kind == pointerType)
1739 argClass = eSystem_FindClass(privateModule, "uintptr");
1740 FreeType(memberExp.member.exp.expType);
1741 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1742 memberExp.member.exp.byReference = true;
1746 char string[1024] = "";
1748 PrintTypeNoConst(type, string, false, true);
1749 classSym = FindClass(string);
1750 if(classSym) argClass = classSym.registered;
1754 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1760 Type type = memberExp ? memberExp.member.exp.expType : null;
1761 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1762 char className[1024];
1764 if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
1765 strcpy(className, "class");
1769 // TESTING: Moved this here...
1770 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1775 // TODO: Unhandled case here, what should happen?
1778 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1779 if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
1780 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1781 cl = cl.templateClass;
1783 // Need the class itself here...
1784 strcpy(className, "__ecereClass_");
1785 FullClassNameCat(className, cl.fullName, true);
1788 cl.symbol = FindClass(cl.fullName);
1790 DeclareClass(curExternal, cl.symbol, className);
1793 if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
1795 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1796 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1797 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1799 else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
1800 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1803 FreeExpression(exp.call.exp);
1804 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1805 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1806 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1810 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1811 // as opposed to the File class vTbl one
1813 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1815 Context context = PushContext();
1817 c = MkExpExtensionCompound(MkCompoundStmt(
1818 MkListOne(MkDeclaration(
1819 (specs = MkListOne(MkSpecifierName("Instance"))),
1820 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1821 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
1822 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1823 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1824 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1825 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
1827 specs->Insert(null, MkSpecifier(CONST));
1829 c.compound.compound.context = context;
1830 PopContext(context);
1831 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1832 MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1839 strcpy(name, "__ecereMethod_");
1840 FullClassNameCat(name, method._class.fullName, false);
1842 strcat(name, method.name);
1845 FreeExpression(exp.call.exp);
1846 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1847 DeclareMethod(curExternal, method, name);
1848 if(memberExp && memberExp.expType && method.dataType)
1850 exp.call.exp.expType = method.dataType;
1851 method.dataType.refCount++;
1854 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1856 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1858 if(!exp.call.arguments)
1859 exp.call.arguments = MkList();
1861 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1863 if(memberExp.member.exp.expType.kind != classType ||
1864 memberExp.member.exp.expType._class.registered.type == enumClass ||
1865 memberExp.member.exp.expType._class.registered.type == unitClass)
1867 char typeString[1024] = "";
1868 if(memberExp.member.exp.expType.kind != classType)
1869 PrintType(memberExp.member.exp.expType, typeString, false, true);
1871 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1874 // memberExp.member.exp.expType.kind = classType;
1875 // memberExp.member.exp.expType._class = FindClass(typeString);
1877 FreeType(memberExp.member.exp.expType);
1878 memberExp.member.exp.expType = Type
1881 _class = FindClass(typeString);
1885 // Default to an int instead
1886 if(!memberExp.member.exp.expType._class)
1888 // TODO: Shouldn't get here...
1889 memberExp.member.exp.expType.kind = TypeInt;
1894 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1896 bool changeReference = false;
1897 bool stillAddReferenceOp = false;
1898 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1899 Type expType = memberExp.member.exp.expType;
1900 Class c = expType.kind == classType && expType._class ? expType._class.registered : null;
1902 // Patched so that class isn't considered SYSTEM...
1903 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1904 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1905 changeReference = true;
1906 if(!expType.classObjectType && ( ( (expType.kind != pointerType && (!c || c.type == structClass) ) ) || method.dataType.byReference) ) // ADDED THIS FOR OnGetDataFromString
1908 if(c && (c.type == normalClass || c.type == noHeadClass))
1909 stillAddReferenceOp = true;
1910 changeReference = true;
1912 if(typedObject && expType.classObjectType && expType.byReference != method.dataType.byReference)
1913 changeReference = true;
1916 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1917 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1919 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1920 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1922 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1924 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1925 memberExp.member.exp.op.exp2 = null;
1927 else if(!memberExp.member.exp.byReference || stillAddReferenceOp)
1929 // TESTING THIS... REUSE THIS CODE?
1930 Expression checkedExp = memberExp.member.exp;
1931 Expression parentExp = null;
1933 bool disconnected = false;
1934 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1936 parentExp = checkedExp;
1938 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1940 checkedExp = checkedExp.list->last;
1941 // Dissociate from memberExp which will get freed
1942 if(checkedExp && !disconnected)
1944 parentExp.list->Remove(checkedExp);
1945 disconnected = true;
1948 else if(checkedExp.type == castExp)
1950 checkedExp = checkedExp.cast.exp;
1951 // Dissociate from memberExp which will get freed
1952 if(checkedExp && !disconnected)
1954 checkedExp.cast.exp = null;
1955 disconnected = true;
1960 nullMemberExp = true;
1962 if(typedObject && !expType.classObjectType && !stillAddReferenceOp)
1963 newExp = checkedExp;
1966 newExp = MkExpOp(null, '&', checkedExp);
1967 newExp.byReference = true;
1969 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1971 parentExp.list->Remove(checkedExp);
1972 parentExp.list->Add(newExp);
1974 else if(parentExp && parentExp.type == castExp)
1976 parentExp.cast.exp = newExp;
1977 // Add a dereference level here
1978 if(newExp.expType && newExp.expType.classObjectType)
1979 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1981 if(typedObject && !expType.classObjectType)
1983 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
1984 FreeType((parentExp ? parentExp : newExp).expType);
1985 FreeType((parentExp ? parentExp : newExp).destType);
1986 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
1987 (parentExp ? parentExp : newExp).destType = destType;
1988 if(checkedExp.expType) checkedExp.expType.refCount++;
1990 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1994 exp.call.arguments->Insert(null, memberExp.member.exp);
1995 nullMemberExp = true;
2000 exp.call.arguments->Insert(null, memberExp.member.exp);
2001 nullMemberExp = true;
2005 char className[1024];
2006 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
2007 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
2008 Class cl = argClass ? argClass : regClass;
2011 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
2012 strcpy(className, "class");
2015 // Need the class itself here...
2016 strcpy(className, "__ecereClass_");
2017 FullClassNameCat(className, cl.fullName, true);
2020 cl.symbol = FindClass(cl.fullName);
2021 DeclareClass(curExternal, cl.symbol, className);
2026 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
2028 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2030 Context context = PushContext();
2033 c = MkExpExtensionCompound(MkCompoundStmt(
2034 MkListOne(MkDeclaration(
2035 (specs = MkListOne(MkSpecifierName("Instance"))),
2036 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2037 MkInitializerAssignment(memberExpMemberExp))))),
2038 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2039 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2040 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2041 MkExpIdentifier(MkIdentifier(className))))))));
2042 c.compound.compound.context = context;
2043 PopContext(context);
2046 specs->Insert(null, MkSpecifier(CONST));
2048 exp.call.arguments->Insert(null, c);
2050 memberExpMemberExp = null; // We used this
2053 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
2057 if(memberExpMemberExp)
2058 FreeExpression(memberExpMemberExp);
2062 exp.call.arguments->Insert(null, memberExp.member.exp);
2063 nullMemberExp = true;
2067 /*else if(method->dataType)
2073 memberExp.member.exp = null;
2074 FreeExpression(memberExp);
2078 if(exp.call.arguments)
2080 for(e = exp.call.arguments->first; e; e = e.next)
2082 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
2083 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
2084 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
2085 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
2087 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
2088 ellipsisDestType = destType;
2091 Type type = e.expType;
2092 Class _class = null;
2093 //Type destType = e.destType;
2095 if(type.kind == classType && type._class && type._class.registered)
2097 _class = type._class.registered;
2099 else if(type.kind == subClassType)
2101 _class = FindClass("ecere::com::Class").registered;
2103 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
2105 _class = FindClass("char *").registered;
2107 else if(type.kind == pointerType)
2109 _class = eSystem_FindClass(privateModule, "uintptr");
2110 FreeType(e.expType);
2111 e.expType = ProcessTypeString("uintptr", false);
2112 // Assume null pointers means 'no object' rather than an object holding a null pointer
2113 e.byReference = true;
2117 char string[1024] = "";
2119 PrintTypeNoConst(type, string, false, true);
2120 classSym = FindClass(string);
2121 if(classSym) _class = classSym.registered;
2122 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2125 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...
2126 (!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))) ||
2127 destType.byReference)))
2129 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2130 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2131 // TESTING WITHOUT THE ABOVE NOW!
2133 Expression checkedExp;
2134 Expression parentExp;
2139 while(checkedExp && (((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp))
2141 parentExp = checkedExp;
2142 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2144 if(checkedExp.type == extensionCompoundExp)
2146 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2149 checkedExp = checkedExp.list->last;
2151 else if(checkedExp.type == castExp)
2152 checkedExp = checkedExp.cast.exp;
2155 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2158 Expression newExp = e.op.exp2;
2159 exp.call.arguments->Insert(e.prev, newExp);
2160 exp.call.arguments->Remove(e);
2165 newExp = checkedExp.op.exp2;
2166 checkedExp.op.exp2 = null;
2167 FreeExpContents(checkedExp);
2169 if(e.expType && e.expType.passAsTemplate)
2172 ComputeTypeSize(e.expType);
2173 sprintf(size, "%d", e.expType.size); // BOOTSTRAP FIX
2174 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2175 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2176 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2179 if(parentExp.type == callExp)
2181 exp.call.arguments->Insert(e.prev, newExp);
2182 exp.call.arguments->Remove(e);
2185 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2187 parentExp.list->Remove(checkedExp);
2188 parentExp.list->Add(newExp);
2190 else if(parentExp.type == castExp)
2192 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2193 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2195 FreeTypeName(parentExp.cast.typeName);
2196 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2198 parentExp.cast.exp = newExp;
2200 else if(parentExp.type == extensionCompoundExp)
2202 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2203 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2205 e.byReference = true;
2207 FreeType(checkedExp.expType);
2208 FreeType(checkedExp.destType);
2211 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2213 Expression checkedExp;
2214 Expression parentExp;
2218 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2220 e.type == identifierExp ||
2221 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2222 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2223 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2226 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2228 Context context = PushContext();
2230 OldList * specs = MkList();
2231 char typeString[1024];
2232 Expression newExp { };
2234 typeString[0] = '\0';
2237 // TOCHECK: Should this read e.destType ???
2239 if(exp.destType) exp.destType.refCount++;
2240 // if(exp.expType) exp.expType.refCount++;
2243 newExp.expType = null;
2245 PrintTypeNoConst(e.expType, typeString, false, true);
2246 decl = SpecDeclFromString(typeString, specs, null);
2247 newExp.destType = ProcessType(specs, decl);
2249 curContext = context;
2250 e.type = extensionCompoundExp;
2252 // We need a current compound for this
2256 OldList * stmts = MkList();
2257 sprintf(name, "__internalValue%03X", internalValueCounter++);
2258 if(!curCompound.compound.declarations)
2259 curCompound.compound.declarations = MkList();
2260 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2261 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2262 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2263 e.compound = MkCompoundStmt(null, stmts);
2266 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2270 e.compound = MkCompoundStmt(
2271 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2272 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2275 e.compound.compound.context = context;
2276 PopContext(context);
2277 curContext = context.parent;
2281 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2284 while(checkedExp && (((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp))
2286 parentExp = checkedExp;
2287 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2289 if(checkedExp.type == extensionCompoundExp)
2291 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2294 checkedExp = checkedExp.list->last;
2296 else if(checkedExp.type == castExp)
2297 checkedExp = checkedExp.cast.exp;
2301 newExp = MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)), (i = MkExpOp(null, '&', checkedExp)));
2302 i.byReference = true;
2303 newExp.byReference = true;
2305 if(parentExp.type == callExp)
2307 exp.call.arguments->Insert(e.prev, newExp);
2308 exp.call.arguments->Remove(e);
2311 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2313 parentExp.list->Remove(checkedExp);
2314 parentExp.list->Add(newExp);
2316 else if(parentExp.type == castExp)
2317 parentExp.cast.exp = newExp;
2318 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2320 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2321 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2327 if(destType.classObjectType == ClassObjectType::typedObject)
2329 char className[1024];
2330 // Need the class itself here...
2331 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2332 _class = eSystem_FindClass(privateModule, "String");
2333 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2335 if(!strcmp(_class.name, "class"))
2337 // Already inside a typed_object function, pass the class through
2338 strcpy(className, "class");
2342 strcpy(className, "__ecereClass_");
2343 FullClassNameCat(className, _class.fullName, true);
2346 _class.symbol = FindClass(_class.fullName);
2348 DeclareClass(curExternal, _class.symbol, className);
2351 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2353 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2355 Context context = PushContext();
2357 // Work around to avoid repeating the BuiltInContainer just to get the type
2358 // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
2359 if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
2360 e.list && e.list->first &&
2361 ((Expression)e.list->first).type == castExp &&
2362 ((Expression)e.list->first).cast.exp &&
2363 ((Expression)e.list->first).cast.exp.type == opExp &&
2364 ((Expression)e.list->first).cast.exp.op.op == '&' &&
2365 ((Expression)e.list->first).cast.exp.op.exp2 &&
2366 ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
2368 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2373 c = MkExpExtensionCompound(MkCompoundStmt(
2374 MkListOne(MkDeclaration(
2375 (specs = MkListOne(MkSpecifierName("Instance"))),
2376 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2377 MkInitializerAssignment(CopyExpression(e)))))),
2378 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2379 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2380 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2381 MkExpIdentifier(MkIdentifier(className))))))));
2382 c.compound.compound.context = context;
2383 PopContext(context);
2386 specs->Insert(null, MkSpecifier(CONST));
2388 exp.call.arguments->Insert(e.prev, c);
2392 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2398 //char debugString[4096] = "";
2399 //PrintExpression(e, debugString);
2401 // If expression type is a simple class, make it an address
2402 FixReference(e, !destType || !destType.declaredWithStruct);
2405 if(ellipsisDestType)
2408 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2409 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2411 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2419 bool changeToPtr = false;
2420 bool noHead = false;
2421 Type type = exp.member.exp ? exp.member.exp.expType : null;
2422 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2423 if(exp.member.member) exp.member.member._class = null;
2425 if(type && type.kind == templateType)
2427 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2428 if(baseType) type = baseType;
2430 if(type && exp.member.member && !type.directClassAccess)
2432 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2433 Property prop = null;
2434 ClassProperty classProperty = null;
2435 Method method = null;
2436 Class convertTo = null;
2437 DataMember member = null;
2438 DataMember subMemberStack[256];
2439 int subMemberStackPos = 0;
2440 bool thisPtr = exp.member.thisPtr;
2441 if(type.kind == subClassType && exp.member.exp.type == classExp)
2442 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2444 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2448 // DANGER: Buffer overflow
2449 char string[2048] = "";
2451 PrintTypeNoConst(type, string, false, true);
2452 classSym = FindClass(string);
2453 _class = classSym ? classSym.registered : null;
2456 if(_class && exp.member.memberType == dataMember)
2458 if(!thisPtr && !exp.member.member.classSym)
2459 member = eClass_FindDataMember(_class, exp.member.member.string, null, subMemberStack, &subMemberStackPos);
2461 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2463 else if(_class && exp.member.memberType == propertyMember)
2465 if(!thisPtr && !exp.member.member.classSym)
2466 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2468 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2469 if(prop && (exp.usage.usageRef ||
2470 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2471 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2473 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2476 exp.member.memberType = dataMember;
2481 if(exp.usage.usageRef)
2482 Compiler_Error($"cannot obtain address of property\n");
2484 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2485 else if(exp.usage.usageDelete)
2486 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2490 else if(_class && exp.member.memberType == methodMember)
2493 method = eClass_FindMethod(_class, exp.member.member.string, null);
2495 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2497 else if(_class && exp.member.memberType == reverseConversionMember)
2500 _class = FindClass(exp.member.member.string).registered;
2501 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2502 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2504 else if(_class && exp.member.memberType == classPropertyMember)
2506 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2510 // Only process Gets here, Set is processed in opExp's '='
2511 if(exp.usage.usageGet)
2515 char getName[1024], setName[1024];
2516 Expression ptr = exp.member.exp;
2517 Class propertyClass;
2518 char * nameToUse = convertTo ? setName : getName;
2520 FreeIdentifier(exp.member.member);
2522 // Process this here since it won't be processed at the end...
2523 exp.member.exp.usage.usageGet = true;
2524 ProcessExpression(exp.member.exp);
2525 // TEST: exp.tempCount = exp.member.exp.tempCount;
2527 DeclareProperty(curExternal, prop, setName, getName);
2528 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2529 propertyClass = convertTo ? _class :
2530 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2532 if(propertyClass && propertyClass.type == bitClass)
2534 // Bit classes shouldn't have properties except for conversions...
2535 OldList * args = MkList();
2536 if(exp.usage.usageDeepGet)
2538 char className[1024];
2540 Declarator declarator;
2541 OldList * specs = MkList(), * decls = MkList();
2544 // Make a declaration in the closest compound statement
2545 // (Do not reuse (since using address for function calls)...)
2546 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2548 SpecDeclFromString(propertyClass.dataTypeString, specs,
2549 MkDeclaratorIdentifier(MkIdentifier(className)));
2551 ListAdd(decls, MkInitDeclarator(declarator, null));
2553 decl = MkDeclaration(specs, decls);
2554 if(!curCompound.compound.declarations)
2555 curCompound.compound.declarations = MkList();
2556 curCompound.compound.declarations->Insert(null, decl);
2558 tempExp = QMkExpId(className);
2559 tempExp.expType = MkClassType(propertyClass.fullName);
2561 exp.op.exp1 = tempExp;
2562 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2569 exp.call.exp = QMkExpId(nameToUse);
2570 exp.call.arguments = args;
2572 ListAdd(args, FixReference(ptr, true));
2574 else if(propertyClass && propertyClass.type == unitClass)
2576 OldList * args = MkList();
2577 ListAdd(args, FixReference(ptr, true));
2579 exp.call.exp = QMkExpId(nameToUse);
2580 exp.call.arguments = args;
2582 else if(propertyClass && propertyClass.type == structClass)
2584 OldList * args = MkList();
2585 char className[1024];
2587 OldList * specs = MkList(), * decls = MkList();
2590 // Make a declaration in the closest compound statement
2591 // (Do not reuse (since using address for function calls)...)
2594 FullClassNameCat(className, propertyClass.fullName, false); //true);
2595 DeclareStruct(curExternal, propertyClass.fullName, false, true);
2597 //ListAdd(specs, MkSpecifierName(className));
2598 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2600 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2602 ListAdd(decls, MkInitDeclarator(
2603 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2605 decl = MkDeclaration(specs, decls);
2608 if(!curCompound.compound.declarations)
2609 curCompound.compound.declarations = MkList();
2610 curCompound.compound.declarations->Insert(null, decl);
2613 tempExp = QMkExpId(className);
2614 tempExp.expType = MkClassType(propertyClass.fullName);
2618 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2619 ListAdd(args, FixReference(ptr, true));
2623 ListAdd(args, FixReference(ptr, true));
2624 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2627 if(exp.usage.usageDeepGet)
2630 exp.call.exp = QMkExpId(nameToUse);
2631 exp.call.arguments = args;
2633 FreeExpression(tempExp);
2637 exp.type = bracketsExp;
2638 exp.list = MkList();
2639 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2640 if(exp.usage.usageMember)
2642 ListAdd(exp.list, FixReference(tempExp, true));
2643 exp.byReference = true;
2646 ListAdd(exp.list, tempExp);
2652 exp.call.exp = QMkExpId(nameToUse);
2653 exp.call.arguments = MkList();
2654 ListAdd(exp.call.arguments, FixReference(ptr, true));
2657 else if(prop.conversion)
2659 void * prev = exp.prev, * next = exp.next;
2660 *exp = *exp.member.exp;
2666 else if(classProperty)
2668 // Only process Gets here, Set is processed in opExp's '='
2669 if(exp.usage.usageGet)
2671 if(classProperty.Get)
2673 Identifier id = exp.member.member;
2674 Expression classExp = exp.member.exp;
2675 OldList * args = MkList();
2681 char typeString[2048];
2682 OldList * specs = MkList();
2685 PrintType(exp.expType, typeString, false, false);
2686 decl = SpecDeclFromString(typeString, specs, null);
2687 exp.cast.typeName = MkTypeName(specs, decl);
2690 exp.cast.typeName = QMkType("uint64", null);
2691 exp.cast.exp = MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty")), args);
2692 if(exp.expType.isPointerType)
2693 exp.cast.exp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), exp.cast.exp);
2695 ListAdd(args, classExp);
2697 char * s = QMkString(id.string);
2698 ListAdd(args, MkExpString(s));
2703 ProcessExpression(exp);
2710 // Get the function address if it's not called
2711 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2715 FreeIdentifier(exp.member.member);
2717 // Process this here since it won't be processed at the end...
2718 exp.member.exp.usage.usageGet = true;
2719 ProcessExpression(exp.member.exp);
2720 // TEST: exp.tempCount = exp.member.exp.tempCount;
2722 if(method.type == virtualMethod)
2724 strcpy(name, "__ecereVMethodID_");
2725 FullClassNameCat(name, method._class.fullName, false);
2727 strcat(name, method.name);
2728 exp.type = indexExp;
2729 if(memberClassSpecifier)
2731 char className[1024];
2732 // Need the class itself here...
2733 strcpy(className, "__ecereClass_");
2734 FullClassNameCat(className, _class.fullName, true);
2737 _class.symbol = FindClass(_class.fullName);
2738 DeclareClass(curExternal, _class.symbol, className);
2740 FreeExpression(exp.member.exp);
2741 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2745 if(exp.thisPtr && _class.type != normalClass)
2747 FreeExpression(exp.member.exp);
2748 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2751 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2753 exp.index.index = MkListOne(QMkExpId(name));
2754 DeclareMethod(curExternal, method, name);
2758 FreeExpression(exp.member.exp);
2759 exp.type = identifierExp;
2760 strcpy(name, "__ecereMethod_");
2761 FullClassNameCat(name, method._class.fullName, false);
2763 strcat(name, method.name);
2764 exp.identifier = MkIdentifier(name);
2765 DeclareMethod(curExternal, method, name);
2771 if(subMemberStackPos)
2774 DataMember parentMember = null;
2775 String s, prefix = null;
2776 for(i = 0; i < subMemberStackPos; i++)
2778 DataMember curMember = subMemberStack[i];
2781 for(m = parentMember ? parentMember.members.first : _class.membersAndProperties.first; m; m = m.next)
2783 if(m && !m.isProperty && (m.type == unionMember || m.type == structMember) && !m.name)
2794 prefix = PrintString(prefix, ".__anon", anonID);
2798 prefix = PrintString("__anon", anonID);
2799 parentMember = curMember;
2802 s = exp.member.member.string;
2803 exp.member.member.string = PrintString(prefix, ".", s);
2807 // Process this here since it won't be processed at the end...
2808 if(exp.usage.usageGet)
2810 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2812 ProcessExpression(exp.member.exp);
2813 // TEST: exp.tempCount = exp.member.exp.tempCount;
2815 if(type.kind == classType && type._class && type._class.registered)
2816 DeclareStruct(curExternal, type._class.registered.fullName, false, true);
2818 // TESTING THIS NOHEAD STUFF...
2819 if(_class.type == noHeadClass)
2823 else if(_class.type == structClass)
2827 else if(_class.type == bitClass)
2829 OldList * list = MkList();
2830 char mask[32], shift[10];
2831 OldList * specs = MkList();
2832 BitMember bitMember = (BitMember) member;
2833 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2834 TypeName type = MkTypeName(specs, decl);
2835 if(bitMember.mask > MAXDWORD)
2836 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2838 sprintf(mask, FORMAT64HEX, bitMember.mask);
2839 sprintf(shift, "%d", bitMember.pos);
2841 FreeIdentifier(exp.member.member);
2843 // ((type) ((color & mask) >> bitPos))
2844 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2845 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2846 MkExpConstant(shift))))));
2848 exp.type = bracketsExp;
2851 else if(_class.type == unitClass)
2856 // If it's a this pointer, replace by precomputed shortcut
2857 if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2859 char pointerName[1024];
2861 strcpy(pointerName, "__ecerePointer_");
2862 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2863 if(exp.member.exp.identifier)
2864 FreeIdentifier(exp.member.exp.identifier);
2865 exp.member.exp.identifier = MkIdentifier(pointerName);
2867 // Otherwise, access the data the hard way
2870 Expression bytePtr, e;
2871 Expression checkedExp;
2872 char structName[1024];
2873 char className[1024];
2874 strcpy(className, "__ecereClass_");
2875 FullClassNameCat(className, member._class.fullName, true);
2877 // classExp = QMkExpId(className);
2879 if(!member._class.symbol)
2880 member._class.symbol = FindClass(member._class.fullName);
2882 DeclareClass(curExternal, member._class.symbol, className);
2883 DeclareStruct(curExternal, member._class.fullName, false, true);
2886 FullClassNameCat(structName, member._class.fullName, false);
2888 checkedExp = exp.member.exp;
2889 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2890 checkedExp.type == castExp)
2892 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2893 checkedExp = checkedExp.list->last;
2894 else if(checkedExp.type == castExp)
2895 checkedExp = checkedExp.cast.exp;
2898 if(checkedExp.type != identifierExp &&
2899 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2900 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2902 char ecereTemp[100];
2904 Context context = PushContext();
2905 if(exp.member.exp.tempCount > exp.tempCount)
2906 exp.tempCount = exp.member.exp.tempCount;
2909 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2910 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2911 curContext = context;
2912 compound = MkCompoundStmt(
2913 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2914 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2915 MkInitializerAssignment(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), QBrackets(exp.member.exp))))))), null);
2916 if(member._class.fixed)
2918 Class c = member._class.templateClass ? member._class.templateClass : member._class;
2923 if(c.offset == c.base.structSize)
2925 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
2926 ProcessExpressionType(se);
2927 se.isConstant = false;
2932 sprintf(string, "%d", c.offset);
2933 se = MkExpConstant(string);
2935 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', se));
2938 e = QMkExpId(ecereTemp);
2942 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2943 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2946 compound.compound.context = context;
2947 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2948 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2949 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2951 exp.member.exp = MkExpExtensionCompound(compound);
2953 PopContext(context);
2954 curContext = context.parent;
2958 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2959 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2961 e = QBrackets(QMkExpCond(exp.member.exp,
2962 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2963 MkExpConstant("0")));
2967 if(member._class.fixed)
2969 Class c = member._class.templateClass ? member._class.templateClass : member._class;
2974 if(c.offset == c.base.structSize)
2976 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
2977 ProcessExpressionType(se);
2978 se.isConstant = false;
2983 sprintf(string, "%d", c.offset);
2984 se = MkExpConstant(string);
2987 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', se)));
2993 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2995 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2996 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2999 exp.type = pointerExp;
3004 // Take Out Any Class Specifier (Should have been used by now)
3005 FreeSpecifier(memberClassSpecifier);
3007 // Just moved this at the end... How is it?
3008 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
3010 exp.member.exp.usage.usageGet = true;
3011 exp.member.exp.usage.usageMember = true;
3012 exp.member.exp.tempCount = exp.tempCount;
3013 ProcessExpression(exp.member.exp);
3014 exp.tempCount = exp.member.exp.tempCount;
3015 if((changeToPtr && exp.member.exp.byReference) || noHead)
3016 exp.type = pointerExp;
3020 case extensionCompoundExp:
3022 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
3024 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
3026 ProcessStatement(exp.compound);
3028 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
3029 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
3034 exp.member.exp.usage.usageGet = true;
3035 ProcessExpression(exp.member.exp);
3040 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
3041 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
3043 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
3046 Expression classExp;
3048 FreeTypeName(exp.typeName);
3050 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
3052 ProcessExpressionType(classExp);
3053 ProcessExpression(classExp);
3055 exp.type = bracketsExp;
3056 exp.list = MkListOne(MkExpMember(classExp, MkIdentifier("typeSize")));
3058 ProcessExpressionType(exp);
3059 ProcessExpression(exp);
3068 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
3069 ProcessExpression(exp.cast.exp);
3071 if(exp.cast.exp.byReference)
3072 exp.byReference = exp.cast.exp.byReference;
3073 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
3074 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
3075 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
3076 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
3077 exp.byReference = true;
3079 // Moved this to 1.5...
3080 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
3086 if(exp.usage.usageGet)
3087 exp.cond.cond.usage.usageGet = true;
3088 ProcessExpression(exp.cond.cond);
3089 for(e = exp.cond.exp->first; e; e = e.next)
3091 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
3092 ProcessExpression(e);
3094 if(exp.usage.usageGet)
3095 exp.cond.elseExp.usage.usageGet = true;
3096 ProcessExpression(exp.cond.elseExp);
3101 // Need the class itself here...
3102 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
3104 Specifier spec = exp._classExp.specifiers->first;
3105 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
3108 FreeList(exp._classExp.specifiers, FreeSpecifier);
3109 if(exp._classExp.decl)
3110 FreeDeclarator(exp._classExp.decl);
3112 exp.type = memberExp; //pointerExp;
3113 exp.member.exp = argExp;
3114 exp.member.member = MkIdentifier("dataTypeClass");
3115 exp.member.memberType = dataMember;
3117 ProcessExpressionType(argExp);
3118 ProcessExpressionType(exp);
3119 ProcessExpression(exp);
3124 char className[1024];
3125 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
3126 Symbol classSym = FindClass(string);
3128 strcpy(className, "__ecereClass_");
3129 FullClassNameCat(className, string, true); // TODO: Verify this
3131 DeclareClass(curExternal, classSym, className);
3134 FreeList(exp._classExp.specifiers, FreeSpecifier);
3135 if(exp._classExp.decl)
3136 FreeDeclarator(exp._classExp.decl);
3138 exp.type = identifierExp;
3139 exp.identifier = MkIdentifier(className);
3145 ProcessExpression(exp.vaArg.exp);
3148 case extensionInitializerExp:
3150 ProcessInitializer(exp.initializer.initializer);
3156 if(exp.needTemplateCast != 2 && (exp.needTemplateCast == 1 || (exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate))))
3158 Expression nbExp = GetNonBracketsExp(exp);
3159 Expression inner = GetInnerExp(nbExp);
3161 if((!exp.expType || exp.expType.kind != templateType || nbExp.type != castExp) && !exp.usage.usageRef &&
3162 (!exp.destType || (!exp.destType.truth && (exp.destType.kind != templateType || (exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType))))) &&
3163 (exp.usage.usageDelete || exp.usage.usageGet || exp.usage.usageArg) &&
3164 (!exp.destType || (!exp.destType.passAsTemplate && exp.expType && (exp.expType.kind != pointerType || (exp.destType.kind == pointerType || exp.destType.kind == intPtrType)) && ((exp.destType.kind != pointerType && exp.destType.kind != intPtrType) || exp.expType.kind == pointerType))) &&
3165 !inner.needCast && inner.type != opExp)
3167 Expression e = MoveExpContents(exp);
3169 OldList * specs = MkList();
3170 char typeString[1024];
3171 bool castingToDest = false;
3172 bool pointerCastExp = false;
3174 typeString[0] = '\0';
3176 e.needTemplateCast = 2;
3177 inner.needTemplateCast = 2;
3178 nbExp.needTemplateCast = 2;
3179 if(exp.usage.usageDelete)
3180 strcpy(typeString, "void *");
3183 if(exp.expType.kind == templateType && exp.expType.templateParameter && exp.expType.templateParameter.dataTypeString)
3184 strcpy(typeString, exp.expType.templateParameter.dataTypeString);
3186 PrintType(exp.expType, typeString, false, false);
3189 decl = SpecDeclFromString(typeString, specs, null);
3191 if(specs && specs->first && ((Specifier)specs->first).type == templateTypeSpecifier &&
3192 exp.destType && !exp.destType.passAsTemplate && exp.destType.kind == templateType && exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType) && !exp.usage.usageArg)
3194 if(decl) FreeDeclarator(decl);
3195 FreeList(specs, FreeSpecifier);
3196 if(exp.destType.templateParameter.dataTypeString)
3199 strcpy(typeString, exp.destType.templateParameter.dataTypeString);
3200 decl = SpecDeclFromString(typeString, specs, null);
3204 specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
3205 decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
3208 castingToDest = true;
3211 e.destType = exp.destType;
3213 exp.destType.refCount++;
3215 exp.type = bracketsExp;
3218 Specifier spec = specs ? specs->first : null;
3219 TemplateParameter tp = (spec && spec.type == templateTypeSpecifier) ? spec.templateParameter : null;
3220 Type type = castingToDest ? exp.destType : exp.expType;
3221 bool specsDeclPointer = (spec.type == nameSpecifier && strcmp(spec.name, "uint64")) ||
3222 (decl && decl.type == pointerDeclarator) ||
3223 (tp && tp.dataType &&
3224 ( (tp.dataType.decl && tp.dataType.decl.type == pointerDeclarator) ||
3225 (tp.dataType.specifiers && ((Specifier)tp.dataType.specifiers->first).type == nameSpecifier && strcmp(((Specifier)tp.dataType.specifiers->first).name, "uint64")) ) );
3226 pointerCastExp = type ? ((type.kind == templateType && specsDeclPointer) || type.isPointerType) : specsDeclPointer;
3231 e = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(e)));
3232 e.needTemplateCast = 2;
3234 exp.list = MkListOne(MkExpCast(MkTypeName(specs, decl), MkExpBrackets(MkListOne(e))));
3235 if(exp.destType && pointerCastExp == (exp.destType.passAsTemplate ||
3236 (!exp.destType.isPointerType || (exp.destType.kind == templateType && (!exp.destType.templateParameter || (!exp.destType.templateParameter.dataType && !exp.destType.templateParameter.dataTypeString))))))
3237 exp.list = MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), decl), MkExpBrackets(exp.list)));
3238 exp.needTemplateCast = 2;
3244 static void ProcessInitializer(Initializer init)
3248 case expInitializer:
3251 init.exp.usage.usageGet = true;
3252 ProcessExpression(init.exp);
3253 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
3254 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
3256 FixReference(init.exp, true);
3258 else if(init.exp.destType && init.exp.destType.kind == classType)
3259 FixReference(init.exp, false);
3262 case listInitializer:
3267 for(i = init.list->first; i; i = i.next)
3268 ProcessInitializer(i);
3275 static void ProcessDeclaration(Declaration decl)
3279 case initDeclaration:
3281 if(decl.declarators)
3285 for(d = decl.declarators->first; d; d = d.next)
3288 ProcessInitializer(d.initializer);
3296 static void ProcessStatement(Statement stmt)
3301 ProcessStatement(stmt.labeled.stmt);
3304 if(stmt.caseStmt.exp)
3306 stmt.caseStmt.exp.usage.usageGet = true;
3308 // This expression should be constant...
3309 ProcessExpression(stmt.caseStmt.exp);
3311 if(stmt.caseStmt.stmt)
3312 ProcessStatement(stmt.caseStmt.stmt);
3316 if(stmt.compound.context)
3320 Statement prevCompound = curCompound;
3321 Context prevContext = curContext;
3323 if(!stmt.compound.isSwitch)
3326 curContext = stmt.compound.context;
3329 if(stmt.compound.declarations)
3331 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3332 ProcessDeclaration(decl);
3334 if(stmt.compound.statements)
3336 for(s = stmt.compound.statements->first; s; s = s.next)
3337 ProcessStatement(s);
3339 curContext = prevContext;
3340 curCompound = prevCompound;
3344 case expressionStmt:
3347 if(stmt.expressions)
3349 for(exp = stmt.expressions->first; exp; exp = exp.next)
3351 ProcessExpression(exp);
3362 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3363 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3365 ProcessExpression(exp);
3368 if(stmt.ifStmt.stmt)
3369 ProcessStatement(stmt.ifStmt.stmt);
3370 if(stmt.ifStmt.elseStmt)
3371 ProcessStatement(stmt.ifStmt.elseStmt);
3377 if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
3379 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3380 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3382 ProcessExpression(exp);
3385 ProcessStatement(stmt.switchStmt.stmt);
3391 if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
3393 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3394 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3396 ProcessExpression(exp);
3399 ProcessStatement(stmt.whileStmt.stmt);
3405 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3407 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3408 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3410 ProcessExpression(exp);
3413 if(stmt.doWhile.stmt)
3414 ProcessStatement(stmt.doWhile.stmt);
3420 if(stmt.forStmt.init)
3421 ProcessStatement(stmt.forStmt.init);
3423 if(stmt.forStmt.check)
3425 if(stmt.forStmt.check.expressions)
3427 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3429 ProcessStatement(stmt.forStmt.check);
3431 if(stmt.forStmt.increment)
3433 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3435 ProcessExpression(exp);
3438 if(stmt.forStmt.stmt)
3439 ProcessStatement(stmt.forStmt.stmt);
3451 if(stmt.expressions)
3453 ((Expression)stmt.expressions->last).usage.usageGet = true;
3454 for(exp = stmt.expressions->first; exp; exp = exp.next)
3456 ProcessExpression(exp);
3457 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3458 if(!exp.next && exp.destType && exp.destType.byReference)
3459 FixReference(exp, true);
3464 case badDeclarationStmt:
3466 ProcessDeclaration(stmt.decl);
3472 if(stmt.asmStmt.inputFields)
3474 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3475 if(field.expression)
3476 ProcessExpression(field.expression);
3478 if(stmt.asmStmt.outputFields)
3480 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3481 if(field.expression)
3482 ProcessExpression(field.expression);
3484 if(stmt.asmStmt.clobberedFields)
3486 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3487 if(field.expression)
3488 ProcessExpression(field.expression);
3495 static void ProcessFunction(FunctionDefinition function)
3498 ProcessStatement(function.body);
3501 static void ProcessMemberInitData(MemberInit member)
3503 if(member.initializer)
3504 ProcessInitializer(member.initializer);
3507 static void ProcessInstantiation(Instantiation inst)
3511 MembersInit members;
3512 for(members = inst.members->first; members; members = members.next)
3514 if(members.type == dataMembersInit)
3516 if(members.dataMembers)
3519 for(member = members.dataMembers->first; member; member = member.next)
3520 ProcessMemberInitData(member);
3523 else if(members.type == methodMembersInit)
3525 ProcessFunction((FunctionDefinition)members.function);
3531 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3532 public void ProcessMemberAccess()
3535 for(external = ast->first; external; external = external.next)
3537 curExternal = external;
3538 // There shouldn't be any class member access here anyways...
3539 if(external.type == declarationExternal)
3541 if(external.declaration)
3542 ProcessDeclaration(external.declaration);
3546 for(external = ast->first; external; external = external.next)
3548 curExternal = external;
3549 if(external.type == functionExternal)
3551 ProcessFunction(external.function);
3553 else if(external.type == declarationExternal)
3555 if(external.declaration)
3556 ProcessDeclaration(external.declaration);
3558 else if(external.type == classExternal)
3560 ClassDefinition _class = external._class;
3561 if(_class.definitions)
3564 Class regClass = _class.symbol.registered;
3566 // Process all functions
3567 for(def = _class.definitions->first; def; def = def.next)
3569 if(def.type == functionClassDef)
3571 curExternal = def.function.declarator.symbol.pointerExternal;
3572 ProcessFunction((FunctionDefinition)def.function);
3574 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3576 ProcessInstantiation(def.decl.inst);
3578 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3580 MemberInit defProperty;
3582 // Add this to the context
3585 string = CopyString("this");
3586 type = MkClassType(regClass.fullName);
3588 globalContext.symbols.Add((BTNode)thisSymbol);
3590 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3592 //thisClass = regClass;
3593 ProcessMemberInitData(defProperty); //, regClass, &id);
3597 //globalContext.symbols.Delete((BTNode)thisSymbol);
3598 globalContext.symbols.Remove((BTNode)thisSymbol);
3599 FreeSymbol(thisSymbol);
3601 else if(def.type == propertyClassDef && def.propertyDef)
3603 PropertyDef prop = def.propertyDef;
3605 // Add this to the context
3608 string = CopyString("this");
3609 type = MkClassType(regClass.fullName);
3611 globalContext.symbols.Add((BTNode)thisSymbol);
3613 //thisClass = regClass;
3616 curExternal = prop.symbol.externalSet;
3617 ProcessStatement(prop.setStmt);
3621 curExternal = prop.symbol.externalGet;
3622 ProcessStatement(prop.getStmt);
3626 curExternal = prop.symbol.externalIsSet;
3627 ProcessStatement(prop.issetStmt);
3632 //globalContext.symbols.Delete((BTNode)thisSymbol);
3633 globalContext.symbols.Remove((BTNode)thisSymbol);
3634 FreeSymbol(thisSymbol);
3636 else if(def.type == classPropertyClassDef && def.propertyDef)
3638 PropertyDef prop = def.propertyDef;
3640 //thisClass = regClass;
3643 curExternal = prop.symbol.externalSet;
3644 ProcessStatement(prop.setStmt);
3648 curExternal = prop.symbol.externalGet;
3649 ProcessStatement(prop.getStmt);
3653 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3655 PropertyWatch propertyWatch = def.propertyWatch;
3657 // Add this to the context
3660 string = CopyString("this");
3661 type = MkClassType(regClass.fullName);
3663 globalContext.symbols.Add((BTNode)thisSymbol);
3665 //thisClass = regClass;
3666 if(propertyWatch.compound)
3670 string = CopyString("this");
3671 type = MkClassType(regClass.fullName);
3673 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3675 ProcessStatement(propertyWatch.compound);
3677 // thisClass = null;
3679 //globalContext.symbols.Delete((BTNode)thisSymbol);
3680 globalContext.symbols.Remove((BTNode)thisSymbol);
3681 FreeSymbol(thisSymbol);