3 #define YYLTYPE Location
6 extern External curExternal;
7 static Statement curCompound;
9 static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
12 Expression memberExp = *memberExpPtr;
13 if(memberExp && memberExp.type == ExpressionType::memberExp &&
14 memberExp.member.exp && (memberExp.member.exp.type == bracketsExp || memberExp.member.exp.type == extensionExpressionExp))
16 Expression bracketExp = memberExp.member.exp;
17 Expression idExp = bracketExp.list->last;
19 if(idExp && idExp.type == identifierExp)
21 Expression newExp = null;
22 Expression exp = *expPtr;
24 // opExp ( memberExp ( bracketsExp ( identifierExp ) ) )
25 // bracketsExp ( opExp ( memberExp ( identifierExp ) ) )
28 newExp = CopyExpression(exp);
31 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
33 memberExp.member.exp = idExp;
35 exp.type = bracketsExp;
36 exp.list = bracketExp.list;
37 bracketExp.list = null;
39 exp.list->Remove(idExp);
40 exp.list->Add(newExp);
41 FreeExpression(bracketExp);
43 *expPtr = exp; //FixRefExp(newExp); // TESTING THIS: exp was not used!
46 else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
47 memberExp && (memberExp.type == bracketsExp || memberExp.type == extensionExpressionExp) && memberExp.list && memberExp.list->count > 1)
49 Expression newExp = null;
50 Expression exp = *expPtr;
53 newExp = CopyExpression(exp);
54 *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
56 exp.type = bracketsExp;
57 exp.list = memberExp.list;
58 memberExp.list = null;
60 exp.list->Remove(exp.list->last);
61 exp.list->Add(newExp);
62 FreeExpression(memberExp);
64 *expPtr = newExp; //FixRefExp(newExp);
68 static Expression FixRefExp(Expression exp)
72 _FixRefExp(&exp, &exp.op.exp1);
73 _FixRefExp(&exp, &exp.op.exp2);
75 else if(exp.type == indexExp)
76 _FixRefExp(&exp, &exp.index.exp);
77 else if(exp.type == memberExp)
78 _FixRefExp(&exp, &exp.member.exp);
82 static Expression FixReference(Expression e, bool wantReference)
84 if(e.expType && e.type != constantExp)
86 Type type = e.expType;
87 bool isPointer = false;
89 if(type.kind == TypePointer && type.type && type.type.kind == classType)
96 if(type.kind == classType) // || type.kind == TypeInt)
98 Class _class = type._class ? type._class.registered : null;
99 // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
100 // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
101 if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
102 (_class.type == systemClass && _class.base &&
103 strcmp(_class.fullName, "uintptr") &&
104 strcmp(_class.fullName, "intptr") &&
105 strcmp(_class.fullName, "uintsize") &&
106 strcmp(_class.fullName, "intsize"))))
108 // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
109 if(wantReference != (e.byReference || isPointer))
114 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
118 exp.byReference = wantReference;
119 exp = exp.list->last;
124 else if(exp.type == castExp)
126 exp.byReference = wantReference;
129 else if(exp.type == conditionExp)
131 if(exp.cond.exp->last)
132 FixReference(exp.cond.exp->last, wantReference);
133 FixReference(exp.cond.elseExp, wantReference);
138 if(wantReference != (exp.byReference || isPointer))
140 Expression newExp { };
145 if(exp.destType) exp.destType.refCount++;
146 if(exp.expType) exp.expType.refCount++;
150 exp.op.exp2 = newExp;
156 e.byReference = wantReference;
157 exp.byReference = wantReference;
170 static Expression GetInnerExp(Expression exp)
173 while(e && (e.type == bracketsExp || e.type == castExp))
175 if(e.type == bracketsExp)
176 e = e.list ? e.list->last : null;
177 else if(e.type == castExp)
183 Expression GetNonBracketsExp(Expression exp)
186 while(e && e.type == bracketsExp)
187 e = e.list ? e.list->last : null;
191 static bool FixMember(Expression exp)
193 bool byReference = false;
196 if(exp.type == bracketsExp || exp.type == extensionExpressionExp)
198 if(exp.list->count > 1)
200 exp = exp.list->last;
202 else if(exp.type == castExp)
209 FixReference(exp, true);
211 byReference = exp.byReference;
218 static void ProcessExpression(Expression exp)
220 Location oldyylloc = yylloc;
222 char debugExpString[1024] = "";
223 PrintExpression(exp, debugExpString);
233 if(exp.expType && exp.expType.kind == methodType)
235 Class _class = exp.expType.methodClass;
236 Method method = exp.expType.method;
237 if(method.type == virtualMethod)
242 OldList * specs = MkList();
243 strcpy(name, "__ecereVMethodID_");
244 FullClassNameCat(name, method._class.fullName, false);
246 strcat(name, method.name);
248 DeclareMethod(curExternal, method, name);
250 // Cast function to its type
251 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
252 if(!method.dataType.staticMethod)
254 Declarator funcDecl = GetFuncDecl(decl);
256 if(!funcDecl.function.parameters)
257 funcDecl.function.parameters = MkList();
259 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
260 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
262 if(firstParam && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
263 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
266 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
267 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
270 typeName = MkTypeName(specs, decl);
274 char className[1024];
275 // Need the class itself here...
276 strcpy(className, "__ecereClass_");
277 FullClassNameCat(className, _class.fullName, true);
280 _class.symbol = FindClass(_class.fullName);
281 DeclareClass(curExternal, _class.symbol, className);
284 FreeIdentifier(exp.identifier);
285 exp.type = bracketsExp;
286 exp.list = MkListOne(MkExpCast(typeName,
287 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
288 MkListOne(MkExpIdentifier(MkIdentifier(name))))));
294 strcpy(name, "__ecereMethod_");
295 FullClassNameCat(name, method._class.fullName, false);
297 strcat(name, method.name);
299 delete exp.identifier.string;
300 FreeSpecifier(exp.identifier._class);
302 exp.identifier._class = null;
303 exp.identifier.string = CopyString(name);
304 DeclareMethod(curExternal, method, name);
308 if(exp.usage & USAGE_MEMBER)
309 FixReference(exp, true);
322 OldList * args = MkList();
324 if(exp.type == renewExp || exp.type == renew0Exp)
325 ListAdd(args, exp._renew.exp);
327 ListAdd(args, MkExpOp(MkExpTypeSize(exp._new.typeName), '*', MkExpBrackets(MkListOne(exp._new.size))));
331 case newExp: exp.call.exp = QMkExpId("ecere::com::eSystem_New"); DeclareFunctionUtil(curExternal, "eSystem_New"); break;
332 case new0Exp: exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); DeclareFunctionUtil(curExternal, "eSystem_New0"); break;
333 case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); DeclareFunctionUtil(curExternal, "eSystem_Renew"); break;
334 case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); DeclareFunctionUtil(curExternal, "eSystem_Renew0"); break;
336 exp.call.arguments = args;
339 ProcessExpression(exp);
344 Expression exp1 = exp.op.exp1;
345 Expression exp2 = exp.op.exp2;
349 // Assignment Operators
352 exp.op.exp2.usage.usageGet = true;
364 exp.op.exp2.usage.usageGet = true;
373 if(exp.op.exp1 && exp.op.exp2)
375 exp.op.exp1.usage.usageGet = true;
376 exp.op.exp2.usage.usageGet = true;
380 exp.op.exp2.usage.usageRef = true;
389 exp.op.exp1.usage.usageGet = true;
394 exp.op.exp2.usage.usageGet = true;
397 // Binary only operators
413 exp.op.exp1.usage.usageGet = true;
415 exp.op.exp2.usage.usageGet = true;
419 if(exp.op.op == '=' || exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN || exp.op.op == ADD_ASSIGN ||
420 exp.op.op == MOD_ASSIGN || exp.op.op == SUB_ASSIGN || exp.op.op == LEFT_ASSIGN ||
421 exp.op.op == RIGHT_ASSIGN || exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN ||
422 exp.op.op == XOR_ASSIGN || exp.op.op == INC_OP || exp.op.op == DEC_OP)
424 Expression memberExp;
425 Expression parentExp = null; // Where to take memberExp out from
426 bool isIndexedContainerAssignment = false;
428 // TOCHECK: See note below for this if
429 if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
431 // Extra bit of code to access deep properties...
432 Expression testExp, topExp = null;
433 Expression lastExp = exp.op.exp1, parentExp = null;
434 Property lastProperty = null;
437 char setName[1024], getName[1024];
438 testExp = exp.op.exp1.member.exp;
441 // Is further fixing needed to address if statement above in the same way?
444 if(testExp.type == castExp)
445 testExp = testExp.cast.exp;
446 else if(testExp.type == bracketsExp || testExp.type == extensionExpressionExp)
447 testExp = testExp.list->last;
448 else if(testExp.type == ExpressionType::memberExp)
455 if(testExp.member.memberType == propertyMember ||
456 testExp.member.memberType == reverseConversionMember)
458 Type type = testExp.member.exp.expType;
461 if(type.kind == classType)
463 Class _class = testExp.member.member.classSym ? testExp.member.member.classSym.registered : type._class.registered;
464 Class convertTo = null;
465 if(testExp.member.memberType == reverseConversionMember)
468 _class = FindClass(testExp.member.member.string).registered;
469 // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
470 lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
474 lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
476 if(lastProperty && lastProperty.Get && lastProperty.Set)
478 DeclareProperty(curExternal, lastProperty, setName, getName);
479 // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
480 propertyClass = convertTo ? _class :
481 ((((Symbol)lastProperty.symbol).type &&
482 ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
483 // TODO: Handle this kind of things with bit classes?
484 if(propertyClass && propertyClass.type == structClass)
489 else if(propertyClass && propertyClass.type == bitClass)
501 testExp = testExp.member.exp;
505 if(propertyClass.type == structClass)
509 char className[1024];
512 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
513 tempExp = QMkExpId(className);
514 tempExp.expType = MkClassType(propertyClass.fullName);
516 parentExp.member.exp = tempExp;
518 value = MkExpBrackets(MkList());
520 copy = CopyExpression(topExp);
521 copy.usage.usageGet = true;
522 copy.usage.usageDeepGet = true;
524 ListAdd(value.list, copy);
525 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
526 ListAdd(value.list, CopyExpression(tempExp));
527 value.expType = tempExp.expType;
528 tempExp.expType.refCount++;
530 // Go on as usual with these new values:
531 exp.op.exp1 = topExp;
538 else if(propertyClass.type == bitClass)
542 char className[1024];
545 sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
546 tempExp = QMkExpId(className);
547 tempExp.expType = MkClassType(propertyClass.fullName);
549 parentExp.member.exp = tempExp;
551 value = MkExpBrackets(MkList());
553 copy = CopyExpression(topExp);
554 copy.usage.usageGet = true;
555 copy.usage.usageDeepGet = true;
557 ListAdd(value.list, copy);
558 ListAdd(value.list, MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2));
559 ListAdd(value.list, CopyExpression(tempExp));
560 value.expType = tempExp.expType;
561 value.expType.refCount++;
563 //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
565 // Go on as usual with these new values:
566 exp.op.exp1 = topExp;
576 memberExp = exp.op.exp1;
578 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
579 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
581 parentExp = memberExp;
582 if(memberExp.type == extensionCompoundExp)
583 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
585 memberExp = memberExp.list->last;
588 if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
589 memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
590 memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
592 Class c = memberExp.index.exp.expType._class.registered;
593 // TODO: Find these once on loadup
594 Class arrayClass = eSystem_FindClass(privateModule, "Array");
595 if(!eClass_IsDerived(c.templateClass ? c.templateClass : c, arrayClass))
597 if(exp.op.exp2 && exp.op.op == '=')
599 modifyPassAsTemplate(&exp.op.exp2.destType, true);
600 CheckTemplateTypes(exp.op.exp2);
602 isIndexedContainerAssignment = true;
605 ProcessExpression(memberExp);
607 while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
608 memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
610 parentExp = memberExp;
611 if(memberExp.type == extensionCompoundExp)
612 memberExp = ((Statement)memberExp.compound.compound.statements->last).expressions->last;
614 memberExp = memberExp.list->last;
617 if(memberExp && memberExp.type == extensionCompoundExp)
619 parentExp = memberExp;
620 if(memberExp.type == extensionCompoundExp)
622 Statement stmt = memberExp.compound.compound.statements ? memberExp.compound.compound.statements->last : null;
623 if(stmt && stmt.type != expressionStmt) stmt = null;
624 memberExp = (stmt && stmt.expressions) ? stmt.expressions->last : null;
627 stmt.expressions->Remove(memberExp);
628 stmt.expressions->Add(MkExpOp(memberExp, exp.op.op, exp.op.exp2));
629 exp.type = bracketsExp;
630 exp.list = MkListOne(parentExp);
631 ProcessExpression(exp);
636 memberExp = memberExp.list->last;
640 if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
642 if(memberExp && memberExp.type == ExpressionType::memberExp && memberExp.member.member)
644 Type type = memberExp.member.exp.expType;
647 // Check if it's an instance
648 if(type.kind == classType || type.kind == subClassType)
650 // TODO: SOMETHING WRONG HERE...
651 Class _class = memberExp.member.member.classSym ? (memberExp.member.member.classSym ? memberExp.member.member.classSym.registered : null) : (type._class ? type._class.registered : null);
653 if(memberExp == exp1)
657 if(parentExp.type == extensionCompoundExp)
658 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(memberExp);
660 parentExp.list->Remove(memberExp);
663 if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
665 BitMember bitMember =
666 (BitMember)eClass_FindDataMember(_class,
667 memberExp.member.member.string, privateModule, null, null);
668 char mask[32], shift[10];
669 OldList * specs = MkList();
670 //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
671 Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
672 TypeName type = MkTypeName(specs, decl);
674 if(bitMember.mask > MAXDWORD)
675 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
677 sprintf(mask, FORMAT64HEX, bitMember.mask);
678 sprintf(shift, "%d", bitMember.pos);
680 // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
681 exp.op.exp1 = memberExp.member.exp;
683 // TESTING THIS FOR: argb.color.r = 1;
684 //ProcessExpression(memberExp.member.exp);
686 // TESTING THIS... FIX ELSEWHRE... FIX FOR OTHER OPS
687 if(exp.op.op == XOR_ASSIGN)
689 exp.op.exp2 = MkExpOp(MkExpBrackets(
690 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift));
694 exp.op.exp2 = MkExpOp(
695 MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
696 MkExpOp(null, '~', MkExpConstant(mask))))), '|',
697 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
698 MkListOne(MkExpCast(type, MkExpBrackets(MkListOne(exp.op.exp2))))), LEFT_OP, MkExpConstant(shift)))));
701 memberExp.member.exp = null;
702 FreeExpression(memberExp);
704 // TESTING THIS FOR: argb.color.r = 1;
705 ProcessExpression(exp);
708 else if(_class && _class.type == unitClass && memberExp.member.memberType == dataMember)
711 else if(memberExp.member.memberType != dataMember)
714 Class convertTo = null;
715 ClassProperty classProperty = null;
717 if(memberExp.member.memberType == reverseConversionMember)
720 _class = FindClass(memberExp.member.member.string).registered;
721 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
722 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
725 prop = eClass_FindProperty(_class, memberExp.member.member.string, privateModule);
727 if(memberExp.member.memberType == classPropertyMember)
728 classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
730 exp.tempCount = memberExp.member.exp.tempCount;
734 // Only process Gets here, Set is processed in opExp's '='
735 if(classProperty.Set)
737 Identifier id = memberExp.member.member;
738 Expression classExp = memberExp.member.exp;
739 Expression value = exp.op.exp2;
741 memberExp.member.exp = null;
742 memberExp.member.member = null;
745 FreeExpContents(memberExp);
749 exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
750 exp.call.arguments = MkList();
751 ListAdd(exp.call.arguments, classExp);
753 char * s = QMkString(id.string);
754 ListAdd(exp.call.arguments, MkExpString(s));
757 if(value.expType.isPointerType)
758 value = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("intptr")), null), value);
759 ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
763 ProcessExpression(exp);
769 if((!convertTo && prop.Set) || (convertTo && prop.Get))
771 Expression value = exp.op.exp2;
772 char setName[1024], getName[1024];
773 char * setToUse = convertTo ? getName : setName;
774 char * getToUse = convertTo ? setName : getName;
775 bool needAddress = false;
776 int operator = exp.op.op;
779 case MUL_ASSIGN: operator = '*'; break;
780 case DIV_ASSIGN: operator = '/'; break;
781 case MOD_ASSIGN: operator = '%'; break;
782 case SUB_ASSIGN: operator = '-'; break;
783 case ADD_ASSIGN: operator = '+'; break;
784 case LEFT_ASSIGN: operator = LEFT_OP; break;
785 case RIGHT_ASSIGN: operator = RIGHT_OP; break;
786 case AND_ASSIGN: operator = '&'; break;
787 case OR_ASSIGN: operator = '|'; break;
788 case XOR_ASSIGN: operator = '^'; break;
793 if(operator == INC_OP)
794 value = MkExpOp(CopyExpression(memberExp),
795 '+', MkExpConstant("1"));
796 else if(operator == DEC_OP)
797 value = MkExpOp(CopyExpression(memberExp),
798 '-', MkExpConstant("1"));
801 value = MkExpOp(CopyExpression(memberExp),
805 value.expType = memberExp.expType;
806 memberExp.expType.refCount++;
807 value.usage.usageArg = true;
809 if(isIndexedContainerAssignment)
811 value.op.exp1.usage.usageGet = true;
812 value.op.exp2.usage.usageGet = true;
813 modifyPassAsTemplate(&value.op.exp1.destType, false);
814 modifyPassAsTemplate(&value.op.exp2.destType, false);
815 CheckTemplateTypes(value.op.exp1);
816 CheckTemplateTypes(value.op.exp2);
818 modifyPassAsTemplate(&value.expType, false);
819 value.destType = value.expType;
820 value.expType.refCount++;
821 modifyPassAsTemplate(&value.destType, true);
822 CheckTemplateTypes(value);
827 // Dont free exp2, we're using it
832 value.usage.usageArg = true;
834 DeclareProperty(curExternal, prop, setName, getName);
836 if(memberExp.member.exp)
838 ProcessExpression(memberExp.member.exp);
839 CheckTemplateTypes(memberExp.member.exp);
842 // If get flag present
843 if(exp.usage.usageGet &&
844 ((!convertTo && prop.Get) || (convertTo && prop.Set)))
846 OldList * list = MkList();
849 Context context = PushContext();
852 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
853 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
855 curContext = context;
856 exp.type = extensionCompoundExp;
857 exp.compound = MkCompoundStmt(
858 MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
859 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
860 MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
867 ListAdd(args, value);
868 ListAdd(args, QMkExpId(ecereTemp));
869 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getName), args))));
873 ListAdd(args, QMkExpId(ecereTemp));
874 ListAdd(args, value);
875 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
881 ListAdd(args, QMkExpId(ecereTemp));
883 args->Insert(null, QMkExpId(ecereTemp));
884 ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(getToUse), args))));
886 exp.compound.compound.context = context;
888 curContext = context.parent;
892 Expression newExp = exp;
894 if(parentExp && parentExp.type == extensionCompoundExp)
896 newExp = Expression { };
897 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
898 FreeType(exp.expType);
899 FreeType(exp.destType);
902 parentExp.type = dummyExp;
903 parentExp.expType = null;
904 parentExp.destType = null;
907 newExp.type = callExp;
908 newExp.call.exp = QMkExpId(setToUse);
909 newExp.call.arguments = MkList();
912 ListAdd(newExp.call.arguments, value);
913 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
917 ListAdd(newExp.call.arguments, FixReference(memberExp.member.exp, true));
918 ListAdd(newExp.call.arguments, value);
923 // Take it out from there
924 memberExp.member.exp = null;
926 // Don't use the temporaries used by the left side...
929 value.tempCount = exp.tempCount;
930 ProcessExpression(value);
932 FixReference(isIndexedContainerAssignment ? GetInnerExp(value) : value, true);
935 FreeExpression(memberExp);
939 DataMember member = eClass_FindDataMember(_class, memberExp.member.member.string, privateModule, null, null);
942 memberExp.member.memberType = dataMember;
945 Compiler_Error($"no set defined for property %s of class %s\n", prop.name, prop._class.fullName);
950 Method method = eClass_FindMethod(_class, memberExp.member.member.string, privateModule);
951 if(method && method.type == virtualMethod && type.kind != subClassType)
953 Expression value = exp.op.exp2;
954 // Don't use the temporaries used by the left side...
955 value.tempCount = exp.tempCount;
956 ProcessExpression(value);
958 if(memberExp.member.exp)
959 ProcessExpression(memberExp.member.exp);
961 if(exp.usage.usageGet)
963 OldList * list = MkList();
968 ListAdd(args, memberExp.member.exp);
970 char * string = QMkString(memberExp.member.member.string);
971 ListAdd(args, MkExpString(string));
974 ListAdd(args, value);
975 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eInstance_SetMethod"), args));
976 ListAdd(list, CopyExpression(value));
977 exp.type = bracketsExp;
984 exp.call.exp = QMkExpId("ecere::com::eInstance_SetMethod");
985 exp.call.arguments = MkList();
986 ListAdd(exp.call.arguments, memberExp.member.exp);
988 char * string = QMkString(memberExp.member.member.string);
989 ListAdd(exp.call.arguments, MkExpString(string));
992 ListAdd(exp.call.arguments, value);
995 memberExp.member.exp = null;
998 FreeExpression(memberExp);
1002 else if(memberExp.member.memberType == dataMember)
1004 //if(exp.usage & USAGE_GET);
1005 //FixReference(value, true);
1006 if(FixMember(memberExp.member.exp))
1008 // TESTING THIS HERE:
1009 ProcessExpression(memberExp);
1011 memberExp.type = pointerExp;
1018 else if(exp.op.op == _INCREF)
1020 Expression object = exp.op.exp2;
1022 FreeExpContents(exp);
1023 FreeType(exp.expType);
1024 FreeType(exp.destType);
1026 exp.destType = null;
1028 exp.op.exp1 = MkExpPointer(object, MkIdentifier("_refCount"));
1030 else if(exp.op.op == DELETE)
1032 Expression object = exp.op.exp2;
1033 OldList * args = MkList();
1035 exp.type = bracketsExp;
1036 exp.list = MkList();
1038 object.usage.usageDelete = true;
1040 ProcessExpression(object);
1042 ListAdd(args, object);
1044 // TOFIX: Same time as when we fix for = 0
1046 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
1047 exp.expType._class.registered.type == normalClass &&
1048 strcmp(exp.expType._class.registered.dataTypeString, "char *"))
1050 Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
1051 ProcessExpressionType(decRefExp);
1052 ListAdd(exp.list, decRefExp);
1054 else if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == noHeadClass)
1057 char className[1024];
1058 OldList * list = MkList();
1060 strcpy(className, "__ecereClass_");
1061 FullClassNameCat(className, exp.expType._class.string, true);
1063 DeclareClass(exp.expType._class, className);
1065 // Call the non virtual destructor
1066 ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
1067 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1069 ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
1071 MkExpBrackets(MkListOne(MkExpCondition(
1072 MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
1073 MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
1078 OldList * list = MkList();
1082 Statement compound = MkCompoundStmt(MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("__ecerePtrToDelete"))),
1083 MkInitializerAssignment(MkExpBrackets(args)))))), MkListOne(stmt = MkExpressionStmt(list)));
1084 Expression stmtExp = MkExpExtensionCompound(compound);
1085 for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
1087 char className[1024];
1089 if(_class.templateClass) _class = _class.templateClass;
1090 strcpy(className, "__ecereClass_");
1091 FullClassNameCat(className, _class.fullName, false /*true*/);
1094 _class.symbol = FindClass(_class.fullName);
1095 DeclareClass(curExternal, _class.symbol, className);
1097 // Call the non virtual destructor
1101 QMkExpId(className),
1102 MkIdentifier("Destructor")
1107 QMkExpId(className),
1108 MkIdentifier("Destructor")
1110 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), MkExpIdentifier(MkIdentifier("__ecerePtrToDelete")) /*CopyExpression(args->first)*/))
1117 ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), MkListOne(MkExpIdentifier(MkIdentifier("__ecerePtrToDelete"))) /*args*/));
1118 DeclareFunctionUtil(curExternal, "eSystem_Delete");
1119 o = CopyExpression(object);
1120 ProcessExpressionType(o);
1121 o.usage.usageGet = true;
1122 ProcessExpression(o);
1130 //MkExpBrackets(list)
1139 else if(exp.expType && exp.expType.kind == templateType)
1141 Expression argExp = GetTemplateArgExp(exp.expType.templateParameter, exp.expType.thisClassFrom, thisClass, false);
1144 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1146 OldList * qualifiers = MkList();
1147 Declarator declarator = SpecDeclFromString("void (*)(void * _class, void * data)", qualifiers, null);
1149 typeName = MkTypeName(qualifiers, declarator);
1151 ProcessExpressionType(classExp);
1152 ProcessExpression(classExp);
1153 args->Insert(null, CopyExpression(classExp));
1154 DeclareMethod(curExternal, eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
1155 ListAdd(exp.list, MkExpCall(
1156 MkExpBrackets(MkListOne(MkExpCast(typeName,
1157 MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
1158 MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
1159 //ProcessExpression(exp.list->last);
1164 ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
1165 DeclareFunctionUtil(curExternal, "eSystem_Delete");
1168 //ProcessExpression(object);
1170 ListAdd(exp.list, MkExpOp(CopyExpression(GetInnerExp(object)), '=', MkExpConstant("0")));
1174 // TESTING THIS HERE...
1175 ProcessExpression(exp);
1178 if(exp.type == opExp)
1180 // Handle assigment of template structures
1181 if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
1182 (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
1184 Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, exp.op.exp1.expType.thisClassFrom, thisClass, false);
1187 // memcpy((byte *)array + (count * dataTypeClass.size), (dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
1189 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1190 OldList * args = MkList();
1191 Expression derefExp = exp.op.exp1;
1194 ProcessExpressionType(classExp);
1195 ProcessExpression(classExp);
1197 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1199 if(exp.op.exp1.type == indexExp)
1201 Expression indexExp = derefExp.index.exp;
1202 OldList * indexExpIndex = derefExp.index.index;
1204 derefExp.index.index = null;
1205 derefExp.index.exp = null;
1206 FreeExpression(derefExp);
1209 derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
1210 MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
1214 Expression indexExp = derefExp.op.exp2;
1215 derefExp.op.exp2 = null;
1216 FreeExpression(derefExp);
1217 derefExp = indexExp;
1220 args->Add(derefExp);
1221 ProcessExpressionType(args->last);
1222 ProcessExpression(args->last);
1224 args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1225 MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1226 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2))))),
1227 MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
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(args->last);
1239 ProcessExpression(args->last);
1242 ProcessExpressionType(args->last);
1243 ProcessExpression(args->last);
1245 DeclareFunctionUtil(curExternal, "memcpy");
1247 exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
1248 exp.type = bracketsExp;
1250 //globalContext.symbols.Delete((BTNode)thisSymbol);
1251 globalContext.symbols.Remove((BTNode)thisSymbol);
1252 FreeSymbol(thisSymbol);
1258 else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
1259 exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
1261 Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, exp.op.exp2.expType.type.thisClassFrom, thisClass, false);
1264 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1267 ProcessExpressionType(classExp);
1268 ProcessExpression(classExp);
1270 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1272 exp.type = bracketsExp;
1273 exp.list = MkListOne(
1275 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1277 // ((class.type == structClass) ?
1278 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1281 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), CopyExpression(exp.op.exp2)))))),
1283 // ((class.size == 1) ?
1284 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1286 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1287 CopyExpression(exp.op.exp2)))))),
1289 // ((class.size == 2) ?
1290 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1291 // *((uint16 *)array)
1292 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1293 CopyExpression(exp.op.exp2)))))),
1295 // ((class.size == 4) ?
1296 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1297 // *((uint32 *)array)
1298 MkListOne(MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1299 CopyExpression(exp.op.exp2)))))),
1301 // *((uint64 *)array)
1302 MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1303 exp.op.exp2))))))))))))))))))));
1305 // Add this to the context
1306 thisClass = curExternal.function ? curExternal.function._class : null;
1310 string = CopyString("this");
1311 type = MkClassType(thisClass.fullName);
1313 globalContext.symbols.Add((BTNode)thisSymbol);
1315 ProcessExpressionType(exp.list->first);
1316 ProcessExpression(exp.list->first);
1318 //globalContext.symbols.Delete((BTNode)thisSymbol);
1319 globalContext.symbols.Remove((BTNode)thisSymbol);
1320 FreeSymbol(thisSymbol);
1331 // TEST: exp.op.exp1.tempCount = Max(exp.op.exp1.tempCount, exp.op.exp2.tempCount);
1332 exp.op.exp1.tempCount = exp.op.exp2.tempCount;
1333 ProcessExpression(exp.op.exp1);
1336 if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
1337 (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
1338 exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
1339 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*/))
1340 FixReference(exp.op.exp1, false);
1341 // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
1345 // Don't use the temporaries used by the left side...
1347 // TEST: exp.op.exp2.tempCount = Max(exp.op.exp2.tempCount, exp.op.exp1.tempCount);
1348 exp.op.exp2.tempCount = exp.op.exp1.tempCount;
1349 ProcessExpression(exp.op.exp2);
1350 if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
1354 (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
1355 (exp.op.exp2.expType._class.registered.type != normalClass &&
1356 exp.op.exp2.expType._class.registered.type != structClass &&
1357 exp.op.exp2.expType._class.registered.type != noHeadClass)))
1359 // TESTING THIS TEMPLATE TYPE CHECK HERE
1360 || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
1362 FixReference(exp.op.exp2, exp.op.exp1 ? exp.op.exp1.byReference : false);
1363 //FixReference(exp.op.exp2, false);
1366 // TEST: exp.tempCount = Max(exp.op.exp2.tempCount, exp.tempCount);
1369 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)
1371 // Preserve prev, next
1372 Expression next = exp.next, prev = exp.prev;
1373 Expression derefExp = exp.op.exp2;
1374 Expression refExp = exp.op.exp2.op.exp2;
1376 derefExp.op.exp2 = null;
1377 FreeExpression(derefExp);
1378 FreeType(exp.expType);
1379 FreeType(exp.destType);
1389 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)
1391 Expression exp2 = exp.op.exp2;
1392 Expression argExp = GetTemplateArgExp(exp2.expType.templateParameter, exp2.expType.thisClassFrom, thisClass, false);
1395 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1398 ProcessExpressionType(classExp);
1399 ProcessExpression(classExp);
1401 exp.type = bracketsExp;
1402 exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
1403 MkExpOp(null, '&', exp2)), '+',
1404 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
1405 MkListOne((e = MkExpMember(classExp, MkIdentifier("typeSize")))))));
1407 // Add this to the context
1408 thisClass = curExternal.function ? curExternal.function._class : null;
1412 string = CopyString("this");
1413 type = MkClassType(thisClass.fullName);
1415 //globalContext.symbols.Add((BTNode)thisSymbol);
1417 ProcessExpressionType(e);
1418 ProcessExpression(e);
1420 //globalContext.symbols.Remove((BTNode)thisSymbol);
1421 //FreeSymbol(thisSymbol);
1430 FreeExpression(exp1);
1432 FreeExpression(exp2);
1437 case extensionExpressionExp:
1442 for(e = exp.list->first; e; e = e.next)
1446 e.usage |= (exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true });
1448 e.tempCount = exp.tempCount;
1449 ProcessExpression(e);
1451 exp.byReference = e.byReference;
1452 exp.tempCount = e.tempCount;
1456 exp.expType = e.expType;
1465 /*bool isBuiltin = exp && exp.index.exp &&
1466 (exp.index.exp.type == ExpressionType::arrayExp ||
1467 (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
1469 Expression checkedExp = exp.index.exp;
1470 bool isBuiltin = false;
1472 while(checkedExp.type == extensionCompoundExp || checkedExp.type == bracketsExp || checkedExp.type == castExp)
1474 if(checkedExp.type == extensionCompoundExp)
1479 else if(checkedExp.type == bracketsExp)
1480 checkedExp = checkedExp.list ? checkedExp.list->last : null;
1482 checkedExp = checkedExp.cast.exp;
1485 exp.index.exp.tempCount = exp.tempCount;
1487 exp.index.exp.usage.usageGet = true;
1488 ProcessExpression(exp.index.exp);
1490 if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
1491 exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
1493 Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, exp.index.exp.expType.type.thisClassFrom, thisClass, false);
1496 Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
1499 ProcessExpressionType(classExp);
1500 ProcessExpression(classExp);
1502 sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
1504 exp.type = bracketsExp;
1505 exp.list = MkListOne(
1507 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
1509 // ((class.type == structClass) ?
1510 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
1511 // ((byte *)array) + (i) * class.size
1512 MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(MkExpOp(
1513 MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
1514 MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp)))))))),
1516 // ((class.size == 1) ?
1517 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
1518 // ((byte *)array)[i]
1519 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
1520 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1522 // ((class.size == 2) ?
1523 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("2")))),
1524 // ((uint16 *)array)[i]
1525 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint16")), MkDeclaratorPointer(MkPointer(null, null), null)),
1526 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1528 // ((class.size == 4) ?
1529 MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(sizeExp, EQ_OP, MkExpConstant("4")))),
1530 // ((uint32 *)array)[i]
1531 MkListOne(MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint32")), MkDeclaratorPointer(MkPointer(null, null), null)),
1532 CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
1534 // ((uint64 *)array)[i]
1535 MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
1536 exp.index.exp))), exp.index.index)))))))))))))))));
1538 // Add this to the context
1539 thisClass = curExternal.function ? curExternal.function._class : null;
1543 string = CopyString("this");
1544 type = MkClassType(thisClass.fullName);
1546 globalContext.symbols.Add((BTNode)thisSymbol);
1548 ProcessExpressionType(exp.list->first);
1549 ProcessExpression(exp.list->first);
1551 //globalContext.symbols.Delete((BTNode)thisSymbol);
1552 globalContext.symbols.Remove((BTNode)thisSymbol);
1553 FreeSymbol(thisSymbol);
1561 for(e = exp.index.index->first; e; e = e.next)
1564 e.usage.usageGet = true;
1565 ProcessExpression(e);
1567 // Ignore temps in the index for now...
1568 exp.tempCount = exp.index.exp.tempCount;
1570 if(exp.index.exp.expType)
1572 Type source = exp.index.exp.expType;
1573 if(/*isBuiltin || */source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
1574 eClass_IsDerived(source._class.registered, containerClass))
1576 Class _class = source._class.registered;
1577 bool isArray = false;
1578 Class arrayClass = eSystem_FindClass(privateModule, "Array");
1579 if(source && eClass_IsDerived(source._class.registered, arrayClass))
1581 if(isArray && _class.templateArgs)
1583 OldList * specs = MkList();
1584 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1585 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1586 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
1587 ProcessExpressionType(exp.index.exp);
1588 ProcessExpression(exp);
1590 else if(isBuiltin && _class.templateArgs)
1592 OldList * specs = MkList();
1593 Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
1594 TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
1595 exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1596 MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
1597 ProcessExpressionType(exp.index.exp);
1598 ProcessExpression(exp);
1600 else if(_class.templateArgs)
1602 // __extension__({ Iterator<type> i { container }; i.Index(e, [ exp.usage.usageSet ]; i.value; });
1604 char iteratorType[1024];
1605 OldList * declarations = MkList();
1606 OldList * statements = MkList();
1607 OldList * args = MkList();
1608 OldList * instMembers = MkList();
1610 Context context = PushContext();
1612 sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
1614 ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
1616 ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
1617 MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
1619 ListAdd(args, MkExpBrackets(exp.index.index));
1620 ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
1622 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
1623 MkIdentifier("Index")), args))));
1625 // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
1626 ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), MkIdentifier("data")))));
1628 exp.type = bracketsExp;
1629 // exp.list = MkListOne(MkExpPointer(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))), MkIdentifier("data")));
1630 exp.list = MkListOne(expExt = (MkExpExtensionCompound(MkCompoundStmt(declarations, statements))));
1631 expExt.compound.compound.context = context;
1632 PopContext(context);
1633 expExt.usage = exp.usage;
1634 ProcessExpressionType(exp.list->first);
1635 ProcessExpressionInstPass(exp.list->first);
1636 ProcessExpression(exp.list->first);
1645 bool typedObject = false;
1646 Type ellipsisDestType = null;
1647 bool usedEllipsis = false;
1648 Expression expCallExp = exp.call.exp;
1649 OldList * arguments = exp.call.arguments;
1650 bool handleNullVMethod = false;
1651 TypeName typeName = null;
1655 for(e = arguments->first; e; e = e.next)
1657 e.usage.usageGet = true;
1658 e.usage.usageArg = true;
1659 e.tempCount = Max(e.tempCount, exp.tempCount);
1660 ProcessExpression(e);
1661 exp.tempCount = Max(exp.tempCount, e.tempCount);
1664 expCallExp.usage.usageGet = true;
1665 expCallExp.usage.usageCall = true;
1666 expCallExp.tempCount = exp.tempCount;
1668 ProcessExpression(expCallExp);
1670 if(expCallExp.expType && expCallExp.expType.kind == methodType)
1672 bool nullMemberExp = false;
1673 Expression memberExp = (expCallExp.type == ExpressionType::memberExp) ? expCallExp : null;
1675 Class _class = expCallExp.expType.methodClass; // For Virtual Method
1676 Class argClass = expCallExp.expType.methodClass; // Class actually passed
1677 Method method = expCallExp.expType.method;
1678 if(method.type == virtualMethod)
1683 OldList * specs = MkList();
1684 strcpy(name, "__ecereVMethodID_");
1685 FullClassNameCat(name, method._class.fullName, false);
1687 strcat(name, method.name);
1689 DeclareMethod(curExternal, method, name);
1692 // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
1693 curContext = (method._class.symbol) ? ((Symbol)method._class.symbol).ctx : globalContext;
1694 // Cast function to its type
1696 Context context = SetupTemplatesContext(method._class);
1698 decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
1700 FinishTemplatesContext(context);
1703 if(method.dataType && !method.dataType.staticMethod)
1705 Declarator funcDecl = GetFuncDecl(decl);
1707 if(!funcDecl.function.parameters)
1708 funcDecl.function.parameters = MkList();
1710 TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
1711 Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
1713 if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
1715 funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
1716 FreeTypeName(firstParam);
1720 if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
1725 param = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
1726 param.qualifiers->Insert(null, MkSpecifier(CONST));
1727 funcDecl.function.parameters->Insert(null, param);
1728 // Testing this for any_object::
1729 if(!method.dataType.extraParam)
1731 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
1732 DeclareStruct(curExternal, "ecere::com::Class", false, true);
1737 funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(
1738 /*MkClassName*/MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), null));
1742 typeName = MkTypeName(specs, decl);
1744 if(memberExp && memberExp.member.exp.expType)
1746 Type type = memberExp.member.exp.expType;
1748 if(type.kind == classType && type._class && type._class.registered)
1750 Class regClass = type._class.registered;
1751 ClassType classType = regClass.type;
1752 if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
1753 argClass = regClass;
1755 else if(type.kind == subClassType)
1757 argClass = FindClass("ecere::com::Class").registered;
1759 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
1761 argClass = FindClass("char *").registered;
1763 else if(type.kind == pointerType)
1765 argClass = eSystem_FindClass(privateModule, "uintptr");
1766 FreeType(memberExp.member.exp.expType);
1767 memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
1768 memberExp.member.exp.byReference = true;
1772 char string[1024] = "";
1774 PrintTypeNoConst(type, string, false, true);
1775 classSym = FindClass(string);
1776 if(classSym) argClass = classSym.registered;
1780 if(!_class && argClass && strcmp(argClass.fullName, "class"))
1786 Type type = memberExp ? memberExp.member.exp.expType : null;
1787 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
1788 char className[1024];
1790 // Added !exp.call.exp.expType.methodClass
1791 if(!expCallExp.expType.methodClass && !_class && type && type.classObjectType)
1792 strcpy(className, "class");
1796 // TESTING: Moved this here...
1797 if(!cl && argClass && strcmp(argClass.fullName, "class"))
1802 // TODO: Unhandled case here, what should happen?
1805 // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
1806 if(cl.templateClass && !_class && expCallExp.expType._class && !expCallExp.expType.methodClass &&
1807 (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
1808 cl = cl.templateClass;
1810 // Need the class itself here...
1811 strcpy(className, "__ecereClass_");
1812 FullClassNameCat(className, cl.fullName, true);
1815 cl.symbol = FindClass(cl.fullName);
1817 DeclareClass(curExternal, cl.symbol, className);
1820 if(type && type.kind == subClassType && !_class && !expCallExp.expType.methodClass && memberExp)
1822 expCallExp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1823 MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
1824 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1826 handleNullVMethod = true;
1828 else if(_class || expCallExp.expType.methodClass || !memberExp ||
1829 !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
1832 FreeExpression(expCallExp);
1833 expCallExp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1834 MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
1835 MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1837 handleNullVMethod = true;
1841 // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
1842 // as opposed to the File class vTbl one
1844 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
1846 Context context = PushContext();
1848 OldList * declList = MkListOne(MkDeclaration(
1849 (specs = MkListOne(MkSpecifierName("Instance"))),
1850 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
1851 MkInitializerAssignment(CopyExpression(memberExp.member.exp))))));
1852 OldList * stmtList = MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
1853 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
1854 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
1855 MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))));
1857 vTblExp = MkExpExtensionCompound(MkCompoundStmt(declList, stmtList));
1860 specs->Insert(null, MkSpecifier(CONST));
1862 vTblExp.loc = exp.loc;
1863 vTblExp.compound.compound.context = context;
1864 PopContext(context);
1866 expCallExp = MkExpBrackets(MkListOne(MkExpCast(typeName,
1867 MkExpIndex(vTblExp, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
1869 handleNullVMethod = true;
1876 strcpy(name, "__ecereMethod_");
1877 FullClassNameCat(name, method._class.fullName, false);
1879 strcat(name, method.name);
1882 FreeExpression(expCallExp);
1883 expCallExp = MkExpIdentifier(MkIdentifier(name));
1884 DeclareMethod(curExternal, method, name);
1885 if(memberExp && memberExp.expType && method.dataType)
1887 expCallExp.expType = method.dataType;
1888 method.dataType.refCount++;
1891 if(memberExp && (!memberExp.member.exp || !memberExp.member.exp.expType || memberExp.member.exp.expType.kind != subClassType))
1893 if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
1896 arguments = MkList();
1898 // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
1900 if(memberExp.member.exp.expType.kind != classType ||
1901 memberExp.member.exp.expType._class.registered.type == enumClass ||
1902 memberExp.member.exp.expType._class.registered.type == unitClass)
1904 char typeString[1024] = "";
1905 if(memberExp.member.exp.expType.kind != classType)
1906 PrintType(memberExp.member.exp.expType, typeString, false, true);
1908 strcpy(typeString, memberExp.member.exp.expType._class.registered.dataTypeString);
1911 // memberExp.member.exp.expType.kind = classType;
1912 // memberExp.member.exp.expType._class = FindClass(typeString);
1914 FreeType(memberExp.member.exp.expType);
1915 memberExp.member.exp.expType = Type
1918 _class = FindClass(typeString);
1922 // Default to an int instead
1923 if(!memberExp.member.exp.expType._class)
1925 // TODO: Shouldn't get here...
1926 memberExp.member.exp.expType.kind = TypeInt;
1931 if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
1933 bool changeReference = false;
1934 bool stillAddReferenceOp = false;
1935 Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
1936 Type expType = memberExp.member.exp.expType;
1937 Class c = expType.kind == classType && expType._class ? expType._class.registered : null;
1939 // Patched so that class isn't considered SYSTEM...
1940 if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
1941 strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
1942 changeReference = true;
1943 if(!expType.classObjectType && ( ( (expType.kind != pointerType && (!c || c.type == structClass) ) ) || method.dataType.byReference) ) // ADDED THIS FOR OnGetDataFromString
1945 if(c && (c.type == normalClass || c.type == noHeadClass))
1946 stillAddReferenceOp = true;
1947 changeReference = true;
1949 if(typedObject && expType.classObjectType && expType.byReference != method.dataType.byReference)
1950 changeReference = true;
1953 if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
1954 ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
1956 arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
1957 ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
1959 else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
1961 arguments->Insert(null, memberExp.member.exp.op.exp2);
1962 memberExp.member.exp.op.exp2 = null;
1964 else if(!memberExp.member.exp.byReference || stillAddReferenceOp)
1966 // TESTING THIS... REUSE THIS CODE?
1967 Expression checkedExp = memberExp.member.exp;
1968 Expression parentExp = null;
1970 bool disconnected = false;
1971 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
1973 parentExp = checkedExp;
1975 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
1977 checkedExp = checkedExp.list->last;
1978 // Dissociate from memberExp which will get freed
1979 if(checkedExp && !disconnected)
1981 parentExp.list->Remove(checkedExp);
1982 disconnected = true;
1985 else if(checkedExp.type == castExp)
1987 checkedExp = checkedExp.cast.exp;
1988 // Dissociate from memberExp which will get freed
1989 if(checkedExp && !disconnected)
1991 checkedExp.cast.exp = null;
1992 disconnected = true;
1997 nullMemberExp = true;
1999 if(typedObject && !expType.classObjectType && !stillAddReferenceOp)
2000 newExp = checkedExp;
2003 newExp = MkExpOp(null, '&', checkedExp);
2004 newExp.byReference = true;
2006 if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
2008 parentExp.list->Remove(checkedExp);
2009 parentExp.list->Add(newExp);
2011 else if(parentExp && parentExp.type == castExp)
2013 parentExp.cast.exp = newExp;
2014 // Add a dereference level here
2015 if(newExp.expType && newExp.expType.classObjectType)
2016 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
2018 if(typedObject && !expType.classObjectType)
2020 Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
2021 FreeType((parentExp ? parentExp : newExp).expType);
2022 FreeType((parentExp ? parentExp : newExp).destType);
2023 (parentExp ? parentExp : newExp).expType = checkedExp.expType;
2024 (parentExp ? parentExp : newExp).destType = destType;
2025 if(checkedExp.expType) checkedExp.expType.refCount++;
2027 arguments->Insert(null, parentExp ? parentExp : newExp);
2031 arguments->Insert(null, memberExp.member.exp);
2032 nullMemberExp = true;
2037 arguments->Insert(null, memberExp.member.exp);
2038 nullMemberExp = true;
2042 char className[1024];
2043 Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
2044 Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
2045 Class cl = argClass ? argClass : regClass;
2048 if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
2049 strcpy(className, "class");
2052 // Need the class itself here...
2053 strcpy(className, "__ecereClass_");
2054 FullClassNameCat(className, cl.fullName, true);
2057 cl.symbol = FindClass(cl.fullName);
2058 DeclareClass(curExternal, cl.symbol, className);
2063 if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
2065 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2067 Context context = PushContext();
2070 c = MkExpExtensionCompound(MkCompoundStmt(
2071 MkListOne(MkDeclaration(
2072 (specs = MkListOne(MkSpecifierName("Instance"))),
2073 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2074 MkInitializerAssignment(memberExpMemberExp))))),
2075 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2076 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2077 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2078 MkExpIdentifier(MkIdentifier(className))))))));
2079 c.compound.compound.context = context;
2080 PopContext(context);
2083 specs->Insert(null, MkSpecifier(CONST));
2085 arguments->Insert(null, c);
2087 memberExpMemberExp = null; // We used this
2090 arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
2094 if(memberExpMemberExp)
2095 FreeExpression(memberExpMemberExp);
2099 arguments->Insert(null, memberExp.member.exp);
2100 nullMemberExp = true;
2104 /*else if(method->dataType)
2110 memberExp.member.exp = null;
2111 FreeExpression(memberExp);
2117 for(e = arguments->first; e; e = e.next)
2119 Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
2120 //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
2121 //if(e.destType && (e.destType.classObjectType == ClassObjectType::typedObject || e.destType.classObjectType == anyObject))
2122 if(destType && (destType.classObjectType == ClassObjectType::typedObject || destType.classObjectType == anyObject))
2124 if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
2125 ellipsisDestType = destType;
2128 Type type = e.expType;
2129 Class _class = null;
2130 //Type destType = e.destType;
2132 if(type.kind == classType && type._class && type._class.registered)
2134 _class = type._class.registered;
2136 else if(type.kind == subClassType)
2138 _class = FindClass("ecere::com::Class").registered;
2140 else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
2142 _class = FindClass("char *").registered;
2144 else if(type.kind == pointerType)
2146 _class = eSystem_FindClass(privateModule, "uintptr");
2147 FreeType(e.expType);
2148 e.expType = ProcessTypeString("uintptr", false);
2149 // Assume null pointers means 'no object' rather than an object holding a null pointer
2150 e.byReference = true;
2154 char string[1024] = "";
2156 PrintTypeNoConst(type, string, false, true);
2157 classSym = FindClass(string);
2158 if(classSym) _class = classSym.registered;
2159 // if(!class) _class = eSystem_FindClass(privateModule, "int");
2162 if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "uintptr") && strcmp(_class.fullName, "intptr")) || // Patched so that class isn't considered SYSTEM...
2163 (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != intPtrType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
2164 destType.byReference)))
2166 //if(!_class || strcmp(_class.fullName, "String")) // TESTING THIS WITH NEW String class...
2167 //if(!_class || strcmp(_class.fullName, "char *")) // TESTING THIS WITH NEW String class...
2168 // TESTING WITHOUT THE ABOVE NOW!
2170 Expression checkedExp;
2171 Expression parentExp;
2176 while(checkedExp && (((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp))
2178 parentExp = checkedExp;
2179 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2181 if(checkedExp.type == extensionCompoundExp)
2183 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2186 checkedExp = checkedExp.list->last;
2188 else if(checkedExp.type == castExp)
2189 checkedExp = checkedExp.cast.exp;
2192 if(checkedExp && checkedExp.type == opExp && checkedExp.op.op == '*' && !checkedExp.op.exp1)
2195 Expression newExp = e.op.exp2;
2196 arguments->Insert(e.prev, newExp);
2197 arguments->Remove(e);
2202 newExp = checkedExp.op.exp2;
2203 checkedExp.op.exp2 = null;
2204 FreeExpContents(checkedExp);
2206 if(e.expType && e.expType.passAsTemplate)
2209 ComputeTypeSize(e.expType);
2210 sprintf(size, "%d", e.expType.size); // BOOTSTRAP FIX
2211 newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
2212 MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
2213 MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
2216 if(parentExp.type == callExp)
2218 arguments->Insert(e.prev, newExp);
2219 arguments->Remove(e);
2222 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2224 parentExp.list->Remove(checkedExp);
2225 parentExp.list->Add(newExp);
2227 else if(parentExp.type == castExp)
2229 // NEW CODE: BETTER WAY TO DO THIS? To prevent (double)(double *)
2230 if(parentExp.destType && parentExp.destType.kind == ellipsisType)
2232 FreeTypeName(parentExp.cast.typeName);
2233 parentExp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
2235 parentExp.cast.exp = newExp;
2237 else if(parentExp.type == extensionCompoundExp)
2239 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2240 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2242 e.byReference = true;
2244 FreeType(checkedExp.expType);
2245 FreeType(checkedExp.destType);
2248 else if((!e.byReference && (!e.expType || !e.expType.classObjectType) ) || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
2250 Expression checkedExp;
2251 Expression parentExp;
2255 // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
2257 e.type == identifierExp ||
2258 (e.type == ExpressionType::memberExp && e.member.memberType == dataMember) ||
2259 (e.type == ExpressionType::pointerExp && e.member.memberType == dataMember) ||
2260 (e.type == opExp && !e.op.exp1 && e.op.op == '*') ||
2263 if(_class && _class.type != noHeadClass && _class.type != normalClass && _class.type != structClass && !hasAddress)
2265 Context context = PushContext();
2267 OldList * specs = MkList();
2268 char typeString[1024];
2269 Expression newExp { };
2271 typeString[0] = '\0';
2274 // TOCHECK: Should this read e.destType ???
2276 if(exp.destType) exp.destType.refCount++;
2277 // if(exp.expType) exp.expType.refCount++;
2280 newExp.expType = null;
2282 PrintTypeNoConst(e.expType, typeString, false, true);
2283 decl = SpecDeclFromString(typeString, specs, null);
2284 newExp.destType = ProcessType(specs, decl);
2285 if(newExp.destType && e.expType && e.expType.passAsTemplate)
2287 Expression nbExp = GetNonBracketsExp(newExp);
2288 if(nbExp.type == castExp)
2290 // Because we're correcting this after the cast was added from the argument for loop at the beginning of this case block
2291 // (CheckTemplateTypes() already called), we'll revert the cast to generic uint64 template type
2292 FreeTypeName(nbExp.cast.typeName);
2293 nbExp.cast.typeName = MkTypeName(MkListOne(MkSpecifierName("uint64")), null);
2296 newExp.expType = newExp.destType;
2297 newExp.destType.refCount++;
2298 modifyPassAsTemplate(&newExp.expType, true);
2301 curContext = context;
2302 e.type = extensionCompoundExp;
2304 // We need a current compound for this
2308 OldList * stmts = MkList();
2309 sprintf(name, "__internalValue%03X", internalValueCounter++);
2310 if(!curCompound.compound.declarations)
2311 curCompound.compound.declarations = MkList();
2312 curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
2313 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
2314 ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
2315 CheckTemplateTypes(newExp);
2316 e.compound = MkCompoundStmt(null, stmts);
2319 printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
2323 e.compound = MkCompoundStmt(
2324 MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
2325 MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
2328 e.compound.compound.context = context;
2329 PopContext(context);
2330 curContext = context.parent;
2334 // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
2337 while(checkedExp && (((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp))
2339 parentExp = checkedExp;
2340 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
2342 if(checkedExp.type == extensionCompoundExp)
2344 checkedExp = ((Statement)checkedExp.compound.compound.statements->last).expressions->last;
2347 checkedExp = checkedExp.list->last;
2349 else if(checkedExp.type == castExp)
2350 checkedExp = checkedExp.cast.exp;
2354 newExp = MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)), (i = MkExpOp(null, '&', checkedExp)));
2355 i.byReference = true;
2356 newExp.byReference = true;
2358 if(parentExp.type == callExp)
2360 arguments->Insert(e.prev, newExp);
2361 arguments->Remove(e);
2364 else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
2366 parentExp.list->Remove(checkedExp);
2367 parentExp.list->Add(newExp);
2369 else if(parentExp.type == castExp)
2370 parentExp.cast.exp = newExp;
2371 else if(parentExp.type == bracketsExp || parentExp.type == extensionCompoundExp)
2373 ((Statement)parentExp.compound.compound.statements->last).expressions->Remove(checkedExp);
2374 ((Statement)parentExp.compound.compound.statements->last).expressions->Add(newExp);
2380 if(destType.classObjectType == ClassObjectType::typedObject)
2382 char className[1024];
2383 // Need the class itself here...
2384 if(!_class && type.kind == pointerType && type.type && type.type.kind == charType)
2385 _class = eSystem_FindClass(privateModule, "String");
2386 if(!_class) _class = eSystem_FindClass(privateModule, "int");
2388 if(!strcmp(_class.name, "class"))
2390 // Already inside a typed_object function, pass the class through
2391 strcpy(className, "class");
2395 strcpy(className, "__ecereClass_");
2396 FullClassNameCat(className, _class.fullName, true);
2399 _class.symbol = FindClass(_class.fullName);
2401 DeclareClass(curExternal, _class.symbol, className);
2404 if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
2406 // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
2408 Context context = PushContext();
2410 // Work around to avoid repeating the BuiltInContainer just to get the type
2411 // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
2412 if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
2413 e.list && e.list->first &&
2414 ((Expression)e.list->first).type == castExp &&
2415 ((Expression)e.list->first).cast.exp &&
2416 ((Expression)e.list->first).cast.exp.type == opExp &&
2417 ((Expression)e.list->first).cast.exp.op.op == '&' &&
2418 ((Expression)e.list->first).cast.exp.op.exp2 &&
2419 ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
2421 arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2426 c = MkExpExtensionCompound(MkCompoundStmt(
2427 MkListOne(MkDeclaration(
2428 (specs = MkListOne(MkSpecifierName("Instance"))),
2429 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
2430 MkInitializerAssignment(CopyExpression(e)))))),
2431 MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
2432 MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
2433 MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
2434 MkExpIdentifier(MkIdentifier(className))))))));
2435 c.compound.compound.context = context;
2436 PopContext(context);
2439 specs->Insert(null, MkSpecifier(CONST));
2441 arguments->Insert(e.prev, c);
2445 arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
2451 //char debugString[4096] = "";
2452 //PrintExpression(e, debugString);
2454 // If expression type is a simple class, make it an address
2455 FixReference(e, !destType || !destType.declaredWithStruct);
2458 if(ellipsisDestType)
2461 (expCallExp.expType && expCallExp.expType.kind == functionType && expCallExp.expType.params.last &&
2462 ((Type)expCallExp.expType.params.last).kind == ellipsisType))
2464 arguments->Insert(arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
2469 if(handleNullVMethod)
2471 Expression compoundExp;
2472 Context context = PushContext();
2473 OldList * declList = MkList();
2474 OldList * stmtList = MkList();
2475 TypeName castTypeName;
2476 OldList * specs = MkList();
2479 for(spec = typeName.qualifiers ? typeName.qualifiers->first : null; spec; spec = spec.next)
2481 if(spec.type != extendedSpecifier)
2482 specs->Add(CopySpecifier(spec));
2485 if(typeName.declarator.type == pointerDeclarator)
2487 Pointer p = typeName.declarator.pointer.pointer.pointer;
2488 castTypeName = MkTypeName(specs, CopyDeclarator(typeName.declarator.declarator.declarator.declarator));
2492 for(pp = castTypeName.declarator.pointer.pointer; pp.pointer; pp = pp.pointer);
2493 pp.pointer = MkPointer(null, null);
2494 pp.qualifiers = CopyList(p.qualifiers, CopySpecifier);
2499 castTypeName = MkTypeName(specs, CopyDeclarator(typeName.declarator.declarator.declarator.declarator));
2501 compoundExp = MkExpExtensionCompound(MkCompoundStmt(declList, stmtList));
2503 declList->Add(MkDeclaration(CopyList(typeName.qualifiers, CopySpecifier),
2504 MkListOne(MkInitDeclarator(PlugDeclarator(CopyDeclarator(typeName.declarator), MkDeclaratorIdentifier(MkIdentifier("__internal_VirtualMethod"))), null))));
2506 stmtList->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("__internal_VirtualMethod")), '=', expCallExp))));
2507 stmtList->Add(MkExpressionStmt(MkListOne(MkExpCondition(
2508 MkExpIdentifier(MkIdentifier("__internal_VirtualMethod")),
2509 MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("__internal_VirtualMethod")), arguments)), MkExpCast(castTypeName, MkExpConstant("1"))))));
2511 compoundExp.loc = exp.loc;
2512 compoundExp.compound.compound.context = context;
2513 PopContext(context);
2515 exp.type = bracketsExp;
2516 exp.list = MkListOne(compoundExp);
2520 exp.call.exp = expCallExp;
2521 exp.call.arguments = arguments;
2527 bool changeToPtr = false;
2528 bool noHead = false;
2529 Type type = exp.member.exp ? exp.member.exp.expType : null;
2530 Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
2531 if(exp.member.member) exp.member.member._class = null;
2533 if(type && type.kind == templateType)
2535 Type baseType = ProcessTemplateParameterType(type.templateParameter);
2536 if(baseType) type = baseType;
2538 if(type && exp.member.member && !type.directClassAccess)
2540 Class _class = exp.member.member.classSym ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
2541 Property prop = null;
2542 ClassProperty classProperty = null;
2543 Method method = null;
2544 Class convertTo = null;
2545 DataMember member = null;
2546 DataMember subMemberStack[256];
2547 int subMemberStackPos = 0;
2548 bool thisPtr = exp.member.thisPtr;
2549 if(type.kind == subClassType && exp.member.exp.type == classExp)
2550 _class = eSystem_FindClass(privateModule, "ecere::com::Class");
2552 // TEST: exp.member.exp.tempCount = Max(exp.tempCount, exp.member.exp.tempCount);
2556 // DANGER: Buffer overflow
2557 char string[2048] = "";
2559 PrintTypeNoConst(type, string, false, true);
2560 classSym = FindClass(string);
2561 _class = classSym ? classSym.registered : null;
2564 if(_class && exp.member.memberType == dataMember)
2566 if(!thisPtr && !exp.member.member.classSym)
2567 member = eClass_FindDataMember(_class, exp.member.member.string, null, subMemberStack, &subMemberStackPos);
2569 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2571 else if(_class && exp.member.memberType == propertyMember)
2573 if(!thisPtr && !exp.member.member.classSym)
2574 prop = eClass_FindProperty(_class, exp.member.member.string, null);
2576 prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
2577 if(prop && (exp.usage.usageRef ||
2578 (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
2579 (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
2581 member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
2584 exp.member.memberType = dataMember;
2589 if(exp.usage.usageRef)
2590 Compiler_Error($"cannot obtain address of property\n");
2592 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2593 else if(exp.usage.usageDelete)
2594 Compiler_Error($"no get defined for property %s of class %s\n", prop.name, prop._class.fullName);
2598 else if(_class && exp.member.memberType == methodMember)
2601 method = eClass_FindMethod(_class, exp.member.member.string, null);
2603 method = eClass_FindMethod(_class, exp.member.member.string, privateModule);
2605 else if(_class && exp.member.memberType == reverseConversionMember)
2608 _class = FindClass(exp.member.member.string).registered;
2609 // prop = eClass_FindProperty(_class, convertTo.name, privateModule);
2610 prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
2612 else if(_class && exp.member.memberType == classPropertyMember)
2614 classProperty = eClass_FindClassProperty(_class, exp.member.member.string);
2618 // Only process Gets here, Set is processed in opExp's '='
2619 if(exp.usage.usageGet)
2623 char getName[1024], setName[1024];
2624 Expression ptr = exp.member.exp;
2625 Class propertyClass;
2626 char * nameToUse = convertTo ? setName : getName;
2628 FreeIdentifier(exp.member.member);
2630 // Process this here since it won't be processed at the end...
2631 exp.member.exp.usage.usageGet = true;
2632 ProcessExpression(exp.member.exp);
2633 // TEST: exp.tempCount = exp.member.exp.tempCount;
2635 DeclareProperty(curExternal, prop, setName, getName);
2636 //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
2637 propertyClass = convertTo ? _class :
2638 ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
2640 if(propertyClass && propertyClass.type == bitClass)
2642 // Bit classes shouldn't have properties except for conversions...
2643 OldList * args = MkList();
2644 if(exp.usage.usageDeepGet)
2646 char className[1024];
2648 Declarator declarator;
2649 OldList * specs = MkList(), * decls = MkList();
2652 // Make a declaration in the closest compound statement
2653 // (Do not reuse (since using address for function calls)...)
2654 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2656 SpecDeclFromString(propertyClass.dataTypeString, specs,
2657 MkDeclaratorIdentifier(MkIdentifier(className)));
2659 ListAdd(decls, MkInitDeclarator(declarator, null));
2661 decl = MkDeclaration(specs, decls);
2662 if(!curCompound.compound.declarations)
2663 curCompound.compound.declarations = MkList();
2664 curCompound.compound.declarations->Insert(null, decl);
2666 tempExp = QMkExpId(className);
2667 tempExp.expType = MkClassType(propertyClass.fullName);
2669 exp.op.exp1 = tempExp;
2670 exp.op.exp2 = MkExpCall(QMkExpId(nameToUse), args);
2677 exp.call.exp = QMkExpId(nameToUse);
2678 exp.call.arguments = args;
2680 ListAdd(args, FixReference(ptr, true));
2682 else if(propertyClass && propertyClass.type == unitClass)
2684 OldList * args = MkList();
2685 ListAdd(args, FixReference(ptr, true));
2687 exp.call.exp = QMkExpId(nameToUse);
2688 exp.call.arguments = args;
2690 else if(propertyClass && propertyClass.type == structClass)
2692 OldList * args = MkList();
2693 char className[1024];
2695 OldList * specs = MkList(), * decls = MkList();
2698 // Make a declaration in the closest compound statement
2699 // (Do not reuse (since using address for function calls)...)
2702 FullClassNameCat(className, propertyClass.fullName, false); //true);
2703 DeclareStruct(curExternal, propertyClass.fullName, false, true);
2705 //ListAdd(specs, MkSpecifierName(className));
2706 ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
2708 sprintf(className, "__simpleStruct%d", curContext.simpleID++);
2710 ListAdd(decls, MkInitDeclarator(
2711 MkDeclaratorIdentifier(MkIdentifier(className)), null));
2713 decl = MkDeclaration(specs, decls);
2716 if(!curCompound.compound.declarations)
2717 curCompound.compound.declarations = MkList();
2718 curCompound.compound.declarations->Insert(null, decl);
2721 tempExp = QMkExpId(className);
2722 tempExp.expType = MkClassType(propertyClass.fullName);
2726 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2727 ListAdd(args, FixReference(ptr, true));
2731 ListAdd(args, FixReference(ptr, true));
2732 ListAdd(args, FixReference(CopyExpression(tempExp), true));
2735 if(exp.usage.usageDeepGet)
2738 exp.call.exp = QMkExpId(nameToUse);
2739 exp.call.arguments = args;
2741 FreeExpression(tempExp);
2745 exp.type = bracketsExp;
2746 exp.list = MkList();
2747 ListAdd(exp.list, MkExpCall(QMkExpId(nameToUse),args));
2748 if(exp.usage.usageMember)
2750 ListAdd(exp.list, FixReference(tempExp, true));
2751 exp.byReference = true;
2754 ListAdd(exp.list, tempExp);
2760 exp.call.exp = QMkExpId(nameToUse);
2761 exp.call.arguments = MkList();
2762 ListAdd(exp.call.arguments, FixReference(ptr, true));
2765 else if(prop.conversion)
2767 void * prev = exp.prev, * next = exp.next;
2768 *exp = *exp.member.exp;
2774 else if(classProperty)
2776 // Only process Gets here, Set is processed in opExp's '='
2777 if(exp.usage.usageGet)
2779 if(classProperty.Get)
2781 Identifier id = exp.member.member;
2782 Expression classExp = exp.member.exp;
2783 OldList * args = MkList();
2789 char typeString[2048];
2790 OldList * specs = MkList();
2793 PrintType(exp.expType, typeString, false, false);
2794 decl = SpecDeclFromString(typeString, specs, null);
2795 exp.cast.typeName = MkTypeName(specs, decl);
2798 exp.cast.typeName = QMkType("uint64", null);
2799 exp.cast.exp = MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty")), args);
2800 if(exp.expType.isPointerType)
2801 exp.cast.exp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), exp.cast.exp);
2803 ListAdd(args, classExp);
2805 char * s = QMkString(id.string);
2806 ListAdd(args, MkExpString(s));
2811 ProcessExpression(exp);
2818 // Get the function address if it's not called
2819 if((exp.usage.usageGet || exp.member.exp.expType.kind == subClassType) && !(exp.usage.usageCall))
2823 FreeIdentifier(exp.member.member);
2825 // Process this here since it won't be processed at the end...
2826 exp.member.exp.usage.usageGet = true;
2827 ProcessExpression(exp.member.exp);
2828 // TEST: exp.tempCount = exp.member.exp.tempCount;
2830 if(method.type == virtualMethod)
2832 strcpy(name, "__ecereVMethodID_");
2833 FullClassNameCat(name, method._class.fullName, false);
2835 strcat(name, method.name);
2836 exp.type = indexExp;
2837 if(memberClassSpecifier)
2839 char className[1024];
2840 // Need the class itself here...
2841 strcpy(className, "__ecereClass_");
2842 FullClassNameCat(className, _class.fullName, true);
2845 _class.symbol = FindClass(_class.fullName);
2846 DeclareClass(curExternal, _class.symbol, className);
2848 FreeExpression(exp.member.exp);
2849 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
2853 if(exp.thisPtr && _class.type != normalClass)
2855 FreeExpression(exp.member.exp);
2856 exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl"));
2859 exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
2861 exp.index.index = MkListOne(QMkExpId(name));
2862 DeclareMethod(curExternal, method, name);
2866 FreeExpression(exp.member.exp);
2867 exp.type = identifierExp;
2868 strcpy(name, "__ecereMethod_");
2869 FullClassNameCat(name, method._class.fullName, false);
2871 strcat(name, method.name);
2872 exp.identifier = MkIdentifier(name);
2873 DeclareMethod(curExternal, method, name);
2879 if(subMemberStackPos)
2882 DataMember parentMember = null;
2883 String s, prefix = null;
2884 for(i = 0; i < subMemberStackPos; i++)
2886 DataMember curMember = subMemberStack[i];
2889 for(m = parentMember ? parentMember.members.first : _class.membersAndProperties.first; m; m = m.next)
2891 if(m && !m.isProperty && (m.type == unionMember || m.type == structMember) && !m.name)
2902 prefix = PrintString(prefix, ".__anon", anonID);
2906 prefix = PrintString("__anon", anonID);
2907 parentMember = curMember;
2910 s = exp.member.member.string;
2911 exp.member.member.string = PrintString(prefix, ".", s);
2915 // Process this here since it won't be processed at the end...
2916 if(exp.usage.usageGet)
2918 exp.member.exp.usage.usageGet = true; // Recently added this... is it ok?
2920 ProcessExpression(exp.member.exp);
2921 // TEST: exp.tempCount = exp.member.exp.tempCount;
2923 if(type.kind == classType && type._class && type._class.registered)
2924 DeclareStruct(curExternal, type._class.registered.fullName, false, true);
2926 // TESTING THIS NOHEAD STUFF...
2927 if(_class.type == noHeadClass)
2931 else if(_class.type == structClass)
2935 else if(_class.type == bitClass)
2937 OldList * list = MkList();
2938 char mask[32], shift[10];
2939 OldList * specs = MkList();
2940 BitMember bitMember = (BitMember) member;
2941 Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
2942 TypeName type = MkTypeName(specs, decl);
2943 if(bitMember.mask > MAXDWORD)
2944 sprintf(mask, FORMAT64HEXLL, bitMember.mask);
2946 sprintf(mask, FORMAT64HEX, bitMember.mask);
2947 sprintf(shift, "%d", bitMember.pos);
2949 FreeIdentifier(exp.member.member);
2951 // ((type) ((color & mask) >> bitPos))
2952 ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
2953 MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
2954 MkExpConstant(shift))))));
2956 exp.type = bracketsExp;
2959 else if(_class.type == unitClass)
2964 // If it's a this pointer, replace by precomputed shortcut
2965 if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
2967 char pointerName[1024];
2969 strcpy(pointerName, "__ecerePointer_");
2970 FullClassNameCat(pointerName, type._class.registered.fullName, false);
2971 if(exp.member.exp.identifier)
2972 FreeIdentifier(exp.member.exp.identifier);
2973 exp.member.exp.identifier = MkIdentifier(pointerName);
2975 // Otherwise, access the data the hard way
2978 Expression bytePtr, e;
2979 Expression checkedExp;
2980 char structName[1024];
2981 char className[1024];
2982 strcpy(className, "__ecereClass_");
2983 FullClassNameCat(className, member._class.fullName, true);
2985 // classExp = QMkExpId(className);
2987 if(!member._class.symbol)
2988 member._class.symbol = FindClass(member._class.fullName);
2990 DeclareClass(curExternal, member._class.symbol, className);
2991 DeclareStruct(curExternal, member._class.fullName, false, true);
2994 FullClassNameCat(structName, member._class.fullName, false);
2996 checkedExp = exp.member.exp;
2997 while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list && checkedExp.list->count == 1) ||
2998 checkedExp.type == castExp)
3000 if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
3001 checkedExp = checkedExp.list->last;
3002 else if(checkedExp.type == castExp)
3003 checkedExp = checkedExp.cast.exp;
3006 if(checkedExp.type != identifierExp &&
3007 checkedExp.type != constantExp && // Added this here... Might mess up if we need address?
3008 checkedExp.type != memberExp && checkedExp.type != pointerExp)
3010 char ecereTemp[100];
3012 Context context = PushContext();
3013 if(exp.member.exp.tempCount > exp.tempCount)
3014 exp.tempCount = exp.member.exp.tempCount;
3017 curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
3018 sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
3019 curContext = context;
3020 compound = MkCompoundStmt(
3021 MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
3022 MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
3023 MkInitializerAssignment(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), QBrackets(exp.member.exp))))))), null);
3024 if(member._class.fixed)
3026 Class c = member._class.templateClass ? member._class.templateClass : member._class;
3031 if(c.offset == c.base.structSize)
3033 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
3034 ProcessExpressionType(se);
3035 se.isConstant = false;
3040 sprintf(string, "%d", c.offset);
3041 se = MkExpConstant(string);
3043 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', se));
3046 e = QMkExpId(ecereTemp);
3050 e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
3051 MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
3054 compound.compound.context = context;
3055 compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
3056 QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
3057 MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
3059 exp.member.exp = MkExpExtensionCompound(compound);
3061 PopContext(context);
3062 curContext = context.parent;
3066 bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
3067 // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
3069 e = QBrackets(QMkExpCond(exp.member.exp,
3070 QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
3071 MkExpConstant("0")));
3075 if(member._class.fixed)
3077 Class c = member._class.templateClass ? member._class.templateClass : member._class;
3082 if(c.offset == c.base.structSize)
3084 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
3085 ProcessExpressionType(se);
3086 se.isConstant = false;
3091 sprintf(string, "%d", c.offset);
3092 se = MkExpConstant(string);
3095 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', se)));
3101 e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(QMkExpId(className), MkIdentifier("offset")))));
3103 // exp.member.exp = QBrackets(MkExpCast(QMkType(structName, QMkPtrDecl(null)), e));
3104 exp.member.exp = QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), QMkPtrDecl(null)), e));
3107 exp.type = pointerExp;
3112 // Take Out Any Class Specifier (Should have been used by now)
3113 FreeSpecifier(memberClassSpecifier);
3115 // Just moved this at the end... How is it?
3116 if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
3118 exp.member.exp.usage.usageGet = true;
3119 exp.member.exp.usage.usageMember = true;
3120 exp.member.exp.tempCount = exp.tempCount;
3121 ProcessExpression(exp.member.exp);
3122 exp.tempCount = exp.member.exp.tempCount;
3123 if((changeToPtr && exp.member.exp.byReference) || noHead)
3124 exp.type = pointerExp;
3128 case extensionCompoundExp:
3130 Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
3132 e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
3134 ProcessStatement(exp.compound);
3136 /*if(((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference)
3137 exp.byReference = ((Expression)((Statement)checkedExp.compound.compound.statements->last).expressions->last).byReference;*/
3142 exp.member.exp.usage.usageGet = true;
3143 ProcessExpression(exp.member.exp);
3148 Specifier spec = exp.typeName.qualifiers ? exp.typeName.qualifiers->first : null;
3149 if(spec && spec.type == templateTypeSpecifier && !exp.typeName.declarator)
3151 Expression argExp = GetTemplateArgExp(spec.templateParameter, null, thisClass, false);
3154 Expression classExp;
3156 FreeTypeName(exp.typeName);
3158 classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
3160 ProcessExpressionType(classExp);
3161 ProcessExpression(classExp);
3163 exp.type = bracketsExp;
3164 exp.list = MkListOne(MkExpMember(classExp, MkIdentifier("typeSize")));
3166 ProcessExpressionType(exp);
3167 ProcessExpression(exp);
3176 exp.cast.exp.usage |= exp.usage & ExpUsage { usageGet = true, usageMember = true };
3177 ProcessExpression(exp.cast.exp);
3179 if(exp.cast.exp.byReference)
3180 exp.byReference = exp.cast.exp.byReference;
3181 if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
3182 exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
3183 exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
3184 !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
3185 exp.byReference = true;
3187 // Moved this to 1.5...
3188 //exp.expType = ProcessType(exp.cast.typeName.qualifiers, exp.cast.typeName.declarator);
3194 if(exp.usage.usageGet)
3195 exp.cond.cond.usage.usageGet = true;
3196 ProcessExpression(exp.cond.cond);
3197 for(e = exp.cond.exp->first; e; e = e.next)
3199 if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
3200 ProcessExpression(e);
3202 if(exp.cond.elseExp)
3204 if(exp.usage.usageGet)
3205 exp.cond.elseExp.usage.usageGet = true;
3206 ProcessExpression(exp.cond.elseExp);
3212 // Need the class itself here...
3213 if(exp._classExp.specifiers && exp._classExp.specifiers->first && ((Specifier)exp._classExp.specifiers->first).type == templateTypeSpecifier)
3215 Specifier spec = exp._classExp.specifiers->first;
3216 Expression argExp = GetTemplateArgExp(spec.templateParameter, null, thisClass, true);
3219 FreeList(exp._classExp.specifiers, FreeSpecifier);
3220 if(exp._classExp.decl)
3221 FreeDeclarator(exp._classExp.decl);
3223 exp.type = memberExp; //pointerExp;
3224 exp.member.exp = argExp;
3225 exp.member.member = MkIdentifier("dataTypeClass");
3226 exp.member.memberType = dataMember;
3228 ProcessExpressionType(argExp);
3229 ProcessExpressionType(exp);
3230 ProcessExpression(exp);
3235 char className[1024];
3236 char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
3237 Symbol classSym = FindClass(string);
3239 strcpy(className, "__ecereClass_");
3240 FullClassNameCat(className, string, true); // TODO: Verify this
3242 DeclareClass(curExternal, classSym, className);
3245 FreeList(exp._classExp.specifiers, FreeSpecifier);
3246 if(exp._classExp.decl)
3247 FreeDeclarator(exp._classExp.decl);
3249 exp.type = identifierExp;
3250 exp.identifier = MkIdentifier(className);
3256 ProcessExpression(exp.vaArg.exp);
3259 case extensionInitializerExp:
3261 ProcessInitializer(exp.initializer.initializer);
3267 if(exp.needTemplateCast != 2 && (exp.needTemplateCast == 1 || (exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate))))
3269 Expression nbExp = GetNonBracketsExp(exp);
3270 Expression inner = GetInnerExp(nbExp);
3272 if((!exp.expType || exp.expType.kind != templateType || nbExp.type != castExp) && !exp.usage.usageRef &&
3273 (!exp.destType || (!exp.destType.truth && (exp.destType.kind != templateType || (exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType))))) &&
3274 (exp.usage.usageDelete || exp.usage.usageGet || exp.usage.usageArg) &&
3275 (!exp.destType || (!exp.destType.passAsTemplate && exp.expType && (exp.expType.kind != pointerType || (exp.destType.kind == pointerType || exp.destType.kind == intPtrType)) && ((exp.destType.kind != pointerType && exp.destType.kind != intPtrType) || exp.expType.kind == pointerType))) &&
3276 !inner.needCast && inner.type != opExp)
3278 Expression e = MoveExpContents(exp);
3280 OldList * specs = MkList();
3281 char typeString[1024];
3282 bool castingToDest = false;
3283 bool pointerCastExp = false;
3285 typeString[0] = '\0';
3287 e.needTemplateCast = 2;
3288 inner.needTemplateCast = 2;
3289 nbExp.needTemplateCast = 2;
3290 if(exp.usage.usageDelete)
3291 strcpy(typeString, "void *");
3294 if(exp.expType.kind == templateType && exp.expType.templateParameter && exp.expType.templateParameter.dataTypeString)
3295 strcpy(typeString, exp.expType.templateParameter.dataTypeString);
3297 PrintType(exp.expType, typeString, false, false);
3300 decl = SpecDeclFromString(typeString, specs, null);
3302 if(specs && specs->first && ((Specifier)specs->first).type == templateTypeSpecifier &&
3303 exp.destType && !exp.destType.passAsTemplate && exp.destType.kind == templateType && exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType) && !exp.usage.usageArg)
3305 if(decl) FreeDeclarator(decl);
3306 FreeList(specs, FreeSpecifier);
3307 if(exp.destType.templateParameter.dataTypeString)
3310 strcpy(typeString, exp.destType.templateParameter.dataTypeString);
3311 decl = SpecDeclFromString(typeString, specs, null);
3315 specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
3316 decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
3319 castingToDest = true;
3322 e.destType = exp.destType;
3324 exp.destType.refCount++;
3326 exp.type = bracketsExp;
3329 Specifier spec = specs ? specs->first : null;
3330 TemplateParameter tp = (spec && spec.type == templateTypeSpecifier) ? spec.templateParameter : null;
3331 Type type = castingToDest ? exp.destType : exp.expType;
3332 bool specsDeclPointer = (spec.type == nameSpecifier && strcmp(spec.name, "uint64")) ||
3333 (decl && decl.type == pointerDeclarator) ||
3334 (tp && tp.dataType &&
3335 ( (tp.dataType.decl && tp.dataType.decl.type == pointerDeclarator) ||
3336 (tp.dataType.specifiers && ((Specifier)tp.dataType.specifiers->first).type == nameSpecifier && strcmp(((Specifier)tp.dataType.specifiers->first).name, "uint64")) ) );
3337 pointerCastExp = type ? ((type.kind == templateType && specsDeclPointer) || type.isPointerType) : specsDeclPointer;
3342 e = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(e)));
3343 e.needTemplateCast = 2;
3345 exp.list = MkListOne(MkExpCast(MkTypeName(specs, decl), MkExpBrackets(MkListOne(e))));
3346 if(exp.destType && pointerCastExp == (exp.destType.passAsTemplate ||
3347 (!exp.destType.isPointerType || (exp.destType.kind == templateType && (!exp.destType.templateParameter || (!exp.destType.templateParameter.dataType && !exp.destType.templateParameter.dataTypeString))))))
3348 exp.list = MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), decl), MkExpBrackets(exp.list)));
3349 exp.needTemplateCast = 2;
3355 static void ProcessInitializer(Initializer init)
3359 case expInitializer:
3362 init.exp.usage.usageGet = true;
3363 ProcessExpression(init.exp);
3364 if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
3365 init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
3367 FixReference(init.exp, true);
3369 else if(init.exp.destType && init.exp.destType.kind == classType)
3370 FixReference(init.exp, false);
3373 case listInitializer:
3378 for(i = init.list->first; i; i = i.next)
3379 ProcessInitializer(i);
3386 static void ProcessDeclaration(Declaration decl)
3390 case initDeclaration:
3392 if(decl.declarators)
3396 for(d = decl.declarators->first; d; d = d.next)
3399 ProcessInitializer(d.initializer);
3407 static void ProcessStatement(Statement stmt)
3412 ProcessStatement(stmt.labeled.stmt);
3415 if(stmt.caseStmt.exp)
3417 stmt.caseStmt.exp.usage.usageGet = true;
3419 // This expression should be constant...
3420 ProcessExpression(stmt.caseStmt.exp);
3422 if(stmt.caseStmt.stmt)
3423 ProcessStatement(stmt.caseStmt.stmt);
3427 if(stmt.compound.context)
3431 Statement prevCompound = curCompound;
3432 Context prevContext = curContext;
3434 if(!stmt.compound.isSwitch)
3437 curContext = stmt.compound.context;
3440 if(stmt.compound.declarations)
3442 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
3443 ProcessDeclaration(decl);
3445 if(stmt.compound.statements)
3447 for(s = stmt.compound.statements->first; s; s = s.next)
3448 ProcessStatement(s);
3450 curContext = prevContext;
3451 curCompound = prevCompound;
3455 case expressionStmt:
3458 if(stmt.expressions)
3460 for(exp = stmt.expressions->first; exp; exp = exp.next)
3462 ProcessExpression(exp);
3473 ((Expression)stmt.ifStmt.exp->last).usage.usageGet = true;
3474 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
3476 ProcessExpression(exp);
3479 if(stmt.ifStmt.stmt)
3480 ProcessStatement(stmt.ifStmt.stmt);
3481 if(stmt.ifStmt.elseStmt)
3482 ProcessStatement(stmt.ifStmt.elseStmt);
3488 if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
3490 ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
3491 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
3493 ProcessExpression(exp);
3496 ProcessStatement(stmt.switchStmt.stmt);
3502 if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
3504 ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
3505 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
3507 ProcessExpression(exp);
3510 ProcessStatement(stmt.whileStmt.stmt);
3516 if(stmt.doWhile.exp && stmt.doWhile.exp->last)
3518 ((Expression)stmt.doWhile.exp->last).usage.usageGet = true;
3519 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
3521 ProcessExpression(exp);
3524 if(stmt.doWhile.stmt)
3525 ProcessStatement(stmt.doWhile.stmt);
3531 if(stmt.forStmt.init)
3532 ProcessStatement(stmt.forStmt.init);
3534 if(stmt.forStmt.check)
3536 if(stmt.forStmt.check.expressions)
3538 ((Expression)stmt.forStmt.check.expressions->last).usage.usageGet = true;
3540 ProcessStatement(stmt.forStmt.check);
3542 if(stmt.forStmt.increment)
3544 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
3546 ProcessExpression(exp);
3549 if(stmt.forStmt.stmt)
3550 ProcessStatement(stmt.forStmt.stmt);
3562 if(stmt.expressions)
3564 ((Expression)stmt.expressions->last).usage.usageGet = true;
3565 for(exp = stmt.expressions->first; exp; exp = exp.next)
3567 ProcessExpression(exp);
3568 // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
3569 if(!exp.next && exp.destType && exp.destType.byReference)
3570 FixReference(exp, true);
3575 case badDeclarationStmt:
3577 ProcessDeclaration(stmt.decl);
3583 if(stmt.asmStmt.inputFields)
3585 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
3586 if(field.expression)
3587 ProcessExpression(field.expression);
3589 if(stmt.asmStmt.outputFields)
3591 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
3592 if(field.expression)
3593 ProcessExpression(field.expression);
3595 if(stmt.asmStmt.clobberedFields)
3597 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
3598 if(field.expression)
3599 ProcessExpression(field.expression);
3606 static void ProcessFunction(FunctionDefinition function)
3609 ProcessStatement(function.body);
3612 static void ProcessMemberInitData(MemberInit member)
3614 if(member.initializer)
3615 ProcessInitializer(member.initializer);
3618 static void ProcessInstantiation(Instantiation inst)
3622 MembersInit members;
3623 for(members = inst.members->first; members; members = members.next)
3625 if(members.type == dataMembersInit)
3627 if(members.dataMembers)
3630 for(member = members.dataMembers->first; member; member = member.next)
3631 ProcessMemberInitData(member);
3634 else if(members.type == methodMembersInit)
3636 ProcessFunction((FunctionDefinition)members.function);
3642 /////////// MEMBER ACCESS PASS /////////////////////////////////////////////
3643 public void ProcessMemberAccess()
3646 for(external = ast->first; external; external = external.next)
3648 curExternal = external;
3649 // There shouldn't be any class member access here anyways...
3650 if(external.type == declarationExternal)
3652 if(external.declaration)
3653 ProcessDeclaration(external.declaration);
3657 for(external = ast->first; external; external = external.next)
3659 curExternal = external;
3660 if(external.type == functionExternal)
3662 ProcessFunction(external.function);
3664 else if(external.type == declarationExternal)
3666 if(external.declaration)
3667 ProcessDeclaration(external.declaration);
3669 else if(external.type == classExternal)
3671 ClassDefinition _class = external._class;
3672 if(_class.definitions)
3675 Class regClass = _class.symbol.registered;
3677 // Process all functions
3678 for(def = _class.definitions->first; def; def = def.next)
3680 if(def.type == functionClassDef)
3682 curExternal = def.function.declarator.symbol.pointerExternal;
3683 ProcessFunction((FunctionDefinition)def.function);
3685 else if(def.type == declarationClassDef && def.decl.type == instDeclaration)
3687 ProcessInstantiation(def.decl.inst);
3689 else if(def.type == defaultPropertiesClassDef && def.defProperties)
3691 MemberInit defProperty;
3693 // Add this to the context
3696 string = CopyString("this");
3697 type = MkClassType(regClass.fullName);
3699 globalContext.symbols.Add((BTNode)thisSymbol);
3701 for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
3703 //thisClass = regClass;
3704 ProcessMemberInitData(defProperty); //, regClass, &id);
3708 //globalContext.symbols.Delete((BTNode)thisSymbol);
3709 globalContext.symbols.Remove((BTNode)thisSymbol);
3710 FreeSymbol(thisSymbol);
3712 else if(def.type == propertyClassDef && def.propertyDef)
3714 PropertyDef prop = def.propertyDef;
3716 // Add this to the context
3719 string = CopyString("this");
3720 type = MkClassType(regClass.fullName);
3722 globalContext.symbols.Add((BTNode)thisSymbol);
3724 //thisClass = regClass;
3727 curExternal = prop.symbol.externalSet;
3728 ProcessStatement(prop.setStmt);
3732 curExternal = prop.symbol.externalGet;
3733 ProcessStatement(prop.getStmt);
3737 curExternal = prop.symbol.externalIsSet;
3738 ProcessStatement(prop.issetStmt);
3743 //globalContext.symbols.Delete((BTNode)thisSymbol);
3744 globalContext.symbols.Remove((BTNode)thisSymbol);
3745 FreeSymbol(thisSymbol);
3747 else if(def.type == classPropertyClassDef && def.propertyDef)
3749 PropertyDef prop = def.propertyDef;
3751 //thisClass = regClass;
3754 curExternal = prop.symbol.externalSet;
3755 ProcessStatement(prop.setStmt);
3759 curExternal = prop.symbol.externalGet;
3760 ProcessStatement(prop.getStmt);
3764 else if(def.type == propertyWatchClassDef && def.propertyWatch)
3766 PropertyWatch propertyWatch = def.propertyWatch;
3768 // Add this to the context
3771 string = CopyString("this");
3772 type = MkClassType(regClass.fullName);
3774 globalContext.symbols.Add((BTNode)thisSymbol);
3776 //thisClass = regClass;
3777 if(propertyWatch.compound)
3781 string = CopyString("this");
3782 type = MkClassType(regClass.fullName);
3784 propertyWatch.compound.compound.context.symbols.Add((BTNode)thisSymbol);
3786 ProcessStatement(propertyWatch.compound);
3788 // thisClass = null;
3790 //globalContext.symbols.Delete((BTNode)thisSymbol);
3791 globalContext.symbols.Remove((BTNode)thisSymbol);
3792 FreeSymbol(thisSymbol);