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);
29 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
31 memberExp.member.exp = idExp;
33 exp.type = bracketsExp;
34 exp.list = bracketExp.list;
35 bracketExp.list = null;
37 exp.list->Remove(idExp);
38 exp.list->Add(newExp);
39 FreeExpression(bracketExp);
41 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
44 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
45 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
47 Expression newExp = null;
48 Expression exp = *expPtr;
51 newExp = CopyExpression(exp);
52 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
54 exp.type = bracketsExp;
55 exp.list = memberExp.list;
56 memberExp.list = null;
58 exp.list->Remove(exp.list->last);
59 exp.list->Add(newExp);
60 FreeExpression(memberExp);
62 *expPtr = newExp; //FixRefExp(newExp);
66 static Expression FixRefExp(Expression exp)
70 _FixRefExp(&exp, &exp.op.exp1);
71 _FixRefExp(&exp, &exp.op.exp2);
73 else if(exp.type == indexExp)
74 _FixRefExp(&exp, &exp.index.exp);
75 else if(exp.type == memberExp)
76 _FixRefExp(&exp, &exp.member.exp);
80 static Expression FixReference(Expression e, bool wantReference)
82 if(e.expType && e.type != constantExp)
84 Type type = e.expType;
85 bool isPointer = false;
87 if(type.kind == TypePointer && type.type && type.type.kind == classType)
94 if(type.kind == classType) // || type.kind == TypeInt)
96 Class _class = type._class ? type._class.registered : null;
97 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
98 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
99 if(_class && (_class.type == structClass || _class.type == noHeadClass ||
100 (_class.type == systemClass && _class.base &&
101 strcmp(_class.fullName, "uintptr") &&
102 strcmp(_class.fullName, "intptr") &&
103 strcmp(_class.fullName, "uintsize") &&
104 strcmp(_class.fullName, "intsize") &&
105 strcmp(_class.fullName, "ecere::com::Instance") &&
106 strcmp(_class.fullName, "ecere::com::Class") &&
107 strcmp(_class.dataTypeString, "char *"))))
109 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
110 if(wantReference != (e.byReference || isPointer))
115 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
119 exp.byReference = wantReference;
120 exp = exp.list->last;
125 else if(exp.type == castExp)
127 exp.byReference = wantReference;
130 else if(exp.type == conditionExp)
132 if(exp.cond.exp->last)
133 FixReference(exp.cond.exp->last, wantReference);
134 FixReference(exp.cond.elseExp, wantReference);
139 if(wantReference != (exp.byReference || isPointer))
141 Expression newExp { };
144 if(exp.destType) exp.destType.refCount++;
145 if(exp.expType) exp.expType.refCount++;
149 exp.op.exp2 = newExp;
155 e.byReference = wantReference;
156 exp.byReference = wantReference;
169 static bool FixMember(Expression exp)
171 bool byReference = false;
174 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
176 if(exp.list->count > 1)
178 exp = exp.list->last;
180 else if(exp.type == castExp)
187 FixReference(exp, true);
189 byReference = exp.byReference;
196 static void ProcessExpression(Expression exp)
198 Location oldyylloc = yylloc;
200 char debugExpString[1024] = "";
201 PrintExpression(exp, debugExpString);
211 if(exp.expType && exp.expType.kind == methodType)
213 Class _class = exp.expType.methodClass;
214 Method method = exp.expType.method;
215 if(method.type == virtualMethod)
220 OldList * specs = MkList();
221 strcpy(name, "__ecereVMethodID_");
222 FullClassNameCat(name, method._class.fullName, false);
224 strcat(name, method.name);
226 DeclareMethod(method, name);
228 // Cast function to its type
229 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
230 if(!method.dataType.staticMethod)
232 Declarator funcDecl = GetFuncDecl(decl);
234 if(!funcDecl.function.parameters)
235 funcDecl.function.parameters = MkList();
237 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
238 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
240 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
241 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
244 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
245 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
248 typeName = MkTypeName(specs, decl);
252 char className[1024];
253 // Need the class itself here...
254 strcpy(className, "__ecereClass_");
255 FullClassNameCat(className, _class.fullName, true);
256 MangleClassName(className);
259 _class.symbol = FindClass(_class.fullName);
260 DeclareClass(_class.symbol, className);
262 exp.type = bracketsExp;
263 exp.list = MkListOne(MkExpCast(typeName,
264 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
265 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
271 strcpy(name, "__ecereMethod_");
272 FullClassNameCat(name, method._class.fullName, false);
274 strcat(name, method.name);
276 delete exp.identifier.string;
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);
714 ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
715 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
719 ProcessExpression(exp);
725 if((!convertTo && prop.Set) || (convertTo && prop.Get))
727 Expression value = exp.op.exp2;
728 char setName[1024], getName[1024];
729 char * setToUse = convertTo ? getName : setName;
730 char * getToUse = convertTo ? setName : getName;
731 bool needAddress = false;
732 int operator = exp.op.op;
735 case MUL_ASSIGN: operator = '*'; break;
736 case DIV_ASSIGN: operator = '/'; break;
737 case MOD_ASSIGN: operator = '%'; break;
738 case SUB_ASSIGN: operator = '-'; break;
739 case ADD_ASSIGN: operator = '+'; break;
740 case LEFT_ASSIGN: operator = LEFT_OP; break;
741 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
742 case AND_ASSIGN: operator = '&'; break;
743 case OR_ASSIGN: operator = '|'; break;
744 case XOR_ASSIGN: operator = '^'; break;
749 if(operator == INC_OP)
750 value = MkExpOp(CopyExpression(memberExp),
751 '+', MkExpConstant("1"));
752 else if(operator == DEC_OP)
753 value = MkExpOp(CopyExpression(memberExp),
754 '-', MkExpConstant("1"));
757 value = MkExpOp(CopyExpression(memberExp),
761 value.expType = memberExp.expType;
762 memberExp.expType.refCount++;
763 value.usage.usageArg = true;
767 // Dont free exp2, we're using it
772 value.usage.usageArg = true;
774 DeclareProperty(prop, setName, getName);
776 if(memberExp.member.exp)
777 ProcessExpression(memberExp.member.exp);
779 // If get flag present
780 if(exp.usage.usageGet &&
781 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
783 OldList * list = MkList();
786 Context context = PushContext();
789 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
790 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
792 curContext = context;
793 exp.type = extensionCompoundExp;
794 exp.compound = MkCompoundStmt(
795 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
796 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
797 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
804 ListAdd(args, value);
805 ListAdd(args, QMkExpId(ecereTemp));
806 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
810 ListAdd(args, QMkExpId(ecereTemp));
811 ListAdd(args, value);
812 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
818 ListAdd(args, QMkExpId(ecereTemp));
820 args->Insert(null, QMkExpId(ecereTemp));
821 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
823 exp.compound.compound.context = context;
825 curContext = context.parent;
829 Expression newExp = exp;
831 if(parentExp && parentExp.type == extensionCompoundExp)
833 newExp = Expression { };
834 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
835 FreeType(exp.expType);
836 FreeType(exp.destType);
839 parentExp.type = dummyExp;
840 parentExp.expType = null;
841 parentExp.destType = null;
844 newExp.type = callExp;
845 newExp.call.exp = QMkExpId(setToUse);
846 newExp.call.arguments = MkList();
849 ListAdd(newExp.call.arguments, value);
850 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
854 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
855 ListAdd(newExp.call.arguments, value);
860 // Take it out from there
861 memberExp.member.exp = null;
863 // Don't use the temporaries used by the left side...
866 value.tempCount = exp.tempCount;
867 ProcessExpression(value);
869 FixReference(value, true);
872 FreeExpression(memberExp);
876 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
879 memberExp.member.memberType = dataMember;
882 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
887 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
888 if(method && method.type == virtualMethod && type.kind != subClassType)
890 Expression value = exp.op.exp2;
891 // Don't use the temporaries used by the left side...
892 value.tempCount = exp.tempCount;
893 ProcessExpression(value);
895 if(memberExp.member.exp)
896 ProcessExpression(memberExp.member.exp);
898 if(exp.usage.usageGet)
900 OldList * list = MkList();
905 ListAdd(args, memberExp.member.exp);
907 char * string = QMkString(memberExp.member.member.string);
908 ListAdd(args, MkExpString(string));
911 ListAdd(args, value);
912 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
913 ListAdd(list, CopyExpression(value));
914 exp.type = bracketsExp;
921 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
922 exp.call.arguments = MkList();
923 ListAdd(exp.call.arguments, memberExp.member.exp);
925 char * string = QMkString(memberExp.member.member.string);
926 ListAdd(exp.call.arguments, MkExpString(string));
929 ListAdd(exp.call.arguments, value);
932 memberExp.member.exp = null;
935 FreeExpression(memberExp);
939 else if(memberExp.member.memberType == dataMember)
941 //if(exp.usage & USAGE_GET);
942 //FixReference(value, true);
943 if(FixMember(memberExp.member.exp))
945 // TESTING THIS HERE:
946 ProcessExpression(memberExp);
948 memberExp.type = pointerExp;
955 else if(exp.op.op == _INCREF)
957 Expression object = exp.op.exp2;
959 FreeExpContents(exp);
963 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
965 else if(exp.op.op == DELETE)
967 Expression object = exp.op.exp2;
968 OldList * args = MkList();
970 exp.type = bracketsExp;
973 object.usage.usageDelete = true;
975 ProcessExpression(object);
977 ListAdd(args, object);
979 // TOFIX: Same time as when we fix for = 0
981 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
982 ((exp.expType._class.registered.type == normalClass &&
983 // TODO: Improve on this, only fixed this issue here... Different String class defined in each module
984 !eClass_IsDerived(exp.expType._class.registered, eSystem_FindClass(exp.expType._class.registered.module, "char *")) /*strcmp(exp.expType._class.string, "String")*/) ||
985 (exp.expType._class.registered.type == systemClass && !strcmp(exp.expType._class.string, "ecere::com::Instance"))))
987 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
988 ProcessExpressionType(decRefExp);
989 ListAdd(exp.list, decRefExp);
991 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
994 char className[1024];
995 OldList * list = MkList();
997 strcpy(className, "__ecereClass_");
998 FullClassNameCat(className, exp.expType._class.string, true);
999 MangleClassName(className);
1001 DeclareClass(exp.expType._class, className);
1003 // Call the non virtual destructor
1004 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1005 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1007 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1009 MkExpBrackets(MkListOne(MkExpCondition(
1010 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1011 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1016 OldList * list = MkList();
1018 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1020 char className[1024];
1022 if(_class.templateClass) _class = _class.templateClass;
1023 strcpy(className, "__ecereClass_");
1024 FullClassNameCat(className, _class.fullName, false /*true*/);
1025 MangleClassName(className);
1028 _class.symbol = FindClass(_class.fullName);
1029 DeclareClass(_class.symbol, className);
1031 // Call the non virtual destructor
1035 QMkExpId(className),
1036 MkIdentifier("Destructor")
1041 QMkExpId(className),
1042 MkIdentifier("Destructor")
1044 CopyList(args, CopyExpression)
1051 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1056 CopyExpression(object),
1066 else if(exp.expType && exp.expType.kind == templateType)
1068 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1071 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1073 OldList * qualifiers = MkList();
1074 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1076 typeName = MkTypeName(qualifiers, declarator);
1078 ProcessExpressionType(classExp);
1079 args->Insert(null, CopyExpression(classExp));
1080 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1081 ListAdd(exp.list, MkExpCall(
1082 MkExpBrackets(MkListOne(MkExpCast(typeName,
1083 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1084 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1085 //ProcessExpression(exp.list->last);
1089 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1091 //ProcessExpression(object);
1093 ListAdd(exp.list, MkExpOp(CopyExpression(object), '=', MkExpConstant("0")));
1097 // TESTING THIS HERE...
1098 ProcessExpression(exp);
1101 if(exp.type == opExp)
1103 // Handle assigment of template structures
1104 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1105 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1107 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1110 // memcpy((byte *)array + (count * dataTypeClass.size), dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1112 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1113 OldList * args = MkList();
1114 Expression derefExp = exp.op.exp1;
1115 Expression sizeExp = MkExpCondition(MkExpBrackets(MkListOne(
1117 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1119 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1120 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1121 MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize")));
1123 if(exp.op.exp1.type == indexExp)
1125 Expression indexExp = derefExp.index.exp;
1126 OldList * indexExpIndex = derefExp.index.index;
1128 derefExp.index.index = null;
1129 derefExp.index.exp = null;
1130 FreeExpression(derefExp);
1132 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1133 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1137 Expression indexExp = derefExp.op.exp2;
1138 derefExp.op.exp2 = null;
1139 FreeExpression(derefExp);
1140 derefExp = indexExp;
1143 args->Add(derefExp);
1144 ProcessExpressionType(args->last);
1145 ProcessExpression(args->last);
1147 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1148 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1149 MkListOne(exp.op.exp2), MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1151 thisClass = curExternal.function ? curExternal.function._class : null;
1155 string = CopyString("this");
1156 type = MkClassType(thisClass.fullName);
1158 globalContext.symbols.Add((BTNode)thisSymbol);
1160 ProcessExpressionType(args->last);
1161 ProcessExpression(args->last);
1164 ProcessExpressionType(args->last);
1165 ProcessExpression(args->last);
1167 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1168 exp.type = bracketsExp;
1170 //globalContext.symbols.Delete((BTNode)thisSymbol);
1171 globalContext.symbols.Remove((BTNode)thisSymbol);
1172 FreeSymbol(thisSymbol);
1178 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1179 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1181 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1184 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1185 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1187 exp.type = bracketsExp;
1188 exp.list = MkListOne(
1190 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1192 // ((class.type == structClass) ?
1193 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1196 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1198 // ((class.type == normalClass || class.type == noHeadClass) ?
1199 MkExpCondition(MkExpBrackets(MkListOne(
1201 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1203 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1204 // *((void **)array)
1205 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1206 CopyExpression(exp.op.exp2))))))),
1208 // ((class.size == 1) ?
1209 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1211 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1212 CopyExpression(exp.op.exp2)))))),
1214 // ((class.size == 2) ?
1215 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1216 // *((uint16 *)array)
1217 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1218 CopyExpression(exp.op.exp2)))))),
1220 // ((class.size == 4) ?
1221 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1222 // *((uint32 *)array)
1223 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1224 CopyExpression(exp.op.exp2)))))),
1226 // *((uint64 *)array)
1227 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1228 exp.op.exp2)))))))))))))))))))));
1230 // Add this to the context
1231 thisClass = curExternal.function ? curExternal.function._class : null;
1235 string = CopyString("this");
1236 type = MkClassType(thisClass.fullName);
1238 globalContext.symbols.Add((BTNode)thisSymbol);
1240 ProcessExpressionType(exp.list->first);
1241 ProcessExpression(exp.list->first);
1243 //globalContext.symbols.Delete((BTNode)thisSymbol);
1244 globalContext.symbols.Remove((BTNode)thisSymbol);
1245 FreeSymbol(thisSymbol);
1256 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1257 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1258 ProcessExpression(exp.op.exp1);
1261 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1262 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1263 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1264 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*/))
1265 FixReference(exp.op.exp1, false);
1266 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1270 // Don't use the temporaries used by the left side...
1272 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1273 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1274 ProcessExpression(exp.op.exp2);
1275 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1279 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1280 (exp.op.exp2.expType._class.registered.type != normalClass &&
1281 exp.op.exp2.expType._class.registered.type != structClass &&
1282 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1284 // TESTING THIS TEMPLATE TYPE CHECK HERE
1285 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1287 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1288 //FixReference(exp.op.exp2, false);
1291 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1294 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)
1296 // Preserve prev, next
1297 Expression next = exp.next, prev = exp.prev;
1298 Expression derefExp = exp.op.exp2;
1299 Expression refExp = exp.op.exp2.op.exp2;
1300 Type expType = exp.expType, destType = exp.destType;
1302 derefExp.op.exp2 = null;
1303 FreeExpression(derefExp);
1304 FreeType(exp.expType);
1305 FreeType(exp.destType);
1315 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)
1317 Expression exp2 = exp.op.exp2;
1318 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1321 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1323 exp.type = bracketsExp;
1324 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1325 MkExpOp(null, '&', exp2)), '+',
1326 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1327 MkListOne((e = MkExpCondition(MkExpBrackets(MkListOne(
1331 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))),
1333 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))),
1335 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))))
1337 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1338 MkExpMember(classExp, MkIdentifier("typeSize"))))))));
1340 // Add this to the context
1341 thisClass = curExternal.function ? curExternal.function._class : null;
1345 string = CopyString("this");
1346 type = MkClassType(thisClass.fullName);
1348 //globalContext.symbols.Add((BTNode)thisSymbol);
1350 ProcessExpressionType(e);
1351 ProcessExpression(e);
1353 //globalContext.symbols.Remove((BTNode)thisSymbol);
1354 //FreeSymbol(thisSymbol);
1363 FreeExpression(exp1);
1365 FreeExpression(exp2);
1370 case extensionExpressionExp:
1375 for(e = exp.list->first; e; e = e.next)
1379 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1381 e.tempCount = exp.tempCount;
1382 ProcessExpression(e);
1384 exp.byReference = e.byReference;
1385 exp.tempCount = e.tempCount;
1389 exp.expType = e.expType;
1398 /*bool isBuiltin = exp && exp.index.exp &&
1399 (exp.index.exp.type == ExpressionType::arrayExp ||
1400 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1402 Expression checkedExp = exp.index.exp;
1403 bool isBuiltin = false;
1405 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1407 if(checkedExp.type == extensionCompoundExp)
1412 else if(checkedExp.type == bracketsExp)
1413 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1415 checkedExp = checkedExp.cast.exp;
1418 exp.index.exp.tempCount = exp.tempCount;
1420 exp.index.exp.usage.usageGet = true;
1421 ProcessExpression(exp.index.exp);
1423 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1424 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1426 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1429 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1430 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1432 exp.type = bracketsExp;
1433 exp.list = MkListOne(
1435 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1437 // ((class.type == structClass) ?
1438 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1439 // ((byte *)array) + (i) * class.size
1440 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1441 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1442 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1444 // ((class.type == normalClass || class.type == noHeadClass) ?
1445 MkExpCondition(MkExpBrackets(MkListOne(
1447 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1449 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1450 // ((void **)array)[i]
1451 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1452 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression)))),
1454 // ((class.size == 1) ?
1455 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1456 // ((byte *)array)[i]
1457 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1458 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1460 // ((class.size == 2) ?
1461 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1462 // ((uint16 *)array)[i]
1463 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1464 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1466 // ((class.size == 4) ?
1467 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1468 // ((uint32 *)array)[i]
1469 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1470 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1472 // ((uint64 *)array)[i]
1473 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1474 exp.index.exp))), exp.index.index))))))))))))))))));
1476 // Add this to the context
1477 thisClass = curExternal.function ? curExternal.function._class : null;
1481 string = CopyString("this");
1482 type = MkClassType(thisClass.fullName);
1484 globalContext.symbols.Add((BTNode)thisSymbol);
1486 ProcessExpressionType(exp.list->first);
1487 ProcessExpression(exp.list->first);
1489 //globalContext.symbols.Delete((BTNode)thisSymbol);
1490 globalContext.symbols.Remove((BTNode)thisSymbol);
1491 FreeSymbol(thisSymbol);
1499 for(e = exp.index.index->first; e; e = e.next)
1502 e.usage.usageGet = true;
1503 ProcessExpression(e);
1505 // Ignore temps in the index for now...
1506 exp.tempCount = exp.index.exp.tempCount;
1508 if(exp.index.exp.expType)
1510 Type source = exp.index.exp.expType;
1511 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1512 eClass_IsDerived(source._class.registered, containerClass))
1514 Class _class = source._class.registered;
1515 bool isArray = false;
1516 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1517 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1519 if(isArray && _class.templateArgs)
1521 OldList * specs = MkList();
1522 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1523 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
1524 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1525 ProcessExpressionType(exp.index.exp);
1526 ProcessExpression(exp);
1528 else if(isBuiltin && _class.templateArgs)
1530 OldList * specs = MkList();
1531 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1532 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
1533 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1534 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1535 ProcessExpressionType(exp.index.exp);
1536 ProcessExpression(exp);
1538 else if(_class.templateArgs)
1540 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1542 char iteratorType[1024];
1543 OldList * declarations = MkList();
1544 OldList * statements = MkList();
1545 OldList * args = MkList();
1546 OldList * instMembers = MkList();
1548 Context context = PushContext();
1550 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1552 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1554 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1555 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1557 ListAdd(args, MkExpBrackets(exp.index.index));
1558 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1560 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1561 MkIdentifier("Index")), args))));
1563 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1564 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1566 exp.type = bracketsExp;
1567 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1568 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1569 expExt.compound.compound.context = context;
1570 PopContext(context);
1571 expExt.usage = exp.usage;
1572 ProcessExpressionType(exp.list->first);
1573 ProcessExpressionInstPass(exp.list->first);
1574 ProcessExpression(exp.list->first);
1583 Expression memberExp;
1584 bool typedObject = false;
1585 Type ellipsisDestType = null;
1586 bool usedEllipsis = false;
1588 if(exp.call.arguments)
1590 for(e = exp.call.arguments->first; e; e = e.next)
1592 e.usage.usageGet = true;
1593 e.usage.usageArg = true;
1594 e.tempCount = Max(e.tempCount, exp.tempCount);
1595 ProcessExpression(e);
1596 exp.tempCount = Max(exp.tempCount, e.tempCount);
1599 exp.call.exp.usage.usageGet = true;
1600 exp.call.exp.usage.usageCall = true;
1601 exp.call.exp.tempCount = exp.tempCount;
1602 ProcessExpression(exp.call.exp);
1603 memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1605 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1607 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1608 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1609 Method method = exp.call.exp.expType.method;
1610 if(method.type == virtualMethod)
1616 OldList * specs = MkList();
1617 strcpy(name, "__ecereVMethodID_");
1618 FullClassNameCat(name, method._class.fullName, false);
1620 strcat(name, method.name);
1622 DeclareMethod(method, name);
1625 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1626 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1627 // Cast function to its type
1629 Context context = SetupTemplatesContext(method._class);
1631 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1633 FinishTemplatesContext(context);
1636 if(method.dataType && !method.dataType.staticMethod)
1638 Declarator funcDecl = GetFuncDecl(decl);
1640 if(!funcDecl.function.parameters)
1641 funcDecl.function.parameters = MkList();
1643 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1644 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1646 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1647 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1650 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1654 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)));
1655 // Testing this for any_object::
1656 if(!method.dataType.extraParam)
1657 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1661 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1662 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1666 typeName = MkTypeName(specs, decl);
1668 // Added !exp.call.exp.expType.methodClass
1669 if(memberExp && memberExp.member.exp.expType)
1671 Type type = memberExp.member.exp.expType;
1673 if(type.kind == classType && type._class && type._class.registered)
1675 ClassType classType = memberExp.member.exp.expType._class.registered.type;
1676 if(classType != normalClass || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1677 argClass = type._class.registered;
1679 else if(type.kind == subClassType)
1681 argClass = FindClass("ecere::com::Class").registered;
1683 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1685 argClass = FindClass("char *").registered;
1687 else if(type.kind == pointerType)
1689 argClass = eSystem_FindClass(privateModule, "uintptr");
1690 FreeType(memberExp.member.exp.expType);
1691 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1692 memberExp.member.exp.byReference = false;
1696 char string[1024] = "";
1698 PrintTypeNoConst(type, string, false, true);
1699 classSym = FindClass(string);
1700 if(classSym) argClass = classSym.registered;
1704 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1709 // *** Added !_class here
1710 if(!exp.call.exp.expType.methodClass && (!memberExp || !_class) && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType)
1712 if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
1713 memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)
1715 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1716 // as opposed to the File class vTbl one
1717 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1718 MkExpIndex(MkExpPointer(MkExpBrackets(MkListOne(CopyExpression(memberExp.member.exp))), MkIdentifier("_vTbl")),
1719 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1723 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1724 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl")),
1725 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1728 else if(memberExp && !_class && exp.call.exp.expType._class &&
1729 (memberExp.member.exp.expType.kind == subClassType || (memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
1730 memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)))
1732 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1733 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1734 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1738 char className[1024];
1740 // TESTING: Moved this here...
1741 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1746 // TODO: Unhandled case here, what should happen?
1747 _class = class(int);
1750 // Need the class itself here...
1751 strcpy(className, "__ecereClass_");
1752 FullClassNameCat(className, _class.fullName, true);
1753 MangleClassName(className);
1756 _class.symbol = FindClass(_class.fullName);
1758 DeclareClass(_class.symbol, className);
1760 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1761 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1762 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1768 strcpy(name, "__ecereMethod_");
1769 FullClassNameCat(name, method._class.fullName, false);
1771 strcat(name, method.name);
1773 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1774 DeclareMethod(method, name);
1775 if(memberExp && memberExp.expType && method.dataType)
1777 exp.call.exp.expType = method.dataType;
1778 method.dataType.refCount++;
1781 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1783 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1785 if(!exp.call.arguments)
1786 exp.call.arguments = MkList();
1788 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1790 if(memberExp.member.exp.expType.kind != classType ||
1791 memberExp.member.exp.expType._class.registered.type == enumClass ||
1792 memberExp.member.exp.expType._class.registered.type == unitClass)
1794 char typeString[1024] = "";
1795 if(memberExp.member.exp.expType.kind != classType)
1796 PrintType(memberExp.member.exp.expType, typeString, false, true);
1798 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1801 // memberExp.member.exp.expType.kind = classType;
1802 // memberExp.member.exp.expType._class = FindClass(typeString);
1804 FreeType(memberExp.member.exp.expType);
1805 memberExp.member.exp.expType = Type
1808 _class = FindClass(typeString);
1812 // Default to an int instead
1813 if(!memberExp.member.exp.expType._class)
1815 // TODO: Shouldn't get here...
1816 memberExp.member.exp.expType.kind = TypeInt;
1821 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1823 bool changeReference = false;
1825 // Patched so that class isn't considered SYSTEM...
1826 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1827 strcmp(argClass.fullName, "ecere::com::Class"))
1828 changeReference = true;
1829 if(!memberExp.member.exp.expType.classObjectType &&
1831 (memberExp.member.exp.expType.kind != pointerType &&
1832 (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1833 !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1834 method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
1835 changeReference = true;
1836 if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
1837 changeReference = true;
1840 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1841 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1843 exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1844 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1846 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1848 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1849 memberExp.member.exp.op.exp2 = null;
1851 else if(!memberExp.member.exp.byReference)
1853 // TESTING THIS... REUSE THIS CODE?
1854 Expression checkedExp = memberExp.member.exp;
1855 Expression parentExp = null;
1857 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1859 parentExp = checkedExp;
1860 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1861 checkedExp = checkedExp.list->last;
1862 else if(checkedExp.type == castExp)
1863 checkedExp = checkedExp.cast.exp;
1865 newExp = MkExpOp(null, '&', checkedExp);
1866 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1868 parentExp.list->Remove(checkedExp);
1869 parentExp.list->Add(newExp);
1871 else if(parentExp && parentExp.type == castExp)
1873 parentExp.cast.exp = newExp;
1874 // Add a dereference level here
1875 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
1877 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1880 exp.call.arguments->Insert(null, memberExp.member.exp);
1883 exp.call.arguments->Insert(null, memberExp.member.exp);
1885 //if(memberExp.member.exp && memberExp.member.exp.type == identifierExp && !strcmp(memberExp.member.exp.identifier.string, "this") && FindSymbol("class", curContext, topContext, false))
1886 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1888 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier("class")));
1892 if(memberExp && !argClass)
1893 exp.call.arguments->Insert(null, MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_class")));
1896 char className[1024];
1897 // Need the class itself here...
1898 strcpy(className, "__ecereClass_");
1899 FullClassNameCat(className, argClass.fullName, true);
1900 MangleClassName(className);
1902 if(!argClass.symbol)
1903 argClass.symbol = FindClass(argClass.fullName);
1904 DeclareClass(argClass.symbol, className);
1905 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
1910 exp.call.arguments->Insert(null, memberExp.member.exp);
1911 memberExp.member.exp = null;
1913 FreeExpression(memberExp);
1915 /*else if(method->dataType)
1919 if(exp.call.arguments)
1921 for(e = exp.call.arguments->first; e; e = e.next)
1923 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
1924 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
1925 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
1926 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
1928 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
1929 ellipsisDestType = destType;
1932 Type type = e.expType;
1933 Class _class = null;
1934 //Type destType = e.destType;
1936 if(type.kind == classType && type._class && type._class.registered)
1938 _class = type._class.registered;
1940 else if(type.kind == subClassType)
1942 _class = FindClass("ecere::com::Class").registered;
1944 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1946 _class = FindClass("char *").registered;
1948 else if(type.kind == pointerType)
1950 _class = eSystem_FindClass(privateModule, "uintptr");
1951 FreeType(e.expType);
1952 e.expType = ProcessTypeString("uintptr", false);
1956 char string[1024] = "";
1958 PrintTypeNoConst(type, string, false, true);
1959 classSym = FindClass(string);
1960 if(classSym) _class = classSym.registered;
1961 // if(!class) _class = eSystem_FindClass(privateModule, "int");
1964 if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
1965 (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
1966 destType.byReference)))
1968 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
1969 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
1970 // TESTING WITHOUT THE ABOVE NOW!
1972 Expression checkedExp;
1973 Expression parentExp;
1978 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
1980 parentExp = checkedExp;
1981 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
1983 if(checkedExp.type == extensionCompoundExp)
1985 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
1988 checkedExp = checkedExp.list->last;
1990 else if(checkedExp.type == castExp)
1991 checkedExp = checkedExp.cast.exp;
1994 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
1997 Expression newExp = e.op.exp2;
1998 exp.call.arguments->Insert(e.prev, newExp);
1999 exp.call.arguments->Remove(e);
2004 newExp = checkedExp.op.exp2;
2005 checkedExp.op.exp2 = null;
2006 FreeExpContents(checkedExp);
2008 if(e.expType && e.expType.passAsTemplate)
2011 ComputeTypeSize(e.expType);
2012 sprintf(size, "%d", e.expType.size);
2013 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2014 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2015 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2018 if(parentExp.type == callExp)
2020 exp.call.arguments->Insert(e.prev, newExp);
2021 exp.call.arguments->Remove(e);
2024 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2026 parentExp.list->Remove(checkedExp);
2027 parentExp.list->Add(newExp);
2029 else if(parentExp.type == castExp)
2031 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2032 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2034 FreeTypeName(parentExp.cast.typeName);
2035 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2037 parentExp.cast.exp = newExp;
2039 else if(parentExp.type == extensionCompoundExp)
2041 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2042 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2044 e.byReference = true;
2046 FreeType(checkedExp.expType);
2047 FreeType(checkedExp.destType);
2050 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2052 Expression checkedExp;
2053 Expression parentExp;
2057 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2059 e.type == identifierExp ||
2060 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2061 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2062 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2065 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2067 Context context = PushContext();
2069 OldList * specs = MkList();
2070 char typeString[1024];
2071 Expression newExp { };
2073 typeString[0] = '\0';
2076 // TOCHECK: Should this read e.destType ???
2078 if(exp.destType) exp.destType.refCount++;
2079 // if(exp.expType) exp.expType.refCount++;
2082 newExp.expType = null;
2084 PrintTypeNoConst(e.expType, typeString, false, true);
2085 decl = SpecDeclFromString(typeString, specs, null);
2086 newExp.destType = ProcessType(specs, decl);
2088 curContext = context;
2089 e.type = extensionCompoundExp;
2091 // We need a current compound for this
2095 OldList * stmts = MkList();
2096 sprintf(name, "__internalValue%03X", internalValueCounter++);
2097 if(!curCompound.compound.declarations)
2098 curCompound.compound.declarations = MkList();
2099 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2100 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2101 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2102 e.compound = MkCompoundStmt(null, stmts);
2105 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2109 e.compound = MkCompoundStmt(
2110 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2111 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2114 e.compound.compound.context = context;
2115 PopContext(context);
2116 curContext = context.parent;
2120 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2123 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2125 parentExp = checkedExp;
2126 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2128 if(checkedExp.type == extensionCompoundExp)
2130 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2133 checkedExp = checkedExp.list->last;
2135 else if(checkedExp.type == castExp)
2136 checkedExp = checkedExp.cast.exp;
2138 newExp = MkExpOp(null, '&', checkedExp);
2139 newExp.byReference = true;
2140 if(parentExp.type == callExp)
2142 exp.call.arguments->Insert(e.prev, newExp);
2143 exp.call.arguments->Remove(e);
2146 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2148 parentExp.list->Remove(checkedExp);
2149 parentExp.list->Add(newExp);
2151 else if(parentExp.type == castExp)
2152 parentExp.cast.exp = newExp;
2153 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2155 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2156 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2162 if(destType.classObjectType == ClassObjectType::typedObject)
2164 char className[1024];
2165 // Need the class itself here...
2166 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2167 _class = eSystem_FindClass(privateModule, "String");
2168 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2170 if(!strcmp(_class.name, "class"))
2172 // Already inside a typed_object function, pass the class through
2173 strcpy(className, "class");
2177 strcpy(className, "__ecereClass_");
2178 FullClassNameCat(className, _class.fullName, true);
2179 MangleClassName(className);
2182 _class.symbol = FindClass(_class.fullName);
2184 DeclareClass(_class.symbol, className);
2186 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2192 //char debugString[4096] = "";
2193 //PrintExpression(e, debugString);
2195 // If expression type is a simple class, make it an address
2196 FixReference(e, true);
2199 if(ellipsisDestType)
2202 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2203 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2205 exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2213 bool changeToPtr = false;
2214 bool noHead = false;
2215 Type type = exp.member.exp.expType;
2216 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2217 if(exp.member.member) exp.member.member._class = null;
2219 if(type && type.kind == templateType)
2221 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2222 if(baseType) type = baseType;
2224 if(type && exp.member.member && !type.directClassAccess)
2226 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2227 Property prop = null;
2228 ClassProperty classProperty = null;
2229 Method method = null;
2230 Class convertTo = null;
2231 DataMember member = null;
2232 bool thisPtr = exp.member.thisPtr;
2233 if(type.kind == subClassType && exp.member.exp.type == classExp)
2234 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2236 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2240 // DANGER: Buffer overflow
2241 char string[2048] = "";
2243 PrintTypeNoConst(type, string, false, true);
2244 classSym = FindClass(string);
2245 _class = classSym ? classSym.registered : null;
2248 if(_class && exp.member.memberType == dataMember)
2250 if(!thisPtr && !exp.member.member.classSym)
2251 member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
2253 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2255 else if(_class && exp.member.memberType == propertyMember)
2257 if(!thisPtr && !exp.member.member.classSym)
2258 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2260 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2261 if(prop && (exp.usage.usageRef ||
2262 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2263 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2265 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2268 exp.member.memberType = dataMember;
2273 if(exp.usage.usageRef)
2274 Compiler_Error($"cannot obtain address of property\n");
2276 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2277 else if(exp.usage.usageDelete)
2278 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2282 else if(_class && exp.member.memberType == methodMember)
2285 method = eClass_FindMethod(_class, exp.member.member.string, null);
2287 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2289 else if(_class && exp.member.memberType == reverseConversionMember)
2292 _class = FindClass(exp.member.member.string).registered;
2293 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2294 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2296 else if(_class && exp.member.memberType == classPropertyMember)
2298 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2302 // Only process Gets here, Set is processed in opExp's '='
2303 if(exp.usage.usageGet)
2307 char getName[1024], setName[1024];
2308 Expression ptr = exp.member.exp;
2309 Class propertyClass;
2310 char * nameToUse = convertTo ? setName : getName;
2312 FreeIdentifier(exp.member.member);
2314 // Process this here since it won't be processed at the end...
2315 exp.member.exp.usage.usageGet = true;
2316 ProcessExpression(exp.member.exp);
2317 // TEST: exp.tempCount = exp.member.exp.tempCount;
2319 DeclareProperty(prop, setName, getName);
2320 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2321 propertyClass = convertTo ? _class :
2322 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2325 if(propertyClass && propertyClass.type == bitClass)
2327 // Bit classes shouldn't have properties except for conversions...
2328 OldList * args = MkList();
2329 if(exp.usage.usageDeepGet)
2331 char className[1024];
2333 Declarator declarator;
2334 OldList * specs = MkList(), * decls = MkList();
2337 // Make a declaration in the closest compound statement
2338 // (Do not reuse (since using address for function calls)...)
2339 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2341 SpecDeclFromString(propertyClass.dataTypeString, specs,
2342 MkDeclaratorIdentifier(MkIdentifier(className)));
2344 ListAdd(decls, MkInitDeclarator(declarator, null));
2346 decl = MkDeclaration(specs, decls);
2347 if(!curCompound.compound.declarations)
2348 curCompound.compound.declarations = MkList();
2349 curCompound.compound.declarations->Insert(null, decl);
2351 tempExp = QMkExpId(className);
2352 tempExp.expType = MkClassType(propertyClass.fullName);
2354 exp.op.exp1 = tempExp;
2355 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2362 exp.call.exp = QMkExpId(nameToUse);
2363 exp.call.arguments = args;
2365 ListAdd(args, FixReference(ptr, true));
2367 else if(propertyClass && propertyClass.type == unitClass)
2369 OldList * args = MkList();
2370 ListAdd(args, FixReference(ptr, true));
2372 exp.call.exp = QMkExpId(nameToUse);
2373 exp.call.arguments = args;
2375 else if(propertyClass && propertyClass.type == structClass)
2377 OldList * args = MkList();
2378 char className[1024];
2380 OldList * specs = MkList(), * decls = MkList();
2383 // Make a declaration in the closest compound statement
2384 // (Do not reuse (since using address for function calls)...)
2387 FullClassNameCat(className, propertyClass.fullName, false); //true);
2389 //ListAdd(specs, MkSpecifierName(className));
2390 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2392 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2394 ListAdd(decls, MkInitDeclarator(
2395 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2397 decl = MkDeclaration(specs, decls);
2400 if(!curCompound.compound.declarations)
2401 curCompound.compound.declarations = MkList();
2402 curCompound.compound.declarations->Insert(null, decl);
2405 tempExp = QMkExpId(className);
2406 tempExp.expType = MkClassType(propertyClass.fullName);
2410 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2411 ListAdd(args, FixReference(ptr, true));
2415 ListAdd(args, FixReference(ptr, true));
2416 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2419 if(exp.usage.usageDeepGet)
2422 exp.call.exp = QMkExpId(nameToUse);
2423 exp.call.arguments = args;
2425 FreeExpression(tempExp);
2429 exp.type = bracketsExp;
2430 exp.list = MkList();
2431 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2432 if(exp.usage.usageMember)
2434 ListAdd(exp.list, FixReference(tempExp, true));
2435 exp.byReference = true;
2438 ListAdd(exp.list, tempExp);
2444 exp.call.exp = QMkExpId(nameToUse);
2445 exp.call.arguments = MkList();
2446 ListAdd(exp.call.arguments, FixReference(ptr, true));
2449 else if(prop.conversion)
2451 void * prev = exp.prev, * next = exp.next;
2452 *exp = *exp.member.exp;
2458 else if(classProperty)
2460 // Only process Gets here, Set is processed in opExp's '='
2461 if(exp.usage.usageGet)
2463 if(classProperty.Get)
2465 Identifier id = exp.member.member;
2466 Expression classExp = exp.member.exp;
2470 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty"));
2471 exp.call.arguments = MkList();
2472 ListAdd(exp.call.arguments, classExp);
2473 ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
2476 ProcessExpression(exp);
2483 // Get the function address if it's not called
2484 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2488 FreeIdentifier(exp.member.member);
2490 // Process this here since it won't be processed at the end...
2491 exp.member.exp.usage.usageGet = true;
2492 ProcessExpression(exp.member.exp);
2493 // TEST: exp.tempCount = exp.member.exp.tempCount;
2495 if(method.type == virtualMethod)
2497 strcpy(name, "__ecereVMethodID_");
2498 FullClassNameCat(name, method._class.fullName, false);
2500 strcat(name, method.name);
2501 exp.type = indexExp;
2502 if(memberClassSpecifier)
2504 char className[1024];
2505 // Need the class itself here...
2506 strcpy(className, "__ecereClass_");
2507 FullClassNameCat(className, _class.fullName, true);
2508 MangleClassName(className);
2511 _class.symbol = FindClass(_class.fullName);
2512 DeclareClass(_class.symbol, className);
2513 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2515 // WHAT HAPPENS TO exp.member.exp ?
2519 if(exp.thisPtr && _class.type != normalClass)
2521 FreeExpression(exp.member.exp);
2522 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2525 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2527 exp.index.index = MkListOne(QMkExpId(name));
2528 DeclareMethod(method, name);
2532 FreeExpression(exp.member.exp);
2533 exp.type = identifierExp;
2534 strcpy(name, "__ecereMethod_");
2535 FullClassNameCat(name, method._class.fullName, false);
2537 strcat(name, method.name);
2538 exp.identifier = MkIdentifier(name);
2539 DeclareMethod(method, name);
2545 // Process this here since it won't be processed at the end...
2546 if(exp.usage.usageGet)
2548 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2550 ProcessExpression(exp.member.exp);
2551 // TEST: exp.tempCount = exp.member.exp.tempCount;
2553 if(type.kind == classType)
2554 DeclareStruct(type._class.registered.fullName, false);
2556 // TESTING THIS NOHEAD STUFF...
2557 if(_class.type == noHeadClass)
2561 else if(_class.type == structClass)
2565 else if(_class.type == bitClass)
2567 OldList * list = MkList();
2568 char mask[32], shift[10];
2569 OldList * specs = MkList();
2570 BitMember bitMember = (BitMember) member;
2571 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2572 TypeName type = MkTypeName(specs, decl);
2573 if(bitMember.mask > MAXDWORD)
2574 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2576 sprintf(mask, FORMAT64HEX, bitMember.mask);
2577 sprintf(shift, "%d", bitMember.pos);
2579 FreeIdentifier(exp.member.member);
2581 // ((type) ((color & mask) >> bitPos))
2582 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2583 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2584 MkExpConstant(shift))))));
2586 exp.type = bracketsExp;
2589 else if(_class.type == unitClass)
2594 // If it's a this pointer, replace by precomputed shortcut
2597 char pointerName[1024];
2599 strcpy(pointerName, "__ecerePointer_");
2600 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2601 FreeIdentifier(exp.member.exp.identifier);
2602 exp.member.exp.identifier = MkIdentifier(pointerName);
2604 // Otherwise, access the data the hard way
2607 Expression bytePtr, e;
2608 Expression classExp;
2609 Expression checkedExp;
2610 char structName[1024];
2611 char className[1024];
2612 strcpy(className, "__ecereClass_");
2613 FullClassNameCat(className, member._class.fullName, true);
2614 MangleClassName(className);
2616 // classExp = QMkExpId(className);
2618 if(!member._class.symbol)
2619 member._class.symbol = FindClass(member._class.fullName);
2621 DeclareClass(member._class.symbol, className);
2622 DeclareStruct(member._class.fullName, false);
2625 FullClassNameCat(structName, member._class.fullName, false);
2627 checkedExp = exp.member.exp;
2628 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2629 checkedExp.type == castExp)
2631 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2632 checkedExp = checkedExp.list->last;
2633 else if(checkedExp.type == castExp)
2634 checkedExp = checkedExp.cast.exp;
2637 if(checkedExp.type != identifierExp &&
2638 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2639 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2641 char ecereTemp[100];
2643 OldList * list = MkList();
2644 Context context = PushContext();
2645 if(exp.member.exp.tempCount > exp.tempCount)
2646 exp.tempCount = exp.member.exp.tempCount;
2649 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2650 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2651 curContext = context;
2652 compound = MkCompoundStmt(
2653 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2654 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2655 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2656 if(member._class.fixed)
2658 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2661 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2662 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2665 e = QMkExpId(ecereTemp);
2669 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2670 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2673 compound.compound.context = context;
2674 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2675 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2676 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2678 exp.member.exp = MkExpExtensionCompound(compound);
2680 PopContext(context);
2681 curContext = context.parent;
2685 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2686 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2688 e = QBrackets(QMkExpCond(exp.member.exp,
2689 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2690 MkExpConstant("0")));
2694 if(member._class.fixed)
2696 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2699 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2700 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2706 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2708 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2709 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2712 exp.type = pointerExp;
2717 // Take Out Any Class Specifier (Should have been used by now)
2718 FreeSpecifier(memberClassSpecifier);
2720 // Just moved this at the end... How is it?
2721 if(exp.type == memberExp || exp.type == pointerExp)
2723 exp.member.exp.usage.usageGet = true;
2724 exp.member.exp.usage.usageMember = true;
2725 exp.member.exp.tempCount = exp.tempCount;
2726 ProcessExpression(exp.member.exp);
2727 exp.tempCount = exp.member.exp.tempCount;
2728 if((changeToPtr && exp.member.exp.byReference) || noHead)
2729 exp.type = pointerExp;
2733 case extensionCompoundExp:
2735 ((Expression)((Statement)exp.compound.compound.statements->last).expressions->last).usage |= exp.usage &
2736 ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2738 ProcessStatement(exp.compound);
2740 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2741 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2746 exp.member.exp.usage.usageGet = true;
2747 ProcessExpression(exp.member.exp);
2752 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2753 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2755 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2758 Expression classExp;
2760 FreeTypeName(exp.typeName);
2762 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
2764 exp.type = bracketsExp;
2765 exp.list = MkListOne(
2766 MkExpCondition(MkExpBrackets(MkListOne(
2769 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2770 MkExpIdentifier(MkIdentifier("normalClass"))),
2773 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2774 MkExpIdentifier(MkIdentifier("noHeadClass"))
2776 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
2777 MkExpMember(classExp, MkIdentifier("typeSize")))
2780 ProcessExpressionType(exp);
2781 ProcessExpression(exp);
2790 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
2791 ProcessExpression(exp.cast.exp);
2793 if(exp.cast.exp.byReference)
2794 exp.byReference = exp.cast.exp.byReference;
2795 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
2796 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
2797 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
2798 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
2799 exp.byReference = true;
2801 // Moved this to 1.5...
2802 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
2808 if(exp.usage.usageGet)
2809 exp.cond.cond.usage.usageGet = true;
2810 ProcessExpression(exp.cond.cond);
2811 for(e = exp.cond.exp->first; e; e = e.next)
2813 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
2814 ProcessExpression(e);
2816 if(exp.usage.usageGet)
2817 exp.cond.elseExp.usage.usageGet = true;
2818 ProcessExpression(exp.cond.elseExp);
2823 // Need the class itself here...
2824 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
2826 Specifier spec = exp._classExp.specifiers->first;
2827 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
2830 FreeList(exp._classExp.specifiers, FreeSpecifier);
2831 if(exp._classExp.decl)
2832 FreeDeclarator(exp._classExp.decl);
2834 exp.type = memberExp; //pointerExp;
2835 exp.member.exp = argExp;
2836 exp.member.member = MkIdentifier("dataTypeClass");
2838 ProcessExpressionType(argExp);
2839 ProcessExpression(exp);
2844 char className[1024];
2845 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
2847 strcpy(className, "__ecereClass_");
2848 FullClassNameCat(className, string, true); // TODO: Verify this
2849 MangleClassName(className);
2850 DeclareClass(FindClass(string), className);
2853 FreeList(exp._classExp.specifiers, FreeSpecifier);
2854 if(exp._classExp.decl)
2855 FreeDeclarator(exp._classExp.decl);
2857 exp.type = identifierExp;
2858 exp.identifier = MkIdentifier(className);
2864 ProcessExpression(exp.vaArg.exp);
2867 case extensionInitializerExp:
2869 ProcessInitializer(exp.initializer.initializer);
2877 static void ProcessInitializer(Initializer init)
2881 case expInitializer:
2882 init.exp.usage.usageGet = true;
2883 ProcessExpression(init.exp);
2884 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
2885 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
2887 FixReference(init.exp, true);
2889 else if(init.exp.destType && init.exp.destType.kind == classType)
2890 FixReference(init.exp, false);
2892 case listInitializer:
2895 for(i = init.list->first; i; i = i.next)
2896 ProcessInitializer(i);
2902 static void ProcessDeclaration(Declaration decl)
2906 case initDeclaration:
2908 if(decl.declarators)
2912 for(d = decl.declarators->first; d; d = d.next)
2915 ProcessInitializer(d.initializer);
2923 static void ProcessStatement(Statement stmt)
2928 ProcessStatement(stmt.labeled.stmt);
2931 if(stmt.caseStmt.exp)
2933 stmt.caseStmt.exp.usage.usageGet = true;
2935 // This expression should be constant...
2936 ProcessExpression(stmt.caseStmt.exp);
2938 if(stmt.caseStmt.stmt)
2939 ProcessStatement(stmt.caseStmt.stmt);
2943 if(stmt.compound.context)
2947 Statement prevCompound = curCompound;
2948 Context prevContext = curContext;
2950 if(!stmt.compound.isSwitch)
2953 curContext = stmt.compound.context;
2956 if(stmt.compound.declarations)
2958 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
2959 ProcessDeclaration(decl);
2961 if(stmt.compound.statements)
2963 for(s = stmt.compound.statements->first; s; s = s.next)
2964 ProcessStatement(s);
2966 curContext = prevContext;
2967 curCompound = prevCompound;
2971 case expressionStmt:
2974 if(stmt.expressions)
2976 for(exp = stmt.expressions->first; exp; exp = exp.next)
2978 ProcessExpression(exp);
2989 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
2990 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
2992 ProcessExpression(exp);
2995 if(stmt.ifStmt.stmt)
2996 ProcessStatement(stmt.ifStmt.stmt);
2997 if(stmt.ifStmt.elseStmt)
2998 ProcessStatement(stmt.ifStmt.elseStmt);
3004 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3005 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3007 ProcessExpression(exp);
3009 ProcessStatement(stmt.switchStmt.stmt);
3015 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3016 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3018 ProcessExpression(exp);
3020 ProcessStatement(stmt.whileStmt.stmt);
3026 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3028 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3029 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3031 ProcessExpression(exp);
3034 if(stmt.doWhile.stmt)
3035 ProcessStatement(stmt.doWhile.stmt);
3041 if(stmt.forStmt.init)
3042 ProcessStatement(stmt.forStmt.init);
3044 if(stmt.forStmt.check)
3046 if(stmt.forStmt.check.expressions)
3048 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3050 ProcessStatement(stmt.forStmt.check);
3052 if(stmt.forStmt.increment)
3054 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3056 ProcessExpression(exp);
3059 if(stmt.forStmt.stmt)
3060 ProcessStatement(stmt.forStmt.stmt);
3072 if(stmt.expressions)
3074 ((Expression)stmt.expressions->last).usage.usageGet = true;
3075 for(exp = stmt.expressions->first; exp; exp = exp.next)
3077 ProcessExpression(exp);
3078 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3079 if(!exp.next && exp.destType && exp.destType.byReference)
3080 FixReference(exp, true);
3085 case badDeclarationStmt:
3087 ProcessDeclaration(stmt.decl);
3093 if(stmt.asmStmt.inputFields)
3095 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3096 if(field.expression)
3097 ProcessExpression(field.expression);
3099 if(stmt.asmStmt.outputFields)
3101 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3102 if(field.expression)
3103 ProcessExpression(field.expression);
3105 if(stmt.asmStmt.clobberedFields)
3107 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3108 if(field.expression)
3109 ProcessExpression(field.expression);
3116 static void ProcessFunction(FunctionDefinition function)
3119 ProcessStatement(function.body);
3122 static void ProcessMemberInitData(MemberInit member)
3124 if(member.initializer)
3125 ProcessInitializer(member.initializer);
3128 static void ProcessInstantiation(Instantiation inst)
3132 MembersInit members;
3133 for(members = inst.members->first; members; members = members.next)
3135 if(members.type == dataMembersInit)
3137 if(members.dataMembers)
3140 for(member = members.dataMembers->first; member; member = member.next)
3141 ProcessMemberInitData(member);
3144 else if(members.type == methodMembersInit)
3146 ProcessFunction((FunctionDefinition)members.function);
3152 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3153 public void ProcessMemberAccess()
3156 for(external = ast->first; external; external = external.next)
3158 curExternal = external;
3159 // There shouldn't be any class member access here anyways...
3160 if(external.type == declarationExternal)
3162 if(external.declaration)
3163 ProcessDeclaration(external.declaration);
3167 for(external = ast->first; external; external = external.next)
3169 curExternal = external;
3170 if(external.type == functionExternal)
3172 ProcessFunction(external.function);
3174 else if(external.type == declarationExternal)
3176 //currentClass = external.function._class;
3177 if(external.declaration)
3178 ProcessDeclaration(external.declaration);
3180 else if(external.type == classExternal)
3182 ClassDefinition _class = external._class;
3183 //currentClass = external.symbol.registered;
3184 if(_class.definitions)
3187 Class regClass = _class.symbol.registered;
3189 // Process all functions
3190 for(def = _class.definitions->first; def; def = def.next)
3192 if(def.type == functionClassDef)
3194 curExternal = def.function.declarator.symbol.pointerExternal;
3195 ProcessFunction((FunctionDefinition)def.function);
3197 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3199 ProcessInstantiation(def.decl.inst);
3201 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3203 MemberInit defProperty;
3205 // Add this to the context
3208 string = CopyString("this");
3209 type = MkClassType(regClass.fullName);
3211 globalContext.symbols.Add((BTNode)thisSymbol);
3213 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3215 //thisClass = regClass;
3216 ProcessMemberInitData(defProperty); //, regClass, &id);
3220 //globalContext.symbols.Delete((BTNode)thisSymbol);
3221 globalContext.symbols.Remove((BTNode)thisSymbol);
3222 FreeSymbol(thisSymbol);
3224 else if(def.type == propertyClassDef && def.propertyDef)
3226 PropertyDef prop = def.propertyDef;
3228 // Add this to the context
3231 string = CopyString("this");
3232 type = MkClassType(regClass.fullName);
3234 globalContext.symbols.Add((BTNode)thisSymbol);
3236 //thisClass = regClass;
3239 curExternal = prop.symbol.externalSet;
3240 ProcessStatement(prop.setStmt);
3244 curExternal = prop.symbol.externalGet;
3245 ProcessStatement(prop.getStmt);
3249 curExternal = prop.symbol.externalIsSet;
3250 ProcessStatement(prop.issetStmt);
3255 //globalContext.symbols.Delete((BTNode)thisSymbol);
3256 globalContext.symbols.Remove((BTNode)thisSymbol);
3257 FreeSymbol(thisSymbol);
3259 else if(def.type == classPropertyClassDef && def.propertyDef)
3261 PropertyDef prop = def.propertyDef;
3263 //thisClass = regClass;
3266 curExternal = prop.symbol.externalSet;
3267 ProcessStatement(prop.setStmt);
3271 curExternal = prop.symbol.externalGet;
3272 ProcessStatement(prop.getStmt);
3276 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3278 PropertyWatch propertyWatch = def.propertyWatch;
3280 // Add this to the context
3283 string = CopyString("this");
3284 type = MkClassType(regClass.fullName);
3286 globalContext.symbols.Add((BTNode)thisSymbol);
3288 //thisClass = regClass;
3289 if(propertyWatch.compound)
3293 string = CopyString("this");
3294 type = MkClassType(regClass.fullName);
3296 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3298 ProcessStatement(propertyWatch.compound);
3300 // thisClass = null;
3302 //globalContext.symbols.Delete((BTNode)thisSymbol);
3303 globalContext.symbols.Remove((BTNode)thisSymbol);
3304 FreeSymbol(thisSymbol);