3 #define YYLTYPE Location
6 extern External curExternal;
7 ///////////////// INSTANCE DECLARATION PASS ///////////////////////
9 // Returns true if we should add a * to the declarator
10 static int ReplaceClassSpec(OldList specs, Specifier spec, bool param)
12 if(spec.type == templateTypeSpecifier)
14 TemplateParameter parameter = spec.templateParameter;
16 if(!param && parameter.dataTypeString)
18 OldList * newSpecs = MkList();
19 Declarator decl = SpecDeclFromString(parameter.dataTypeString, newSpecs, null);
22 Specifier newSpec = CopySpecifier(newSpecs->first);
26 FreeList(newSpecs, FreeSpecifier);
30 bool isPointer = decl.type == pointerDeclarator;
37 else if(!param && parameter.dataType)
39 OldList * newSpecs = parameter.dataType.specifiers;
40 Declarator decl = parameter.dataType.decl;
43 Specifier newSpec = CopySpecifier(newSpecs->first);
50 bool isPointer = decl.type == pointerDeclarator;
57 spec.type = nameSpecifier;
58 spec.name = CopyString("uint64");
59 spec.symbol = FindClass("uint64");
63 if(spec.type == nameSpecifier || spec.type == subClassSpecifier)
65 // TODO: Apply more care because nameSpecifier / subClassSpecifier use different parts of the union!
66 Symbol classSym = spec.symbol;
67 if(spec.type == subClassSpecifier)
69 classSym = FindClass("ecere::com::Class");
74 Class _class = classSym.registered;
76 FreeSpecifierContents(spec);
78 spec.type = nameSpecifier;
79 if(_class && _class.type == structClass)
84 FullClassNameCat(name, _class.fullName, false);
85 FreeSpecifierContents(spec);
86 spec.type = structSpecifier;
87 spec.baseSpecs = null;
88 spec.id = MkIdentifier(name);
90 spec.definitions = null;
92 spec.addNameSpace = false;
94 else if(_class && _class.type == noHeadClass)
97 FullClassNameCat(name, _class.fullName, false);
98 spec.type = structSpecifier;
99 spec.baseSpecs = null;
100 spec.id = MkIdentifier(name);
102 spec.definitions = null;
104 spec.addNameSpace = false;
108 if((_class.type != systemClass ||
109 !strcmp(_class.fullName, "enum") ||
110 (_class.dataTypeString && !strcmp(_class.dataTypeString, "char *")) ||
111 //strcmp(_class.fullName, "bool") &&
112 !strcmp(_class.fullName, "uint64") ||
113 !strcmp(_class.fullName, "uint32") ||
114 !strcmp(_class.fullName, "uint16") ||
115 !strcmp(_class.fullName, "uintptr") ||
116 !strcmp(_class.fullName, "intptr") ||
117 !strcmp(_class.fullName, "uintsize") ||
118 !strcmp(_class.fullName, "intsize") ||
119 !strcmp(_class.fullName, "uint") ||
120 !strcmp(_class.fullName, "byte")))
122 if(_class.dataTypeString)
124 if(!strcmp(_class.dataTypeString, "uint64") ||
125 !strcmp(_class.dataTypeString, "uint32") ||
126 !strcmp(_class.dataTypeString, "uint16") ||
127 !strcmp(_class.dataTypeString, "uintptr") ||
128 !strcmp(_class.dataTypeString, "intptr") ||
129 !strcmp(_class.dataTypeString, "uintsize") ||
130 !strcmp(_class.dataTypeString, "intsize") ||
131 !strcmp(_class.dataTypeString, "uint") ||
132 !strcmp(_class.dataTypeString, "byte"))
135 _class.dataType = ProcessTypeString(_class.dataTypeString, false);
136 if(_class.dataType && _class.dataType.kind == classType)
137 classSym = _class.dataType._class;
139 classSym = FindClass(_class.dataTypeString);
140 _class = classSym ? classSym.registered : null;
143 spec.name = CopyString(!strcmp(_class.dataTypeString, "char *") ? "char" : _class.dataTypeString);
148 spec.name = CopyString(null);
152 else if(!_class.base)
154 spec.type = baseSpecifier;
155 spec.specifier = VOID;
161 spec.type = structSpecifier;
162 spec.id = MkIdentifier("__ecereNameSpace__ecere__com__Instance");
164 spec.baseSpecs = null;
165 spec.definitions = null;
167 spec.addNameSpace = false;
170 if(_class && _class.dataTypeString && !strcmp(_class.dataTypeString, "char *"))
172 if(!_class || _class.type == normalClass || _class.type == noHeadClass)
174 else if(param && _class.type == structClass)
178 else if(spec.type == baseSpecifier)
180 if(spec.specifier == ANY_OBJECT || spec.specifier == CLASS)
182 spec.specifier = CONST;
183 specs.Add(MkSpecifier(VOID));
190 static void ReplaceByInstancePtr(Specifier spec, Declarator * declPtr, int type)
192 Declarator decl = *declPtr;
193 if(decl && decl.type == pointerDeclarator)
195 // Pointers to simple classes shouldn't be added pointers
199 decl.pointer.pointer = MkPointer(null, decl.pointer.pointer);
203 Declarator newDecl { };
207 decl.declarator = newDecl;
211 decl.type = pointerDeclarator;
212 decl.pointer.pointer = MkPointer(null, null);
217 static void InstDeclPassSpecifier(Specifier spec, bool byRefTypedObject)
222 if(spec.specifier == TYPED_OBJECT)
224 spec.type = extendedSpecifier;
225 spec.extDecl = MkExtDeclString(CopyString(byRefTypedObject ?
226 "struct __ecereNameSpace__ecere__com__Class * class, void *" :
227 "struct __ecereNameSpace__ecere__com__Class * class, const void *"));
228 DeclareStruct(curExternal, "ecere::com::Class", false, true);
238 for(e = spec.list->first; e; e = e.next)
245 case structSpecifier:
251 for(def = spec.definitions->first; def; def = def.next)
253 InstDeclPassDeclaration(def.decl);
256 InstDeclPassIdentifier(spec.id);
259 case extendedSpecifier:
260 if(spec.extDecl && spec.extDecl.type == extDeclString && spec.extDecl.s)
262 if(!strcmp(spec.extDecl.s, "dllexport"))
265 delete spec.extDecl.s;
266 for(prevSpec = spec.prev; prevSpec; prevSpec = prevSpec.prev)
267 if(prevSpec.type == baseSpecifier && prevSpec.specifier == EXTERN)
271 if(targetPlatform == win32)
272 spec.extDecl.s = CopyString("__declspec(dllexport)");
274 spec.extDecl.s = CopyString("__attribute__ ((visibility(\"default\")))");
278 if(targetPlatform == win32)
279 spec.extDecl.s = CopyString("extern __declspec(dllexport)");
281 spec.extDecl.s = CopyString("extern __attribute__ ((visibility(\"default\")))");
284 else if(!strcmp(spec.extDecl.s, "stdcall") || !strcmp(spec.extDecl.s, "_stdcall") ||
285 !strcmp(spec.extDecl.s, "__stdcall") || !strcmp(spec.extDecl.s, "__stdcall__"))
287 delete spec.extDecl.s;
288 if(targetPlatform == win32)
289 spec.extDecl.s = CopyString("__attribute__((__stdcall__))");
291 spec.extDecl.s = CopyString("");
298 static void InstDeclPassDeclarator(Declarator decl)
302 case structDeclarator:
304 InstDeclPassDeclarator(decl.declarator);
306 case identifierDeclarator:
309 InstDeclPassIdentifier(decl.identifier);
312 case bracketsDeclarator:
314 InstDeclPassDeclarator(decl.declarator);
316 case arrayDeclarator:
318 InstDeclPassDeclarator(decl.declarator);
320 case functionDeclarator:
323 InstDeclPassDeclarator(decl.declarator);
324 if(decl.function.parameters)
328 InstDeclPassDeclarator(decl.declarator);
329 for(type = decl.function.parameters->first; type; type = type.next)
331 bool typedObject = false;
332 Specifier spec = null;
335 spec = (Specifier)type.qualifiers->first;
336 if(spec && spec.type == nameSpecifier && !strcmp(spec.name, "class"))
340 InstDeclPassTypeName(type, true);
345 qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
346 declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
348 DeclareStruct(curExternal, "ecere::com::Class", false, true);
349 decl.function.parameters->Insert(spec.prev, _class);
355 case pointerDeclarator:
356 case extendedDeclarator:
357 case extendedDeclaratorEnd:
358 if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended)
360 if(decl.extended.extended.type == extDeclString && decl.extended.extended.s && !strcmp(decl.extended.extended.s, "dllexport"))
362 delete decl.extended.extended.s;
363 if(targetPlatform == win32)
364 decl.extended.extended.s = CopyString("extern __declspec(dllexport)");
366 decl.extended.extended.s = CopyString("extern __attribute__ ((visibility(\"default\")))");
368 else if(decl.extended.extended.type == extDeclString && decl.extended.extended.s &&
369 (!strcmp(decl.extended.extended.s, "stdcall") || !strcmp(decl.extended.extended.s, "_stdcall") ||
370 !strcmp(decl.extended.extended.s, "__stdcall") || !strcmp(decl.extended.extended.s, "__stdcall__")))
372 delete decl.extended.extended.s;
373 if(targetPlatform == win32)
374 decl.extended.extended.s = CopyString("__attribute__((__stdcall__))");
376 decl.extended.extended.s = CopyString("");
380 InstDeclPassDeclarator(decl.declarator);
385 /*static */void InstDeclPassTypeName(TypeName type, bool param)
390 for(spec = type.qualifiers->first; spec; spec = spec.next)
393 if((result = ReplaceClassSpec(type.qualifiers, spec, param)))
394 ReplaceByInstancePtr(spec, &type.declarator, result);
397 Symbol classSym = (spec.type == nameSpecifier) ? spec.symbol /*FindClass(spec.name)*/ : null;
398 if(type.classObjectType && (!classSym || (classSym && classSym.registered &&
399 (classSym.registered.type == enumClass || classSym.registered.type == bitClass || classSym.registered.type == unitClass))))
400 ReplaceByInstancePtr(spec, &type.declarator, 2);
402 InstDeclPassSpecifier(spec, type.declarator && type.declarator.type == pointerDeclarator);
406 InstDeclPassDeclarator(type.declarator);
409 static void InstDeclPassIdentifier(Identifier id)
411 if(strchr(id.string, ':'))
417 strcpy(newID, "__ecereNameSpace__");
420 for(c = 0; (ch = id.string[c]); c++)
422 if(ch == ':') ch = '_';
428 id.string = CopyString(newID);
432 /*static */bool IsVoidPtrCast(TypeName typeName)
435 Declarator d = typeName.declarator;
436 if(d && d.type == pointerDeclarator && d.pointer.pointer && !d.pointer.pointer.pointer)
438 if(typeName.qualifiers)
441 for(s = typeName.qualifiers->first; s; s = s.next)
443 if(s.type == baseSpecifier && s.specifier == VOID)
451 static void AddPointerCast(Expression e)
453 Type src = e.expType;
455 if(src && (src.kind == templateType || src.kind == classType))
457 if(e.type != castExp || !IsVoidPtrCast(e.cast.typeName))
459 if(src) src.refCount++;
460 if(src.kind == templateType && src.templateParameter && src.templateParameter.type == type)
463 if(src.templateParameter.dataTypeString)
464 newType = ProcessTypeString(src.templateParameter.dataTypeString, false);
465 else if(src.templateParameter.dataType)
466 newType = ProcessType(src.templateParameter.dataType.specifiers, src.templateParameter.dataType.decl);
473 if(src && src.kind == classType && src._class)
475 Class sc = src._class.registered;
476 if(src.thisClassFrom && src.thisClassFrom.base)
477 sc = src.thisClassFrom;
479 if(sc && (sc.type == structClass || sc.type == noHeadClass))
481 Type dest = e.destType;
483 if(dest && (dest.kind == templateType || dest.kind == classType))
485 if(dest) dest.refCount++;
487 if(dest.kind == templateType && dest.templateParameter && dest.templateParameter.type == type)
490 if(dest.templateParameter.dataTypeString)
491 newType = ProcessTypeString(dest.templateParameter.dataTypeString, false);
492 else if(dest.templateParameter.dataType)
493 newType = ProcessType(dest.templateParameter.dataType.specifiers, dest.templateParameter.dataType.decl);
500 if(!dest.passAsTemplate && dest.kind == classType && dest._class && dest._class.registered)
502 Class dc = dest._class.registered;
504 if(sc.templateClass) sc = sc.templateClass;
505 if(dc.templateClass) dc = dc.templateClass;
506 if(dc.base && sc != dc)
508 e.cast.exp = MkExpBrackets(MkListOne(MoveExpContents(e)));
510 e.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null));
520 else if(src && src.kind == intPtrType && e.destType && e.destType.classObjectType)
522 Expression nbExp = GetNonBracketsExp(e);
523 if(nbExp.type != castExp || !IsVoidPtrCast(nbExp.cast.typeName))
525 e.cast.exp = MkExpBrackets(MkListOne(MoveExpContents(e)));
527 e.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null));
532 static void InstDeclPassExpression(Expression exp)
539 InstDeclPassIdentifier(exp.identifier);
548 InstDeclPassExpression(exp.op.exp1);
551 InstDeclPassExpression(exp.op.exp2);
552 if(exp.op.op != '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == pointerType && exp.op.exp1.expType.type && exp.op.exp1.expType.type.kind == templateType &&
553 exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType && exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
555 Expression e = exp.op.exp2;
556 e.cast.exp = MkExpBrackets(MkListOne(MoveExpContents(e)));
558 e.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null));
561 e.cast.exp = MkExpBrackets(MkListOne(MoveExpContents(e)));
563 e.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null));
565 else if(exp.op.exp1 && (exp.op.op == '=' || exp.op.op == EQ_OP || exp.op.op == NE_OP))
566 AddPointerCast(exp.op.exp2);
569 case extensionExpressionExp:
573 for(e = exp.list->first; e; e = e.next)
574 InstDeclPassExpression(e);
580 InstDeclPassExpression(exp.index.exp);
581 for(e = exp.index.index->first; e; e = e.next)
582 InstDeclPassExpression(e);
588 InstDeclPassExpression(exp.call.exp);
589 if(exp.call.arguments)
591 for(e = exp.call.arguments->first; e; e = e.next)
593 bool addCast = false;
594 InstDeclPassExpression(e);
597 if(e.expType && e.expType.kind == pointerType && e.expType.type && (e.expType.type.kind == classType || (e.expType.type.kind == pointerType && e.expType.type.type && e.expType.type.type.kind != voidType)) &&
598 e.destType && e.destType.kind == pointerType && e.destType.type && e.destType.type.kind == pointerType && e.destType.type.type && e.destType.type.type.kind == voidType)
600 // Fix for adding a cast to Unserialize with a struct passed as a parameter:
601 else if(e.expType && e.expType.kind == classType && e.expType._class && e.expType._class.registered && e.expType._class.registered.type == structClass && e.byReference &&
602 e.destType && e.destType.kind == classType && e.destType.classObjectType && e.destType.byReference)
605 if(addCast && (e.type != castExp || !IsVoidPtrCast(e.cast.typeName)))
607 e.cast.exp = MkExpBrackets(MkListOne(MoveExpContents(e)));
609 e.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null));
618 InstDeclPassExpression(exp.member.exp);
624 InstDeclPassExpression(exp.member.exp);
628 InstDeclPassTypeName(exp.typeName, false);
632 Type type = exp.expType;
633 // Remove casts to simple structs... (Watch out for pointers later...)
634 if(type && type.kind == classType && type._class.registered && type._class.registered.type == structClass && !exp.needCast)
636 if(exp.destType && exp.destType.classObjectType == typedObject && exp.destType.byReference)
638 // For Unserialize with a StaticString
639 FreeTypeName(exp.cast.typeName);
640 exp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null));
644 Expression castExp = exp.cast.exp;
645 Expression prev = exp.prev, next = exp.next;
647 FreeExpContents(exp);
648 FreeType(exp.expType);
649 FreeType(exp.destType);
654 InstDeclPassExpression(exp);
659 if(exp.expType && exp.expType.kind == pointerType)
661 if(exp.cast.exp && exp.cast.exp.expType && exp.cast.exp.expType.kind == templateType && !exp.cast.exp.expType.isPointerType)
662 exp.cast.exp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), exp.cast.exp);
665 InstDeclPassTypeName(exp.cast.typeName, exp.usage.usageArg /*false*/);
668 if(exp.expType && exp.expType.kind == templateType && exp.destType &&
669 (exp.destType.passAsTemplate || (!exp.destType.templateParameter || (!exp.destType.templateParameter.dataType && !exp.destType.templateParameter.dataTypeString))) &&
670 exp.cast.exp.expType && !exp.cast.exp.expType.passAsTemplate && exp.cast.exp.expType.isPointerType)
671 exp.cast.exp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), exp.cast.exp);
672 InstDeclPassExpression(exp.cast.exp);
680 InstDeclPassExpression(exp.cond.cond);
681 for(e = exp.cond.exp->first; e; e = e.next)
682 InstDeclPassExpression(e);
683 InstDeclPassExpression(exp.cond.elseExp);
686 case extensionCompoundExp:
688 InstDeclPassStatement(exp.compound);
693 InstDeclPassExpression(exp.vaArg.exp);
696 case extensionInitializerExp:
698 InstDeclPassTypeName(exp.initializer.typeName, false);
699 InstDeclPassInitializer(exp.initializer.initializer);
705 static void InstDeclPassInitializer(Initializer init)
712 InstDeclPassExpression(init.exp);
713 AddPointerCast(init.exp);
716 case listInitializer:
719 for(i = init.list->first; i; i = i.next)
720 InstDeclPassInitializer(i);
726 static void InstDeclPassDeclaration(Declaration decl)
730 case initDeclaration:
735 for(spec = decl.specifiers->first; spec; spec = spec.next)
738 if((type = ReplaceClassSpec(decl.specifiers, spec, false)))
743 for(d = decl.declarators->first; d; d = d.next)
744 ReplaceByInstancePtr(spec, &d.declarator, type);
747 InstDeclPassSpecifier(spec, false);
753 for(d = decl.declarators->first; d; d = d.next)
755 InstDeclPassDeclarator(d.declarator);
757 InstDeclPassInitializer(d.initializer);
762 case structDeclaration:
767 for(spec = decl.specifiers->first; spec; spec = spec.next)
770 if((type = ReplaceClassSpec(decl.specifiers, spec, false)))
775 for(d = decl.declarators->first; d; d = d.next)
776 ReplaceByInstancePtr(spec, &d, type);
779 InstDeclPassSpecifier(spec, false);
786 for(d = decl.declarators->first; d; d = d.next)
787 InstDeclPassDeclarator(d);
791 // This should be removed by now?
792 case instDeclaration:
793 // InstDeclPassInstantiation(decl.inst);
798 static void InstDeclPassStatement(Statement stmt)
802 case badDeclarationStmt:
804 InstDeclPassDeclaration(stmt.decl);
807 InstDeclPassStatement(stmt.labeled.stmt);
810 // This expression should be constant...
811 if(stmt.caseStmt.exp)
812 InstDeclPassExpression(stmt.caseStmt.exp);
813 if(stmt.caseStmt.stmt)
814 InstDeclPassStatement(stmt.caseStmt.stmt);
820 Context prevContext = curContext;
822 if(!stmt.compound.isSwitch)
823 curContext = stmt.compound.context;
825 if(stmt.compound.declarations)
827 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
828 InstDeclPassDeclaration(decl);
830 if(stmt.compound.statements)
832 for(s = stmt.compound.statements->first; s; s = s.next)
833 InstDeclPassStatement(s);
835 curContext = prevContext;
843 for(exp = stmt.expressions->first; exp; exp = exp.next)
844 InstDeclPassExpression(exp);
853 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
854 InstDeclPassExpression(exp);
857 InstDeclPassStatement(stmt.ifStmt.stmt);
858 if(stmt.ifStmt.elseStmt)
859 InstDeclPassStatement(stmt.ifStmt.elseStmt);
865 if(stmt.switchStmt.exp)
867 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
868 InstDeclPassExpression(exp);
870 InstDeclPassStatement(stmt.switchStmt.stmt);
876 if(stmt.whileStmt.exp)
878 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
879 InstDeclPassExpression(exp);
881 InstDeclPassStatement(stmt.whileStmt.stmt);
889 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
890 InstDeclPassExpression(exp);
892 if(stmt.doWhile.stmt)
893 InstDeclPassStatement(stmt.doWhile.stmt);
899 if(stmt.forStmt.init)
900 InstDeclPassStatement(stmt.forStmt.init);
901 if(stmt.forStmt.check)
902 InstDeclPassStatement(stmt.forStmt.check);
903 if(stmt.forStmt.increment)
905 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
906 InstDeclPassExpression(exp);
908 if(stmt.forStmt.stmt)
909 InstDeclPassStatement(stmt.forStmt.stmt);
923 for(exp = stmt.expressions->first; exp; exp = exp.next)
924 InstDeclPassExpression(exp);
925 AddPointerCast(stmt.expressions->last);
932 if(stmt.asmStmt.inputFields)
934 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
936 InstDeclPassExpression(field.expression);
938 if(stmt.asmStmt.outputFields)
940 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
942 InstDeclPassExpression(field.expression);
944 if(stmt.asmStmt.clobberedFields)
946 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
948 InstDeclPassExpression(field.expression);
955 void TopoSort(OldList * input)
963 for(n = input->first; n; n = next)
966 if(n.type == declarationExternal && !n.declaration)
969 if(n.symbol && n.symbol.structExternal == n)
970 n.symbol.structExternal = null;
973 else if(!n.incoming.count)
978 else if(!n.nonBreakableIncoming)
985 for(x = input->first; x; x = x.next)
988 for(e : x.incoming; !e.breakable)
990 if(count != x.nonBreakableIncoming)
991 printf("Bug in input");
993 if(!x.incoming.count)
994 printf("This node should be in S!\n");
997 External y, from = e.from;
998 for(y = input->first; y; y = y.next)
1003 for(y = B.first; y; y = y.next)
1010 for(y = S.first; y; y = y.next)
1016 printf("This node is nowhere!\n");
1027 for(x = input->first; x; x = x.next)
1030 for(e : x.incoming; !e.breakable)
1032 if(count != x.nonBreakableIncoming)
1033 printf("Bug in input");
1034 if(!x.incoming.count)
1035 printf("This node should be in S!\n");
1038 External y, from = e.from;
1039 for(y = input->first; y; y = y.next)
1044 for(y = B.first; y; y = y.next)
1051 for(y = S.first; y; y = y.next)
1057 printf("This node is nowhere!\n");
1062 //DebugPrint("*** Free Node: [", n.id, "]\n\t", n.output);
1063 S.Remove((IteratorPointer)n);
1066 if(n && n.symbol && n.symbol.string && !strcmp(n.symbol.string, "ecere::com::Instance"))
1067 printf("Adding Instance\n");
1071 for(e = n.outgoing.first; e; e = ne)
1076 //DebugPrint(" This Free Node has an edge to [", m.id, "] ", m.output);
1077 if(m.nonBreakableIncoming)
1079 //DebugPrint("... which we think is in input");
1084 //DebugPrint("... which we think is in B");
1089 PrintLn("!!! Something's wrong !!!");
1095 if(!m.nonBreakableIncoming)
1098 m.nonBreakableIncoming--;
1099 //DebugPrint("Reducing non breakable incoming, now ", m.nonBreakableIncoming);
1102 n.outgoing.Remove((IteratorPointer)e);
1103 m.incoming.Remove((IteratorPointer)e);
1106 if(!m.incoming.count)
1108 //DebugPrint("Last edge to this node taken out, moving to S...");
1112 else if(!m.nonBreakableIncoming)
1114 //DebugPrint("Last non-breakable edge to this node taken out, moving to B...");
1120 else if((n = B.first))
1122 //DebugPrint("Breaking some of the ", n.incoming.count, " incoming edges to [", n.id, "] ", n.output);
1123 B.Remove((IteratorPointer)n);
1125 // Break the edges of this node
1126 for(e = n.incoming.first; e; e = ne)
1129 External m = e.from;
1132 for(x = input->first; x; x = x.next)
1135 for(e : x.incoming; !e.breakable)
1137 if(count != x.nonBreakableIncoming)
1138 printf("Bug in input");
1139 if(!x.incoming.count)
1140 printf("This node should be in S!\n");
1143 External y, from = e.from;
1144 for(y = input->first; y; y = y.next)
1149 for(y = B.first; y; y = y.next)
1156 for(y = S.first; y; y = y.next)
1162 printf("This node is nowhere!\n");
1167 f = m.ForwardDeclare();
1170 for(x = input->first; x; x = x.next)
1173 for(e : x.incoming; !e.breakable)
1175 if(count != x.nonBreakableIncoming)
1176 printf("Bug in input");
1177 if(!x.incoming.count)
1178 printf("This node should be in S!\n");
1181 External y, from = e.from;
1182 for(y = input->first; y; y = y.next)
1187 for(y = B.first; y; y = y.next)
1194 for(y = S.first; y; y = y.next)
1198 if(!y && from != n && from != f)
1200 printf("This node is nowhere!\n");
1205 // Recheck input for edges created by forward declaration
1208 for(c = input->first; c; c = next)
1211 if(!c.incoming.count)
1216 else if(!c.nonBreakableIncoming)
1224 //DebugPrint("Breaking edge from ", e.from.id, " to ", e.to.id);
1225 //DebugPrint("Creating a forward decl node [", f.id, "] for [", m.id, "]");
1227 for(e2 = m.outgoing.first; e2; e2 = n2)
1232 External to = e2.to;
1235 ;//DebugPrint("Breaking this particular connection");
1237 ;//DebugPrint("Also redirecting connection from ", m.id, " to ", to.id, " to come from ", f.id, " instead.");
1238 e2.breakable = false;
1240 m.outgoing.Remove((IteratorPointer)e2);
1242 to.nonBreakableIncoming++;
1243 if(e2 != e && to.nonBreakableIncoming == 1)
1245 // If this node was previously in B, move it to input
1250 //DebugPrint("Node ", e2.to.id, " now has ", e2.to.nonBreakableIncoming, " non-breakable incoming edges.");
1254 for(x = input->first; x; x = x.next)
1257 for(e : x.incoming; !e.breakable)
1259 if(count != x.nonBreakableIncoming)
1260 printf("Bug in input");
1261 if(!x.incoming.count)
1262 printf("This node should be in S!\n");
1265 External y, from = e.from;
1266 for(y = input->first; y; y = y.next)
1271 for(y = B.first; y; y = y.next)
1278 for(y = S.first; y; y = y.next)
1282 if(!y && from != n && from != f)
1284 printf("This node is nowhere!\n");
1288 if(!f.incoming.count)
1290 else if(!f.nonBreakableIncoming)
1295 for(x = input->first; x; x = x.next)
1298 for(e : x.incoming; !e.breakable)
1300 if(count != x.nonBreakableIncoming)
1301 printf("Bug in input");
1302 if(!x.incoming.count)
1303 printf("This node should be in S!\n");
1306 External y, from = e.from;
1307 for(y = input->first; y; y = y.next)
1312 for(y = B.first; y; y = y.next)
1319 for(y = S.first; y; y = y.next)
1326 for(y = L.first; y; y = y.next)
1329 PrintLn("This node is already in L!");
1336 ConsoleFile file { };
1337 printf("This node is nowhere!\n");
1338 OutputExternal(from, file);
1344 // Avoid needless edge breaking by processing a node as soon as one shows up in S
1349 // Put n back in input because it now has unbreakable edges
1358 External e = input->first;
1360 Compiler_Error("declarations cycles found\n");
1362 //OutputTree(input, f);
1364 for(x = input->first; x; x = x.next)
1367 for(e : x.incoming; !e.breakable)
1369 if(count != x.nonBreakableIncoming)
1370 printf("Bug in input");
1371 if(!x.incoming.count)
1372 printf("This node should be in S!\n");
1376 External y, from = e.from;
1377 for(y = input->first; y; y = y.next)
1382 for(y = B.first; y; y = y.next)
1389 for(y = S.first; y; y = y.next)
1395 printf("This node is nowhere!\n");
1400 SetOutputLineNumbers(false);
1401 OutputExternal(e, f);
1403 PrintLn("\nDepends on:\n");
1404 { TopoEdge i; for(i = e.incoming.last; i && !i.breakable && i.from.incoming.count; i = i.in.next) { e = i.from; break; } }
1406 OutputExternal(e, f);
1408 PrintLn("\nWhile that depends on:\n");
1409 { TopoEdge i; for(i = e.incoming.first; i && !i.breakable && i.from.incoming.count; i = i.in.next) { e = i.from; break; } }
1411 OutputExternal(e, f);
1413 PrintLn("\nWhile that depends on:\n");
1414 { TopoEdge i; for(i = e.incoming.first; i && !i.breakable && i.from.incoming.count; i = i.in.next) { e = i.from; break; } }
1416 OutputExternal(e, f);
1418 PrintLn("\nWhile that depends on:\n");
1419 { TopoEdge i; for(i = e.incoming.first; i && !i.breakable && i.from.incoming.count; i = i.in.next) { e = i.from; break; } }
1421 OutputExternal(e, f);
1426 while((e = input->first))
1440 for(n = input->first; n; n = next)
1443 if(n.type == declarationExternal && (!n.declaration || ((!n.declaration.specifiers || !n.declaration.specifiers->count) && (!n.declaration.declarators || !n.declaration.declarators->count))))
1446 if(n.symbol && n.symbol.structExternal == n)
1447 n.symbol.structExternal = null;
1453 public void ProcessInstanceDeclarations()
1456 curContext = globalContext;
1457 for(external = ast->first; external; external = external.next)
1459 curExternal = external;
1460 if(external.type == functionExternal)
1462 FunctionDefinition func = external.function;
1466 for(spec = func.specifiers->first; spec; spec = spec.next)
1469 if((type = ReplaceClassSpec(func.specifiers, spec, false)))
1470 ReplaceByInstancePtr(spec, &func.declarator, type);
1471 InstDeclPassSpecifier(spec, false);
1474 InstDeclPassDeclarator(func.declarator);
1476 InstDeclPassStatement(func.body);
1478 else if(external.type == declarationExternal)
1480 if(external.declaration)
1481 InstDeclPassDeclaration(external.declaration);
1485 // Perform topological sort