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