b0cce7be2bcbb27177e15a8dfe1ff533a2907757
[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       switch(spec.type)
274       {
275          case nameSpecifier:
276          //case classSpecifier:
277             delete spec.name;
278             if(spec.templateArgs)
279                FreeList(spec.templateArgs, FreeTemplateArgument);
280             break;
281          case extendedSpecifier:
282             if(spec.extDecl)
283                FreeExtDecl(spec.extDecl);
284             break;
285          case enumSpecifier:
286             if(spec.baseSpecs)
287                FreeList(spec.baseSpecs, FreeSpecifier);
288             if(spec.id)
289                FreeIdentifier(spec.id);
290             if(spec.list)
291                FreeList(spec.list, FreeEnumerator);
292             if(spec.definitions)
293                FreeList(spec.definitions, FreeClassDef);
294             break;
295          case structSpecifier:
296          case unionSpecifier:
297             if(spec.id)
298                FreeIdentifier(spec.id);
299             if(spec.definitions)
300                FreeList(spec.definitions, FreeClassDef);
301             if(spec.baseSpecs)
302                FreeList(spec.baseSpecs, FreeSpecifier);
303             if(spec.extDeclStruct)
304                FreeExtDecl(spec.extDeclStruct);
305             if(spec.ctx)
306             {
307                FreeContext(spec.ctx);
308                delete spec.ctx;
309             }
310             break;
311          case subClassSpecifier:
312             if(spec._class)
313                FreeSpecifier(spec._class);
314             break;
315       }
316       delete spec;
317    }
318 }
319
320 public void FreeIdentifier(Identifier id)
321 {
322    if(id.badID)
323       FreeIdentifier(id.badID);
324    delete id.string;
325    if(id._class)
326       FreeSpecifier(id._class);
327    delete id;
328 }
329
330 void FreeTypeName(TypeName typeName)
331 {
332    if(typeName.qualifiers)
333       FreeList(typeName.qualifiers, FreeSpecifier);
334    if(typeName.declarator)
335       FreeDeclarator(typeName.declarator);
336    if(typeName.bitCount)
337       FreeExpression(typeName.bitCount);
338
339    delete typeName;
340 }
341
342 public void FreeExpContents(Expression exp)
343 {
344    _FreeExpression(exp, false);
345 }
346
347 public void FreeExpression(Expression exp)
348 {
349    _FreeExpression(exp, true);
350 }
351
352 static void _FreeExpression(Expression exp, bool freePointer)
353 {
354 #ifdef _DEBUG
355    char debugExpString[4096];
356    debugExpString[0] = '\0';
357    PrintExpression(exp, debugExpString);
358 #endif
359    switch(exp.type)
360    {
361       case newExp:
362       case new0Exp:
363          FreeExpression(exp._new.size);
364          FreeTypeName(exp._new.typeName);
365          break;
366       case renewExp:
367       case renew0Exp:
368          FreeExpression(exp._renew.exp);
369          FreeExpression(exp._renew.size);
370          FreeTypeName(exp._renew.typeName);
371          break;
372       case constantExp:
373          delete exp.constant;
374          break;
375       case identifierExp:
376          if(exp.identifier)
377             FreeIdentifier(exp.identifier);
378          break;
379       case instanceExp:
380          if(exp.instance)
381          {
382             FreeInstance(exp.instance);
383             exp.instance = null;
384          }
385          break;
386       case stringExp:
387          delete exp.string;
388          break;
389       case opExp:
390          if(exp.op.exp1)
391             FreeExpression(exp.op.exp1);
392          if(exp.op.exp2)
393             FreeExpression(exp.op.exp2);
394          break;
395       case bracketsExp:
396       {
397          FreeList(exp.list, FreeExpression);
398          break;
399       }
400       case indexExp:
401       {
402          if(exp.index.exp)
403             FreeExpression(exp.index.exp);
404          if(exp.index.index)
405             FreeList(exp.index.index, FreeExpression);
406          break;
407       }
408       case callExp:
409       {
410          FreeExpression(exp.call.exp);
411          if(exp.call.arguments)
412             FreeList(exp.call.arguments, FreeExpression);
413          break;
414       }
415       case memberExp:
416       case pointerExp:
417          if(exp.member.exp)
418             FreeExpression(exp.member.exp);
419          if(exp.member.member)
420             FreeIdentifier(exp.member.member);
421          break;
422       case typeSizeExp:
423          FreeTypeName(exp._new.typeName);
424          break;
425       case typeAlignExp:
426          FreeTypeName(exp._new.typeName);
427          break;
428       case castExp:
429          if(exp.cast.exp)
430             FreeExpression(exp.cast.exp);
431          FreeTypeName(exp.cast.typeName);
432          break;
433       case conditionExp:
434       {
435          if(exp.cond.cond)
436             FreeExpression(exp.cond.cond);
437          if(exp.cond.exp)
438             FreeList(exp.cond.exp, FreeExpression);
439          if(exp.cond.elseExp)
440             FreeExpression(exp.cond.elseExp);
441          break;
442       }
443       case extensionCompoundExp:
444       {
445          if(exp.compound)
446             FreeStatement(exp.compound);
447          break;
448       }
449       case extensionExpressionExp:
450       {
451          if(exp.list)
452             FreeList(exp.list, FreeExpression);
453          break;
454       }
455       case extensionInitializerExp:
456       {
457          if(exp.initializer.typeName)
458             FreeTypeName(exp.initializer.typeName);
459          if(exp.initializer.initializer)
460             FreeInitializer(exp.initializer.initializer);
461          break;
462       }
463       case dummyExp:
464          break;
465       case classExp:
466          if(exp._classExp.specifiers)
467             FreeList(exp._classExp.specifiers, FreeSpecifier);
468          if(exp._classExp.decl)
469             FreeDeclarator(exp._classExp.decl);
470          break;
471       case dbfieldExp:
472       case dbindexExp:
473       case dbtableExp:
474          if(exp.db.id)
475             FreeIdentifier(exp.db.id);
476          delete exp.db.table;
477          break;
478       case dbopenExp:
479          /*
480          if(exp.call.arguments)
481             FreeList(exp.call.arguments, FreeExpression);
482          */
483          if(exp.dbopen.ds)
484             FreeExpression(exp.dbopen.ds);
485          if(exp.dbopen.name)
486             FreeExpression(exp.dbopen.name);
487          break;
488       case vaArgExp:
489          if(exp.vaArg.exp)
490             FreeExpression(exp.vaArg.exp);
491          if(exp.vaArg.typeName)
492             FreeTypeName(exp.vaArg.typeName);
493          break;
494       case arrayExp:
495          if(exp.list)
496             FreeList(exp.list, FreeExpression);
497          break;
498       case classSizeExp:
499          if(exp._class)
500             FreeSpecifier(exp._class);
501          break;
502       case classDataExp:
503          if(exp.classData.id)
504             FreeIdentifier(exp.classData.id);
505             break;
506       case symbolErrorExp:
507          if(exp.identifier)
508             FreeIdentifier(exp.identifier);
509          break;
510       case memoryErrorExp:
511          delete exp.constant;
512          break;
513       case memberPropertyErrorExp:
514       case memberSymbolErrorExp:
515          if(exp.member.exp)
516             FreeExpression(exp.member.exp);
517          if(exp.member.member)
518             FreeIdentifier(exp.member.member);
519          break;
520       case dereferenceErrorExp:
521       case unknownErrorExp:
522       case noDebuggerErrorExp:
523          break;
524    }
525    if(freePointer)
526    {
527       if(exp.expType)
528          FreeType(exp.expType);
529       if(exp.destType)
530          FreeType(exp.destType);
531       delete exp;
532    }
533 }
534
535 void FreePointer(Pointer pointer)
536 {
537    if(pointer.pointer)
538       FreePointer(pointer.pointer);
539    if(pointer.qualifiers)
540       FreeList(pointer.qualifiers, FreeSpecifier);
541    delete pointer;
542 }
543
544 void FreeAttrib(Attrib attr)
545 {
546    if(attr.attribs)
547       FreeList(attr.attribs, FreeAttribute);
548    delete attr;
549 }
550
551 void FreeAttribute(Attribute attr)
552 {
553    delete attr.attr;
554    if(attr.exp)
555       FreeExpression(attr.exp);
556    delete attr;
557 }
558
559 void FreeExtDecl(ExtDecl extDecl)
560 {
561    if(extDecl.type == extDeclAttrib && extDecl.attr)
562       FreeAttrib(extDecl.attr);
563    else if(extDecl.type == extDeclString)
564       delete extDecl.s;
565    delete extDecl;
566 }
567
568 void FreeDeclarator(Declarator decl)
569 {
570    if(decl.declarator)
571       FreeDeclarator(decl.declarator);
572
573    switch(decl.type)
574    {
575       case structDeclarator:
576          if(decl.structDecl.exp)
577             FreeExpression(decl.structDecl.exp);
578          if(decl.structDecl.posExp)
579             FreeExpression(decl.structDecl.posExp);
580          if(decl.structDecl.attrib)
581             FreeAttrib(decl.structDecl.attrib);
582          break;
583       case identifierDeclarator:
584          FreeIdentifier(decl.identifier);
585          break;
586       case bracketsDeclarator:
587          break;
588       case arrayDeclarator:
589          if(decl.array.exp)
590             FreeExpression(decl.array.exp);
591          if(decl.array.enumClass)
592             FreeSpecifier(decl.array.enumClass);
593          break;
594       case functionDeclarator:
595          FreeList(decl.function.parameters, FreeTypeName);
596          break;
597       case pointerDeclarator:
598          if(decl.pointer.pointer)
599             FreePointer(decl.pointer.pointer);
600          break;
601       case extendedDeclarator:
602       case extendedDeclaratorEnd:
603          if(decl.extended.extended)
604             FreeExtDecl(decl.extended.extended);
605          break;
606    }
607    delete decl;
608 }
609
610 void FreePropertyWatch(PropertyWatch watcher)
611 {
612    if(watcher.properties)
613       FreeList(watcher.properties, FreeIdentifier);
614    if(watcher.compound)
615       FreeStatement(watcher.compound);
616    delete watcher;
617 }
618
619 void FreeAsmField(AsmField field)
620 {
621    if(field.expression)
622       FreeExpression(field.expression);
623    if(field.symbolic)
624       FreeIdentifier(field.symbolic);
625    delete field.command;
626    delete field;
627 }
628
629 void FreeStatement(Statement stmt)
630 {
631    switch(stmt.type)
632    {
633       case asmStmt:
634       {
635          if(stmt.asmStmt.spec)
636             FreeSpecifier(stmt.asmStmt.spec);
637          if(stmt.asmStmt.inputFields)
638             FreeList(stmt.asmStmt.inputFields, FreeAsmField);
639          if(stmt.asmStmt.outputFields)
640             FreeList(stmt.asmStmt.outputFields, FreeAsmField);
641          if(stmt.asmStmt.clobberedFields)
642             FreeList(stmt.asmStmt.clobberedFields, FreeAsmField);
643          delete stmt.asmStmt.statements;
644          break;
645       }
646       case labeledStmt:
647          if(stmt.labeled.stmt)
648             FreeStatement(stmt.labeled.stmt);
649          break;
650       case caseStmt:
651          if(stmt.caseStmt.exp)
652             FreeExpression(stmt.caseStmt.exp);
653          if(stmt.caseStmt.stmt)
654             FreeStatement(stmt.caseStmt.stmt);
655          break;
656       case badDeclarationStmt:
657          if(stmt.decl)
658             FreeDeclaration(stmt.decl);
659          break;
660       case compoundStmt:
661       {
662          if(stmt.compound.declarations)
663             FreeList(stmt.compound.declarations, FreeDeclaration);
664          if(stmt.compound.statements)
665             FreeList(stmt.compound.statements, FreeStatement);
666          if(stmt.compound.context)
667          {
668             FreeContext(stmt.compound.context);
669             delete stmt.compound.context;
670          }
671          break;
672       }
673       case expressionStmt:
674       {
675          if(stmt.expressions)
676             FreeList(stmt.expressions, FreeExpression);
677          break;
678       }
679       case ifStmt:
680       {
681          if(stmt.ifStmt.exp)
682             FreeList(stmt.ifStmt.exp, FreeExpression);
683          if(stmt.ifStmt.stmt)
684             FreeStatement(stmt.ifStmt.stmt);
685          if(stmt.ifStmt.elseStmt)
686             FreeStatement(stmt.ifStmt.elseStmt);
687          break;
688       }
689       case switchStmt:
690       {
691          if(stmt.switchStmt.exp)
692             FreeList(stmt.switchStmt.exp, FreeExpression);
693          if(stmt.switchStmt.stmt)
694             FreeStatement(stmt.switchStmt.stmt);
695          break;
696       }
697       case whileStmt:
698       {
699          if(stmt.whileStmt.exp)
700             FreeList(stmt.whileStmt.exp, FreeExpression);
701          if(stmt.whileStmt.stmt)
702             FreeStatement(stmt.whileStmt.stmt);
703          break;
704       }
705       case doWhileStmt:
706       {
707          if(stmt.doWhile.stmt)
708             FreeStatement(stmt.doWhile.stmt);
709
710          if(stmt.doWhile.exp)
711             FreeList(stmt.doWhile.exp, FreeExpression);
712          break;
713       }
714       case forStmt:
715       {
716          if(stmt.forStmt.init)
717             FreeStatement(stmt.forStmt.init);
718
719          if(stmt.forStmt.check)
720             FreeStatement(stmt.forStmt.check);
721
722          if(stmt.forStmt.increment)
723             FreeList(stmt.forStmt.increment, FreeExpression);
724          if(stmt.forStmt.stmt)
725             FreeStatement(stmt.forStmt.stmt);
726          break;
727       }
728       case forEachStmt:
729       {
730          if(stmt.forEachStmt.id)
731             FreeIdentifier(stmt.forEachStmt.id);
732          if(stmt.forEachStmt.exp)
733             FreeList(stmt.forEachStmt.exp, FreeExpression);
734          if(stmt.forEachStmt.filter)
735             FreeList(stmt.forEachStmt.filter, FreeExpression);
736          if(stmt.forEachStmt.stmt)
737             FreeStatement(stmt.forEachStmt.stmt);
738          break;
739       }
740       case gotoStmt:
741          break;
742       case continueStmt:
743          break;
744       case breakStmt:
745          break;
746       case returnStmt:
747          if(stmt.expressions)
748             FreeList(stmt.expressions, FreeExpression);
749          break;
750       case watchStmt:
751       case fireWatchersStmt:
752       case stopWatchingStmt:
753       {
754          if(stmt._watch.watcher)
755             FreeExpression(stmt._watch.watcher);
756          if(stmt._watch.object)
757             FreeExpression(stmt._watch.object);
758          if(stmt._watch.watches)
759             FreeList(stmt._watch.watches, (stmt.type == watchStmt) ? FreePropertyWatch : FreeIdentifier);
760          break;
761       }
762    }
763    delete stmt;
764 }
765
766 void FreeInitializer(Initializer initializer)
767 {
768    switch(initializer.type)
769    {
770       case listInitializer:
771       {
772          FreeList(initializer.list, FreeInitializer);
773          break;
774       }
775       case expInitializer:
776          if(initializer.exp)
777             FreeExpression(initializer.exp);
778          break;
779    }
780    delete initializer;
781 }
782
783 void FreeInitDeclarator(InitDeclarator decl)
784 {
785    if(decl.declarator)
786       FreeDeclarator(decl.declarator);
787    if(decl.initializer)
788       FreeInitializer(decl.initializer);
789    delete decl;
790 }
791
792 void FreeDeclaration(Declaration decl)
793 {
794    if(decl.symbol && !decl.symbol.type)
795    {
796       //FreeSymbol(decl.symbol);
797    }
798    switch(decl.type)
799    {
800       case structDeclaration:
801       {
802          if(decl.specifiers)
803             FreeList(decl.specifiers, FreeSpecifier);
804          if(decl.declarators)
805             FreeList(decl.declarators, FreeDeclarator);
806          if(decl.extStorage)
807             FreeSpecifier(decl.extStorage);
808          break;
809       }
810       case initDeclaration:
811       {
812          if(decl.specifiers)
813             FreeList(decl.specifiers, FreeSpecifier);
814          if(decl.declarators)
815             FreeList(decl.declarators, FreeInitDeclarator);
816          break;
817       }
818       case instDeclaration:
819          if(decl.inst)
820             FreeInstance(decl.inst);
821          break;
822       case defineDeclaration:
823       {
824          if(decl.exp)
825             FreeExpression(decl.exp);
826          if(decl.id)
827             FreeIdentifier(decl.id);
828          break;
829       }
830    }
831    delete decl;
832 }
833
834 void FreeFunction(FunctionDefinition func)
835 {
836    if(func.body)
837       FreeStatement(func.body);
838    if(func.declarator)
839       FreeDeclarator(func.declarator);
840    if(func.specifiers)
841       FreeList(func.specifiers, FreeSpecifier);
842    if(func.declarations)
843       FreeList(func.declarations, FreeDeclaration);
844
845    if(func.type)
846       FreeType(func.type);
847
848    delete func;
849 }
850
851 void FreeMemberInit(MemberInit init)
852 {
853    if(init.initializer)
854       FreeInitializer(init.initializer);
855    if(init.identifiers)
856       FreeList(init.identifiers, FreeIdentifier);
857    delete init;
858 }
859
860 void FreeMembersInit(MembersInit init)
861 {
862    if(init.type == dataMembersInit && init.dataMembers)
863       FreeList(init.dataMembers, FreeMemberInit);
864
865    if(init.type == methodMembersInit && init.function)
866    {
867       FreeClassFunction(init.function);
868    }
869    delete init;
870 }
871
872 void FreeInstance(Instantiation inst)
873 {
874    if(inst.members)
875    {
876       FreeList(inst.members, FreeMembersInit);
877    }
878
879    if(inst.exp)
880       FreeExpression(inst.exp);
881
882    if(inst.data)
883    {
884       Symbol classSym = FindClass(inst._class.name);
885       Class _class = classSym ? classSym.registered : null;
886       if(_class)
887       {
888          if(_class.type == normalClass)
889          {
890             Instance instance = (Instance)inst.data;
891             delete instance;
892          }
893          else if(_class.type == noHeadClass)
894          {
895             if(_class.Destructor)
896                _class.Destructor((Instance)inst.data);
897             delete inst.data;
898          }
899          else if(_class.type == structClass)
900          {
901             delete inst.data;
902          }
903       }
904       else
905       {
906          Instance instance = (Instance)inst.data;
907          delete instance;
908       }
909    }
910
911    if(inst._class)
912       FreeSpecifier(inst._class);
913
914    // Free symbol?
915    // Free data;
916
917    delete inst;
918 }
919
920 public void FreeClassFunction(ClassFunction func)
921 {
922    // Tricky Stuff...
923    if(func.declarator && func.declarator.symbol)
924    {
925       //FreeSymbol(func.declarator.symbol);
926    }
927
928    if(func.type)
929       FreeType(func.type);
930
931    if(func.body)
932       FreeStatement(func.body);
933    if(func.declarator)
934       FreeDeclarator(func.declarator);
935    if(func.specifiers)
936       FreeList(func.specifiers, FreeSpecifier);
937    if(func.declarations)
938       FreeList(func.declarations, FreeDeclaration);
939
940    func.attached.Free(null);
941
942    delete func;
943 }
944
945 void FreeProperty(PropertyDef def)
946 {
947    if(def.specifiers)
948       FreeList(def.specifiers, FreeSpecifier);
949    if(def.declarator)
950       FreeDeclarator(def.declarator);
951    if(def.id)
952       FreeIdentifier(def.id);
953    if(def.getStmt)
954       FreeStatement(def.getStmt);
955    if(def.setStmt)
956       FreeStatement(def.setStmt);
957    if(def.issetStmt)
958       FreeStatement(def.issetStmt);
959    if(def.category)
960       FreeExpression(def.category);
961
962    /*
963    if(def.getFunction)
964       FreeFunction(def.getFunction);
965    if(def.setFunction)
966       FreeFunction(def.setFunction);
967    */
968    if(def.symbol)
969    {
970       // FreeSymbol(def.symbol);
971    }
972
973    delete def;
974 }
975
976 void FreeClassDef(ClassDef def)
977 {
978    switch(def.type)
979    {
980       case declarationClassDef:
981          if(def.decl)
982             FreeDeclaration(def.decl);
983          break;
984       case defaultPropertiesClassDef:
985       {
986          FreeList(def.defProperties, FreeMemberInit);
987          break;
988       }
989       case functionClassDef:
990          if(def.function)
991             FreeClassFunction(def.function);
992          break;
993       case propertyClassDef:
994          if(def.propertyDef)
995             FreeProperty(def.propertyDef);
996          break;
997       case classPropertyClassDef:
998          if(def.propertyDef)
999             FreeProperty(def.propertyDef);
1000          break;
1001       case accessOverrideClassDef:
1002          break;
1003       case classDataClassDef:
1004       {
1005          if(def.decl)
1006             FreeDeclaration(def.decl);
1007          break;
1008       }
1009       case classDesignerClassDef:
1010       {
1011          delete def.designer;
1012          break;
1013       }
1014       case classFixedClassDef:
1015          break;
1016       case classNoExpansionClassDef:
1017          break;
1018       case classPropertyValueClassDef:
1019          if(def.id)
1020             FreeIdentifier(def.id);
1021          if(def.initializer)
1022             FreeInitializer(def.initializer);
1023          break;
1024       case designerDefaultPropertyClassDef:
1025       {
1026          if(def.defaultProperty)
1027             FreeIdentifier(def.defaultProperty);
1028          break;
1029       }
1030       case memberAccessClassDef:
1031          break;
1032       case propertyWatchClassDef:
1033       {
1034          if(def.propertyWatch)
1035             FreePropertyWatch(def.propertyWatch);
1036          break;
1037       }
1038    }
1039    delete def;
1040 }
1041
1042 void FreeClass(ClassDefinition _class)
1043 {
1044    if(_class.definitions)
1045       FreeList(_class.definitions, FreeClassDef);
1046    if(_class._class)
1047       FreeSpecifier(_class._class);
1048    if(_class.baseSpecs)
1049       FreeList(_class.baseSpecs, FreeSpecifier);
1050
1051    delete _class;
1052 }
1053
1054 void FreeDBIndexItem(DBIndexItem item)
1055 {
1056    if(item.id)
1057       FreeIdentifier(item.id);
1058    delete item;
1059 }
1060
1061 void FreeDBTableEntry(DBTableEntry entry)
1062 {
1063    if(entry.id)
1064       FreeIdentifier(entry.id);
1065    switch(entry.type)
1066    {
1067       case fieldEntry:
1068          if(entry.dataType)
1069             FreeTypeName(entry.dataType);
1070          if(entry.name)
1071             delete entry.name;
1072          break;
1073       case indexEntry:
1074          if(entry.items)
1075             FreeList(entry.items, FreeDBIndexItem);
1076          break;
1077    }
1078    delete entry;
1079 }
1080
1081 void FreeDBTable(DBTableDef table)
1082 {
1083    if(table.definitions)
1084       FreeList(table.definitions, FreeDBTableEntry);
1085    /*if(table.symbol)
1086       FreeIdentifier(table.symbol);*/
1087    if(table.name)
1088       delete table.name;
1089    delete table;
1090 }
1091
1092 void FreeExternal(External external)
1093 {
1094    switch(external.type)
1095    {
1096       case functionExternal:
1097          if(external.function)
1098             FreeFunction(external.function);
1099          break;
1100       case declarationExternal:
1101          if(external.declaration)
1102             FreeDeclaration(external.declaration);
1103          break;
1104       case classExternal:
1105          if(external._class)
1106             FreeClass(external._class);
1107          break;
1108       case importExternal:
1109          delete external.importString;
1110          break;
1111       case nameSpaceExternal:
1112          FreeIdentifier(external.id);
1113          break;
1114       case dbtableExternal:
1115          if(external.table)
1116             FreeDBTable(external.table);
1117          break;
1118    }
1119    delete external;
1120 }
1121
1122 public void FreeASTTree(OldList ast)
1123 {
1124    if(ast != null)
1125    {
1126       External external;
1127       while(external = ast.first)
1128       {
1129          ast.Remove(external);
1130          FreeExternal(external);
1131       }
1132       delete ast;
1133    }
1134 }
1135
1136 static void FreeDataMember(DataMember parentMember)
1137 {
1138    DataMember dataMember;
1139
1140    for(dataMember = parentMember.members.first; dataMember; dataMember = dataMember.next)
1141    {
1142       if(dataMember.type == structMember || dataMember.type == unionMember)
1143          FreeDataMember(dataMember);
1144
1145       if(dataMember.dataType)
1146       {
1147          FreeType(dataMember.dataType);
1148          dataMember.dataType = null;
1149       }
1150    }
1151 }
1152
1153 static void FreeClassProperties(ClassProperty classProp)
1154 {
1155    if(classProp.left) FreeClassProperties(classProp.left);
1156    if(classProp.right) FreeClassProperties(classProp.right);
1157    if(classProp.dataType)
1158    {
1159       FreeType(classProp.dataType);
1160       classProp.dataType = null;
1161    }
1162 }
1163
1164 void FreeModuleData(Module module)
1165 {
1166    Class _class;
1167    GlobalFunction function;
1168
1169    // Unload classes
1170    for(_class = module.classes.first; _class; _class = _class.next)
1171    {
1172       DataMember dataMember;
1173       Method method;
1174       ClassTemplateParameter param;
1175       ClassProperty classProp;
1176
1177       if(_class.dataType)
1178       {
1179          FreeType(_class.dataType);
1180          _class.dataType = null;
1181       }
1182       for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
1183       {
1184          if(dataMember.isProperty)
1185          {
1186             Property prop = (Property)dataMember;
1187             if(prop.symbol)
1188             {
1189                FreeSymbol(prop.symbol);
1190             }
1191          }
1192          else
1193          {
1194             if(dataMember.type == structMember || dataMember.type == unionMember)
1195                FreeDataMember(dataMember);
1196          }
1197          if(dataMember.dataType)
1198          {
1199             FreeType(dataMember.dataType);
1200             dataMember.dataType = null;
1201          }
1202       }
1203       for(dataMember = _class.conversions.first; dataMember; dataMember = dataMember.next)
1204       {
1205          Property prop = (Property) dataMember;
1206          if(prop.symbol)
1207          {
1208             FreeSymbol(prop.symbol);
1209          }
1210          if(prop.dataType)
1211          {
1212             FreeType(prop.dataType);
1213             prop.dataType = null;
1214          }
1215       }
1216       if(_class.classProperties.first)
1217          FreeClassProperties((ClassProperty)_class.classProperties.first);
1218       for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next)
1219       {
1220          if(method.dataType)
1221          {
1222             FreeType(method.dataType);
1223             method.dataType = null;
1224          }
1225
1226          if(method.symbol)
1227          {
1228             FreeSymbol(method.symbol);
1229          }
1230       }
1231       for(param = _class.templateParams.first; param; param = param.next)
1232       {
1233          if(param.param)
1234          {
1235             FreeTemplateParameter(param.param);
1236             param.param = null;
1237          }
1238       }
1239    }
1240
1241    for(function = module.functions.first; function; function = function.next)
1242    {
1243       if(function.dataType)
1244          FreeType(function.dataType);
1245       if(function.symbol)
1246          FreeSymbol(function.symbol);
1247    }
1248
1249    // Free the extra module instance on closing the last code editor using it
1250    if(!inCompiler)
1251    {
1252       MapIterator <String, List<Module> > mapIt { map = loadedModules };
1253       while(mapIt.Next())
1254       {
1255          List<Module> list = mapIt.data;
1256          Iterator<Module> it { list };
1257          bool found = false;
1258          while(it.Next())
1259          {
1260             if(it.data == module)
1261             {
1262                list.Remove(it.pointer);
1263                found = true;
1264                break;
1265             }
1266          }
1267          if(found)
1268          {
1269             if(list.count == 1)
1270             {
1271                // Unload the initial module that we loaded for safe sharing
1272                Module mod = list[0];
1273                list.Remove(list.GetFirst());
1274                loadedModules.Remove(mapIt.pointer);
1275                delete list;
1276                eModule_Unload(__thisModule.application, mod);
1277             }
1278             break;
1279          }
1280       }
1281    }
1282 }
1283
1284 public void FreeTypeData(Module privateModule)
1285 {
1286    Module m;
1287    for(m = privateModule.application.allModules.first; m; m = m.next)
1288    {
1289       FreeModuleData(m);
1290    }
1291    FreeModuleData(privateModule);
1292 }