compiler/grammar: Added support for extended declarator in between struct and identifier
[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 FreeStatement(Statement stmt)
597 {
598    switch(stmt.type)
599    {
600       case labeledStmt:
601          if(stmt.labeled.stmt)
602             FreeStatement(stmt.labeled.stmt);
603          break;
604       case caseStmt:
605          if(stmt.caseStmt.exp)
606             FreeExpression(stmt.caseStmt.exp);
607          if(stmt.caseStmt.stmt)
608             FreeStatement(stmt.caseStmt.stmt);
609          break;
610       case badDeclarationStmt:
611          FreeDeclaration(stmt.decl);
612          break;
613       case compoundStmt:
614       {
615          if(stmt.compound.declarations)
616             FreeList(stmt.compound.declarations, FreeDeclaration);
617          if(stmt.compound.statements)
618             FreeList(stmt.compound.statements, FreeStatement);
619          if(stmt.compound.context)
620          {
621             FreeContext(stmt.compound.context);
622             delete stmt.compound.context;
623          }
624          break;
625       }
626       case expressionStmt:
627       {
628          if(stmt.expressions)
629             FreeList(stmt.expressions, FreeExpression);
630          break;
631       }
632       case ifStmt:
633       {
634          if(stmt.ifStmt.exp)
635             FreeList(stmt.ifStmt.exp, FreeExpression);
636          if(stmt.ifStmt.stmt)
637             FreeStatement(stmt.ifStmt.stmt);
638          if(stmt.ifStmt.elseStmt)
639             FreeStatement(stmt.ifStmt.elseStmt);
640          break;
641       }
642       case switchStmt:
643       {
644          if(stmt.switchStmt.exp)
645             FreeList(stmt.switchStmt.exp, FreeExpression);
646          if(stmt.switchStmt.stmt)
647             FreeStatement(stmt.switchStmt.stmt);
648          break;
649       }
650       case whileStmt:
651       {
652          if(stmt.whileStmt.exp)
653             FreeList(stmt.whileStmt.exp, FreeExpression);
654          if(stmt.whileStmt.stmt)
655             FreeStatement(stmt.whileStmt.stmt);
656          break;
657       }
658       case doWhileStmt:
659       {
660          if(stmt.doWhile.stmt)
661             FreeStatement(stmt.doWhile.stmt);
662
663          if(stmt.doWhile.exp)
664             FreeList(stmt.doWhile.exp, FreeExpression);
665          break;
666       }
667       case forStmt:
668       {
669          if(stmt.forStmt.init)
670             FreeStatement(stmt.forStmt.init);
671          
672          if(stmt.forStmt.check)
673             FreeStatement(stmt.forStmt.check);
674          
675          if(stmt.forStmt.increment)
676             FreeList(stmt.forStmt.increment, FreeExpression);
677          if(stmt.forStmt.stmt)
678             FreeStatement(stmt.forStmt.stmt);
679          break;
680       }
681       case forEachStmt:
682       {
683          if(stmt.forEachStmt.id)
684             FreeIdentifier(stmt.forEachStmt.id);
685          if(stmt.forEachStmt.exp)
686             FreeList(stmt.forEachStmt.exp, FreeExpression);
687          if(stmt.forEachStmt.filter)
688             FreeList(stmt.forEachStmt.filter, FreeExpression);
689          if(stmt.forEachStmt.stmt)
690             FreeStatement(stmt.forEachStmt.stmt);
691          break;
692       }
693       case gotoStmt:
694          break;
695       case continueStmt:
696          break;
697       case breakStmt:
698          break;
699       case returnStmt:
700          if(stmt.expressions)
701             FreeList(stmt.expressions, FreeExpression);
702          break;
703       case watchStmt:
704       case fireWatchersStmt:
705       case stopWatchingStmt:
706       {
707          if(stmt._watch.watcher)
708             FreeExpression(stmt._watch.watcher);
709          if(stmt._watch.object)
710             FreeExpression(stmt._watch.object);
711          if(stmt._watch.watches)
712             FreeList(stmt._watch.watches, (stmt.type == watchStmt) ? FreePropertyWatch : FreeIdentifier);
713          break;
714       }
715    }
716    delete stmt;
717 }
718
719 void FreeInitializer(Initializer initializer)
720 {
721    switch(initializer.type)
722    {
723       case listInitializer:
724       {
725          FreeList(initializer.list, FreeInitializer);
726          break;
727       }
728       case expInitializer:
729          if(initializer.exp)
730             FreeExpression(initializer.exp);
731          break;
732    }
733    delete initializer;
734 }
735
736 void FreeInitDeclarator(InitDeclarator decl)
737 {
738    if(decl.declarator)
739       FreeDeclarator(decl.declarator);
740    if(decl.initializer)
741       FreeInitializer(decl.initializer);
742    delete decl;
743 }
744
745 void FreeDeclaration(Declaration decl)
746 {
747    if(decl.symbol && !decl.symbol.type)
748    {
749       //FreeSymbol(decl.symbol);
750    }
751    switch(decl.type)
752    {
753       case structDeclaration:
754       {
755          if(decl.specifiers)
756             FreeList(decl.specifiers, FreeSpecifier);
757          if(decl.declarators)
758             FreeList(decl.declarators, FreeDeclarator);
759          if(decl.extStorage)
760             FreeSpecifier(decl.extStorage);
761          break;
762       }
763       case initDeclaration:
764       {
765          if(decl.specifiers)
766             FreeList(decl.specifiers, FreeSpecifier);
767          if(decl.declarators)
768             FreeList(decl.declarators, FreeInitDeclarator);
769          break;
770       }
771       case instDeclaration:
772          if(decl.inst)
773             FreeInstance(decl.inst);
774          break;
775       case defineDeclaration:
776       {
777          if(decl.exp)
778             FreeExpression(decl.exp);
779          if(decl.id)
780             FreeIdentifier(decl.id);
781          break;
782       }
783    }
784    delete decl;
785 }
786
787 void FreeFunction(FunctionDefinition func)
788 {
789    if(func.body)
790       FreeStatement(func.body);
791    if(func.declarator)
792       FreeDeclarator(func.declarator);
793    if(func.specifiers)
794       FreeList(func.specifiers, FreeSpecifier);
795    if(func.declarations)
796       FreeList(func.declarations, FreeDeclaration);
797
798    if(func.type)
799       FreeType(func.type);
800
801    delete func;
802 }
803
804 void FreeMemberInit(MemberInit init)
805 {
806    if(init.initializer)
807       FreeInitializer(init.initializer);
808    if(init.identifiers)
809       FreeList(init.identifiers, FreeIdentifier);
810    delete init;
811 }
812
813 void FreeMembersInit(MembersInit init)
814 {
815    if(init.type == dataMembersInit && init.dataMembers)
816       FreeList(init.dataMembers, FreeMemberInit);
817
818    if(init.type == methodMembersInit && init.function)
819    {
820       FreeClassFunction(init.function);
821    }
822    delete init;
823 }
824
825 void FreeInstance(Instantiation inst)
826 {
827    if(inst.members)
828    {
829       FreeList(inst.members, FreeMembersInit);
830    }
831
832    if(inst.exp)
833       FreeExpression(inst.exp);
834
835    if(inst.data)
836    {
837       Symbol classSym = FindClass(inst._class.name);
838       Class _class = classSym ? classSym.registered : null;
839       if(_class)
840       {
841          if(_class.type == normalClass)
842          {
843             Instance instance = (Instance)inst.data;
844             delete instance;
845          }
846          else if(_class.type == noHeadClass)
847          {
848             if(_class.Destructor)
849                _class.Destructor((Instance)inst.data);
850             delete inst.data;
851          }
852          else if(_class.type == structClass)
853          {
854             delete inst.data;
855          }
856       }
857       else
858       {
859          Instance instance = (Instance)inst.data;
860          delete instance;
861       }
862    }
863
864    if(inst._class)
865       FreeSpecifier(inst._class);
866    
867    // Free symbol?
868    // Free data;
869
870    delete inst;
871 }
872
873 public void FreeClassFunction(ClassFunction func)
874 {
875    // Tricky Stuff...
876    if(func.declarator && func.declarator.symbol)
877    {
878       //FreeSymbol(func.declarator.symbol);
879    }
880
881    if(func.type)
882       FreeType(func.type);
883
884    if(func.body)
885       FreeStatement(func.body);
886    if(func.declarator)
887       FreeDeclarator(func.declarator);
888    if(func.specifiers)
889       FreeList(func.specifiers, FreeSpecifier);
890    if(func.declarations)
891       FreeList(func.declarations, FreeDeclaration);
892
893    func.attached.Free(null);
894
895    delete func;
896 }
897
898 void FreeProperty(PropertyDef def)
899 {
900    if(def.specifiers)
901       FreeList(def.specifiers, FreeSpecifier);
902    if(def.declarator)
903       FreeDeclarator(def.declarator);
904    if(def.id)
905       FreeIdentifier(def.id);
906    if(def.getStmt)
907       FreeStatement(def.getStmt);
908    if(def.setStmt)
909       FreeStatement(def.setStmt);
910    if(def.issetStmt)
911       FreeStatement(def.issetStmt);
912    if(def.category)
913       FreeExpression(def.category);
914    
915    /*
916    if(def.getFunction)
917       FreeFunction(def.getFunction);
918    if(def.setFunction)
919       FreeFunction(def.setFunction);
920    */
921    if(def.symbol)
922    {
923       // FreeSymbol(def.symbol);
924    }
925
926    delete def;
927 }
928
929 void FreeClassDef(ClassDef def)
930 {
931    switch(def.type)
932    {
933       case declarationClassDef:
934          if(def.decl)
935             FreeDeclaration(def.decl);
936          break;
937       case defaultPropertiesClassDef:
938       {
939          FreeList(def.defProperties, FreeMemberInit);
940          break;
941       }
942       case functionClassDef:
943          if(def.function)
944             FreeClassFunction(def.function);
945          break;
946       case propertyClassDef:
947          if(def.propertyDef)
948             FreeProperty(def.propertyDef);
949          break;
950       case classPropertyClassDef:
951          if(def.propertyDef)
952             FreeProperty(def.propertyDef);
953          break;
954       case accessOverrideClassDef:
955          break;
956       case classDataClassDef:
957       {
958          if(def.decl)
959             FreeDeclaration(def.decl);
960          break;
961       }
962       case classDesignerClassDef:
963       {
964          delete def.designer;
965          break;
966       }
967       case classFixedClassDef:
968          break;
969       case classNoExpansionClassDef:
970          break;
971       case classPropertyValueClassDef:
972          if(def.id)
973             FreeIdentifier(def.id);
974          if(def.initializer)
975             FreeInitializer(def.initializer);
976          break;
977       case designerDefaultPropertyClassDef:
978       {
979          if(def.defaultProperty)
980             FreeIdentifier(def.defaultProperty);
981          break;
982       }
983       case memberAccessClassDef:
984          break;
985       case propertyWatchClassDef:
986       {
987          if(def.propertyWatch)
988             FreePropertyWatch(def.propertyWatch);
989          break;
990       }
991    }
992    delete def;
993 }
994
995 void FreeClass(ClassDefinition _class)
996 {
997    if(_class.definitions)
998       FreeList(_class.definitions, FreeClassDef);
999    if(_class._class)
1000       FreeSpecifier(_class._class);
1001    if(_class.baseSpecs)
1002       FreeList(_class.baseSpecs, FreeSpecifier);
1003
1004    delete _class;
1005 }
1006
1007 void FreeDBIndexItem(DBIndexItem item)
1008 {
1009    if(item.id)
1010       FreeIdentifier(item.id);
1011    delete item;
1012 }
1013
1014 void FreeDBTableEntry(DBTableEntry entry)
1015 {
1016    if(entry.id)
1017       FreeIdentifier(entry.id);
1018    switch(entry.type)
1019    {
1020       case fieldEntry:
1021          if(entry.dataType)
1022             FreeTypeName(entry.dataType);
1023          if(entry.name)
1024             delete entry.name;
1025          break;
1026       case indexEntry:
1027          if(entry.items)
1028             FreeList(entry.items, FreeDBIndexItem);
1029          break;
1030    }
1031    delete entry;
1032 }
1033
1034 void FreeDBTable(DBTableDef table)
1035 {
1036    if(table.definitions)
1037       FreeList(table.definitions, FreeDBTableEntry);
1038    /*if(table.symbol)
1039       FreeIdentifier(table.symbol);*/
1040    if(table.name)
1041       delete table.name;
1042    delete table;
1043 }
1044
1045 void FreeExternal(External external)
1046 {
1047    switch(external.type)
1048    {
1049       case functionExternal: 
1050          if(external.function)
1051             FreeFunction(external.function);
1052          break;
1053       case declarationExternal: 
1054          if(external.declaration)
1055             FreeDeclaration(external.declaration);
1056          break;
1057       case classExternal: 
1058          if(external._class)
1059             FreeClass(external._class);
1060          break;
1061       case importExternal:
1062          delete external.importString;
1063          break;
1064       case nameSpaceExternal:
1065          FreeIdentifier(external.id);
1066          break;
1067       case dbtableExternal:
1068          if(external.table)
1069             FreeDBTable(external.table);
1070          break;
1071    }
1072    delete external;
1073 }
1074
1075 public void FreeASTTree(OldList ast)
1076 {
1077    if(ast != null)
1078    {
1079       External external;
1080       while(external = ast.first)
1081       {
1082          ast.Remove(external);
1083          FreeExternal(external);
1084       }
1085       delete ast;
1086    }
1087 }
1088
1089 static void FreeDataMember(DataMember parentMember)
1090 {
1091    DataMember dataMember;
1092
1093    for(dataMember = parentMember.members.first; dataMember; dataMember = dataMember.next)
1094    {
1095       if(dataMember.type == structMember || dataMember.type == unionMember)
1096          FreeDataMember(dataMember);
1097
1098       if(dataMember.dataType)
1099       {
1100          FreeType(dataMember.dataType);
1101          dataMember.dataType = null;
1102       }
1103    }
1104 }
1105
1106 void FreeModuleData(Module module)
1107 {
1108    Class _class;
1109    GlobalFunction function;
1110    
1111    // Unload classes
1112    for(_class = module.classes.first; _class; _class = _class.next)
1113    {
1114       DataMember dataMember;
1115       Method method;
1116       ClassTemplateParameter param;
1117       ClassProperty classProp;
1118
1119       if(_class.dataType)
1120       {
1121          FreeType(_class.dataType);
1122          _class.dataType = null;
1123       }
1124       for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
1125       {
1126          if(dataMember.isProperty)
1127          {
1128             Property prop = (Property)dataMember;
1129             if(prop.symbol)
1130             {
1131                FreeSymbol(prop.symbol);
1132             }
1133          }
1134          else
1135          {
1136             if(dataMember.type == structMember || dataMember.type == unionMember)
1137                FreeDataMember(dataMember);
1138          }
1139          if(dataMember.dataType)
1140          {
1141             FreeType(dataMember.dataType);
1142             dataMember.dataType = null;
1143          }
1144       }
1145       for(dataMember = _class.conversions.first; dataMember; dataMember = dataMember.next)
1146       {
1147          Property prop = (Property) dataMember;
1148          if(prop.symbol)
1149          {
1150             FreeSymbol(prop.symbol);
1151          }
1152          if(prop.dataType)
1153          {
1154             FreeType(prop.dataType);
1155             prop.dataType = null;
1156          }
1157       }
1158       for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next)
1159       {
1160          if(method.dataType)
1161          {
1162             FreeType(method.dataType);
1163             method.dataType = null;
1164          }
1165
1166          if(method.symbol)
1167          {
1168             FreeSymbol(method.symbol);
1169          }
1170       }
1171       for(param = _class.templateParams.first; param; param = param.next)
1172       {
1173          if(param.param)
1174          {
1175             FreeTemplateParameter(param.param);
1176             param.param = null;
1177          }
1178       }
1179    }
1180    
1181    for(function = module.functions.first; function; function = function.next)
1182    {
1183       if(function.dataType) 
1184          FreeType(function.dataType);
1185       if(function.symbol) 
1186          FreeSymbol(function.symbol);
1187    }
1188
1189    // Free the extra module instance on closing the last code editor using it
1190    if(!inCompiler)
1191    {
1192       MapIterator <String, List<Module> > mapIt { map = loadedModules };
1193       while(mapIt.Next())
1194       {
1195          List<Module> list = mapIt.data;
1196          Iterator<Module> it { list };
1197          bool found = false;
1198          while(it.Next())
1199          {
1200             if(it.data == module)
1201             {
1202                list.Remove(it.pointer);
1203                found = true;
1204                break;
1205             }
1206          }
1207          if(found)
1208          {
1209             if(list.count == 1)
1210             {
1211                // Unload the initial module that we loaded for safe sharing
1212                Module mod = list[0];
1213                list.Remove(list.GetFirst());
1214                loadedModules.Remove(mapIt.pointer);
1215                delete list;
1216                eModule_Unload(__thisModule, mod);
1217             }
1218             break;
1219          }
1220       }
1221    }
1222 }
1223
1224 public void FreeTypeData(Module privateModule)
1225 {
1226    Module m;
1227    for(m = privateModule.application.allModules.first; m; m = m.next)
1228    {
1229       FreeModuleData(m);
1230    }
1231    FreeModuleData(privateModule);
1232 }