3 #define YYLTYPE Location
6 extern External curExternal;
7 static Statement curCompound;
9 static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
12 Expression memberExp = *memberExpPtr;
13 if(memberExp && memberExp.type == ExpressionType::memberExp &&
14 memberExp.member.exp && (memberExp.member.exp.type == bracketsExp || memberExp.member.exp.type == extensionExpressionExp))
16 Expression bracketExp = memberExp.member.exp;
17 Expression idExp = bracketExp.list->last;
19 if(idExp && idExp.type == identifierExp)
21 Expression newExp = null;
22 Expression exp = *expPtr;
24 // opExp ( memberExp ( bracketsExp ( identifierExp ) ) )
25 // bracketsExp ( opExp ( memberExp ( identifierExp ) ) )
28 newExp = CopyExpression(exp);
31 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
33 memberExp.member.exp = idExp;
35 exp.type = bracketsExp;
36 exp.list = bracketExp.list;
37 bracketExp.list = null;
39 exp.list->Remove(idExp);
40 exp.list->Add(newExp);
41 FreeExpression(bracketExp);
43 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
46 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
47 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
49 Expression newExp = null;
50 Expression exp = *expPtr;
53 newExp = CopyExpression(exp);
54 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
56 exp.type = bracketsExp;
57 exp.list = memberExp.list;
58 memberExp.list = null;
60 exp.list->Remove(exp.list->last);
61 exp.list->Add(newExp);
62 FreeExpression(memberExp);
64 *expPtr = newExp; //FixRefExp(newExp);
68 static Expression FixRefExp(Expression exp)
72 _FixRefExp(&exp, &exp.op.exp1);
73 _FixRefExp(&exp, &exp.op.exp2);
75 else if(exp.type == indexExp)
76 _FixRefExp(&exp, &exp.index.exp);
77 else if(exp.type == memberExp)
78 _FixRefExp(&exp, &exp.member.exp);
82 static Expression FixReference(Expression e, bool wantReference)
84 if(e.expType && e.type != constantExp)
86 Type type = e.expType;
87 bool isPointer = false;
89 if(type.kind == TypePointer && type.type && type.type.kind == classType)
96 if(type.kind == classType) // || type.kind == TypeInt)
98 Class _class = type._class ? type._class.registered : null;
99 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
100 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
101 if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
102 (_class.type == systemClass && _class.base &&
103 strcmp(_class.fullName, "uintptr") &&
104 strcmp(_class.fullName, "intptr") &&
105 strcmp(_class.fullName, "uintsize") &&
106 strcmp(_class.fullName, "intsize"))))
108 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
109 if(wantReference != (e.byReference || isPointer))
114 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
118 exp.byReference = wantReference;
119 exp = exp.list->last;
124 else if(exp.type == castExp)
126 exp.byReference = wantReference;
129 else if(exp.type == conditionExp)
131 if(exp.cond.exp->last)
132 FixReference(exp.cond.exp->last, wantReference);
133 FixReference(exp.cond.elseExp, wantReference);
138 if(wantReference != (exp.byReference || isPointer))
140 Expression newExp { };
143 if(exp.destType) exp.destType.refCount++;
144 if(exp.expType) exp.expType.refCount++;
148 exp.op.exp2 = newExp;
154 e.byReference = wantReference;
155 exp.byReference = wantReference;
168 static bool FixMember(Expression exp)
170 bool byReference = false;
173 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
175 if(exp.list->count > 1)
177 exp = exp.list->last;
179 else if(exp.type == castExp)
186 FixReference(exp, true);
188 byReference = exp.byReference;
195 static void ProcessExpression(Expression exp)
197 Location oldyylloc = yylloc;
199 char debugExpString[1024] = "";
200 PrintExpression(exp, debugExpString);
210 if(exp.expType && exp.expType.kind == methodType)
212 Class _class = exp.expType.methodClass;
213 Method method = exp.expType.method;
214 if(method.type == virtualMethod)
219 OldList * specs = MkList();
220 strcpy(name, "__ecereVMethodID_");
221 FullClassNameCat(name, method._class.fullName, false);
223 strcat(name, method.name);
225 DeclareMethod(method, name);
227 // Cast function to its type
228 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
229 if(!method.dataType.staticMethod)
231 Declarator funcDecl = GetFuncDecl(decl);
233 if(!funcDecl.function.parameters)
234 funcDecl.function.parameters = MkList();
236 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
237 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
239 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
240 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
243 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
244 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
247 typeName = MkTypeName(specs, decl);
251 char className[1024];
252 // Need the class itself here...
253 strcpy(className, "__ecereClass_");
254 FullClassNameCat(className, _class.fullName, true);
255 MangleClassName(className);
258 _class.symbol = FindClass(_class.fullName);
259 DeclareClass(_class.symbol, className);
261 exp.type = bracketsExp;
262 exp.list = MkListOne(MkExpCast(typeName,
263 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
264 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
270 strcpy(name, "__ecereMethod_");
271 FullClassNameCat(name, method._class.fullName, false);
273 strcat(name, method.name);
275 delete exp.identifier.string;
276 FreeSpecifier(exp.identifier._class);
278 exp.identifier._class = null;
279 exp.identifier.string = CopyString(name);
280 DeclareMethod(method, name);
284 if(exp.usage & USAGE_MEMBER)
285 FixReference(exp, true);
298 OldList * args = MkList();
300 if(exp.type == renewExp || exp.type == renew0Exp)
301 ListAdd(args, exp._renew.exp);
303 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
307 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
308 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
309 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
310 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
312 exp.call.arguments = args;
315 ProcessExpression(exp);
320 Expression exp1 = exp.op.exp1;
321 Expression exp2 = exp.op.exp2;
325 // Assignment Operators
328 exp.op.exp2.usage.usageGet = true;
340 exp.op.exp2.usage.usageGet = true;
349 if(exp.op.exp1 && exp.op.exp2)
351 exp.op.exp1.usage.usageGet = true;
352 exp.op.exp2.usage.usageGet = true;
356 exp.op.exp2.usage.usageRef = true;
365 exp.op.exp1.usage.usageGet = true;
370 exp.op.exp2.usage.usageGet = true;
373 // Binary only operators
389 exp.op.exp1.usage.usageGet = true;
391 exp.op.exp2.usage.usageGet = true;
395 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
396 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
397 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
398 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
400 Expression memberExp;
401 Expression parentExp = null; // Where to take memberExp out from
403 // TOCHECK: See note below for this if
404 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
406 // Extra bit of code to access deep properties...
407 Expression testExp, topExp = null;
408 Expression lastExp = exp.op.exp1, parentExp = null;
409 Property lastProperty = null;
412 char setName[1024], getName[1024];
413 testExp = exp.op.exp1.member.exp;
416 // Is further fixing needed to address if statement above in the same way?
419 if(testExp.type == castExp)
420 testExp = testExp.cast.exp;
421 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
422 testExp = testExp.list->last;
423 else if(testExp.type == ExpressionType::memberExp)
430 if(testExp.member.memberType == propertyMember ||
431 testExp.member.memberType == reverseConversionMember)
433 Type type = testExp.member.exp.expType;
436 if(type.kind == classType)
438 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
439 Class convertTo = null;
440 if(testExp.member.memberType == reverseConversionMember)
443 _class = FindClass(testExp.member.member.string).registered;
444 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
445 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
449 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
451 if(lastProperty && lastProperty.Get && lastProperty.Set)
453 DeclareProperty(lastProperty, setName, getName);
454 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
455 propertyClass = convertTo ? _class :
456 ((((Symbol)lastProperty.symbol).type &&
457 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
458 // TODO: Handle this kind of things with bit classes?
459 if(propertyClass && propertyClass.type == structClass)
464 else if(propertyClass && propertyClass.type == bitClass)
476 testExp = testExp.member.exp;
480 if(propertyClass.type == structClass)
484 char className[1024];
487 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
488 tempExp = QMkExpId(className);
489 tempExp.expType = MkClassType(propertyClass.fullName);
491 parentExp.member.exp = tempExp;
493 value = MkExpBrackets(MkList());
495 copy = CopyExpression(topExp);
496 copy.usage.usageGet = true;
497 copy.usage.usageDeepGet = true;
499 ListAdd(value.list, copy);
500 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
501 ListAdd(value.list, CopyExpression(tempExp));
502 value.expType = tempExp.expType;
503 tempExp.expType.refCount++;
505 // Go on as usual with these new values:
506 exp.op.exp1 = topExp;
513 else if(propertyClass.type == bitClass)
517 char className[1024];
520 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
521 tempExp = QMkExpId(className);
522 tempExp.expType = MkClassType(propertyClass.fullName);
524 parentExp.member.exp = tempExp;
526 value = MkExpBrackets(MkList());
528 copy = CopyExpression(topExp);
529 copy.usage.usageGet = true;
530 copy.usage.usageDeepGet = true;
532 ListAdd(value.list, copy);
533 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
534 ListAdd(value.list, CopyExpression(tempExp));
535 value.expType = tempExp.expType;
536 value.expType.refCount++;
538 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
540 // Go on as usual with these new values:
541 exp.op.exp1 = topExp;
551 memberExp = exp.op.exp1;
553 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
554 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
556 parentExp = memberExp;
557 if(memberExp.type == extensionCompoundExp)
558 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
560 memberExp = memberExp.list->last;
563 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
564 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
565 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
567 ProcessExpression(memberExp);
569 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
570 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
572 parentExp = memberExp;
573 if(memberExp.type == extensionCompoundExp)
574 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
576 memberExp = memberExp.list->last;
579 if(memberExp && memberExp.type == extensionCompoundExp)
581 parentExp = memberExp;
582 if(memberExp.type == extensionCompoundExp)
584 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
585 if(stmt && stmt.type != expressionStmt) stmt = null;
586 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
589 stmt.expressions->Remove(memberExp);
590 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
591 exp.type = bracketsExp;
592 exp.list = MkListOne(parentExp);
593 ProcessExpression(exp);
598 memberExp = memberExp.list->last;
602 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
604 if(memberExp && memberExp.type == ExpressionType::memberExp)
606 Type type = memberExp.member.exp.expType;
609 // Check if it's an instance
610 if(type.kind == classType || type.kind == subClassType)
612 // TODO: SOMETHING WRONG HERE...
613 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
615 if(memberExp == exp1)
619 if(parentExp.type == extensionCompoundExp)
620 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
622 parentExp.list->Remove(memberExp);
625 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
627 BitMember bitMember =
628 (BitMember)eClass_FindDataMember(_class,
629 memberExp.member.member.string, privateModule, null, null);
630 char mask[32], shift[10];
631 OldList * specs = MkList();
632 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
633 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
634 TypeName type = MkTypeName(specs, decl);
636 if(bitMember.mask > MAXDWORD)
637 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
639 sprintf(mask, FORMAT64HEX, bitMember.mask);
640 sprintf(shift, "%d", bitMember.pos);
642 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
643 exp.op.exp1 = memberExp.member.exp;
645 // TESTING THIS FOR: argb.color.r = 1;
646 //ProcessExpression(memberExp.member.exp);
648 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
649 if(exp.op.op == XOR_ASSIGN)
651 exp.op.exp2 = MkExpOp(MkExpBrackets(
652 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
656 exp.op.exp2 = MkExpOp(
657 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
658 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
659 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
660 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift)))));
663 memberExp.member.exp = null;
664 FreeExpression(memberExp);
666 // TESTING THIS FOR: argb.color.r = 1;
667 ProcessExpression(exp);
670 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
673 else if(memberExp.member.memberType != dataMember)
676 Class convertTo = null;
677 ClassProperty classProperty = null;
679 if(memberExp.member.memberType == reverseConversionMember)
682 _class = FindClass(memberExp.member.member.string).registered;
683 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
684 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
687 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
689 if(memberExp.member.memberType == classPropertyMember)
690 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
692 exp.tempCount = memberExp.member.exp.tempCount;
696 // Only process Gets here, Set is processed in opExp's '='
697 if(classProperty.Set)
699 Identifier id = memberExp.member.member;
700 Expression classExp = memberExp.member.exp;
701 Expression value = exp.op.exp2;
703 memberExp.member.exp = null;
704 memberExp.member.member = null;
707 FreeExpContents(memberExp);
711 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
712 exp.call.arguments = MkList();
713 ListAdd(exp.call.arguments, classExp);
715 char * s = QMkString(id.string);
716 ListAdd(exp.call.arguments, MkExpString(s));
719 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
723 ProcessExpression(exp);
729 if((!convertTo && prop.Set) || (convertTo && prop.Get))
731 Expression value = exp.op.exp2;
732 char setName[1024], getName[1024];
733 char * setToUse = convertTo ? getName : setName;
734 char * getToUse = convertTo ? setName : getName;
735 bool needAddress = false;
736 int operator = exp.op.op;
739 case MUL_ASSIGN: operator = '*'; break;
740 case DIV_ASSIGN: operator = '/'; break;
741 case MOD_ASSIGN: operator = '%'; break;
742 case SUB_ASSIGN: operator = '-'; break;
743 case ADD_ASSIGN: operator = '+'; break;
744 case LEFT_ASSIGN: operator = LEFT_OP; break;
745 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
746 case AND_ASSIGN: operator = '&'; break;
747 case OR_ASSIGN: operator = '|'; break;
748 case XOR_ASSIGN: operator = '^'; break;
753 if(operator == INC_OP)
754 value = MkExpOp(CopyExpression(memberExp),
755 '+', MkExpConstant("1"));
756 else if(operator == DEC_OP)
757 value = MkExpOp(CopyExpression(memberExp),
758 '-', MkExpConstant("1"));
761 value = MkExpOp(CopyExpression(memberExp),
765 value.expType = memberExp.expType;
766 memberExp.expType.refCount++;
767 value.usage.usageArg = true;
771 // Dont free exp2, we're using it
776 value.usage.usageArg = true;
778 DeclareProperty(prop, setName, getName);
780 if(memberExp.member.exp)
781 ProcessExpression(memberExp.member.exp);
783 // If get flag present
784 if(exp.usage.usageGet &&
785 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
787 OldList * list = MkList();
790 Context context = PushContext();
793 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
794 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
796 curContext = context;
797 exp.type = extensionCompoundExp;
798 exp.compound = MkCompoundStmt(
799 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
800 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
801 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
808 ListAdd(args, value);
809 ListAdd(args, QMkExpId(ecereTemp));
810 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
814 ListAdd(args, QMkExpId(ecereTemp));
815 ListAdd(args, value);
816 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
822 ListAdd(args, QMkExpId(ecereTemp));
824 args->Insert(null, QMkExpId(ecereTemp));
825 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
827 exp.compound.compound.context = context;
829 curContext = context.parent;
833 Expression newExp = exp;
835 if(parentExp && parentExp.type == extensionCompoundExp)
837 newExp = Expression { };
838 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
839 FreeType(exp.expType);
840 FreeType(exp.destType);
843 parentExp.type = dummyExp;
844 parentExp.expType = null;
845 parentExp.destType = null;
848 newExp.type = callExp;
849 newExp.call.exp = QMkExpId(setToUse);
850 newExp.call.arguments = MkList();
853 ListAdd(newExp.call.arguments, value);
854 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
858 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
859 ListAdd(newExp.call.arguments, value);
864 // Take it out from there
865 memberExp.member.exp = null;
867 // Don't use the temporaries used by the left side...
870 value.tempCount = exp.tempCount;
871 ProcessExpression(value);
873 FixReference(value, true);
876 FreeExpression(memberExp);
880 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
883 memberExp.member.memberType = dataMember;
886 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
891 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
892 if(method && method.type == virtualMethod && type.kind != subClassType)
894 Expression value = exp.op.exp2;
895 // Don't use the temporaries used by the left side...
896 value.tempCount = exp.tempCount;
897 ProcessExpression(value);
899 if(memberExp.member.exp)
900 ProcessExpression(memberExp.member.exp);
902 if(exp.usage.usageGet)
904 OldList * list = MkList();
909 ListAdd(args, memberExp.member.exp);
911 char * string = QMkString(memberExp.member.member.string);
912 ListAdd(args, MkExpString(string));
915 ListAdd(args, value);
916 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
917 ListAdd(list, CopyExpression(value));
918 exp.type = bracketsExp;
925 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
926 exp.call.arguments = MkList();
927 ListAdd(exp.call.arguments, memberExp.member.exp);
929 char * string = QMkString(memberExp.member.member.string);
930 ListAdd(exp.call.arguments, MkExpString(string));
933 ListAdd(exp.call.arguments, value);
936 memberExp.member.exp = null;
939 FreeExpression(memberExp);
943 else if(memberExp.member.memberType == dataMember)
945 //if(exp.usage & USAGE_GET);
946 //FixReference(value, true);
947 if(FixMember(memberExp.member.exp))
949 // TESTING THIS HERE:
950 ProcessExpression(memberExp);
952 memberExp.type = pointerExp;
959 else if(exp.op.op == _INCREF)
961 Expression object = exp.op.exp2;
963 FreeExpContents(exp);
964 FreeType(exp.expType);
965 FreeType(exp.destType);
969 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
971 else if(exp.op.op == DELETE)
973 Expression object = exp.op.exp2;
974 OldList * args = MkList();
976 exp.type = bracketsExp;
979 object.usage.usageDelete = true;
981 ProcessExpression(object);
983 ListAdd(args, object);
985 // TOFIX: Same time as when we fix for = 0
987 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
988 exp.expType._class.registered.type == normalClass &&
989 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
991 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
992 ProcessExpressionType(decRefExp);
993 ListAdd(exp.list, decRefExp);
995 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
998 char className[1024];
999 OldList * list = MkList();
1001 strcpy(className, "__ecereClass_");
1002 FullClassNameCat(className, exp.expType._class.string, true);
1003 MangleClassName(className);
1005 DeclareClass(exp.expType._class, className);
1007 // Call the non virtual destructor
1008 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1009 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1011 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1013 MkExpBrackets(MkListOne(MkExpCondition(
1014 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1015 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1020 OldList * list = MkList();
1022 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1024 char className[1024];
1026 if(_class.templateClass) _class = _class.templateClass;
1027 strcpy(className, "__ecereClass_");
1028 FullClassNameCat(className, _class.fullName, false /*true*/);
1029 MangleClassName(className);
1032 _class.symbol = FindClass(_class.fullName);
1033 DeclareClass(_class.symbol, className);
1035 // Call the non virtual destructor
1039 QMkExpId(className),
1040 MkIdentifier("Destructor")
1045 QMkExpId(className),
1046 MkIdentifier("Destructor")
1048 CopyList(args, CopyExpression)
1055 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1060 CopyExpression(object),
1070 else if(exp.expType && exp.expType.kind == templateType)
1072 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1075 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1077 OldList * qualifiers = MkList();
1078 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1080 typeName = MkTypeName(qualifiers, declarator);
1082 ProcessExpressionType(classExp);
1083 args->Insert(null, CopyExpression(classExp));
1084 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1085 ListAdd(exp.list, MkExpCall(
1086 MkExpBrackets(MkListOne(MkExpCast(typeName,
1087 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1088 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1089 //ProcessExpression(exp.list->last);
1093 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1095 //ProcessExpression(object);
1097 ListAdd(exp.list, MkExpOp(CopyExpression(object), '=', MkExpConstant("0")));
1101 // TESTING THIS HERE...
1102 ProcessExpression(exp);
1105 if(exp.type == opExp)
1107 // Handle assigment of template structures
1108 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1109 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1111 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1114 // memcpy((byte *)array + (count * dataTypeClass.size), dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1116 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1117 OldList * args = MkList();
1118 Expression derefExp = exp.op.exp1;
1119 Expression sizeExp = MkExpCondition(MkExpBrackets(MkListOne(
1121 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1123 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1124 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1125 MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize")));
1127 if(exp.op.exp1.type == indexExp)
1129 Expression indexExp = derefExp.index.exp;
1130 OldList * indexExpIndex = derefExp.index.index;
1132 derefExp.index.index = null;
1133 derefExp.index.exp = null;
1134 FreeExpression(derefExp);
1136 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1137 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1141 Expression indexExp = derefExp.op.exp2;
1142 derefExp.op.exp2 = null;
1143 FreeExpression(derefExp);
1144 derefExp = indexExp;
1147 args->Add(derefExp);
1148 ProcessExpressionType(args->last);
1149 ProcessExpression(args->last);
1151 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1152 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1153 MkListOne(exp.op.exp2), MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1155 thisClass = curExternal.function ? curExternal.function._class : null;
1159 string = CopyString("this");
1160 type = MkClassType(thisClass.fullName);
1162 globalContext.symbols.Add((BTNode)thisSymbol);
1164 ProcessExpressionType(args->last);
1165 ProcessExpression(args->last);
1168 ProcessExpressionType(args->last);
1169 ProcessExpression(args->last);
1171 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1172 exp.type = bracketsExp;
1174 //globalContext.symbols.Delete((BTNode)thisSymbol);
1175 globalContext.symbols.Remove((BTNode)thisSymbol);
1176 FreeSymbol(thisSymbol);
1182 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1183 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1185 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1188 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1189 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1191 exp.type = bracketsExp;
1192 exp.list = MkListOne(
1194 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1196 // ((class.type == structClass) ?
1197 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1200 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1202 // ((class.type == normalClass || class.type == noHeadClass) ?
1203 MkExpCondition(MkExpBrackets(MkListOne(
1205 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1207 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1208 // *((void **)array)
1209 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1210 CopyExpression(exp.op.exp2))))))),
1212 // ((class.size == 1) ?
1213 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1215 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1216 CopyExpression(exp.op.exp2)))))),
1218 // ((class.size == 2) ?
1219 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1220 // *((uint16 *)array)
1221 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1222 CopyExpression(exp.op.exp2)))))),
1224 // ((class.size == 4) ?
1225 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1226 // *((uint32 *)array)
1227 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1228 CopyExpression(exp.op.exp2)))))),
1230 // *((uint64 *)array)
1231 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1232 exp.op.exp2)))))))))))))))))))));
1234 // Add this to the context
1235 thisClass = curExternal.function ? curExternal.function._class : null;
1239 string = CopyString("this");
1240 type = MkClassType(thisClass.fullName);
1242 globalContext.symbols.Add((BTNode)thisSymbol);
1244 ProcessExpressionType(exp.list->first);
1245 ProcessExpression(exp.list->first);
1247 //globalContext.symbols.Delete((BTNode)thisSymbol);
1248 globalContext.symbols.Remove((BTNode)thisSymbol);
1249 FreeSymbol(thisSymbol);
1260 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1261 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1262 ProcessExpression(exp.op.exp1);
1265 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1266 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1267 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1268 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*/))
1269 FixReference(exp.op.exp1, false);
1270 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1274 // Don't use the temporaries used by the left side...
1276 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1277 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1278 ProcessExpression(exp.op.exp2);
1279 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1283 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1284 (exp.op.exp2.expType._class.registered.type != normalClass &&
1285 exp.op.exp2.expType._class.registered.type != structClass &&
1286 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1288 // TESTING THIS TEMPLATE TYPE CHECK HERE
1289 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1291 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1292 //FixReference(exp.op.exp2, false);
1295 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1298 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)
1300 // Preserve prev, next
1301 Expression next = exp.next, prev = exp.prev;
1302 Expression derefExp = exp.op.exp2;
1303 Expression refExp = exp.op.exp2.op.exp2;
1304 Type expType = exp.expType, destType = exp.destType;
1306 derefExp.op.exp2 = null;
1307 FreeExpression(derefExp);
1308 FreeType(exp.expType);
1309 FreeType(exp.destType);
1319 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)
1321 Expression exp2 = exp.op.exp2;
1322 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1325 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1327 exp.type = bracketsExp;
1328 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1329 MkExpOp(null, '&', exp2)), '+',
1330 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1331 MkListOne((e = MkExpCondition(MkExpBrackets(MkListOne(
1335 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))),
1337 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))),
1339 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))))
1341 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1342 MkExpMember(classExp, MkIdentifier("typeSize"))))))));
1344 // Add this to the context
1345 thisClass = curExternal.function ? curExternal.function._class : null;
1349 string = CopyString("this");
1350 type = MkClassType(thisClass.fullName);
1352 //globalContext.symbols.Add((BTNode)thisSymbol);
1354 ProcessExpressionType(e);
1355 ProcessExpression(e);
1357 //globalContext.symbols.Remove((BTNode)thisSymbol);
1358 //FreeSymbol(thisSymbol);
1367 FreeExpression(exp1);
1369 FreeExpression(exp2);
1374 case extensionExpressionExp:
1379 for(e = exp.list->first; e; e = e.next)
1383 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1385 e.tempCount = exp.tempCount;
1386 ProcessExpression(e);
1388 exp.byReference = e.byReference;
1389 exp.tempCount = e.tempCount;
1393 exp.expType = e.expType;
1402 /*bool isBuiltin = exp && exp.index.exp &&
1403 (exp.index.exp.type == ExpressionType::arrayExp ||
1404 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1406 Expression checkedExp = exp.index.exp;
1407 bool isBuiltin = false;
1409 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1411 if(checkedExp.type == extensionCompoundExp)
1416 else if(checkedExp.type == bracketsExp)
1417 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1419 checkedExp = checkedExp.cast.exp;
1422 exp.index.exp.tempCount = exp.tempCount;
1424 exp.index.exp.usage.usageGet = true;
1425 ProcessExpression(exp.index.exp);
1427 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1428 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1430 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1433 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1434 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1436 exp.type = bracketsExp;
1437 exp.list = MkListOne(
1439 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1441 // ((class.type == structClass) ?
1442 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1443 // ((byte *)array) + (i) * class.size
1444 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1445 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1446 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1448 // ((class.type == normalClass || class.type == noHeadClass) ?
1449 MkExpCondition(MkExpBrackets(MkListOne(
1451 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1453 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1454 // ((void **)array)[i]
1455 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1456 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression)))),
1458 // ((class.size == 1) ?
1459 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1460 // ((byte *)array)[i]
1461 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1462 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1464 // ((class.size == 2) ?
1465 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1466 // ((uint16 *)array)[i]
1467 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1468 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1470 // ((class.size == 4) ?
1471 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1472 // ((uint32 *)array)[i]
1473 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1474 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1476 // ((uint64 *)array)[i]
1477 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1478 exp.index.exp))), exp.index.index))))))))))))))))));
1480 // Add this to the context
1481 thisClass = curExternal.function ? curExternal.function._class : null;
1485 string = CopyString("this");
1486 type = MkClassType(thisClass.fullName);
1488 globalContext.symbols.Add((BTNode)thisSymbol);
1490 ProcessExpressionType(exp.list->first);
1491 ProcessExpression(exp.list->first);
1493 //globalContext.symbols.Delete((BTNode)thisSymbol);
1494 globalContext.symbols.Remove((BTNode)thisSymbol);
1495 FreeSymbol(thisSymbol);
1503 for(e = exp.index.index->first; e; e = e.next)
1506 e.usage.usageGet = true;
1507 ProcessExpression(e);
1509 // Ignore temps in the index for now...
1510 exp.tempCount = exp.index.exp.tempCount;
1512 if(exp.index.exp.expType)
1514 Type source = exp.index.exp.expType;
1515 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1516 eClass_IsDerived(source._class.registered, containerClass))
1518 Class _class = source._class.registered;
1519 bool isArray = false;
1520 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1521 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1523 if(isArray && _class.templateArgs)
1525 OldList * specs = MkList();
1526 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1527 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1528 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1529 ProcessExpressionType(exp.index.exp);
1530 ProcessExpression(exp);
1532 else if(isBuiltin && _class.templateArgs)
1534 OldList * specs = MkList();
1535 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1536 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1537 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1538 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1539 ProcessExpressionType(exp.index.exp);
1540 ProcessExpression(exp);
1542 else if(_class.templateArgs)
1544 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1546 char iteratorType[1024];
1547 OldList * declarations = MkList();
1548 OldList * statements = MkList();
1549 OldList * args = MkList();
1550 OldList * instMembers = MkList();
1552 Context context = PushContext();
1554 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1556 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1558 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1559 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1561 ListAdd(args, MkExpBrackets(exp.index.index));
1562 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1564 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1565 MkIdentifier("Index")), args))));
1567 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1568 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1570 exp.type = bracketsExp;
1571 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1572 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1573 expExt.compound.compound.context = context;
1574 PopContext(context);
1575 expExt.usage = exp.usage;
1576 ProcessExpressionType(exp.list->first);
1577 ProcessExpressionInstPass(exp.list->first);
1578 ProcessExpression(exp.list->first);
1587 bool typedObject = false;
1588 Type ellipsisDestType = null;
1589 bool usedEllipsis = false;
1591 if(exp.call.arguments)
1593 for(e = exp.call.arguments->first; e; e = e.next)
1595 e.usage.usageGet = true;
1596 e.usage.usageArg = true;
1597 e.tempCount = Max(e.tempCount, exp.tempCount);
1598 ProcessExpression(e);
1599 exp.tempCount = Max(exp.tempCount, e.tempCount);
1602 exp.call.exp.usage.usageGet = true;
1603 exp.call.exp.usage.usageCall = true;
1604 exp.call.exp.tempCount = exp.tempCount;
1606 ProcessExpression(exp.call.exp);
1608 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1610 bool nullMemberExp = false;
1611 Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1613 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1614 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1615 Method method = exp.call.exp.expType.method;
1616 if(method.type == virtualMethod)
1622 OldList * specs = MkList();
1623 strcpy(name, "__ecereVMethodID_");
1624 FullClassNameCat(name, method._class.fullName, false);
1626 strcat(name, method.name);
1628 DeclareMethod(method, name);
1631 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1632 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1633 // Cast function to its type
1635 Context context = SetupTemplatesContext(method._class);
1637 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1639 FinishTemplatesContext(context);
1642 if(method.dataType && !method.dataType.staticMethod)
1644 Declarator funcDecl = GetFuncDecl(decl);
1646 if(!funcDecl.function.parameters)
1647 funcDecl.function.parameters = MkList();
1649 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1650 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1652 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1654 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1655 FreeTypeName(firstParam);
1659 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1663 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)));
1664 // Testing this for any_object::
1665 if(!method.dataType.extraParam)
1666 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1670 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1671 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1675 typeName = MkTypeName(specs, decl);
1677 // Added !exp.call.exp.expType.methodClass
1678 if(memberExp && memberExp.member.exp.expType)
1680 Type type = memberExp.member.exp.expType;
1682 if(type.kind == classType && type._class && type._class.registered)
1684 Class regClass = type._class.registered;
1685 ClassType classType = regClass.type;
1686 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1687 argClass = regClass;
1689 else if(type.kind == subClassType)
1691 argClass = FindClass("ecere::com::Class").registered;
1693 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1695 argClass = FindClass("char *").registered;
1697 else if(type.kind == pointerType)
1699 argClass = eSystem_FindClass(privateModule, "uintptr");
1700 FreeType(memberExp.member.exp.expType);
1701 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1702 memberExp.member.exp.byReference = true;
1706 char string[1024] = "";
1708 PrintTypeNoConst(type, string, false, true);
1709 classSym = FindClass(string);
1710 if(classSym) argClass = classSym.registered;
1714 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1720 Type type = memberExp ? memberExp.member.exp.expType : null;
1721 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1722 char className[1024];
1723 bool useInstance = false;
1725 if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
1726 strcpy(className, "class");
1730 // TESTING: Moved this here...
1731 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1736 // TODO: Unhandled case here, what should happen?
1739 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1740 if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
1741 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1742 cl = cl.templateClass;
1744 // Need the class itself here...
1745 strcpy(className, "__ecereClass_");
1746 FullClassNameCat(className, cl.fullName, true);
1747 MangleClassName(className);
1750 cl.symbol = FindClass(cl.fullName);
1752 DeclareClass(cl.symbol, className);
1755 if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
1757 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1758 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1759 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1761 else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
1762 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1764 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1765 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1766 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1770 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1771 // as opposed to the File class vTbl one
1773 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1775 Context context = PushContext();
1776 c = MkExpExtensionCompound(MkCompoundStmt(
1777 MkListOne(MkDeclaration(
1778 MkListOne(MkSpecifierName("Instance")),
1779 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1780 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
1781 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1782 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1783 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1784 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
1786 c.compound.compound.context = context;
1787 PopContext(context);
1788 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1789 MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1796 strcpy(name, "__ecereMethod_");
1797 FullClassNameCat(name, method._class.fullName, false);
1799 strcat(name, method.name);
1802 FreeExpression(exp.call.exp);
1803 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1804 DeclareMethod(method, name);
1805 if(memberExp && memberExp.expType && method.dataType)
1807 exp.call.exp.expType = method.dataType;
1808 method.dataType.refCount++;
1811 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1813 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1815 if(!exp.call.arguments)
1816 exp.call.arguments = MkList();
1818 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1820 if(memberExp.member.exp.expType.kind != classType ||
1821 memberExp.member.exp.expType._class.registered.type == enumClass ||
1822 memberExp.member.exp.expType._class.registered.type == unitClass)
1824 char typeString[1024] = "";
1825 if(memberExp.member.exp.expType.kind != classType)
1826 PrintType(memberExp.member.exp.expType, typeString, false, true);
1828 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1831 // memberExp.member.exp.expType.kind = classType;
1832 // memberExp.member.exp.expType._class = FindClass(typeString);
1834 FreeType(memberExp.member.exp.expType);
1835 memberExp.member.exp.expType = Type
1838 _class = FindClass(typeString);
1842 // Default to an int instead
1843 if(!memberExp.member.exp.expType._class)
1845 // TODO: Shouldn't get here...
1846 memberExp.member.exp.expType.kind = TypeInt;
1851 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1853 bool changeReference = false;
1854 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1856 // Patched so that class isn't considered SYSTEM...
1857 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1858 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1859 changeReference = true;
1860 if(!memberExp.member.exp.expType.classObjectType &&
1862 (memberExp.member.exp.expType.kind != pointerType &&
1863 (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1864 !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1865 method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
1866 changeReference = true;
1867 if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
1868 changeReference = true;
1871 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1872 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1874 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1875 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1877 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1879 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1880 memberExp.member.exp.op.exp2 = null;
1882 else if(!memberExp.member.exp.byReference)
1884 // TESTING THIS... REUSE THIS CODE?
1885 Expression checkedExp = memberExp.member.exp;
1886 Expression parentExp = null;
1888 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1890 parentExp = checkedExp;
1892 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1894 checkedExp = checkedExp.list->last;
1895 // Dissociate from memberExp which will get freed
1896 if(checkedExp) parentExp.list->Remove(checkedExp);
1898 else if(checkedExp.type == castExp)
1900 checkedExp = checkedExp.cast.exp;
1901 // Dissociate from memberExp which will get freed
1902 checkedExp.cast.exp = null;
1906 nullMemberExp = true;
1908 newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
1909 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1911 parentExp.list->Remove(checkedExp);
1912 parentExp.list->Add(newExp);
1914 else if(parentExp && parentExp.type == castExp)
1916 parentExp.cast.exp = newExp;
1917 // Add a dereference level here
1918 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1920 if(typedObject && !memberExp.member.exp.expType.classObjectType)
1922 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
1923 FreeType((parentExp ? parentExp : newExp).expType);
1924 FreeType((parentExp ? parentExp : newExp).destType);
1925 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
1926 (parentExp ? parentExp : newExp).destType = destType;
1927 if(checkedExp.expType) checkedExp.expType.refCount++;
1929 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1933 exp.call.arguments->Insert(null, memberExp.member.exp);
1934 nullMemberExp = true;
1939 exp.call.arguments->Insert(null, memberExp.member.exp);
1940 nullMemberExp = true;
1944 char className[1024];
1945 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
1946 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1947 Class cl = argClass ? argClass : regClass;
1950 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1951 strcpy(className, "class");
1954 // Need the class itself here...
1955 strcpy(className, "__ecereClass_");
1956 FullClassNameCat(className, cl.fullName, true);
1957 MangleClassName(className);
1960 cl.symbol = FindClass(cl.fullName);
1961 DeclareClass(cl.symbol, className);
1966 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
1968 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
1970 Context context = PushContext();
1971 c = MkExpExtensionCompound(MkCompoundStmt(
1972 MkListOne(MkDeclaration(
1973 MkListOne(MkSpecifierName("Instance")),
1974 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1975 MkInitializerAssignment(memberExpMemberExp))))),
1976 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1977 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1978 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
1979 MkExpIdentifier(MkIdentifier(className))))))));
1980 c.compound.compound.context = context;
1981 PopContext(context);
1983 exp.call.arguments->Insert(null, c);
1985 memberExpMemberExp = null; // We used this
1988 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
1992 if(memberExpMemberExp)
1993 FreeExpression(memberExpMemberExp);
1997 exp.call.arguments->Insert(null, memberExp.member.exp);
1998 nullMemberExp = true;
2002 /*else if(method->dataType)
2008 memberExp.member.exp = null;
2009 FreeExpression(memberExp);
2013 if(exp.call.arguments)
2015 for(e = exp.call.arguments->first; e; e = e.next)
2017 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
2018 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
2019 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
2020 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
2022 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
2023 ellipsisDestType = destType;
2026 Type type = e.expType;
2027 Class _class = null;
2028 //Type destType = e.destType;
2030 if(type.kind == classType && type._class && type._class.registered)
2032 _class = type._class.registered;
2034 else if(type.kind == subClassType)
2036 _class = FindClass("ecere::com::Class").registered;
2038 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
2040 _class = FindClass("char *").registered;
2042 else if(type.kind == pointerType)
2044 _class = eSystem_FindClass(privateModule, "uintptr");
2045 FreeType(e.expType);
2046 e.expType = ProcessTypeString("uintptr", false);
2047 // Assume null pointers means 'no object' rather than an object holding a null pointer
2048 e.byReference = true;
2052 char string[1024] = "";
2054 PrintTypeNoConst(type, string, false, true);
2055 classSym = FindClass(string);
2056 if(classSym) _class = classSym.registered;
2057 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2060 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...
2061 (!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))) ||
2062 destType.byReference)))
2064 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2065 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2066 // TESTING WITHOUT THE ABOVE NOW!
2068 Expression checkedExp;
2069 Expression parentExp;
2074 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2076 parentExp = checkedExp;
2077 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2079 if(checkedExp.type == extensionCompoundExp)
2081 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2084 checkedExp = checkedExp.list->last;
2086 else if(checkedExp.type == castExp)
2087 checkedExp = checkedExp.cast.exp;
2090 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2093 Expression newExp = e.op.exp2;
2094 exp.call.arguments->Insert(e.prev, newExp);
2095 exp.call.arguments->Remove(e);
2100 newExp = checkedExp.op.exp2;
2101 checkedExp.op.exp2 = null;
2102 FreeExpContents(checkedExp);
2104 if(e.expType && e.expType.passAsTemplate)
2107 ComputeTypeSize(e.expType);
2108 sprintf(size, "%d", e.expType.size);
2109 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2110 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2111 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2114 if(parentExp.type == callExp)
2116 exp.call.arguments->Insert(e.prev, newExp);
2117 exp.call.arguments->Remove(e);
2120 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2122 parentExp.list->Remove(checkedExp);
2123 parentExp.list->Add(newExp);
2125 else if(parentExp.type == castExp)
2127 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2128 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2130 FreeTypeName(parentExp.cast.typeName);
2131 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2133 parentExp.cast.exp = newExp;
2135 else if(parentExp.type == extensionCompoundExp)
2137 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2138 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2140 e.byReference = true;
2142 FreeType(checkedExp.expType);
2143 FreeType(checkedExp.destType);
2146 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2148 Expression checkedExp;
2149 Expression parentExp;
2153 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2155 e.type == identifierExp ||
2156 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2157 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2158 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2161 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2163 Context context = PushContext();
2165 OldList * specs = MkList();
2166 char typeString[1024];
2167 Expression newExp { };
2169 typeString[0] = '\0';
2172 // TOCHECK: Should this read e.destType ???
2174 if(exp.destType) exp.destType.refCount++;
2175 // if(exp.expType) exp.expType.refCount++;
2178 newExp.expType = null;
2180 PrintTypeNoConst(e.expType, typeString, false, true);
2181 decl = SpecDeclFromString(typeString, specs, null);
2182 newExp.destType = ProcessType(specs, decl);
2184 curContext = context;
2185 e.type = extensionCompoundExp;
2187 // We need a current compound for this
2191 OldList * stmts = MkList();
2192 sprintf(name, "__internalValue%03X", internalValueCounter++);
2193 if(!curCompound.compound.declarations)
2194 curCompound.compound.declarations = MkList();
2195 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2196 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2197 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2198 e.compound = MkCompoundStmt(null, stmts);
2201 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2205 e.compound = MkCompoundStmt(
2206 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2207 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2210 e.compound.compound.context = context;
2211 PopContext(context);
2212 curContext = context.parent;
2216 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2219 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2221 parentExp = checkedExp;
2222 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2224 if(checkedExp.type == extensionCompoundExp)
2226 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2229 checkedExp = checkedExp.list->last;
2231 else if(checkedExp.type == castExp)
2232 checkedExp = checkedExp.cast.exp;
2234 newExp = MkExpOp(null, '&', checkedExp);
2235 newExp.byReference = true;
2236 if(parentExp.type == callExp)
2238 exp.call.arguments->Insert(e.prev, newExp);
2239 exp.call.arguments->Remove(e);
2242 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2244 parentExp.list->Remove(checkedExp);
2245 parentExp.list->Add(newExp);
2247 else if(parentExp.type == castExp)
2248 parentExp.cast.exp = newExp;
2249 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2251 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2252 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2258 if(destType.classObjectType == ClassObjectType::typedObject)
2260 char className[1024];
2261 // Need the class itself here...
2262 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2263 _class = eSystem_FindClass(privateModule, "String");
2264 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2266 if(!strcmp(_class.name, "class"))
2268 // Already inside a typed_object function, pass the class through
2269 strcpy(className, "class");
2273 strcpy(className, "__ecereClass_");
2274 FullClassNameCat(className, _class.fullName, true);
2275 MangleClassName(className);
2278 _class.symbol = FindClass(_class.fullName);
2280 DeclareClass(_class.symbol, className);
2283 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2285 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2287 Context context = PushContext();
2289 // Work around to avoid repeating the BuiltInContainer just to get the type
2290 // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
2291 if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
2292 e.list && e.list->first &&
2293 ((Expression)e.list->first).type == castExp &&
2294 ((Expression)e.list->first).cast.exp &&
2295 ((Expression)e.list->first).cast.exp.type == opExp &&
2296 ((Expression)e.list->first).cast.exp.op.op == '&' &&
2297 ((Expression)e.list->first).cast.exp.op.exp2 &&
2298 ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
2300 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2304 c = MkExpExtensionCompound(MkCompoundStmt(
2305 MkListOne(MkDeclaration(
2306 MkListOne(MkSpecifierName("Instance")),
2307 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2308 MkInitializerAssignment(CopyExpression(e)))))),
2309 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2310 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2311 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2312 MkExpIdentifier(MkIdentifier(className))))))));
2313 c.compound.compound.context = context;
2314 PopContext(context);
2316 exp.call.arguments->Insert(e.prev, c);
2320 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2326 //char debugString[4096] = "";
2327 //PrintExpression(e, debugString);
2329 // If expression type is a simple class, make it an address
2330 FixReference(e, !destType || !destType.declaredWithStruct);
2333 if(ellipsisDestType)
2336 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2337 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2339 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2347 bool changeToPtr = false;
2348 bool noHead = false;
2349 Type type = exp.member.exp ? exp.member.exp.expType : null;
2350 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2351 if(exp.member.member) exp.member.member._class = null;
2353 if(type && type.kind == templateType)
2355 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2356 if(baseType) type = baseType;
2358 if(type && exp.member.member && !type.directClassAccess)
2360 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2361 Property prop = null;
2362 ClassProperty classProperty = null;
2363 Method method = null;
2364 Class convertTo = null;
2365 DataMember member = null;
2366 bool thisPtr = exp.member.thisPtr;
2367 if(type.kind == subClassType && exp.member.exp.type == classExp)
2368 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2370 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2374 // DANGER: Buffer overflow
2375 char string[2048] = "";
2377 PrintTypeNoConst(type, string, false, true);
2378 classSym = FindClass(string);
2379 _class = classSym ? classSym.registered : null;
2382 if(_class && exp.member.memberType == dataMember)
2384 if(!thisPtr && !exp.member.member.classSym)
2385 member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
2387 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2389 else if(_class && exp.member.memberType == propertyMember)
2391 if(!thisPtr && !exp.member.member.classSym)
2392 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2394 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2395 if(prop && (exp.usage.usageRef ||
2396 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2397 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2399 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2402 exp.member.memberType = dataMember;
2407 if(exp.usage.usageRef)
2408 Compiler_Error($"cannot obtain address of property\n");
2410 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2411 else if(exp.usage.usageDelete)
2412 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2416 else if(_class && exp.member.memberType == methodMember)
2419 method = eClass_FindMethod(_class, exp.member.member.string, null);
2421 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2423 else if(_class && exp.member.memberType == reverseConversionMember)
2426 _class = FindClass(exp.member.member.string).registered;
2427 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2428 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2430 else if(_class && exp.member.memberType == classPropertyMember)
2432 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2436 // Only process Gets here, Set is processed in opExp's '='
2437 if(exp.usage.usageGet)
2441 char getName[1024], setName[1024];
2442 Expression ptr = exp.member.exp;
2443 Class propertyClass;
2444 char * nameToUse = convertTo ? setName : getName;
2446 FreeIdentifier(exp.member.member);
2448 // Process this here since it won't be processed at the end...
2449 exp.member.exp.usage.usageGet = true;
2450 ProcessExpression(exp.member.exp);
2451 // TEST: exp.tempCount = exp.member.exp.tempCount;
2453 DeclareProperty(prop, setName, getName);
2454 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2455 propertyClass = convertTo ? _class :
2456 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2459 if(propertyClass && propertyClass.type == bitClass)
2461 // Bit classes shouldn't have properties except for conversions...
2462 OldList * args = MkList();
2463 if(exp.usage.usageDeepGet)
2465 char className[1024];
2467 Declarator declarator;
2468 OldList * specs = MkList(), * decls = MkList();
2471 // Make a declaration in the closest compound statement
2472 // (Do not reuse (since using address for function calls)...)
2473 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2475 SpecDeclFromString(propertyClass.dataTypeString, specs,
2476 MkDeclaratorIdentifier(MkIdentifier(className)));
2478 ListAdd(decls, MkInitDeclarator(declarator, null));
2480 decl = MkDeclaration(specs, decls);
2481 if(!curCompound.compound.declarations)
2482 curCompound.compound.declarations = MkList();
2483 curCompound.compound.declarations->Insert(null, decl);
2485 tempExp = QMkExpId(className);
2486 tempExp.expType = MkClassType(propertyClass.fullName);
2488 exp.op.exp1 = tempExp;
2489 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2496 exp.call.exp = QMkExpId(nameToUse);
2497 exp.call.arguments = args;
2499 ListAdd(args, FixReference(ptr, true));
2501 else if(propertyClass && propertyClass.type == unitClass)
2503 OldList * args = MkList();
2504 ListAdd(args, FixReference(ptr, true));
2506 exp.call.exp = QMkExpId(nameToUse);
2507 exp.call.arguments = args;
2509 else if(propertyClass && propertyClass.type == structClass)
2511 OldList * args = MkList();
2512 char className[1024];
2514 OldList * specs = MkList(), * decls = MkList();
2517 // Make a declaration in the closest compound statement
2518 // (Do not reuse (since using address for function calls)...)
2521 FullClassNameCat(className, propertyClass.fullName, false); //true);
2523 //ListAdd(specs, MkSpecifierName(className));
2524 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2526 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2528 ListAdd(decls, MkInitDeclarator(
2529 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2531 decl = MkDeclaration(specs, decls);
2534 if(!curCompound.compound.declarations)
2535 curCompound.compound.declarations = MkList();
2536 curCompound.compound.declarations->Insert(null, decl);
2539 tempExp = QMkExpId(className);
2540 tempExp.expType = MkClassType(propertyClass.fullName);
2544 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2545 ListAdd(args, FixReference(ptr, true));
2549 ListAdd(args, FixReference(ptr, true));
2550 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2553 if(exp.usage.usageDeepGet)
2556 exp.call.exp = QMkExpId(nameToUse);
2557 exp.call.arguments = args;
2559 FreeExpression(tempExp);
2563 exp.type = bracketsExp;
2564 exp.list = MkList();
2565 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2566 if(exp.usage.usageMember)
2568 ListAdd(exp.list, FixReference(tempExp, true));
2569 exp.byReference = true;
2572 ListAdd(exp.list, tempExp);
2578 exp.call.exp = QMkExpId(nameToUse);
2579 exp.call.arguments = MkList();
2580 ListAdd(exp.call.arguments, FixReference(ptr, true));
2583 else if(prop.conversion)
2585 void * prev = exp.prev, * next = exp.next;
2586 *exp = *exp.member.exp;
2592 else if(classProperty)
2594 // Only process Gets here, Set is processed in opExp's '='
2595 if(exp.usage.usageGet)
2597 if(classProperty.Get)
2599 Identifier id = exp.member.member;
2600 Expression classExp = exp.member.exp;
2604 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty"));
2605 exp.call.arguments = MkList();
2606 ListAdd(exp.call.arguments, classExp);
2608 char * s = QMkString(id.string);
2609 ListAdd(exp.call.arguments, MkExpString(s));
2614 ProcessExpression(exp);
2621 // Get the function address if it's not called
2622 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2626 FreeIdentifier(exp.member.member);
2628 // Process this here since it won't be processed at the end...
2629 exp.member.exp.usage.usageGet = true;
2630 ProcessExpression(exp.member.exp);
2631 // TEST: exp.tempCount = exp.member.exp.tempCount;
2633 if(method.type == virtualMethod)
2635 strcpy(name, "__ecereVMethodID_");
2636 FullClassNameCat(name, method._class.fullName, false);
2638 strcat(name, method.name);
2639 exp.type = indexExp;
2640 if(memberClassSpecifier)
2642 char className[1024];
2643 // Need the class itself here...
2644 strcpy(className, "__ecereClass_");
2645 FullClassNameCat(className, _class.fullName, true);
2646 MangleClassName(className);
2649 _class.symbol = FindClass(_class.fullName);
2650 DeclareClass(_class.symbol, className);
2652 FreeExpression(exp.member.exp);
2653 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2657 if(exp.thisPtr && _class.type != normalClass)
2659 FreeExpression(exp.member.exp);
2660 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2663 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2665 exp.index.index = MkListOne(QMkExpId(name));
2666 DeclareMethod(method, name);
2670 FreeExpression(exp.member.exp);
2671 exp.type = identifierExp;
2672 strcpy(name, "__ecereMethod_");
2673 FullClassNameCat(name, method._class.fullName, false);
2675 strcat(name, method.name);
2676 exp.identifier = MkIdentifier(name);
2677 DeclareMethod(method, name);
2683 // Process this here since it won't be processed at the end...
2684 if(exp.usage.usageGet)
2686 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2688 ProcessExpression(exp.member.exp);
2689 // TEST: exp.tempCount = exp.member.exp.tempCount;
2691 if(type.kind == classType && type._class && type._class.registered)
2692 DeclareStruct(type._class.registered.fullName, false);
2694 // TESTING THIS NOHEAD STUFF...
2695 if(_class.type == noHeadClass)
2699 else if(_class.type == structClass)
2703 else if(_class.type == bitClass)
2705 OldList * list = MkList();
2706 char mask[32], shift[10];
2707 OldList * specs = MkList();
2708 BitMember bitMember = (BitMember) member;
2709 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2710 TypeName type = MkTypeName(specs, decl);
2711 if(bitMember.mask > MAXDWORD)
2712 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2714 sprintf(mask, FORMAT64HEX, bitMember.mask);
2715 sprintf(shift, "%d", bitMember.pos);
2717 FreeIdentifier(exp.member.member);
2719 // ((type) ((color & mask) >> bitPos))
2720 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2721 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2722 MkExpConstant(shift))))));
2724 exp.type = bracketsExp;
2727 else if(_class.type == unitClass)
2732 // If it's a this pointer, replace by precomputed shortcut
2733 if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2735 char pointerName[1024];
2737 strcpy(pointerName, "__ecerePointer_");
2738 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2739 if(exp.member.exp.identifier)
2740 FreeIdentifier(exp.member.exp.identifier);
2741 exp.member.exp.identifier = MkIdentifier(pointerName);
2743 // Otherwise, access the data the hard way
2746 Expression bytePtr, e;
2747 Expression classExp;
2748 Expression checkedExp;
2749 char structName[1024];
2750 char className[1024];
2751 strcpy(className, "__ecereClass_");
2752 FullClassNameCat(className, member._class.fullName, true);
2753 MangleClassName(className);
2755 // classExp = QMkExpId(className);
2757 if(!member._class.symbol)
2758 member._class.symbol = FindClass(member._class.fullName);
2760 DeclareClass(member._class.symbol, className);
2761 DeclareStruct(member._class.fullName, false);
2764 FullClassNameCat(structName, member._class.fullName, false);
2766 checkedExp = exp.member.exp;
2767 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2768 checkedExp.type == castExp)
2770 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2771 checkedExp = checkedExp.list->last;
2772 else if(checkedExp.type == castExp)
2773 checkedExp = checkedExp.cast.exp;
2776 if(checkedExp.type != identifierExp &&
2777 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2778 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2780 char ecereTemp[100];
2782 OldList * list = MkList();
2783 Context context = PushContext();
2784 if(exp.member.exp.tempCount > exp.tempCount)
2785 exp.tempCount = exp.member.exp.tempCount;
2788 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2789 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2790 curContext = context;
2791 compound = MkCompoundStmt(
2792 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2793 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2794 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2795 if(member._class.fixed)
2797 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2800 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2801 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2804 e = QMkExpId(ecereTemp);
2808 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2809 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2812 compound.compound.context = context;
2813 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2814 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2815 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2817 exp.member.exp = MkExpExtensionCompound(compound);
2819 PopContext(context);
2820 curContext = context.parent;
2824 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2825 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2827 e = QBrackets(QMkExpCond(exp.member.exp,
2828 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2829 MkExpConstant("0")));
2833 if(member._class.fixed)
2835 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2838 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2839 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2845 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2847 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2848 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2851 exp.type = pointerExp;
2856 // Take Out Any Class Specifier (Should have been used by now)
2857 FreeSpecifier(memberClassSpecifier);
2859 // Just moved this at the end... How is it?
2860 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
2862 exp.member.exp.usage.usageGet = true;
2863 exp.member.exp.usage.usageMember = true;
2864 exp.member.exp.tempCount = exp.tempCount;
2865 ProcessExpression(exp.member.exp);
2866 exp.tempCount = exp.member.exp.tempCount;
2867 if((changeToPtr && exp.member.exp.byReference) || noHead)
2868 exp.type = pointerExp;
2872 case extensionCompoundExp:
2874 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
2876 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2878 ProcessStatement(exp.compound);
2880 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2881 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2886 exp.member.exp.usage.usageGet = true;
2887 ProcessExpression(exp.member.exp);
2892 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2893 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2895 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2898 Expression classExp;
2900 FreeTypeName(exp.typeName);
2902 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
2904 exp.type = bracketsExp;
2905 exp.list = MkListOne(
2906 MkExpCondition(MkExpBrackets(MkListOne(
2909 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2910 MkExpIdentifier(MkIdentifier("normalClass"))),
2913 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2914 MkExpIdentifier(MkIdentifier("noHeadClass"))
2916 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
2917 MkExpMember(classExp, MkIdentifier("typeSize")))
2920 ProcessExpressionType(exp);
2921 ProcessExpression(exp);
2930 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
2931 ProcessExpression(exp.cast.exp);
2933 if(exp.cast.exp.byReference)
2934 exp.byReference = exp.cast.exp.byReference;
2935 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
2936 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
2937 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
2938 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
2939 exp.byReference = true;
2941 // Moved this to 1.5...
2942 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
2948 if(exp.usage.usageGet)
2949 exp.cond.cond.usage.usageGet = true;
2950 ProcessExpression(exp.cond.cond);
2951 for(e = exp.cond.exp->first; e; e = e.next)
2953 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
2954 ProcessExpression(e);
2956 if(exp.usage.usageGet)
2957 exp.cond.elseExp.usage.usageGet = true;
2958 ProcessExpression(exp.cond.elseExp);
2963 // Need the class itself here...
2964 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
2966 Specifier spec = exp._classExp.specifiers->first;
2967 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
2970 FreeList(exp._classExp.specifiers, FreeSpecifier);
2971 if(exp._classExp.decl)
2972 FreeDeclarator(exp._classExp.decl);
2974 exp.type = memberExp; //pointerExp;
2975 exp.member.exp = argExp;
2976 exp.member.member = MkIdentifier("dataTypeClass");
2978 ProcessExpressionType(argExp);
2979 ProcessExpression(exp);
2984 char className[1024];
2985 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
2986 Symbol classSym = FindClass(string);
2988 strcpy(className, "__ecereClass_");
2989 FullClassNameCat(className, string, true); // TODO: Verify this
2990 MangleClassName(className);
2991 DeclareClass(classSym, className);
2994 FreeList(exp._classExp.specifiers, FreeSpecifier);
2995 if(exp._classExp.decl)
2996 FreeDeclarator(exp._classExp.decl);
2998 exp.type = identifierExp;
2999 exp.identifier = MkIdentifier(className);
3005 ProcessExpression(exp.vaArg.exp);
3008 case extensionInitializerExp:
3010 ProcessInitializer(exp.initializer.initializer);
3018 static void ProcessInitializer(Initializer init)
3022 case expInitializer:
3025 init.exp.usage.usageGet = true;
3026 ProcessExpression(init.exp);
3027 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
3028 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
3030 FixReference(init.exp, true);
3032 else if(init.exp.destType && init.exp.destType.kind == classType)
3033 FixReference(init.exp, false);
3036 case listInitializer:
3041 for(i = init.list->first; i; i = i.next)
3042 ProcessInitializer(i);
3049 static void ProcessDeclaration(Declaration decl)
3053 case initDeclaration:
3055 if(decl.declarators)
3059 for(d = decl.declarators->first; d; d = d.next)
3062 ProcessInitializer(d.initializer);
3070 static void ProcessStatement(Statement stmt)
3075 ProcessStatement(stmt.labeled.stmt);
3078 if(stmt.caseStmt.exp)
3080 stmt.caseStmt.exp.usage.usageGet = true;
3082 // This expression should be constant...
3083 ProcessExpression(stmt.caseStmt.exp);
3085 if(stmt.caseStmt.stmt)
3086 ProcessStatement(stmt.caseStmt.stmt);
3090 if(stmt.compound.context)
3094 Statement prevCompound = curCompound;
3095 Context prevContext = curContext;
3097 if(!stmt.compound.isSwitch)
3100 curContext = stmt.compound.context;
3103 if(stmt.compound.declarations)
3105 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3106 ProcessDeclaration(decl);
3108 if(stmt.compound.statements)
3110 for(s = stmt.compound.statements->first; s; s = s.next)
3111 ProcessStatement(s);
3113 curContext = prevContext;
3114 curCompound = prevCompound;
3118 case expressionStmt:
3121 if(stmt.expressions)
3123 for(exp = stmt.expressions->first; exp; exp = exp.next)
3125 ProcessExpression(exp);
3136 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3137 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3139 ProcessExpression(exp);
3142 if(stmt.ifStmt.stmt)
3143 ProcessStatement(stmt.ifStmt.stmt);
3144 if(stmt.ifStmt.elseStmt)
3145 ProcessStatement(stmt.ifStmt.elseStmt);
3151 if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
3153 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3154 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3156 ProcessExpression(exp);
3159 ProcessStatement(stmt.switchStmt.stmt);
3165 if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
3167 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3168 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3170 ProcessExpression(exp);
3173 ProcessStatement(stmt.whileStmt.stmt);
3179 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3181 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3182 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3184 ProcessExpression(exp);
3187 if(stmt.doWhile.stmt)
3188 ProcessStatement(stmt.doWhile.stmt);
3194 if(stmt.forStmt.init)
3195 ProcessStatement(stmt.forStmt.init);
3197 if(stmt.forStmt.check)
3199 if(stmt.forStmt.check.expressions)
3201 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3203 ProcessStatement(stmt.forStmt.check);
3205 if(stmt.forStmt.increment)
3207 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3209 ProcessExpression(exp);
3212 if(stmt.forStmt.stmt)
3213 ProcessStatement(stmt.forStmt.stmt);
3225 if(stmt.expressions)
3227 ((Expression)stmt.expressions->last).usage.usageGet = true;
3228 for(exp = stmt.expressions->first; exp; exp = exp.next)
3230 ProcessExpression(exp);
3231 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3232 if(!exp.next && exp.destType && exp.destType.byReference)
3233 FixReference(exp, true);
3238 case badDeclarationStmt:
3240 ProcessDeclaration(stmt.decl);
3246 if(stmt.asmStmt.inputFields)
3248 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3249 if(field.expression)
3250 ProcessExpression(field.expression);
3252 if(stmt.asmStmt.outputFields)
3254 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3255 if(field.expression)
3256 ProcessExpression(field.expression);
3258 if(stmt.asmStmt.clobberedFields)
3260 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3261 if(field.expression)
3262 ProcessExpression(field.expression);
3269 static void ProcessFunction(FunctionDefinition function)
3272 ProcessStatement(function.body);
3275 static void ProcessMemberInitData(MemberInit member)
3277 if(member.initializer)
3278 ProcessInitializer(member.initializer);
3281 static void ProcessInstantiation(Instantiation inst)
3285 MembersInit members;
3286 for(members = inst.members->first; members; members = members.next)
3288 if(members.type == dataMembersInit)
3290 if(members.dataMembers)
3293 for(member = members.dataMembers->first; member; member = member.next)
3294 ProcessMemberInitData(member);
3297 else if(members.type == methodMembersInit)
3299 ProcessFunction((FunctionDefinition)members.function);
3305 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3306 public void ProcessMemberAccess()
3309 for(external = ast->first; external; external = external.next)
3311 curExternal = external;
3312 // There shouldn't be any class member access here anyways...
3313 if(external.type == declarationExternal)
3315 if(external.declaration)
3316 ProcessDeclaration(external.declaration);
3320 for(external = ast->first; external; external = external.next)
3322 curExternal = external;
3323 if(external.type == functionExternal)
3325 ProcessFunction(external.function);
3327 else if(external.type == declarationExternal)
3329 //currentClass = external.function._class;
3330 if(external.declaration)
3331 ProcessDeclaration(external.declaration);
3333 else if(external.type == classExternal)
3335 ClassDefinition _class = external._class;
3336 //currentClass = external.symbol.registered;
3337 if(_class.definitions)
3340 Class regClass = _class.symbol.registered;
3342 // Process all functions
3343 for(def = _class.definitions->first; def; def = def.next)
3345 if(def.type == functionClassDef)
3347 curExternal = def.function.declarator.symbol.pointerExternal;
3348 ProcessFunction((FunctionDefinition)def.function);
3350 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3352 ProcessInstantiation(def.decl.inst);
3354 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3356 MemberInit defProperty;
3358 // Add this to the context
3361 string = CopyString("this");
3362 type = MkClassType(regClass.fullName);
3364 globalContext.symbols.Add((BTNode)thisSymbol);
3366 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3368 //thisClass = regClass;
3369 ProcessMemberInitData(defProperty); //, regClass, &id);
3373 //globalContext.symbols.Delete((BTNode)thisSymbol);
3374 globalContext.symbols.Remove((BTNode)thisSymbol);
3375 FreeSymbol(thisSymbol);
3377 else if(def.type == propertyClassDef && def.propertyDef)
3379 PropertyDef prop = def.propertyDef;
3381 // Add this to the context
3384 string = CopyString("this");
3385 type = MkClassType(regClass.fullName);
3387 globalContext.symbols.Add((BTNode)thisSymbol);
3389 //thisClass = regClass;
3392 curExternal = prop.symbol.externalSet;
3393 ProcessStatement(prop.setStmt);
3397 curExternal = prop.symbol.externalGet;
3398 ProcessStatement(prop.getStmt);
3402 curExternal = prop.symbol.externalIsSet;
3403 ProcessStatement(prop.issetStmt);
3408 //globalContext.symbols.Delete((BTNode)thisSymbol);
3409 globalContext.symbols.Remove((BTNode)thisSymbol);
3410 FreeSymbol(thisSymbol);
3412 else if(def.type == classPropertyClassDef && def.propertyDef)
3414 PropertyDef prop = def.propertyDef;
3416 //thisClass = regClass;
3419 curExternal = prop.symbol.externalSet;
3420 ProcessStatement(prop.setStmt);
3424 curExternal = prop.symbol.externalGet;
3425 ProcessStatement(prop.getStmt);
3429 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3431 PropertyWatch propertyWatch = def.propertyWatch;
3433 // Add this to the context
3436 string = CopyString("this");
3437 type = MkClassType(regClass.fullName);
3439 globalContext.symbols.Add((BTNode)thisSymbol);
3441 //thisClass = regClass;
3442 if(propertyWatch.compound)
3446 string = CopyString("this");
3447 type = MkClassType(regClass.fullName);
3449 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3451 ProcessStatement(propertyWatch.compound);
3453 // thisClass = null;
3455 //globalContext.symbols.Delete((BTNode)thisSymbol);
3456 globalContext.symbols.Remove((BTNode)thisSymbol);
3457 FreeSymbol(thisSymbol);