ecere/com/instance: Fixed crashes on Ecere classes templatized in other modules
[sdk] / compiler / libec / src / freeAst.ec
1 import "ecdefs"
2
3 /****  FREEING  ****/
4
5 void FreeList(OldList list, void (* FreeFunction)(void *))
6 {
7    if(list != null)
8    {
9       Item item;
10       while((item = list.first))
11       {
12          list.Remove(item);
13          FreeFunction(item);
14       }
15       delete list;
16    }
17 }
18
19 public void FreeType(Type type)
20 {
21    if(type)
22    {
23       type.refCount--;
24       if(type.refCount <= 0)
25       {
26          switch(type.kind)
27          {
28             case enumType:
29             {
30                NamedLink64 member, next;
31                delete type.enumName;
32                for(member = type.members.first; member; member = next)
33                {
34                   next = member.next;
35                   type.members.Remove(member);
36                   delete member.name;
37                   delete member;
38                }
39                break;
40             }
41             case structType:
42             case unionType:
43             {
44                Type member, next;
45                delete type.enumName;
46                for(member = type.members.first; member; member = next)
47                {
48                   next = member.next;
49                   // Remove from list only when reaching last reference
50                   // (The list is copied)
51                   if(member.refCount == 1)
52                      type.members.Remove(member);
53                   FreeType(member);
54                }
55                break;
56             }
57             case functionType:
58             {
59                Type param, next;
60                if(type.returnType)
61                   FreeType(type.returnType);
62                for(param = type.params.first; param; param = next)
63                {
64                   next = param.next;
65                   // WARNING: Don't unlink these as they might be reused
66                   // type.params.Remove(param);
67                   FreeType(param);
68                }
69                break;
70             }
71             case arrayType:
72                if(type.freeExp && type.arraySizeExp)
73                   FreeExpression(type.arraySizeExp);
74             case pointerType:
75                if(type.type)
76                   FreeType(type.type);
77                break;
78          }
79          delete type.name;
80          delete type.typeName;
81          delete type;
82       }
83    }
84 }
85
86 void FreeSymbol(Symbol symbol)
87 {
88    OldLink link;
89
90    if(symbol.propCategory)
91       FreeExpression(symbol.propCategory);
92
93    FreeType(symbol.type);
94
95    while((link = symbol.templatedClasses.first))
96       symbol.templatedClasses.Delete(link);
97
98    delete symbol.string;
99
100    if(symbol.templateParams)
101       FreeList(symbol.templateParams, FreeTemplateParameter);
102
103    // Used to be in ClassDefinition
104    delete symbol.constructorName;
105    delete symbol.structName;
106    delete symbol.className;
107    delete symbol.destructorName;
108    delete symbol.shortName;
109    if(symbol.ctx)
110    {
111       FreeContext(symbol.ctx);
112       delete symbol.ctx;
113    }
114    delete symbol;
115 }
116
117 void FreeMethodImport(MethodImport imp)
118 {
119    delete imp.name;
120 }
121
122 void FreePropertyImport(MethodImport imp)
123 {
124    delete imp.name;
125 }
126
127 void FreeClassImport(ClassImport imp)
128 {
129    delete imp.name;
130    imp.methods.Free(FreeMethodImport);
131    imp.properties.Free(FreePropertyImport);
132 }
133
134 void FreeFunctionImport(ClassImport imp)
135 {
136    delete imp.name;
137 }
138
139 public void FreeModuleImport(ModuleImport imp)
140 {
141    delete imp.name;
142    imp.classes.Free(FreeClassImport);
143    imp.functions.Free(FreeFunctionImport);
144 }
145
146 public void FreeModuleDefine(Definition def)
147 {
148    delete def.name;
149 }
150
151 public void FreeExcludedSymbols(OldList excludedSymbols)
152 {
153    Symbol symbol;
154
155    while((symbol = excludedSymbols.first))
156    {
157       excludedSymbols.Remove(symbol);
158       FreeSymbol(symbol);
159    }
160 }
161
162 public void FreeTemplateArgument(TemplateArgument arg)
163 {
164    switch(arg.type)
165    {
166       case expression:
167          if(arg.expression)
168             FreeExpression(arg.expression);
169          break;
170       case identifier:
171          if(arg.identifier)
172             FreeIdentifier(arg.identifier);
173          break;
174       case type:
175          if(arg.templateDatatype)
176             FreeTemplateDataType(arg.templateDatatype);
177          break;
178    }
179    if(arg.name)
180       FreeIdentifier(arg.name);
181    delete arg;
182 }
183
184 public void FreeTemplateDataType(TemplateDatatype type)
185 {
186    if(type.decl)
187       FreeDeclarator(type.decl);
188    if(type.specifiers)
189       FreeList(type.specifiers, FreeSpecifier);
190    delete type;
191 }
192
193 public void FreeTemplateParameter(TemplateParameter param)
194 {
195    if(param.identifier)
196    {
197       FreeIdentifier(param.identifier);
198    }
199    if(param.type == type || param.type == expression)
200    {
201       if(param.dataType)
202          FreeTemplateDataType(param.dataType);
203    }
204    if(param.defaultArgument)
205       FreeTemplateArgument(param.defaultArgument);
206    if(param.baseType)
207       FreeType(param.baseType);
208    delete param;
209 }
210
211 public void FreeTemplateType(TemplatedType type)
212 {
213    /*if(type.ownParam)
214    {
215       FreeTemplateParameter(type.param);
216    }*/
217    delete type;
218 }
219
220 public void FreeContext(Context context)
221 {
222    Symbol symbol;
223
224    if(context == curContext)
225       curContext = globalContext;
226
227    while((symbol = (Symbol)context.types.root))
228    {
229       context.types.Remove((BTNode)symbol);
230       FreeSymbol(symbol);
231    }
232    while((symbol = (Symbol)context.classes.root))
233    {
234       context.classes.Remove((BTNode)symbol);
235       FreeSymbol(symbol);
236    }
237    while((symbol = (Symbol)context.symbols.root))
238    {
239       context.symbols.Remove((BTNode)symbol);
240       FreeSymbol(symbol);
241    }
242    while((symbol = (Symbol)context.structSymbols.root))
243    {
244       context.structSymbols.Remove((BTNode)symbol);
245       FreeSymbol(symbol);
246    }
247    while((symbol = (Symbol)context.templateTypes.root))
248    {
249       context.templateTypes.Remove((BTNode)symbol);
250       FreeTemplateType((TemplatedType)symbol);
251    }
252
253    context.nextID = 0;
254    context.simpleID = 0;
255    context.parent = null;
256 }
257
258 void FreeEnumerator(Enumerator enumerator)
259 {
260    if(enumerator.id)
261       FreeIdentifier(enumerator.id);
262    if(enumerator.exp)
263       FreeExpression(enumerator.exp);
264
265    delete enumerator;
266 }
267
268 void FreeSpecifier(Specifier spec)
269 {
270    if(spec)
271    {
272       FreeSpecifierContents(spec);
273       delete spec;
274    }
275 }
276
277 void FreeSpecifierContents(Specifier spec)
278 {
279    switch(spec.type)
280    {
281       case nameSpecifier:
282       //case classSpecifier:
283          delete spec.name;
284          if(spec.templateArgs)
285          {
286             FreeList(spec.templateArgs, FreeTemplateArgument);
287             spec.templateArgs = null;
288          }
289          if(spec.nsSpec)
290          {
291             FreeSpecifier(spec.nsSpec);
292             spec.nsSpec = null;
293          }
294          break;
295       case extendedSpecifier:
296          if(spec.extDecl)
297          {
298             FreeExtDecl(spec.extDecl);
299             spec.extDecl = null;
300          }
301          break;
302       case enumSpecifier:
303          if(spec.baseSpecs)
304          {
305             FreeList(spec.baseSpecs, FreeSpecifier);
306             spec.baseSpecs = null;
307          }
308          if(spec.id)
309          {
310             FreeIdentifier(spec.id);
311             spec.id = null;
312          }
313          if(spec.list)
314          {
315             FreeList(spec.list, FreeEnumerator);
316             spec.list = null;
317          }
318          if(spec.definitions)
319          {
320             FreeList(spec.definitions, FreeClassDef);
321             spec.definitions = null;
322          }
323          break;
324       case structSpecifier:
325       case unionSpecifier:
326          if(spec.id)
327          {
328             FreeIdentifier(spec.id);
329             spec.id = null;
330          }
331          if(spec.definitions)
332          {
333             FreeList(spec.definitions, FreeClassDef);
334             spec.definitions = null;
335          }
336          if(spec.baseSpecs)
337          {
338             FreeList(spec.baseSpecs, FreeSpecifier);
339             spec.baseSpecs = null;
340          }
341          if(spec.extDeclStruct)
342          {
343             FreeExtDecl(spec.extDeclStruct);
344             spec.extDeclStruct = null;
345          }
346          if(spec.ctx)
347          {
348             FreeContext(spec.ctx);
349             delete spec.ctx;
350          }
351          break;
352       case subClassSpecifier:
353          if(spec._class)
354          {
355             FreeSpecifier(spec._class);
356             spec._class = null;
357          }
358          break;
359    }
360 }
361
362 public void FreeIdentifier(Identifier id)
363 {
364    if(id.badID)
365       FreeIdentifier(id.badID);
366    delete id.string;
367    if(id._class)
368       FreeSpecifier(id._class);
369    delete id;
370 }
371
372 void FreeTypeName(TypeName typeName)
373 {
374    if(typeName.qualifiers)
375       FreeList(typeName.qualifiers, FreeSpecifier);
376    if(typeName.declarator)
377       FreeDeclarator(typeName.declarator);
378    if(typeName.bitCount)
379       FreeExpression(typeName.bitCount);
380
381    delete typeName;
382 }
383
384 public void FreeExpContents(Expression exp)
385 {
386    _FreeExpression(exp, false);
387 }
388
389 public void FreeExpression(Expression exp)
390 {
391    _FreeExpression(exp, true);
392 }
393
394 static void _FreeExpression(Expression exp, bool freePointer)
395 {
396 #ifdef _DEBUG
397    char debugExpString[4096];
398    debugExpString[0] = '\0';
399    PrintExpression(exp, debugExpString);
400 #endif
401    switch(exp.type)
402    {
403       case newExp:
404       case new0Exp:
405          FreeExpression(exp._new.size);
406          FreeTypeName(exp._new.typeName);
407          break;
408       case renewExp:
409       case renew0Exp:
410          FreeExpression(exp._renew.exp);
411          FreeExpression(exp._renew.size);
412          FreeTypeName(exp._renew.typeName);
413          break;
414       case constantExp:
415          delete exp.constant;
416          break;
417       case identifierExp:
418          if(exp.identifier)
419             FreeIdentifier(exp.identifier);
420          break;
421       case instanceExp:
422          if(exp.instance)
423          {
424             FreeInstance(exp.instance);
425             exp.instance = null;
426          }
427          break;
428       case stringExp:
429          delete exp.string;
430          break;
431       case opExp:
432          if(exp.op.exp1)
433             FreeExpression(exp.op.exp1);
434          if(exp.op.exp2)
435             FreeExpression(exp.op.exp2);
436          break;
437       case bracketsExp:
438       {
439          FreeList(exp.list, FreeExpression);
440          break;
441       }
442       case indexExp:
443       {
444          if(exp.index.exp)
445             FreeExpression(exp.index.exp);
446          if(exp.index.index)
447             FreeList(exp.index.index, FreeExpression);
448          break;
449       }
450       case callExp:
451       {
452          if(exp.call.exp)
453             FreeExpression(exp.call.exp);
454          if(exp.call.arguments)
455             FreeList(exp.call.arguments, FreeExpression);
456          break;
457       }
458       case memberExp:
459       case pointerExp:
460          if(exp.member.exp)
461             FreeExpression(exp.member.exp);
462          if(exp.member.member)
463             FreeIdentifier(exp.member.member);
464          break;
465       case typeSizeExp:
466          FreeTypeName(exp.typeName);
467          break;
468       case typeAlignExp:
469          FreeTypeName(exp.typeName);
470          break;
471       case offsetOfExp:
472          if(exp.offset.typeName)
473             FreeTypeName(exp.offset.typeName);
474          if(exp.offset.id)
475             FreeIdentifier(exp.offset.id);
476          break;
477       case castExp:
478          if(exp.cast.exp)
479             FreeExpression(exp.cast.exp);
480          FreeTypeName(exp.cast.typeName);
481          break;
482       case conditionExp:
483       {
484          if(exp.cond.cond)
485             FreeExpression(exp.cond.cond);
486          if(exp.cond.exp)
487             FreeList(exp.cond.exp, FreeExpression);
488          if(exp.cond.elseExp)
489             FreeExpression(exp.cond.elseExp);
490          break;
491       }
492       case extensionCompoundExp:
493       {
494          if(exp.compound)
495             FreeStatement(exp.compound);
496          break;
497       }
498       case extensionExpressionExp:
499       {
500          if(exp.list)
501             FreeList(exp.list, FreeExpression);
502          break;
503       }
504       case extensionInitializerExp:
505       {
506          if(exp.initializer.typeName)
507             FreeTypeName(exp.initializer.typeName);
508          if(exp.initializer.initializer)
509             FreeInitializer(exp.initializer.initializer);
510          break;
511       }
512       case dummyExp:
513          break;
514       case classExp:
515          if(exp._classExp.specifiers)
516             FreeList(exp._classExp.specifiers, FreeSpecifier);
517          if(exp._classExp.decl)
518             FreeDeclarator(exp._classExp.decl);
519          break;
520       case dbfieldExp:
521       case dbindexExp:
522       case dbtableExp:
523          if(exp.db.id)
524             FreeIdentifier(exp.db.id);
525          delete exp.db.table;
526          break;
527       case dbopenExp:
528          /*
529          if(exp.call.arguments)
530             FreeList(exp.call.arguments, FreeExpression);
531          */
532          if(exp.dbopen.ds)
533             FreeExpression(exp.dbopen.ds);
534          if(exp.dbopen.name)
535             FreeExpression(exp.dbopen.name);
536          break;
537       case vaArgExp:
538          if(exp.vaArg.exp)
539             FreeExpression(exp.vaArg.exp);
540          if(exp.vaArg.typeName)
541             FreeTypeName(exp.vaArg.typeName);
542          break;
543       case arrayExp:
544          if(exp.list)
545             FreeList(exp.list, FreeExpression);
546          break;
547       case classSizeExp:
548          if(exp._class)
549             FreeSpecifier(exp._class);
550          break;
551       case classDataExp:
552          if(exp.classData.id)
553             FreeIdentifier(exp.classData.id);
554             break;
555       case symbolErrorExp:
556          if(exp.identifier)
557             FreeIdentifier(exp.identifier);
558          break;
559       case memoryErrorExp:
560          delete exp.constant;
561          break;
562       case memberPropertyErrorExp:
563       case memberSymbolErrorExp:
564          if(exp.member.exp)
565             FreeExpression(exp.member.exp);
566          if(exp.member.member)
567             FreeIdentifier(exp.member.member);
568          break;
569       case functionCallErrorExp:
570          if(exp.call.exp)
571             FreeExpression(exp.call.exp);
572          if(exp.call.arguments)
573             FreeList(exp.call.arguments, FreeExpression);
574          break;
575       case dereferenceErrorExp:
576       case unknownErrorExp:
577       case noDebuggerErrorExp:
578          break;
579    }
580    if(freePointer)
581    {
582       if(exp.expType)
583          FreeType(exp.expType);
584       if(exp.destType)
585          FreeType(exp.destType);
586       delete exp;
587    }
588 }
589
590 void FreePointer(Pointer pointer)
591 {
592    if(pointer.pointer)
593       FreePointer(pointer.pointer);
594    if(pointer.qualifiers)
595       FreeList(pointer.qualifiers, FreeSpecifier);
596    delete pointer;
597 }
598
599 void FreeAttrib(Attrib attr)
600 {
601    if(attr.attribs)
602       FreeList(attr.attribs, FreeAttribute);
603    delete attr;
604 }
605
606 void FreeAttribute(Attribute attr)
607 {
608    delete attr.attr;
609    if(attr.exp)
610       FreeExpression(attr.exp);
611    delete attr;
612 }
613
614 void FreeExtDecl(ExtDecl extDecl)
615 {
616    if(extDecl.type == extDeclAttrib && extDecl.attr)
617       FreeAttrib(extDecl.attr);
618    else if(extDecl.type == extDeclString)
619       delete extDecl.s;
620    delete extDecl;
621 }
622
623 void FreeDeclarator(Declarator decl)
624 {
625    if(decl.declarator)
626       FreeDeclarator(decl.declarator);
627
628    switch(decl.type)
629    {
630       case structDeclarator:
631          if(decl.structDecl.exp)
632             FreeExpression(decl.structDecl.exp);
633          if(decl.structDecl.posExp)
634             FreeExpression(decl.structDecl.posExp);
635          if(decl.structDecl.attrib)
636             FreeAttrib(decl.structDecl.attrib);
637          break;
638       case identifierDeclarator:
639          FreeIdentifier(decl.identifier);
640          break;
641       case bracketsDeclarator:
642          break;
643       case arrayDeclarator:
644          if(decl.array.exp)
645             FreeExpression(decl.array.exp);
646          if(decl.array.enumClass)
647             FreeSpecifier(decl.array.enumClass);
648          break;
649       case functionDeclarator:
650          FreeList(decl.function.parameters, FreeTypeName);
651          break;
652       case pointerDeclarator:
653          if(decl.pointer.pointer)
654             FreePointer(decl.pointer.pointer);
655          break;
656       case extendedDeclarator:
657       case extendedDeclaratorEnd:
658          if(decl.extended.extended)
659             FreeExtDecl(decl.extended.extended);
660          break;
661    }
662    delete decl;
663 }
664
665 void FreePropertyWatch(PropertyWatch watcher)
666 {
667    if(watcher.properties)
668       FreeList(watcher.properties, FreeIdentifier);
669    if(watcher.compound)
670       FreeStatement(watcher.compound);
671    delete watcher;
672 }
673
674 void FreeAsmField(AsmField field)
675 {
676    if(field.expression)
677       FreeExpression(field.expression);
678    if(field.symbolic)
679       FreeIdentifier(field.symbolic);
680    delete field.command;
681    delete field;
682 }
683
684 void FreeStatement(Statement stmt)
685 {
686    switch(stmt.type)
687    {
688       case asmStmt:
689       {
690          if(stmt.asmStmt.spec)
691             FreeSpecifier(stmt.asmStmt.spec);
692          if(stmt.asmStmt.inputFields)
693             FreeList(stmt.asmStmt.inputFields, FreeAsmField);
694          if(stmt.asmStmt.outputFields)
695             FreeList(stmt.asmStmt.outputFields, FreeAsmField);
696          if(stmt.asmStmt.clobberedFields)
697             FreeList(stmt.asmStmt.clobberedFields, FreeAsmField);
698          delete stmt.asmStmt.statements;
699          break;
700       }
701       case labeledStmt:
702          if(stmt.labeled.stmt)
703             FreeStatement(stmt.labeled.stmt);
704          break;
705       case caseStmt:
706          if(stmt.caseStmt.exp)
707             FreeExpression(stmt.caseStmt.exp);
708          if(stmt.caseStmt.stmt)
709             FreeStatement(stmt.caseStmt.stmt);
710          break;
711       case badDeclarationStmt:
712          if(stmt.decl)
713             FreeDeclaration(stmt.decl);
714          break;
715       case compoundStmt:
716       {
717          if(stmt.compound.declarations)
718             FreeList(stmt.compound.declarations, FreeDeclaration);
719          if(stmt.compound.statements)
720             FreeList(stmt.compound.statements, FreeStatement);
721          if(stmt.compound.context)
722          {
723             FreeContext(stmt.compound.context);
724             delete stmt.compound.context;
725          }
726          break;
727       }
728       case expressionStmt:
729       {
730          if(stmt.expressions)
731             FreeList(stmt.expressions, FreeExpression);
732          break;
733       }
734       case ifStmt:
735       {
736          if(stmt.ifStmt.exp)
737             FreeList(stmt.ifStmt.exp, FreeExpression);
738          if(stmt.ifStmt.stmt)
739             FreeStatement(stmt.ifStmt.stmt);
740          if(stmt.ifStmt.elseStmt)
741             FreeStatement(stmt.ifStmt.elseStmt);
742          break;
743       }
744       case switchStmt:
745       {
746          if(stmt.switchStmt.exp)
747             FreeList(stmt.switchStmt.exp, FreeExpression);
748          if(stmt.switchStmt.stmt)
749             FreeStatement(stmt.switchStmt.stmt);
750          break;
751       }
752       case whileStmt:
753       {
754          if(stmt.whileStmt.exp)
755             FreeList(stmt.whileStmt.exp, FreeExpression);
756          if(stmt.whileStmt.stmt)
757             FreeStatement(stmt.whileStmt.stmt);
758          break;
759       }
760       case doWhileStmt:
761       {
762          if(stmt.doWhile.stmt)
763             FreeStatement(stmt.doWhile.stmt);
764
765          if(stmt.doWhile.exp)
766             FreeList(stmt.doWhile.exp, FreeExpression);
767          break;
768       }
769       case forStmt:
770       {
771          if(stmt.forStmt.init)
772             FreeStatement(stmt.forStmt.init);
773
774          if(stmt.forStmt.check)
775             FreeStatement(stmt.forStmt.check);
776
777          if(stmt.forStmt.increment)
778             FreeList(stmt.forStmt.increment, FreeExpression);
779          if(stmt.forStmt.stmt)
780             FreeStatement(stmt.forStmt.stmt);
781          break;
782       }
783       case forEachStmt:
784       {
785          if(stmt.forEachStmt.id)
786             FreeIdentifier(stmt.forEachStmt.id);
787          if(stmt.forEachStmt.exp)
788             FreeList(stmt.forEachStmt.exp, FreeExpression);
789          if(stmt.forEachStmt.filter)
790             FreeList(stmt.forEachStmt.filter, FreeExpression);
791          if(stmt.forEachStmt.stmt)
792             FreeStatement(stmt.forEachStmt.stmt);
793          break;
794       }
795       case gotoStmt:
796          break;
797       case continueStmt:
798          break;
799       case breakStmt:
800          break;
801       case returnStmt:
802          if(stmt.expressions)
803             FreeList(stmt.expressions, FreeExpression);
804          break;
805       case watchStmt:
806       case fireWatchersStmt:
807       case stopWatchingStmt:
808       {
809          if(stmt._watch.watcher)
810             FreeExpression(stmt._watch.watcher);
811          if(stmt._watch.object)
812             FreeExpression(stmt._watch.object);
813          if(stmt._watch.watches)
814             FreeList(stmt._watch.watches, (stmt.type == watchStmt) ? (void *)FreePropertyWatch : (void *)FreeIdentifier);
815          break;
816       }
817    }
818    delete stmt;
819 }
820
821 void FreeInitializer(Initializer initializer)
822 {
823    switch(initializer.type)
824    {
825       case listInitializer:
826          FreeList(initializer.list, FreeInitializer);
827          break;
828       case expInitializer:
829          if(initializer.exp)
830             FreeExpression(initializer.exp);
831          break;
832    }
833    if(initializer.id)
834       FreeIdentifier(initializer.id);
835    delete initializer;
836 }
837
838 void FreeInitDeclarator(InitDeclarator decl)
839 {
840    if(decl.declarator)
841       FreeDeclarator(decl.declarator);
842    if(decl.initializer)
843       FreeInitializer(decl.initializer);
844    delete decl;
845 }
846
847 void FreeDeclaration(Declaration decl)
848 {
849    if(decl.symbol && !decl.symbol.type)
850    {
851       //FreeSymbol(decl.symbol);
852    }
853    switch(decl.type)
854    {
855       case structDeclaration:
856       {
857          if(decl.specifiers)
858             FreeList(decl.specifiers, FreeSpecifier);
859          if(decl.declarators)
860             FreeList(decl.declarators, FreeDeclarator);
861          if(decl.extStorage)
862             FreeSpecifier(decl.extStorage);
863          break;
864       }
865       case initDeclaration:
866       {
867          if(decl.specifiers)
868             FreeList(decl.specifiers, FreeSpecifier);
869          if(decl.declarators)
870             FreeList(decl.declarators, FreeInitDeclarator);
871          break;
872       }
873       case instDeclaration:
874          if(decl.inst)
875             FreeInstance(decl.inst);
876          break;
877       case defineDeclaration:
878       {
879          if(decl.exp)
880             FreeExpression(decl.exp);
881          if(decl.id)
882             FreeIdentifier(decl.id);
883          break;
884       }
885    }
886    delete decl;
887 }
888
889 void FreeFunction(FunctionDefinition func)
890 {
891    if(func.body)
892       FreeStatement(func.body);
893    if(func.declarator)
894       FreeDeclarator(func.declarator);
895    if(func.specifiers)
896       FreeList(func.specifiers, FreeSpecifier);
897    if(func.declarations)
898       FreeList(func.declarations, FreeDeclaration);
899
900    if(func.type)
901       FreeType(func.type);
902
903    delete func;
904 }
905
906 void FreeMemberInit(MemberInit init)
907 {
908    if(init.initializer)
909       FreeInitializer(init.initializer);
910    if(init.identifiers)
911       FreeList(init.identifiers, FreeIdentifier);
912    delete init;
913 }
914
915 void FreeMembersInit(MembersInit init)
916 {
917    if(init.type == dataMembersInit && init.dataMembers)
918       FreeList(init.dataMembers, FreeMemberInit);
919
920    if(init.type == methodMembersInit && init.function)
921    {
922       FreeClassFunction(init.function);
923    }
924    delete init;
925 }
926
927 public void FreeInstance(Instantiation inst)
928 {
929    if(inst.members)
930    {
931       FreeList(inst.members, FreeMembersInit);
932    }
933
934    if(inst.exp)
935       FreeExpression(inst.exp);
936
937    if(inst.data)
938    {
939       Symbol classSym = FindClass(inst._class.name);
940       Class _class = classSym ? classSym.registered : null;
941       if(_class)
942       {
943          if(_class.type == normalClass)
944          {
945             Instance instance = (Instance)inst.data;
946             delete instance;
947          }
948          else if(_class.type == noHeadClass)
949          {
950             if(_class.Destructor)
951                _class.Destructor((Instance)inst.data);
952             delete inst.data;
953          }
954          else if(_class.type == structClass)
955          {
956             delete inst.data;
957          }
958       }
959       else
960       {
961          Instance instance = (Instance)inst.data;
962          delete instance;
963       }
964    }
965
966    if(inst._class)
967       FreeSpecifier(inst._class);
968
969    // Free symbol?
970    // Free data;
971
972    delete inst;
973 }
974
975 public void FreeClassFunction(ClassFunction func)
976 {
977    // Tricky Stuff...
978    if(func.declarator && func.declarator.symbol)
979    {
980       //FreeSymbol(func.declarator.symbol);
981    }
982
983    if(func.type)
984       FreeType(func.type);
985
986    if(func.body)
987       FreeStatement(func.body);
988    if(func.declarator)
989       FreeDeclarator(func.declarator);
990    if(func.specifiers)
991       FreeList(func.specifiers, FreeSpecifier);
992    if(func.declarations)
993       FreeList(func.declarations, FreeDeclaration);
994
995    func.attached.Free(null);
996
997    delete func;
998 }
999
1000 void FreeProperty(PropertyDef def)
1001 {
1002    if(def.specifiers)
1003       FreeList(def.specifiers, FreeSpecifier);
1004    if(def.declarator)
1005       FreeDeclarator(def.declarator);
1006    if(def.id)
1007       FreeIdentifier(def.id);
1008    if(def.getStmt)
1009       FreeStatement(def.getStmt);
1010    if(def.setStmt)
1011       FreeStatement(def.setStmt);
1012    if(def.issetStmt)
1013       FreeStatement(def.issetStmt);
1014    if(def.category)
1015       FreeExpression(def.category);
1016
1017    /*
1018    if(def.getFunction)
1019       FreeFunction(def.getFunction);
1020    if(def.setFunction)
1021       FreeFunction(def.setFunction);
1022    */
1023    if(def.symbol)
1024    {
1025       // FreeSymbol(def.symbol);
1026    }
1027
1028    delete def;
1029 }
1030
1031 void FreeClassDef(ClassDef def)
1032 {
1033    switch(def.type)
1034    {
1035       case declarationClassDef:
1036          if(def.decl)
1037             FreeDeclaration(def.decl);
1038          break;
1039       case defaultPropertiesClassDef:
1040       {
1041          FreeList(def.defProperties, FreeMemberInit);
1042          break;
1043       }
1044       case functionClassDef:
1045          if(def.function)
1046             FreeClassFunction(def.function);
1047          break;
1048       case propertyClassDef:
1049          if(def.propertyDef)
1050             FreeProperty(def.propertyDef);
1051          break;
1052       case classPropertyClassDef:
1053          if(def.propertyDef)
1054             FreeProperty(def.propertyDef);
1055          break;
1056       case accessOverrideClassDef:
1057          break;
1058       case classDataClassDef:
1059       {
1060          if(def.decl)
1061             FreeDeclaration(def.decl);
1062          break;
1063       }
1064       case classDesignerClassDef:
1065       {
1066          delete def.designer;
1067          break;
1068       }
1069       case classFixedClassDef:
1070          break;
1071       case classNoExpansionClassDef:
1072          break;
1073       case classPropertyValueClassDef:
1074          if(def.id)
1075             FreeIdentifier(def.id);
1076          if(def.initializer)
1077             FreeInitializer(def.initializer);
1078          break;
1079       case designerDefaultPropertyClassDef:
1080       {
1081          if(def.defaultProperty)
1082             FreeIdentifier(def.defaultProperty);
1083          break;
1084       }
1085       case memberAccessClassDef:
1086          break;
1087       case propertyWatchClassDef:
1088       {
1089          if(def.propertyWatch)
1090             FreePropertyWatch(def.propertyWatch);
1091          break;
1092       }
1093    }
1094    delete def;
1095 }
1096
1097 void FreeClass(ClassDefinition _class)
1098 {
1099    if(_class.definitions)
1100       FreeList(_class.definitions, FreeClassDef);
1101    if(_class._class)
1102       FreeSpecifier(_class._class);
1103    if(_class.baseSpecs)
1104       FreeList(_class.baseSpecs, FreeSpecifier);
1105
1106    delete _class;
1107 }
1108
1109 void FreeDBIndexItem(DBIndexItem item)
1110 {
1111    if(item.id)
1112       FreeIdentifier(item.id);
1113    delete item;
1114 }
1115
1116 void FreeDBTableEntry(DBTableEntry entry)
1117 {
1118    if(entry.id)
1119       FreeIdentifier(entry.id);
1120    switch(entry.type)
1121    {
1122       case fieldEntry:
1123          if(entry.dataType)
1124             FreeTypeName(entry.dataType);
1125          if(entry.name)
1126             delete entry.name;
1127          break;
1128       case indexEntry:
1129          if(entry.items)
1130             FreeList(entry.items, FreeDBIndexItem);
1131          break;
1132    }
1133    delete entry;
1134 }
1135
1136 void FreeDBTable(DBTableDef table)
1137 {
1138    if(table.definitions)
1139       FreeList(table.definitions, FreeDBTableEntry);
1140    /*if(table.symbol)
1141       FreeIdentifier(table.symbol);*/
1142    if(table.name)
1143       delete table.name;
1144    delete table;
1145 }
1146
1147 void FreeExternal(External external)
1148 {
1149    TopoEdge e;
1150    while((e = external.incoming.first))
1151    {
1152       e.from.outgoing.Remove((IteratorPointer)e);
1153       external.incoming.Remove((IteratorPointer)e);
1154       delete e;
1155    }
1156    while((e = external.outgoing.first))
1157    {
1158       e.to.incoming.Remove((IteratorPointer)e);
1159       external.outgoing.Remove((IteratorPointer)e);
1160       if(!e.breakable)
1161          e.to.nonBreakableIncoming--;
1162       delete e;
1163    }
1164    switch(external.type)
1165    {
1166       case functionExternal:
1167          if(external.function)
1168             FreeFunction(external.function);
1169          break;
1170       case declarationExternal:
1171          if(external.declaration)
1172             FreeDeclaration(external.declaration);
1173          break;
1174       case classExternal:
1175          if(external._class)
1176             FreeClass(external._class);
1177          break;
1178       case importExternal:
1179          delete external.importString;
1180          break;
1181       case nameSpaceExternal:
1182          FreeIdentifier(external.id);
1183          break;
1184       case dbtableExternal:
1185          if(external.table)
1186             FreeDBTable(external.table);
1187          break;
1188    }
1189    delete external;
1190 }
1191
1192 public void FreeASTTree(OldList ast)
1193 {
1194    if(ast != null)
1195    {
1196       External external;
1197       while((external = ast.first))
1198       {
1199          ast.Remove(external);
1200          FreeExternal(external);
1201       }
1202       delete ast;
1203    }
1204 }
1205
1206 static void FreeDataMember(DataMember parentMember)
1207 {
1208    DataMember dataMember;
1209
1210    for(dataMember = parentMember.members.first; dataMember; dataMember = dataMember.next)
1211    {
1212       if(dataMember.type == structMember || dataMember.type == unionMember)
1213          FreeDataMember(dataMember);
1214
1215       if(dataMember.dataType)
1216       {
1217          FreeType(dataMember.dataType);
1218          dataMember.dataType = null;
1219       }
1220    }
1221 }
1222
1223 static void FreeClassProperties(ClassProperty classProp)
1224 {
1225    if(classProp.left) FreeClassProperties(classProp.left);
1226    if(classProp.right) FreeClassProperties(classProp.right);
1227    if(classProp.dataType)
1228    {
1229       FreeType(classProp.dataType);
1230       classProp.dataType = null;
1231    }
1232 }
1233
1234 void FreeModuleData(Module module)
1235 {
1236    Class _class;
1237    GlobalFunction function;
1238
1239    // Unload classes
1240    for(_class = module.classes.first; _class; _class = _class.next)
1241    {
1242       DataMember dataMember;
1243       Method method;
1244       ClassTemplateParameter param;
1245
1246       if(_class.templateClass) continue;
1247
1248       if(_class.dataType)
1249       {
1250          FreeType(_class.dataType);
1251          _class.dataType = null;
1252       }
1253       for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
1254       {
1255          if(dataMember.isProperty)
1256          {
1257             Property prop = (Property)dataMember;
1258             if(prop.symbol)
1259             {
1260                FreeSymbol(prop.symbol);
1261             }
1262          }
1263          else
1264          {
1265             if(dataMember.type == structMember || dataMember.type == unionMember)
1266                FreeDataMember(dataMember);
1267          }
1268          if(dataMember.dataType)
1269          {
1270             FreeType(dataMember.dataType);
1271             dataMember.dataType = null;
1272          }
1273       }
1274       for(dataMember = _class.conversions.first; dataMember; dataMember = dataMember.next)
1275       {
1276          Property prop = (Property) dataMember;
1277          if(prop.symbol)
1278          {
1279             FreeSymbol(prop.symbol);
1280          }
1281          if(prop.dataType)
1282          {
1283             FreeType(prop.dataType);
1284             prop.dataType = null;
1285          }
1286       }
1287       if(_class.classProperties.first)
1288          FreeClassProperties((ClassProperty)_class.classProperties.first);
1289       for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next)
1290       {
1291          if(method.dataType)
1292          {
1293             FreeType(method.dataType);
1294             method.dataType = null;
1295          }
1296
1297          if(method.symbol)
1298          {
1299             FreeSymbol(method.symbol);
1300          }
1301       }
1302       for(param = _class.templateParams.first; param; param = param.next)
1303       {
1304          if(param.param)
1305          {
1306             FreeTemplateParameter(param.param);
1307             param.param = null;
1308          }
1309       }
1310    }
1311
1312    for(function = module.functions.first; function; function = function.next)
1313    {
1314       if(function.dataType)
1315          FreeType(function.dataType);
1316       if(function.symbol)
1317          FreeSymbol(function.symbol);
1318    }
1319
1320    // Free the extra module instance on closing the last code editor using it
1321    if(!inCompiler)
1322    {
1323       MapIterator <String, List<Module> > mapIt { map = loadedModules };
1324       while(mapIt.Next())
1325       {
1326          List<Module> list = mapIt.data;
1327          Iterator<Module> it { list };
1328          bool found = false;
1329          while(it.Next())
1330          {
1331             if(it.data == module)
1332             {
1333                list.Remove(it.pointer);
1334                found = true;
1335                break;
1336             }
1337          }
1338          if(found)
1339          {
1340             if(list.count == 1)
1341             {
1342                // Unload the initial module that we loaded for safe sharing
1343                Module mod = list[0];
1344                list.Remove(list.GetFirst());
1345                loadedModules.Remove(mapIt.pointer);
1346                delete list;
1347                eModule_Unload(__thisModule.application, mod);
1348             }
1349             break;
1350          }
1351       }
1352    }
1353 }
1354
1355 public void FreeTypeData(Module privateModule)
1356 {
1357    Module m;
1358    for(m = privateModule.application.allModules.first; m; m = m.next)
1359    {
1360       FreeModuleData(m);
1361    }
1362    FreeModuleData(privateModule);
1363 }