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 = newExp; //FixRefExp(newExp);
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, "ecere::com::Instance") &&
104 strcmp(_class.fullName, "ecere::com::Class") &&
105 strcmp(_class.dataTypeString, "char *"))))
107 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
108 if(wantReference != (e.byReference || isPointer))
113 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
117 exp.byReference = wantReference;
118 exp = exp.list->last;
123 else if(exp.type == castExp)
125 exp.byReference = wantReference;
128 else if(exp.type == conditionExp)
130 if(exp.cond.exp->last)
131 FixReference(exp.cond.exp->last, wantReference);
132 FixReference(exp.cond.elseExp, wantReference);
137 if(wantReference != (exp.byReference || isPointer))
139 Expression newExp { };
142 if(exp.destType) exp.destType.refCount++;
143 if(exp.expType) exp.expType.refCount++;
147 exp.op.exp2 = newExp;
153 e.byReference = wantReference;
154 exp.byReference = wantReference;
167 static bool FixMember(Expression exp)
169 bool byReference = false;
172 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
174 if(exp.list->count > 1)
176 exp = exp.list->last;
178 else if(exp.type == castExp)
185 FixReference(exp, true);
187 byReference = exp.byReference;
194 static void ProcessExpression(Expression exp)
196 Location oldyylloc = yylloc;
198 char debugExpString[1024] = "";
199 PrintExpression(exp, debugExpString);
209 if(exp.expType && exp.expType.kind == methodType)
211 Class _class = exp.expType.methodClass;
212 Method method = exp.expType.method;
213 if(method.type == virtualMethod)
218 OldList * specs = MkList();
219 strcpy(name, "__ecereVMethodID_");
220 FullClassNameCat(name, method._class.fullName, false);
222 strcat(name, method.name);
224 DeclareMethod(method, name);
226 // Cast function to its type
227 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
228 if(!method.dataType.staticMethod)
230 Declarator funcDecl = GetFuncDecl(decl);
232 if(!funcDecl.function.parameters)
233 funcDecl.function.parameters = MkList();
235 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
236 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
238 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
239 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
242 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
243 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
246 typeName = MkTypeName(specs, decl);
250 char className[1024];
251 // Need the class itself here...
252 strcpy(className, "__ecereClass_");
253 FullClassNameCat(className, _class.fullName, true);
254 MangleClassName(className);
257 _class.symbol = FindClass(_class.fullName);
258 DeclareClass(_class.symbol, className);
260 exp.type = bracketsExp;
261 exp.list = MkListOne(MkExpCast(typeName,
262 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
263 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
269 strcpy(name, "__ecereMethod_");
270 FullClassNameCat(name, method._class.fullName, false);
272 strcat(name, method.name);
274 delete exp.identifier.string;
276 exp.identifier._class = null;
277 exp.identifier.string = CopyString(name);
278 DeclareMethod(method, name);
282 if(exp.usage & USAGE_MEMBER)
283 FixReference(exp, true);
296 OldList * args = MkList();
298 if(exp.type == renewExp || exp.type == renew0Exp)
299 ListAdd(args, exp._renew.exp);
301 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
305 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
306 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
307 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
308 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
310 exp.call.arguments = args;
313 ProcessExpression(exp);
318 Expression exp1 = exp.op.exp1;
319 Expression exp2 = exp.op.exp2;
323 // Assignment Operators
326 exp.op.exp2.usage.usageGet = true;
338 exp.op.exp2.usage.usageGet = true;
347 if(exp.op.exp1 && exp.op.exp2)
349 exp.op.exp1.usage.usageGet = true;
350 exp.op.exp2.usage.usageGet = true;
354 exp.op.exp2.usage.usageRef = true;
363 exp.op.exp1.usage.usageGet = true;
368 exp.op.exp2.usage.usageGet = true;
371 // Binary only operators
387 exp.op.exp1.usage.usageGet = true;
389 exp.op.exp2.usage.usageGet = true;
393 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
394 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
395 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
396 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
398 Expression memberExp;
399 Expression parentExp = null; // Where to take memberExp out from
401 // TOCHECK: See note below for this if
402 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
404 // Extra bit of code to access deep properties...
405 Expression testExp, topExp = null;
406 Expression lastExp = exp.op.exp1, parentExp = null;
407 Property lastProperty = null;
410 char setName[1024], getName[1024];
411 testExp = exp.op.exp1.member.exp;
414 // Is further fixing needed to address if statement above in the same way?
417 if(testExp.type == castExp)
418 testExp = testExp.cast.exp;
419 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
420 testExp = testExp.list->last;
421 else if(testExp.type == ExpressionType::memberExp)
428 if(testExp.member.memberType == propertyMember ||
429 testExp.member.memberType == reverseConversionMember)
431 Type type = testExp.member.exp.expType;
434 if(type.kind == classType)
436 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
437 Class convertTo = null;
438 if(testExp.member.memberType == reverseConversionMember)
441 _class = FindClass(testExp.member.member.string).registered;
442 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
443 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
447 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
449 if(lastProperty && lastProperty.Get && lastProperty.Set)
451 DeclareProperty(lastProperty, setName, getName);
452 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
453 propertyClass = convertTo ? _class :
454 ((((Symbol)lastProperty.symbol).type &&
455 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
456 // TODO: Handle this kind of things with bit classes?
457 if(propertyClass && propertyClass.type == structClass)
462 else if(propertyClass && propertyClass.type == bitClass)
474 testExp = testExp.member.exp;
478 if(propertyClass.type == structClass)
482 char className[1024];
485 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
486 tempExp = QMkExpId(className);
487 tempExp.expType = MkClassType(propertyClass.fullName);
489 parentExp.member.exp = tempExp;
491 value = MkExpBrackets(MkList());
493 copy = CopyExpression(topExp);
494 copy.usage.usageGet = true;
495 copy.usage.usageDeepGet = true;
497 ListAdd(value.list, copy);
498 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
499 ListAdd(value.list, CopyExpression(tempExp));
500 value.expType = tempExp.expType;
501 tempExp.expType.refCount++;
503 // Go on as usual with these new values:
504 exp.op.exp1 = topExp;
511 else if(propertyClass.type == bitClass)
515 char className[1024];
518 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
519 tempExp = QMkExpId(className);
520 tempExp.expType = MkClassType(propertyClass.fullName);
522 parentExp.member.exp = tempExp;
524 value = MkExpBrackets(MkList());
526 copy = CopyExpression(topExp);
527 copy.usage.usageGet = true;
528 copy.usage.usageDeepGet = true;
530 ListAdd(value.list, copy);
531 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
532 ListAdd(value.list, CopyExpression(tempExp));
533 value.expType = tempExp.expType;
534 value.expType.refCount++;
536 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
538 // Go on as usual with these new values:
539 exp.op.exp1 = topExp;
549 memberExp = exp.op.exp1;
551 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
552 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
554 parentExp = memberExp;
555 if(memberExp.type == extensionCompoundExp)
556 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
558 memberExp = memberExp.list->last;
561 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
562 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
563 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
565 ProcessExpression(memberExp);
567 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
568 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
570 parentExp = memberExp;
571 if(memberExp.type == extensionCompoundExp)
572 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
574 memberExp = memberExp.list->last;
577 if(memberExp && memberExp.type == extensionCompoundExp)
579 parentExp = memberExp;
580 if(memberExp.type == extensionCompoundExp)
582 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
583 if(stmt && stmt.type != expressionStmt) stmt = null;
584 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
587 stmt.expressions->Remove(memberExp);
588 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
589 exp.type = bracketsExp;
590 exp.list = MkListOne(parentExp);
591 ProcessExpression(exp);
596 memberExp = memberExp.list->last;
600 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
602 if(memberExp && memberExp.type == ExpressionType::memberExp)
604 Type type = memberExp.member.exp.expType;
607 // Check if it's an instance
608 if(type.kind == classType || type.kind == subClassType)
610 // TODO: SOMETHING WRONG HERE...
611 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
613 if(memberExp == exp1)
617 if(parentExp.type == extensionCompoundExp)
618 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
620 parentExp.list->Remove(memberExp);
623 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
625 BitMember bitMember =
626 (BitMember)eClass_FindDataMember(_class,
627 memberExp.member.member.string, privateModule, null, null);
628 char mask[32], shift[10];
629 OldList * specs = MkList();
630 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
631 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
632 TypeName type = MkTypeName(specs, decl);
634 if(bitMember.mask > MAXDWORD)
635 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
637 sprintf(mask, FORMAT64HEX, bitMember.mask);
638 sprintf(shift, "%d", bitMember.pos);
640 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
641 exp.op.exp1 = memberExp.member.exp;
643 // TESTING THIS FOR: argb.color.r = 1;
644 //ProcessExpression(memberExp.member.exp);
646 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
647 if(exp.op.op == XOR_ASSIGN)
649 exp.op.exp2 = MkExpOp(MkExpBrackets(
650 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
654 exp.op.exp2 = MkExpOp(
655 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
656 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
657 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
658 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift)))));
661 memberExp.member.exp = null;
662 FreeExpression(memberExp);
664 // TESTING THIS FOR: argb.color.r = 1;
665 ProcessExpression(exp);
668 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
671 else if(memberExp.member.memberType != dataMember)
674 Class convertTo = null;
675 ClassProperty classProperty = null;
677 if(memberExp.member.memberType == reverseConversionMember)
680 _class = FindClass(memberExp.member.member.string).registered;
681 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
682 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
685 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
687 if(memberExp.member.memberType == classPropertyMember)
688 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
690 exp.tempCount = memberExp.member.exp.tempCount;
694 // Only process Gets here, Set is processed in opExp's '='
695 if(classProperty.Set)
697 Identifier id = memberExp.member.member;
698 Expression classExp = memberExp.member.exp;
699 Expression value = exp.op.exp2;
701 memberExp.member.exp = null;
702 memberExp.member.member = null;
705 FreeExpContents(memberExp);
709 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
710 exp.call.arguments = MkList();
711 ListAdd(exp.call.arguments, classExp);
712 ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
713 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT)), null), value));
717 ProcessExpression(exp);
723 if((!convertTo && prop.Set) || (convertTo && prop.Get))
725 Expression value = exp.op.exp2;
726 char setName[1024], getName[1024];
727 char * setToUse = convertTo ? getName : setName;
728 char * getToUse = convertTo ? setName : getName;
729 bool needAddress = false;
730 int operator = exp.op.op;
733 case MUL_ASSIGN: operator = '*'; break;
734 case DIV_ASSIGN: operator = '/'; break;
735 case MOD_ASSIGN: operator = '%'; break;
736 case SUB_ASSIGN: operator = '-'; break;
737 case ADD_ASSIGN: operator = '+'; break;
738 case LEFT_ASSIGN: operator = LEFT_OP; break;
739 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
740 case AND_ASSIGN: operator = '&'; break;
741 case OR_ASSIGN: operator = '|'; break;
742 case XOR_ASSIGN: operator = '^'; break;
747 if(operator == INC_OP)
748 value = MkExpOp(CopyExpression(memberExp),
749 '+', MkExpConstant("1"));
750 else if(operator == DEC_OP)
751 value = MkExpOp(CopyExpression(memberExp),
752 '-', MkExpConstant("1"));
755 value = MkExpOp(CopyExpression(memberExp),
759 value.expType = memberExp.expType;
760 memberExp.expType.refCount++;
761 value.usage.usageArg = true;
765 // Dont free exp2, we're using it
770 value.usage.usageArg = true;
772 DeclareProperty(prop, setName, getName);
774 if(memberExp.member.exp)
775 ProcessExpression(memberExp.member.exp);
777 // If get flag present
778 if(exp.usage.usageGet &&
779 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
781 OldList * list = MkList();
784 Context context = PushContext();
787 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
788 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
790 curContext = context;
791 exp.type = extensionCompoundExp;
792 exp.compound = MkCompoundStmt(
793 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
794 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
795 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
802 ListAdd(args, value);
803 ListAdd(args, QMkExpId(ecereTemp));
804 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
808 ListAdd(args, QMkExpId(ecereTemp));
809 ListAdd(args, value);
810 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
816 ListAdd(args, QMkExpId(ecereTemp));
818 args->Insert(null, QMkExpId(ecereTemp));
819 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
821 exp.compound.compound.context = context;
823 curContext = context.parent;
827 Expression newExp = exp;
829 if(parentExp && parentExp.type == extensionCompoundExp)
831 newExp = Expression { };
832 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
833 FreeType(exp.expType);
834 FreeType(exp.destType);
837 parentExp.type = dummyExp;
838 parentExp.expType = null;
839 parentExp.destType = null;
842 newExp.type = callExp;
843 newExp.call.exp = QMkExpId(setToUse);
844 newExp.call.arguments = MkList();
847 ListAdd(newExp.call.arguments, value);
848 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
852 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
853 ListAdd(newExp.call.arguments, value);
858 // Take it out from there
859 memberExp.member.exp = null;
861 // Don't use the temporaries used by the left side...
864 value.tempCount = exp.tempCount;
865 ProcessExpression(value);
867 FixReference(value, true);
870 FreeExpression(memberExp);
874 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
877 memberExp.member.memberType = dataMember;
880 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
885 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
886 if(method && method.type == virtualMethod && type.kind != subClassType)
888 Expression value = exp.op.exp2;
889 // Don't use the temporaries used by the left side...
890 value.tempCount = exp.tempCount;
891 ProcessExpression(value);
893 if(memberExp.member.exp)
894 ProcessExpression(memberExp.member.exp);
896 if(exp.usage.usageGet)
898 OldList * list = MkList();
903 ListAdd(args, memberExp.member.exp);
905 char * string = QMkString(memberExp.member.member.string);
906 ListAdd(args, MkExpString(string));
909 ListAdd(args, value);
910 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
911 ListAdd(list, CopyExpression(value));
912 exp.type = bracketsExp;
919 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
920 exp.call.arguments = MkList();
921 ListAdd(exp.call.arguments, memberExp.member.exp);
923 char * string = QMkString(memberExp.member.member.string);
924 ListAdd(exp.call.arguments, MkExpString(string));
927 ListAdd(exp.call.arguments, value);
930 memberExp.member.exp = null;
933 FreeExpression(memberExp);
937 else if(memberExp.member.memberType == dataMember)
939 //if(exp.usage & USAGE_GET);
940 //FixReference(value, true);
941 if(FixMember(memberExp.member.exp))
943 // TESTING THIS HERE:
944 ProcessExpression(memberExp);
946 memberExp.type = pointerExp;
953 else if(exp.op.op == _INCREF)
955 Expression object = exp.op.exp2;
957 FreeExpContents(exp);
961 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
963 else if(exp.op.op == DELETE)
965 Expression object = exp.op.exp2;
966 OldList * args = MkList();
968 exp.type = bracketsExp;
971 object.usage.usageDelete = true;
973 ProcessExpression(object);
975 ListAdd(args, object);
977 // TOFIX: Same time as when we fix for = 0
979 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
980 ((exp.expType._class.registered.type == normalClass &&
981 // TODO: Improve on this, only fixed this issue here... Different String class defined in each module
982 !eClass_IsDerived(exp.expType._class.registered, eSystem_FindClass(exp.expType._class.registered.module, "char *")) /*strcmp(exp.expType._class.string, "String")*/) ||
983 (exp.expType._class.registered.type == systemClass && !strcmp(exp.expType._class.string, "ecere::com::Instance"))))
985 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
986 ProcessExpressionType(decRefExp);
987 ListAdd(exp.list, decRefExp);
989 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
992 char className[1024];
993 OldList * list = MkList();
995 strcpy(className, "__ecereClass_");
996 FullClassNameCat(className, exp.expType._class.string, true);
997 MangleClassName(className);
999 DeclareClass(exp.expType._class, className);
1001 // Call the non virtual destructor
1002 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1003 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1005 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1007 MkExpBrackets(MkListOne(MkExpCondition(
1008 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1009 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1014 OldList * list = MkList();
1016 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1018 char className[1024];
1020 if(_class.templateClass) _class = _class.templateClass;
1021 strcpy(className, "__ecereClass_");
1022 FullClassNameCat(className, _class.fullName, false /*true*/);
1023 MangleClassName(className);
1026 _class.symbol = FindClass(_class.fullName);
1027 DeclareClass(_class.symbol, className);
1029 // Call the non virtual destructor
1033 QMkExpId(className),
1034 MkIdentifier("Destructor")
1039 QMkExpId(className),
1040 MkIdentifier("Destructor")
1042 CopyList(args, CopyExpression)
1049 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1054 CopyExpression(object),
1064 else if(exp.expType && exp.expType.kind == templateType)
1066 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, thisClass, false);
1069 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1071 OldList * qualifiers = MkList();
1072 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1074 typeName = MkTypeName(qualifiers, declarator);
1076 ProcessExpressionType(classExp);
1077 args->Insert(null, CopyExpression(classExp));
1078 DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1079 ListAdd(exp.list, MkExpCall(
1080 MkExpBrackets(MkListOne(MkExpCast(typeName,
1081 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1082 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1083 //ProcessExpression(exp.list->last);
1087 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1089 //ProcessExpression(object);
1091 ListAdd(exp.list, MkExpOp(CopyExpression(object), '=', MkExpConstant("0")));
1095 // TESTING THIS HERE...
1096 ProcessExpression(exp);
1099 if(exp.type == opExp)
1101 // Handle assigment of template structures
1102 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1103 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1105 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
1108 // memcpy((byte *)array + (count * dataTypeClass.size), dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1110 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1111 OldList * args = MkList();
1112 Expression derefExp = exp.op.exp1;
1113 Expression sizeExp = MkExpCondition(MkExpBrackets(MkListOne(
1115 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1117 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1118 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1119 MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize")));
1121 if(exp.op.exp1.type == indexExp)
1123 Expression indexExp = derefExp.index.exp;
1124 OldList * indexExpIndex = derefExp.index.index;
1126 derefExp.index.index = null;
1127 derefExp.index.exp = null;
1128 FreeExpression(derefExp);
1130 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1131 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1135 Expression indexExp = derefExp.op.exp2;
1136 derefExp.op.exp2 = null;
1137 FreeExpression(derefExp);
1138 derefExp = indexExp;
1141 args->Add(derefExp);
1142 ProcessExpressionType(args->last);
1143 ProcessExpression(args->last);
1145 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1146 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1147 MkListOne(exp.op.exp2), MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
1149 thisClass = curExternal.function ? curExternal.function._class : null;
1153 string = CopyString("this");
1154 type = MkClassType(thisClass.fullName);
1156 globalContext.symbols.Add((BTNode)thisSymbol);
1158 ProcessExpressionType(args->last);
1159 ProcessExpression(args->last);
1162 ProcessExpressionType(args->last);
1163 ProcessExpression(args->last);
1165 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1166 exp.type = bracketsExp;
1168 //globalContext.symbols.Delete((BTNode)thisSymbol);
1169 globalContext.symbols.Remove((BTNode)thisSymbol);
1170 FreeSymbol(thisSymbol);
1176 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1177 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1179 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
1182 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1183 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1185 exp.type = bracketsExp;
1186 exp.list = MkListOne(
1188 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1190 // ((class.type == structClass) ?
1191 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1194 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
1196 // ((class.type == normalClass || class.type == noHeadClass) ?
1197 MkExpCondition(MkExpBrackets(MkListOne(
1199 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1201 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1202 // *((void **)array)
1203 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1204 CopyExpression(exp.op.exp2))))))),
1206 // ((class.size == 1) ?
1207 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1209 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1210 CopyExpression(exp.op.exp2)))))),
1212 // ((class.size == 2) ?
1213 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1214 // *((uint16 *)array)
1215 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1216 CopyExpression(exp.op.exp2)))))),
1218 // ((class.size == 4) ?
1219 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1220 // *((uint32 *)array)
1221 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1222 CopyExpression(exp.op.exp2)))))),
1224 // *((uint64 *)array)
1225 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1226 exp.op.exp2)))))))))))))))))))));
1228 // Add this to the context
1229 thisClass = curExternal.function ? curExternal.function._class : null;
1233 string = CopyString("this");
1234 type = MkClassType(thisClass.fullName);
1236 globalContext.symbols.Add((BTNode)thisSymbol);
1238 ProcessExpressionType(exp.list->first);
1239 ProcessExpression(exp.list->first);
1241 //globalContext.symbols.Delete((BTNode)thisSymbol);
1242 globalContext.symbols.Remove((BTNode)thisSymbol);
1243 FreeSymbol(thisSymbol);
1254 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1255 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1256 ProcessExpression(exp.op.exp1);
1259 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1260 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1261 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1262 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*/))
1263 FixReference(exp.op.exp1, false);
1264 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1268 // Don't use the temporaries used by the left side...
1270 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1271 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1272 ProcessExpression(exp.op.exp2);
1273 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1277 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1278 (exp.op.exp2.expType._class.registered.type != normalClass &&
1279 exp.op.exp2.expType._class.registered.type != structClass &&
1280 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1282 // TESTING THIS TEMPLATE TYPE CHECK HERE
1283 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1285 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1286 //FixReference(exp.op.exp2, false);
1289 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1292 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)
1294 // Preserve prev, next
1295 Expression next = exp.next, prev = exp.prev;
1296 Expression derefExp = exp.op.exp2;
1297 Expression refExp = exp.op.exp2.op.exp2;
1298 Type expType = exp.expType, destType = exp.destType;
1300 derefExp.op.exp2 = null;
1301 FreeExpression(derefExp);
1302 FreeType(exp.expType);
1303 FreeType(exp.destType);
1313 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)
1315 Expression exp2 = exp.op.exp2;
1316 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, thisClass, false);
1319 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1321 exp.type = bracketsExp;
1322 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1323 MkExpOp(null, '&', exp2)), '+',
1324 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1325 MkListOne((e = MkExpCondition(MkExpBrackets(MkListOne(
1329 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))),
1331 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))),
1333 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))))
1335 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
1336 MkExpMember(classExp, MkIdentifier("typeSize"))))))));
1338 // Add this to the context
1339 thisClass = curExternal.function ? curExternal.function._class : null;
1343 string = CopyString("this");
1344 type = MkClassType(thisClass.fullName);
1346 //globalContext.symbols.Add((BTNode)thisSymbol);
1348 ProcessExpressionType(e);
1349 ProcessExpression(e);
1351 //globalContext.symbols.Remove((BTNode)thisSymbol);
1352 //FreeSymbol(thisSymbol);
1361 FreeExpression(exp1);
1363 FreeExpression(exp2);
1368 case extensionExpressionExp:
1373 for(e = exp.list->first; e; e = e.next)
1377 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1379 e.tempCount = exp.tempCount;
1380 ProcessExpression(e);
1382 exp.byReference = e.byReference;
1383 exp.tempCount = e.tempCount;
1387 exp.expType = e.expType;
1396 /*bool isBuiltin = exp && exp.index.exp &&
1397 (exp.index.exp.type == ExpressionType::arrayExp ||
1398 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1400 Expression checkedExp = exp.index.exp;
1401 bool isBuiltin = false;
1403 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1405 if(checkedExp.type == extensionCompoundExp)
1410 else if(checkedExp.type == bracketsExp)
1411 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1413 checkedExp = checkedExp.cast.exp;
1416 exp.index.exp.tempCount = exp.tempCount;
1418 exp.index.exp.usage.usageGet = true;
1419 ProcessExpression(exp.index.exp);
1421 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1422 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1424 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
1427 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1428 Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1430 exp.type = bracketsExp;
1431 exp.list = MkListOne(
1433 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1435 // ((class.type == structClass) ?
1436 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1437 // ((byte *)array) + (i) * class.size
1438 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
1439 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1440 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
1442 // ((class.type == normalClass || class.type == noHeadClass) ?
1443 MkExpCondition(MkExpBrackets(MkListOne(
1445 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
1447 MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
1448 // ((void **)array)[i]
1449 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
1450 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression)))),
1452 // ((class.size == 1) ?
1453 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1454 // ((byte *)array)[i]
1455 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1456 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1458 // ((class.size == 2) ?
1459 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1460 // ((uint16 *)array)[i]
1461 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1462 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1464 // ((class.size == 4) ?
1465 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1466 // ((uint32 *)array)[i]
1467 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1468 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1470 // ((uint64 *)array)[i]
1471 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1472 exp.index.exp))), exp.index.index))))))))))))))))));
1474 // Add this to the context
1475 thisClass = curExternal.function ? curExternal.function._class : null;
1479 string = CopyString("this");
1480 type = MkClassType(thisClass.fullName);
1482 globalContext.symbols.Add((BTNode)thisSymbol);
1484 ProcessExpressionType(exp.list->first);
1485 ProcessExpression(exp.list->first);
1487 //globalContext.symbols.Delete((BTNode)thisSymbol);
1488 globalContext.symbols.Remove((BTNode)thisSymbol);
1489 FreeSymbol(thisSymbol);
1497 for(e = exp.index.index->first; e; e = e.next)
1500 e.usage.usageGet = true;
1501 ProcessExpression(e);
1503 // Ignore temps in the index for now...
1504 exp.tempCount = exp.index.exp.tempCount;
1506 if(exp.index.exp.expType)
1508 Type source = exp.index.exp.expType;
1509 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1510 eClass_IsDerived(source._class.registered, containerClass))
1512 Class _class = source._class.registered;
1513 bool isArray = false;
1514 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1515 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1517 if(isArray && _class.templateArgs)
1519 OldList * specs = MkList();
1520 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1521 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
1522 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1523 ProcessExpressionType(exp.index.exp);
1524 ProcessExpression(exp);
1526 else if(isBuiltin && _class.templateArgs)
1528 OldList * specs = MkList();
1529 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1530 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
1531 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1532 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1533 ProcessExpressionType(exp.index.exp);
1534 ProcessExpression(exp);
1536 else if(_class.templateArgs)
1538 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1540 char iteratorType[1024];
1541 OldList * declarations = MkList();
1542 OldList * statements = MkList();
1543 OldList * args = MkList();
1544 OldList * instMembers = MkList();
1546 Context context = PushContext();
1548 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1550 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1552 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1553 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1555 ListAdd(args, MkExpBrackets(exp.index.index));
1556 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1558 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1559 MkIdentifier("Index")), args))));
1561 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1562 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1564 exp.type = bracketsExp;
1565 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1566 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1567 expExt.compound.compound.context = context;
1568 PopContext(context);
1569 expExt.usage = exp.usage;
1570 ProcessExpressionType(exp.list->first);
1571 ProcessExpressionInstPass(exp.list->first);
1572 ProcessExpression(exp.list->first);
1581 Expression memberExp;
1582 bool typedObject = false;
1583 Type ellipsisDestType = null;
1584 bool usedEllipsis = false;
1586 if(exp.call.arguments)
1588 for(e = exp.call.arguments->first; e; e = e.next)
1590 e.usage.usageGet = true;
1591 e.usage.usageArg = true;
1592 e.tempCount = Max(e.tempCount, exp.tempCount);
1593 ProcessExpression(e);
1594 exp.tempCount = Max(exp.tempCount, e.tempCount);
1597 exp.call.exp.usage.usageGet = true;
1598 exp.call.exp.usage.usageCall = true;
1599 exp.call.exp.tempCount = exp.tempCount;
1600 ProcessExpression(exp.call.exp);
1601 memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
1603 if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
1605 Class _class = exp.call.exp.expType.methodClass; // For Virtual Method
1606 Class argClass = exp.call.exp.expType.methodClass; // Class actually passed
1607 Method method = exp.call.exp.expType.method;
1608 if(method.type == virtualMethod)
1614 OldList * specs = MkList();
1615 strcpy(name, "__ecereVMethodID_");
1616 FullClassNameCat(name, method._class.fullName, false);
1618 strcat(name, method.name);
1620 DeclareMethod(method, name);
1623 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1624 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1625 // Cast function to its type
1627 Context context = SetupTemplatesContext(method._class);
1629 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1631 FinishTemplatesContext(context);
1634 if(method.dataType && !method.dataType.staticMethod)
1636 Declarator funcDecl = GetFuncDecl(decl);
1638 if(!funcDecl.function.parameters)
1639 funcDecl.function.parameters = MkList();
1641 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1642 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1644 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1645 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1648 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1652 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)));
1653 // Testing this for any_object::
1654 if(!method.dataType.extraParam)
1655 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1659 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1660 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1664 typeName = MkTypeName(specs, decl);
1666 // Added !exp.call.exp.expType.methodClass
1667 if(memberExp && memberExp.member.exp.expType)
1669 if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class && memberExp.member.exp.expType._class.registered)
1671 ClassType type = memberExp.member.exp.expType._class.registered.type;
1672 if(type != normalClass || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1673 argClass = memberExp.member.exp.expType._class.registered;
1677 switch(memberExp.member.exp.expType.kind)
1681 argClass = eSystem_FindClass(privateModule, "int");
1687 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1692 // *** Added !_class here
1693 if(!exp.call.exp.expType.methodClass && (!memberExp || !_class) && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType)
1695 if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
1696 memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)
1698 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1699 // as opposed to the File class vTbl one
1700 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1701 MkExpIndex(MkExpPointer(MkExpBrackets(MkListOne(CopyExpression(memberExp.member.exp))), MkIdentifier("_vTbl")),
1702 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1706 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1707 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl")),
1708 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1711 else if(memberExp && !_class && exp.call.exp.expType._class &&
1712 (memberExp.member.exp.expType.kind == subClassType || (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 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1716 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1717 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1721 char className[1024];
1723 // TESTING: Moved this here...
1724 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1729 // TODO: Unhandled case here, what should happen?
1730 _class = class(int);
1733 // Need the class itself here...
1734 strcpy(className, "__ecereClass_");
1735 FullClassNameCat(className, _class.fullName, true);
1736 MangleClassName(className);
1739 _class.symbol = FindClass(_class.fullName);
1741 DeclareClass(_class.symbol, className);
1743 exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1744 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1745 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1751 strcpy(name, "__ecereMethod_");
1752 FullClassNameCat(name, method._class.fullName, false);
1754 strcat(name, method.name);
1756 exp.call.exp = MkExpIdentifier(MkIdentifier(name));
1757 DeclareMethod(method, name);
1758 if(memberExp && memberExp.expType && method.dataType)
1760 exp.call.exp.expType = method.dataType;
1761 method.dataType.refCount++;
1764 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1766 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1768 if(!exp.call.arguments)
1769 exp.call.arguments = MkList();
1771 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1773 if(memberExp.member.exp.expType.kind != classType ||
1774 memberExp.member.exp.expType._class.registered.type == enumClass ||
1775 memberExp.member.exp.expType._class.registered.type == unitClass)
1777 char typeString[1024] = "";
1778 if(memberExp.member.exp.expType.kind != classType)
1779 PrintType(memberExp.member.exp.expType, typeString, false, true);
1781 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1784 // memberExp.member.exp.expType.kind = classType;
1785 // memberExp.member.exp.expType._class = FindClass(typeString);
1787 FreeType(memberExp.member.exp.expType);
1788 memberExp.member.exp.expType = Type
1791 _class = FindClass(typeString);
1795 // Default to an int instead
1796 if(!memberExp.member.exp.expType._class)
1798 // TODO: Shouldn't get here...
1799 memberExp.member.exp.expType.kind = TypeInt;
1804 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1807 (argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") && strcmp(argClass.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
1808 (!memberExp.member.exp.expType.classObjectType &&
1810 (memberExp.member.exp.expType.kind != pointerType && (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
1811 !memberExp.member.exp.expType._class.registered ||
1812 memberExp.member.exp.expType._class.registered.type == structClass)))) ||
1813 method.dataType.byReference))) // ADDED THIS FOR OnGetDataFromString
1815 if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1817 exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
1818 memberExp.member.exp.op.exp2 = null;
1820 else if(!memberExp.member.exp.byReference)
1822 // TESTING THIS... REUSE THIS CODE?
1823 Expression checkedExp = memberExp.member.exp;
1824 Expression parentExp = null;
1826 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1828 parentExp = checkedExp;
1829 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1830 checkedExp = checkedExp.list->last;
1831 else if(checkedExp.type == castExp)
1832 checkedExp = checkedExp.cast.exp;
1834 newExp = MkExpOp(null, '&', checkedExp);
1835 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
1837 parentExp.list->Remove(checkedExp);
1838 parentExp.list->Add(newExp);
1840 else if(parentExp && parentExp.type == castExp)
1841 parentExp.cast.exp = newExp;
1843 exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
1846 exp.call.arguments->Insert(null, memberExp.member.exp);
1849 exp.call.arguments->Insert(null, memberExp.member.exp);
1851 //if(memberExp.member.exp && memberExp.member.exp.type == identifierExp && !strcmp(memberExp.member.exp.identifier.string, "this") && FindSymbol("class", curContext, topContext, false))
1852 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
1854 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier("class")));
1858 if(memberExp && !argClass)
1859 exp.call.arguments->Insert(null, MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_class")));
1862 char className[1024];
1863 // Need the class itself here...
1864 strcpy(className, "__ecereClass_");
1865 FullClassNameCat(className, argClass.fullName, true);
1866 MangleClassName(className);
1868 if(!argClass.symbol)
1869 argClass.symbol = FindClass(argClass.fullName);
1870 DeclareClass(argClass.symbol, className);
1871 exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
1876 exp.call.arguments->Insert(null, memberExp.member.exp);
1877 memberExp.member.exp = null;
1879 FreeExpression(memberExp);
1881 /*else if(method->dataType)
1885 if(exp.call.arguments)
1887 for(e = exp.call.arguments->first; e; e = e.next)
1889 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
1890 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
1891 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
1892 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
1894 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
1895 ellipsisDestType = destType;
1898 Type type = e.expType;
1899 Class _class = null;
1900 //Type destType = e.destType;
1902 if(type.kind == classType && type._class && type._class.registered)
1904 _class = type._class.registered;
1906 else if(type.kind == subClassType)
1908 _class = FindClass("ecere::com::Class").registered;
1910 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1912 _class = FindClass("char *").registered;
1916 char string[1024] = "";
1919 PrintType(type, string, false, true);
1920 classSym = FindClass(string);
1921 if(classSym) _class = classSym.registered;
1922 // if(!class) _class = eSystem_FindClass(privateModule, "int");
1925 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...
1926 (!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))) ||
1927 destType.byReference)))
1929 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
1930 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
1931 // TESTING WITHOUT THE ABOVE NOW!
1933 Expression checkedExp;
1934 Expression parentExp;
1939 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
1941 parentExp = checkedExp;
1942 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
1944 if(checkedExp.type == extensionCompoundExp)
1946 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
1949 checkedExp = checkedExp.list->last;
1951 else if(checkedExp.type == castExp)
1952 checkedExp = checkedExp.cast.exp;
1955 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
1958 Expression newExp = e.op.exp2;
1959 exp.call.arguments->Insert(e.prev, newExp);
1960 exp.call.arguments->Remove(e);
1965 newExp = checkedExp.op.exp2;
1966 checkedExp.op.exp2 = null;
1967 FreeExpContents(checkedExp);
1969 if(e.expType && e.expType.passAsTemplate)
1972 ComputeTypeSize(e.expType);
1973 sprintf(size, "%d", e.expType.size);
1974 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
1975 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
1976 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
1979 if(parentExp.type == callExp)
1981 exp.call.arguments->Insert(e.prev, newExp);
1982 exp.call.arguments->Remove(e);
1985 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
1987 parentExp.list->Remove(checkedExp);
1988 parentExp.list->Add(newExp);
1990 else if(parentExp.type == castExp)
1992 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
1993 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
1995 FreeTypeName(parentExp.cast.typeName);
1996 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
1998 parentExp.cast.exp = newExp;
2000 else if(parentExp.type == extensionCompoundExp)
2002 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2003 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2005 e.byReference = true;
2007 FreeType(checkedExp.expType);
2008 FreeType(checkedExp.destType);
2011 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2013 Expression checkedExp;
2014 Expression parentExp;
2018 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2020 e.type == identifierExp ||
2021 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2022 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2023 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2026 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2028 Context context = PushContext();
2030 OldList * specs = MkList();
2031 char typeString[1024];
2032 Expression newExp { };
2034 typeString[0] = '\0';
2037 // TOCHECK: Should this read e.destType ???
2039 if(exp.destType) exp.destType.refCount++;
2040 // if(exp.expType) exp.expType.refCount++;
2043 newExp.expType = null;
2045 PrintType(e.expType, typeString, false, true);
2046 decl = SpecDeclFromString(typeString, specs, null);
2047 newExp.destType = ProcessType(specs, decl);
2049 curContext = context;
2050 e.type = extensionCompoundExp;
2052 // We need a current compound for this
2056 OldList * stmts = MkList();
2057 sprintf(name, "__internalValue%03X", internalValueCounter++);
2058 if(!curCompound.compound.declarations)
2059 curCompound.compound.declarations = MkList();
2060 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2061 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2062 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2063 e.compound = MkCompoundStmt(null, stmts);
2066 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2070 e.compound = MkCompoundStmt(
2071 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2072 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2075 e.compound.compound.context = context;
2076 PopContext(context);
2077 curContext = context.parent;
2081 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2084 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
2086 parentExp = checkedExp;
2087 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2089 if(checkedExp.type == extensionCompoundExp)
2091 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2094 checkedExp = checkedExp.list->last;
2096 else if(checkedExp.type == castExp)
2097 checkedExp = checkedExp.cast.exp;
2099 newExp = MkExpOp(null, '&', checkedExp);
2100 newExp.byReference = true;
2101 if(parentExp.type == callExp)
2103 exp.call.arguments->Insert(e.prev, newExp);
2104 exp.call.arguments->Remove(e);
2107 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2109 parentExp.list->Remove(checkedExp);
2110 parentExp.list->Add(newExp);
2112 else if(parentExp.type == castExp)
2113 parentExp.cast.exp = newExp;
2114 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2116 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2117 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2123 if(destType.classObjectType == ClassObjectType::typedObject)
2125 char className[1024];
2126 // Need the class itself here...
2127 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2128 _class = eSystem_FindClass(privateModule, "String");
2129 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2131 if(!strcmp(_class.name, "class"))
2133 // Already inside a typed_object function, pass the class through
2134 strcpy(className, "class");
2138 strcpy(className, "__ecereClass_");
2139 FullClassNameCat(className, _class.fullName, true);
2140 MangleClassName(className);
2143 _class.symbol = FindClass(_class.fullName);
2145 DeclareClass(_class.symbol, className);
2147 exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2153 //char debugString[4096] = "";
2154 //PrintExpression(e, debugString);
2156 // If expression type is a simple class, make it an address
2157 FixReference(e, true);
2160 if(ellipsisDestType)
2163 (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
2164 ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
2166 exp.call.arguments->Insert(exp.call.arguments->last, MkExpConstant("0"));
2174 bool changeToPtr = false;
2175 bool noHead = false;
2176 Type type = exp.member.exp.expType;
2177 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2178 if(exp.member.member) exp.member.member._class = null;
2180 if(type && type.kind == templateType)
2182 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2183 if(baseType) type = baseType;
2185 if(type && exp.member.member && !type.directClassAccess)
2187 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2188 Property prop = null;
2189 ClassProperty classProperty = null;
2190 Method method = null;
2191 Class convertTo = null;
2192 DataMember member = null;
2193 bool thisPtr = exp.member.thisPtr;
2194 if(type.kind == subClassType && exp.member.exp.type == classExp)
2195 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2197 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2201 // DANGER: Buffer overflow
2202 char string[2048] = "";
2204 PrintType(type, string, false, true);
2205 classSym = FindClass(string);
2206 _class = classSym ? classSym.registered : null;
2209 if(_class && exp.member.memberType == dataMember)
2211 if(!thisPtr && !exp.member.member.classSym)
2212 member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
2214 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2216 else if(_class && exp.member.memberType == propertyMember)
2218 if(!thisPtr && !exp.member.member.classSym)
2219 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2221 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2222 if(prop && (exp.usage.usageRef ||
2223 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2224 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2226 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
2229 exp.member.memberType = dataMember;
2234 if(exp.usage.usageRef)
2235 Compiler_Error($"cannot obtain address of property\n");
2237 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2238 else if(exp.usage.usageDelete)
2239 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2243 else if(_class && exp.member.memberType == methodMember)
2246 method = eClass_FindMethod(_class, exp.member.member.string, null);
2248 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2250 else if(_class && exp.member.memberType == reverseConversionMember)
2253 _class = FindClass(exp.member.member.string).registered;
2254 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2255 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2257 else if(_class && exp.member.memberType == classPropertyMember)
2259 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2263 // Only process Gets here, Set is processed in opExp's '='
2264 if(exp.usage.usageGet)
2268 char getName[1024], setName[1024];
2269 Expression ptr = exp.member.exp;
2270 Class propertyClass;
2271 char * nameToUse = convertTo ? setName : getName;
2273 FreeIdentifier(exp.member.member);
2275 // Process this here since it won't be processed at the end...
2276 exp.member.exp.usage.usageGet = true;
2277 ProcessExpression(exp.member.exp);
2278 // TEST: exp.tempCount = exp.member.exp.tempCount;
2280 DeclareProperty(prop, setName, getName);
2281 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2282 propertyClass = convertTo ? _class :
2283 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2286 if(propertyClass && propertyClass.type == bitClass)
2288 // Bit classes shouldn't have properties except for conversions...
2289 OldList * args = MkList();
2290 if(exp.usage.usageDeepGet)
2292 char className[1024];
2294 Declarator declarator;
2295 OldList * specs = MkList(), * decls = MkList();
2298 // Make a declaration in the closest compound statement
2299 // (Do not reuse (since using address for function calls)...)
2300 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2302 SpecDeclFromString(propertyClass.dataTypeString, specs,
2303 MkDeclaratorIdentifier(MkIdentifier(className)));
2305 ListAdd(decls, MkInitDeclarator(declarator, null));
2307 decl = MkDeclaration(specs, decls);
2308 if(!curCompound.compound.declarations)
2309 curCompound.compound.declarations = MkList();
2310 curCompound.compound.declarations->Insert(null, decl);
2312 tempExp = QMkExpId(className);
2313 tempExp.expType = MkClassType(propertyClass.fullName);
2315 exp.op.exp1 = tempExp;
2316 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2323 exp.call.exp = QMkExpId(nameToUse);
2324 exp.call.arguments = args;
2326 ListAdd(args, FixReference(ptr, true));
2328 else if(propertyClass && propertyClass.type == unitClass)
2330 OldList * args = MkList();
2331 ListAdd(args, FixReference(ptr, true));
2333 exp.call.exp = QMkExpId(nameToUse);
2334 exp.call.arguments = args;
2336 else if(propertyClass && propertyClass.type == structClass)
2338 OldList * args = MkList();
2339 char className[1024];
2341 OldList * specs = MkList(), * decls = MkList();
2344 // Make a declaration in the closest compound statement
2345 // (Do not reuse (since using address for function calls)...)
2348 FullClassNameCat(className, propertyClass.fullName, false); //true);
2350 //ListAdd(specs, MkSpecifierName(className));
2351 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2353 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2355 ListAdd(decls, MkInitDeclarator(
2356 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2358 decl = MkDeclaration(specs, decls);
2361 if(!curCompound.compound.declarations)
2362 curCompound.compound.declarations = MkList();
2363 curCompound.compound.declarations->Insert(null, decl);
2366 tempExp = QMkExpId(className);
2367 tempExp.expType = MkClassType(propertyClass.fullName);
2371 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2372 ListAdd(args, FixReference(ptr, true));
2376 ListAdd(args, FixReference(ptr, true));
2377 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2380 if(exp.usage.usageDeepGet)
2383 exp.call.exp = QMkExpId(nameToUse);
2384 exp.call.arguments = args;
2386 FreeExpression(tempExp);
2390 exp.type = bracketsExp;
2391 exp.list = MkList();
2392 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2393 if(exp.usage.usageMember)
2395 ListAdd(exp.list, FixReference(tempExp, true));
2396 exp.byReference = true;
2399 ListAdd(exp.list, tempExp);
2405 exp.call.exp = QMkExpId(nameToUse);
2406 exp.call.arguments = MkList();
2407 ListAdd(exp.call.arguments, FixReference(ptr, true));
2410 else if(prop.conversion)
2412 void * prev = exp.prev, * next = exp.next;
2413 *exp = *exp.member.exp;
2419 else if(classProperty)
2421 // Only process Gets here, Set is processed in opExp's '='
2422 if(exp.usage.usageGet)
2424 if(classProperty.Get)
2426 Identifier id = exp.member.member;
2427 Expression classExp = exp.member.exp;
2431 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty"));
2432 exp.call.arguments = MkList();
2433 ListAdd(exp.call.arguments, classExp);
2434 ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
2437 ProcessExpression(exp);
2444 // Get the function address if it's not called
2445 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2449 FreeIdentifier(exp.member.member);
2451 // Process this here since it won't be processed at the end...
2452 exp.member.exp.usage.usageGet = true;
2453 ProcessExpression(exp.member.exp);
2454 // TEST: exp.tempCount = exp.member.exp.tempCount;
2456 if(method.type == virtualMethod)
2458 strcpy(name, "__ecereVMethodID_");
2459 FullClassNameCat(name, method._class.fullName, false);
2461 strcat(name, method.name);
2462 exp.type = indexExp;
2463 if(memberClassSpecifier)
2465 char className[1024];
2466 // Need the class itself here...
2467 strcpy(className, "__ecereClass_");
2468 FullClassNameCat(className, _class.fullName, true);
2469 MangleClassName(className);
2472 _class.symbol = FindClass(_class.fullName);
2473 DeclareClass(_class.symbol, className);
2474 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2476 // WHAT HAPPENS TO exp.member.exp ?
2480 if(exp.thisPtr && _class.type != normalClass)
2482 FreeExpression(exp.member.exp);
2483 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2486 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2488 exp.index.index = MkListOne(QMkExpId(name));
2489 DeclareMethod(method, name);
2493 FreeExpression(exp.member.exp);
2494 exp.type = identifierExp;
2495 strcpy(name, "__ecereMethod_");
2496 FullClassNameCat(name, method._class.fullName, false);
2498 strcat(name, method.name);
2499 exp.identifier = MkIdentifier(name);
2500 DeclareMethod(method, name);
2506 // Process this here since it won't be processed at the end...
2507 if(exp.usage.usageGet)
2509 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2511 ProcessExpression(exp.member.exp);
2512 // TEST: exp.tempCount = exp.member.exp.tempCount;
2514 if(type.kind == classType)
2515 DeclareStruct(type._class.registered.fullName, false);
2517 // TESTING THIS NOHEAD STUFF...
2518 if(_class.type == noHeadClass)
2522 else if(_class.type == structClass)
2526 else if(_class.type == bitClass)
2528 OldList * list = MkList();
2529 char mask[32], shift[10];
2530 OldList * specs = MkList();
2531 BitMember bitMember = (BitMember) member;
2532 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2533 TypeName type = MkTypeName(specs, decl);
2534 if(bitMember.mask > MAXDWORD)
2535 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2537 sprintf(mask, FORMAT64HEX, bitMember.mask);
2538 sprintf(shift, "%d", bitMember.pos);
2540 FreeIdentifier(exp.member.member);
2542 // ((type) ((color & mask) >> bitPos))
2543 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2544 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2545 MkExpConstant(shift))))));
2547 exp.type = bracketsExp;
2550 else if(_class.type == unitClass)
2555 // If it's a this pointer, replace by precomputed shortcut
2558 char pointerName[1024];
2560 strcpy(pointerName, "__ecerePointer_");
2561 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2562 FreeIdentifier(exp.member.exp.identifier);
2563 exp.member.exp.identifier = MkIdentifier(pointerName);
2565 // Otherwise, access the data the hard way
2568 Expression bytePtr, e;
2569 Expression classExp;
2570 Expression checkedExp;
2571 char structName[1024];
2572 char className[1024];
2573 strcpy(className, "__ecereClass_");
2574 FullClassNameCat(className, member._class.fullName, true);
2575 MangleClassName(className);
2577 // classExp = QMkExpId(className);
2579 if(!member._class.symbol)
2580 member._class.symbol = FindClass(member._class.fullName);
2582 DeclareClass(member._class.symbol, className);
2583 DeclareStruct(member._class.fullName, false);
2586 FullClassNameCat(structName, member._class.fullName, false);
2588 checkedExp = exp.member.exp;
2589 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2590 checkedExp.type == castExp)
2592 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
2593 checkedExp = checkedExp.list->last;
2594 else if(checkedExp.type == castExp)
2595 checkedExp = checkedExp.cast.exp;
2598 if(checkedExp.type != identifierExp &&
2599 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
2600 checkedExp.type != memberExp && checkedExp.type != pointerExp)
2602 char ecereTemp[100];
2604 OldList * list = MkList();
2605 Context context = PushContext();
2606 if(exp.member.exp.tempCount > exp.tempCount)
2607 exp.tempCount = exp.member.exp.tempCount;
2610 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
2611 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
2612 curContext = context;
2613 compound = MkCompoundStmt(
2614 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
2615 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
2616 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
2617 if(member._class.fixed)
2619 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2622 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2623 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
2626 e = QMkExpId(ecereTemp);
2630 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
2631 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
2634 compound.compound.context = context;
2635 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
2636 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
2637 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
2639 exp.member.exp = MkExpExtensionCompound(compound);
2641 PopContext(context);
2642 curContext = context.parent;
2646 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
2647 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
2649 e = QBrackets(QMkExpCond(exp.member.exp,
2650 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
2651 MkExpConstant("0")));
2655 if(member._class.fixed)
2657 if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
2660 sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
2661 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
2667 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
2669 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
2670 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
2673 exp.type = pointerExp;
2678 // Take Out Any Class Specifier (Should have been used by now)
2679 FreeSpecifier(memberClassSpecifier);
2681 // Just moved this at the end... How is it?
2682 if(exp.type == memberExp || exp.type == pointerExp)
2684 exp.member.exp.usage.usageGet = true;
2685 exp.member.exp.usage.usageMember = true;
2686 exp.member.exp.tempCount = exp.tempCount;
2687 ProcessExpression(exp.member.exp);
2688 exp.tempCount = exp.member.exp.tempCount;
2689 if((changeToPtr && exp.member.exp.byReference) || noHead)
2690 exp.type = pointerExp;
2694 case extensionCompoundExp:
2696 ((Expression)((Statement)exp.compound.compound.statements->last).expressions->last).usage |= exp.usage &
2697 ExpUsage { usageGet = true, usageArg = true, usageMember = true };
2699 ProcessStatement(exp.compound);
2701 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
2702 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
2707 exp.member.exp.usage.usageGet = true;
2708 ProcessExpression(exp.member.exp);
2713 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
2714 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
2716 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, false);
2719 Expression classExp;
2721 FreeTypeName(exp.typeName);
2723 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
2725 exp.type = bracketsExp;
2726 exp.list = MkListOne(
2727 MkExpCondition(MkExpBrackets(MkListOne(
2730 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2731 MkExpIdentifier(MkIdentifier("normalClass"))),
2734 MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
2735 MkExpIdentifier(MkIdentifier("noHeadClass"))
2737 MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
2738 MkExpMember(classExp, MkIdentifier("typeSize")))
2741 ProcessExpressionType(exp);
2742 ProcessExpression(exp);
2751 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
2752 ProcessExpression(exp.cast.exp);
2754 if(exp.cast.exp.byReference)
2755 exp.byReference = exp.cast.exp.byReference;
2756 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
2757 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
2758 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
2759 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
2760 exp.byReference = true;
2762 // Moved this to 1.5...
2763 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
2769 if(exp.usage.usageGet)
2770 exp.cond.cond.usage.usageGet = true;
2771 ProcessExpression(exp.cond.cond);
2772 for(e = exp.cond.exp->first; e; e = e.next)
2774 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
2775 ProcessExpression(e);
2777 if(exp.usage.usageGet)
2778 exp.cond.elseExp.usage.usageGet = true;
2779 ProcessExpression(exp.cond.elseExp);
2784 // Need the class itself here...
2785 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
2787 Specifier spec = exp._classExp.specifiers->first;
2788 Expression argExp = GetTemplateArgExp(spec.templateParameter, thisClass, true);
2791 FreeList(exp._classExp.specifiers, FreeSpecifier);
2792 if(exp._classExp.decl)
2793 FreeDeclarator(exp._classExp.decl);
2795 exp.type = memberExp; //pointerExp;
2796 exp.member.exp = argExp;
2797 exp.member.member = MkIdentifier("dataTypeClass");
2799 ProcessExpressionType(argExp);
2800 ProcessExpression(exp);
2805 char className[1024];
2806 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
2808 strcpy(className, "__ecereClass_");
2809 FullClassNameCat(className, string, true); // TODO: Verify this
2810 MangleClassName(className);
2811 DeclareClass(FindClass(string), className);
2814 FreeList(exp._classExp.specifiers, FreeSpecifier);
2815 if(exp._classExp.decl)
2816 FreeDeclarator(exp._classExp.decl);
2818 exp.type = identifierExp;
2819 exp.identifier = MkIdentifier(className);
2825 ProcessExpression(exp.vaArg.exp);
2828 case extensionInitializerExp:
2830 ProcessInitializer(exp.initializer.initializer);
2838 static void ProcessInitializer(Initializer init)
2842 case expInitializer:
2843 init.exp.usage.usageGet = true;
2844 ProcessExpression(init.exp);
2845 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
2846 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
2848 FixReference(init.exp, true);
2850 else if(init.exp.destType && init.exp.destType.kind == classType)
2851 FixReference(init.exp, false);
2853 case listInitializer:
2856 for(i = init.list->first; i; i = i.next)
2857 ProcessInitializer(i);
2863 static void ProcessDeclaration(Declaration decl)
2867 case initDeclaration:
2869 if(decl.declarators)
2873 for(d = decl.declarators->first; d; d = d.next)
2876 ProcessInitializer(d.initializer);
2884 static void ProcessStatement(Statement stmt)
2889 ProcessStatement(stmt.labeled.stmt);
2892 if(stmt.caseStmt.exp)
2894 stmt.caseStmt.exp.usage.usageGet = true;
2896 // This expression should be constant...
2897 ProcessExpression(stmt.caseStmt.exp);
2899 if(stmt.caseStmt.stmt)
2900 ProcessStatement(stmt.caseStmt.stmt);
2904 if(stmt.compound.context)
2908 Statement prevCompound = curCompound;
2909 Context prevContext = curContext;
2911 if(!stmt.compound.isSwitch)
2914 curContext = stmt.compound.context;
2917 if(stmt.compound.declarations)
2919 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
2920 ProcessDeclaration(decl);
2922 if(stmt.compound.statements)
2924 for(s = stmt.compound.statements->first; s; s = s.next)
2925 ProcessStatement(s);
2927 curContext = prevContext;
2928 curCompound = prevCompound;
2932 case expressionStmt:
2935 if(stmt.expressions)
2937 for(exp = stmt.expressions->first; exp; exp = exp.next)
2939 ProcessExpression(exp);
2950 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
2951 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
2953 ProcessExpression(exp);
2956 if(stmt.ifStmt.stmt)
2957 ProcessStatement(stmt.ifStmt.stmt);
2958 if(stmt.ifStmt.elseStmt)
2959 ProcessStatement(stmt.ifStmt.elseStmt);
2965 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
2966 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
2968 ProcessExpression(exp);
2970 ProcessStatement(stmt.switchStmt.stmt);
2976 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
2977 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
2979 ProcessExpression(exp);
2981 ProcessStatement(stmt.whileStmt.stmt);
2987 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
2989 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
2990 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
2992 ProcessExpression(exp);
2995 if(stmt.doWhile.stmt)
2996 ProcessStatement(stmt.doWhile.stmt);
3002 if(stmt.forStmt.init)
3003 ProcessStatement(stmt.forStmt.init);
3005 if(stmt.forStmt.check)
3007 if(stmt.forStmt.check.expressions)
3009 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3011 ProcessStatement(stmt.forStmt.check);
3013 if(stmt.forStmt.increment)
3015 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3017 ProcessExpression(exp);
3020 if(stmt.forStmt.stmt)
3021 ProcessStatement(stmt.forStmt.stmt);
3033 if(stmt.expressions)
3035 ((Expression)stmt.expressions->last).usage.usageGet = true;
3036 for(exp = stmt.expressions->first; exp; exp = exp.next)
3038 ProcessExpression(exp);
3043 case badDeclarationStmt:
3045 ProcessDeclaration(stmt.decl);
3051 if(stmt.asmStmt.inputFields)
3053 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3054 if(field.expression)
3055 ProcessExpression(field.expression);
3057 if(stmt.asmStmt.outputFields)
3059 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3060 if(field.expression)
3061 ProcessExpression(field.expression);
3063 if(stmt.asmStmt.clobberedFields)
3065 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3066 if(field.expression)
3067 ProcessExpression(field.expression);
3074 static void ProcessFunction(FunctionDefinition function)
3078 ProcessStatement(function.body);
3079 if(function.tempCount)
3081 Statement stmt = function.body;
3083 // Declare ecereTemp here, we need it!
3084 if(!stmt.compound.declarations)
3085 stmt.compound.declarations = MkList();
3086 curContext = stmt.compound.context;
3087 for(c = 1; c<=function.tempCount; c++)
3089 char ecereTemp[100];
3090 sprintf(ecereTemp, "__ecereTemp%d", c);
3091 stmt.compound.declarations->Insert(null,
3092 QMkDeclarationBase(VOID, MkInitDeclarator(QMkPtrDecl(ecereTemp), null)));
3094 curContext = stmt.compound.context.parent;
3099 static void ProcessMemberInitData(MemberInit member)
3101 if(member.initializer)
3102 ProcessInitializer(member.initializer);
3105 static void ProcessInstantiation(Instantiation inst)
3109 MembersInit members;
3110 for(members = inst.members->first; members; members = members.next)
3112 if(members.type == dataMembersInit)
3114 if(members.dataMembers)
3117 for(member = members.dataMembers->first; member; member = member.next)
3118 ProcessMemberInitData(member);
3121 else if(members.type == methodMembersInit)
3123 ProcessFunction((FunctionDefinition)members.function);
3129 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3130 public void ProcessMemberAccess()
3133 for(external = ast->first; external; external = external.next)
3135 curExternal = external;
3136 // There shouldn't be any class member access here anyways...
3137 if(external.type == declarationExternal)
3139 if(external.declaration)
3140 ProcessDeclaration(external.declaration);
3144 for(external = ast->first; external; external = external.next)
3146 curExternal = external;
3147 if(external.type == functionExternal)
3149 ProcessFunction(external.function);
3151 else if(external.type == declarationExternal)
3153 //currentClass = external.function._class;
3154 if(external.declaration)
3155 ProcessDeclaration(external.declaration);
3157 else if(external.type == classExternal)
3159 ClassDefinition _class = external._class;
3160 //currentClass = external.symbol.registered;
3161 if(_class.definitions)
3164 Class regClass = _class.symbol.registered;
3166 // Process all functions
3167 for(def = _class.definitions->first; def; def = def.next)
3169 if(def.type == functionClassDef)
3171 curExternal = def.function.declarator.symbol.pointerExternal;
3172 ProcessFunction((FunctionDefinition)def.function);
3174 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3176 ProcessInstantiation(def.decl.inst);
3178 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3180 MemberInit defProperty;
3182 // Add this to the context
3185 string = CopyString("this");
3186 type = MkClassType(regClass.fullName);
3188 globalContext.symbols.Add((BTNode)thisSymbol);
3190 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3192 //thisClass = regClass;
3193 ProcessMemberInitData(defProperty); //, regClass, &id);
3197 //globalContext.symbols.Delete((BTNode)thisSymbol);
3198 globalContext.symbols.Remove((BTNode)thisSymbol);
3199 FreeSymbol(thisSymbol);
3201 else if(def.type == propertyClassDef && def.propertyDef)
3203 PropertyDef prop = def.propertyDef;
3205 // Add this to the context
3208 string = CopyString("this");
3209 type = MkClassType(regClass.fullName);
3211 globalContext.symbols.Add((BTNode)thisSymbol);
3213 //thisClass = regClass;
3216 curExternal = prop.symbol.externalSet;
3217 ProcessStatement(prop.setStmt);
3221 curExternal = prop.symbol.externalGet;
3222 ProcessStatement(prop.getStmt);
3226 curExternal = prop.symbol.externalIsSet;
3227 ProcessStatement(prop.issetStmt);
3232 //globalContext.symbols.Delete((BTNode)thisSymbol);
3233 globalContext.symbols.Remove((BTNode)thisSymbol);
3234 FreeSymbol(thisSymbol);
3236 else if(def.type == classPropertyClassDef && def.propertyDef)
3238 PropertyDef prop = def.propertyDef;
3240 //thisClass = regClass;
3243 curExternal = prop.symbol.externalSet;
3244 ProcessStatement(prop.setStmt);
3248 curExternal = prop.symbol.externalGet;
3249 ProcessStatement(prop.getStmt);
3253 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3255 PropertyWatch propertyWatch = def.propertyWatch;
3257 // Add this to the context
3260 string = CopyString("this");
3261 type = MkClassType(regClass.fullName);
3263 globalContext.symbols.Add((BTNode)thisSymbol);
3265 //thisClass = regClass;
3266 if(propertyWatch.compound)
3270 string = CopyString("this");
3271 type = MkClassType(regClass.fullName);
3273 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3275 ProcessStatement(propertyWatch.compound);
3277 // thisClass = null;
3279 //globalContext.symbols.Delete((BTNode)thisSymbol);
3280 globalContext.symbols.Remove((BTNode)thisSymbol);
3281 FreeSymbol(thisSymbol);