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