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