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