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