b4a84bc0b947782006199e105b8a8419a198091a
[sdk] / compiler / libec / src / pass3.ec
1 import "ecdefs"
2
3 #define YYLTYPE Location
4 #include "grammar.h"
5
6 extern External curExternal;
7 ///////////////// INSTANCE DECLARATION PASS ///////////////////////
8
9 // Returns true if we should add a * to the declarator
10 static int ReplaceClassSpec(OldList specs, Specifier spec, bool param)
11 {
12    if(spec.type == templateTypeSpecifier)
13    {
14       TemplateParameter parameter = spec.templateParameter;
15
16       if(!param && parameter.dataTypeString)
17       {
18          OldList * newSpecs = MkList();
19          Declarator decl = SpecDeclFromString(parameter.dataTypeString, newSpecs, null);
20          if(newSpecs->first)
21          {
22             Specifier newSpec = CopySpecifier(newSpecs->first);
23             *spec = *newSpec;
24             delete newSpec;
25          }
26          FreeList(newSpecs, FreeSpecifier);
27
28          if(decl)
29          {
30             bool isPointer = decl.type == pointerDeclarator;
31             if(decl)
32                FreeDeclarator(decl);
33             if(isPointer)
34                return 1;
35          }
36       }
37       else if(!param && parameter.dataType)
38       {
39          OldList * newSpecs = parameter.dataType.specifiers;
40          Declarator decl = parameter.dataType.decl;
41          if(newSpecs->first)
42          {
43             Specifier newSpec = CopySpecifier(newSpecs->first);
44             *spec = *newSpec;
45             delete newSpec;
46          }
47
48          if(decl)
49          {
50             bool isPointer = decl.type == pointerDeclarator;
51             if(isPointer)
52                return 1;
53          }
54       }
55       else
56       {
57          spec.type = nameSpecifier;
58          spec.name = CopyString("uint64");
59          spec.symbol = FindClass("uint64");
60       }
61    }
62
63    if(spec.type == nameSpecifier || spec.type == subClassSpecifier)
64    {
65       // TODO: Apply more care because nameSpecifier / subClassSpecifier use different parts of the union!
66       Symbol classSym = spec.symbol;
67       if(spec.type == subClassSpecifier)
68       {
69          classSym = FindClass("ecere::com::Class");
70       }
71
72       if(classSym)
73       {
74          Class _class = classSym.registered;
75
76          FreeSpecifierContents(spec);
77
78          spec.type = nameSpecifier;
79          if(_class && _class.type == structClass)
80          {
81             //Externalexternal;
82             char name[1024];
83             name[0] = 0;
84             FullClassNameCat(name, _class.fullName, false);
85             FreeSpecifierContents(spec);
86             spec.type = structSpecifier;
87             spec.baseSpecs = null;
88             spec.id = MkIdentifier(name);
89             spec.list = null;
90             spec.definitions = null;
91             spec.ctx = null;
92             spec.addNameSpace = false;
93          }
94          else if(_class && _class.type == noHeadClass)
95          {
96             char name[1024] = "";
97             FullClassNameCat(name, _class.fullName, false);
98             spec.type = structSpecifier;
99             spec.baseSpecs = null;
100             spec.id = MkIdentifier(name);
101             spec.list = null;
102             spec.definitions = null;
103             spec.ctx = null;
104             spec.addNameSpace = false;
105          }
106          else if(_class)
107          {
108             if((_class.type != systemClass ||
109                !strcmp(_class.fullName, "enum") ||
110                (_class.dataTypeString && !strcmp(_class.dataTypeString, "char *")) ||
111                //strcmp(_class.fullName, "bool") &&
112                !strcmp(_class.fullName, "uint64") ||
113                !strcmp(_class.fullName, "uint32") ||
114                !strcmp(_class.fullName, "uint16") ||
115                !strcmp(_class.fullName, "uintptr") ||
116                !strcmp(_class.fullName, "intptr") ||
117                !strcmp(_class.fullName, "uintsize") ||
118                !strcmp(_class.fullName, "intsize") ||
119                !strcmp(_class.fullName, "uint") ||
120                !strcmp(_class.fullName, "byte")))
121             {
122                if(_class.dataTypeString)
123                {
124                   if(!strcmp(_class.dataTypeString, "uint64") ||
125                      !strcmp(_class.dataTypeString, "uint32") ||
126                      !strcmp(_class.dataTypeString, "uint16") ||
127                      !strcmp(_class.dataTypeString, "uintptr") ||
128                      !strcmp(_class.dataTypeString, "intptr") ||
129                      !strcmp(_class.dataTypeString, "uintsize") ||
130                      !strcmp(_class.dataTypeString, "intsize") ||
131                      !strcmp(_class.dataTypeString, "uint") ||
132                      !strcmp(_class.dataTypeString, "byte"))
133                   {
134                      if(!_class.dataType)
135                         _class.dataType = ProcessTypeString(_class.dataTypeString, false);
136                      if(_class.dataType && _class.dataType.kind == classType)
137                         classSym = _class.dataType._class;
138                      else
139                         classSym = FindClass(_class.dataTypeString);
140                      _class = classSym ? classSym.registered : null;
141                   }
142
143                   spec.name = CopyString(!strcmp(_class.dataTypeString, "char *") ? "char" : _class.dataTypeString);
144                   spec.symbol = null;
145                }
146                else
147                {
148                   spec.name = CopyString(null);
149                   spec.symbol = null;
150                }
151             }
152             else if(!_class.base)
153             {
154                spec.type = baseSpecifier;
155                spec.specifier = VOID;
156                return 1;
157             }
158          }
159          else
160          {
161             spec.type = structSpecifier;
162             spec.id = MkIdentifier("__ecereNameSpace__ecere__com__Instance");
163             spec.list = null;
164             spec.baseSpecs = null;
165             spec.definitions = null;
166             spec.ctx = null;
167             spec.addNameSpace = false;
168          }
169
170          if(_class && _class.dataTypeString && !strcmp(_class.dataTypeString, "char *"))
171             return 1; //false;
172          if(!_class || _class.type == normalClass || _class.type == noHeadClass)
173             return 1;
174          else if(param && _class.type == structClass)
175             return 2;
176       }
177    }
178    else if(spec.type == baseSpecifier)
179    {
180       if(spec.specifier == ANY_OBJECT)
181       {
182          spec.specifier = VOID;
183          return 1;
184       }
185    }
186    return 0;
187 }
188
189 static void ReplaceByInstancePtr(Specifier spec, Declarator * declPtr, int type)
190 {
191    Declarator decl = *declPtr;
192    if(decl && decl.type == pointerDeclarator)
193    {
194       // Pointers to simple classes shouldn't be added pointers
195       if(type == 2);
196       else
197       // Add pointer
198          decl.pointer.pointer = MkPointer(null, decl.pointer.pointer);
199    }
200    else
201    {
202       Declarator newDecl { };
203       if(decl)
204       {
205          *newDecl = *decl;
206          decl.declarator = newDecl;
207       }
208       else
209          decl = newDecl;
210       decl.type = pointerDeclarator;
211       decl.pointer.pointer = MkPointer(null, null);
212       *declPtr = decl;
213    }
214 }
215
216 static void InstDeclPassSpecifier(Specifier spec)
217 {
218    switch(spec.type)
219    {
220       case baseSpecifier:
221          if(spec.specifier == TYPED_OBJECT)
222          {
223             spec.type = extendedSpecifier;
224             spec.extDecl = MkExtDeclString(CopyString("struct __ecereNameSpace__ecere__com__Class * class, void *"));
225          }
226          break;
227       case nameSpecifier:
228          break;
229       case enumSpecifier:
230       {
231          Enumerator e;
232          if(spec.list)
233          {
234             for(e = spec.list->first; e; e = e.next)
235             {
236
237             }
238          }
239          break;
240       }
241       case structSpecifier:
242       case unionSpecifier:
243       {
244          if(spec.definitions)
245          {
246             ClassDef def;
247             for(def = spec.definitions->first; def; def = def.next)
248                if(def.decl)
249                   InstDeclPassDeclaration(def.decl);
250          }
251          if(spec.id)
252             InstDeclPassIdentifier(spec.id);
253          break;
254       }
255       case extendedSpecifier:
256          if(spec.extDecl && spec.extDecl.type == extDeclString && spec.extDecl.s)
257          {
258             if(!strcmp(spec.extDecl.s, "dllexport"))
259             {
260                Specifier prevSpec;
261                delete spec.extDecl.s;
262                for(prevSpec = spec.prev; prevSpec; prevSpec = prevSpec.prev)
263                   if(prevSpec.type == baseSpecifier && prevSpec.specifier == EXTERN)
264                      break;
265                if(prevSpec)
266                {
267                   if(targetPlatform == win32)
268                      spec.extDecl.s = CopyString("__declspec(dllexport)");
269                   else
270                      spec.extDecl.s = CopyString("__attribute__ ((visibility(\"default\")))");
271                }
272                else
273                {
274                   if(targetPlatform == win32)
275                      spec.extDecl.s = CopyString("extern __declspec(dllexport)");
276                   else
277                      spec.extDecl.s = CopyString("extern __attribute__ ((visibility(\"default\")))");
278                }
279             }
280             else if(!strcmp(spec.extDecl.s, "stdcall") || !strcmp(spec.extDecl.s, "_stdcall") ||
281                !strcmp(spec.extDecl.s, "__stdcall") || !strcmp(spec.extDecl.s, "__stdcall__"))
282             {
283                delete spec.extDecl.s;
284                if(targetPlatform == win32)
285                   spec.extDecl.s = CopyString("__attribute__((__stdcall__))");
286                else
287                   spec.extDecl.s = CopyString("");
288             }
289          }
290          break;
291    }
292 }
293
294 static void InstDeclPassDeclarator(Declarator decl)
295 {
296    switch(decl.type)
297    {
298       case structDeclarator:
299          if(decl.declarator)
300             InstDeclPassDeclarator(decl.declarator);
301          break;
302       case identifierDeclarator:
303       {
304          if(decl.identifier)
305             InstDeclPassIdentifier(decl.identifier);
306          break;
307       }
308       case bracketsDeclarator:
309          if(decl.declarator)
310             InstDeclPassDeclarator(decl.declarator);
311          break;
312       case arrayDeclarator:
313          if(decl.declarator)
314             InstDeclPassDeclarator(decl.declarator);
315          break;
316       case functionDeclarator:
317       {
318          if(decl.declarator)
319             InstDeclPassDeclarator(decl.declarator);
320          if(decl.function.parameters)
321          {
322             TypeName type;
323             if(decl.declarator)
324                InstDeclPassDeclarator(decl.declarator);
325             for(type = decl.function.parameters->first; type; type = type.next)
326             {
327                bool typedObject = false;
328                Specifier spec = null;
329                if(type.qualifiers)
330                {
331                   spec = (Specifier)type.qualifiers->first;
332                   if(spec && spec.type == nameSpecifier && !strcmp(spec.name, "class"))
333                      typedObject = true;
334                }
335
336                InstDeclPassTypeName(type, true);
337                if(typedObject)
338                {
339                   TypeName _class
340                   {
341                      qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
342                      declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
343                   };
344                   decl.function.parameters->Insert(spec.prev, _class);
345                }
346             }
347          }
348          break;
349       }
350       case pointerDeclarator:
351       case extendedDeclarator:
352       case extendedDeclaratorEnd:
353          if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended)
354          {
355             if(decl.extended.extended.type == extDeclString && decl.extended.extended.s && !strcmp(decl.extended.extended.s, "dllexport"))
356             {
357                delete decl.extended.extended.s;
358                if(targetPlatform == win32)
359                   decl.extended.extended.s = CopyString("extern __declspec(dllexport)");
360                else
361                   decl.extended.extended.s = CopyString("extern __attribute__ ((visibility(\"default\")))");
362             }
363             else if(decl.extended.extended.type == extDeclString && decl.extended.extended.s &&
364                (!strcmp(decl.extended.extended.s, "stdcall") || !strcmp(decl.extended.extended.s, "_stdcall") ||
365                !strcmp(decl.extended.extended.s, "__stdcall") || !strcmp(decl.extended.extended.s, "__stdcall__")))
366             {
367                delete decl.extended.extended.s;
368                if(targetPlatform == win32)
369                   decl.extended.extended.s = CopyString("__attribute__((__stdcall__))");
370                else
371                   decl.extended.extended.s = CopyString("");
372             }
373          }
374          if(decl.declarator)
375             InstDeclPassDeclarator(decl.declarator);
376          break;
377    }
378 }
379
380 /*static */void InstDeclPassTypeName(TypeName type, bool param)
381 {
382    if(type.qualifiers)
383    {
384       Specifier spec;
385       for(spec = type.qualifiers->first; spec; spec = spec.next)
386       {
387          int result;
388          if((result = ReplaceClassSpec(type.qualifiers, spec, param)))
389             ReplaceByInstancePtr(spec, &type.declarator, result);
390          else
391          {
392             Symbol classSym = (spec.type == nameSpecifier) ? spec.symbol /*FindClass(spec.name)*/ : null;
393             if(type.classObjectType && (!classSym || (classSym && classSym.registered &&
394                (classSym.registered.type == enumClass || classSym.registered.type == bitClass || classSym.registered.type == unitClass))))
395                ReplaceByInstancePtr(spec, &type.declarator, 2);
396          }
397          InstDeclPassSpecifier(spec);
398       }
399    }
400    if(type.declarator)
401       InstDeclPassDeclarator(type.declarator);
402 }
403
404 static void InstDeclPassIdentifier(Identifier id)
405 {
406    if(strchr(id.string, ':'))
407    {
408       char newID[1024];
409       int c;
410       char ch;
411       int len;
412       strcpy(newID, "__ecereNameSpace__");
413       len = strlen(newID);
414
415       for(c = 0; (ch = id.string[c]); c++)
416       {
417          if(ch == ':') ch = '_';
418
419          newID[len++] = ch;
420       }
421       newID[len] = 0;
422       delete id.string;
423       id.string = CopyString(newID);
424    }
425 }
426
427 static void InstDeclPassExpression(Expression exp)
428 {
429    switch(exp.type)
430    {
431       case identifierExp:
432       {
433          if(exp.identifier)
434             InstDeclPassIdentifier(exp.identifier);
435          break;
436       }
437       case constantExp:
438          break;
439       case stringExp:
440          break;
441       case opExp:
442          if(exp.op.exp1)
443             InstDeclPassExpression(exp.op.exp1);
444          if(exp.op.exp2)
445             InstDeclPassExpression(exp.op.exp2);
446          break;
447       case extensionExpressionExp:
448       case bracketsExp:
449       {
450          Expression e;
451          for(e = exp.list->first; e; e = e.next)
452             InstDeclPassExpression(e);
453          break;
454       }
455       case indexExp:
456       {
457          Expression e;
458          InstDeclPassExpression(exp.index.exp);
459          for(e = exp.index.index->first; e; e = e.next)
460             InstDeclPassExpression(e);
461          break;
462       }
463       case callExp:
464       {
465          Expression e;
466          InstDeclPassExpression(exp.call.exp);
467          if(exp.call.arguments)
468          {
469             for(e = exp.call.arguments->first; e; e = e.next)
470                InstDeclPassExpression(e);
471          }
472          break;
473       }
474       case memberExp:
475       {
476          if(exp.member.exp)
477             InstDeclPassExpression(exp.member.exp);
478          break;
479       }
480       case pointerExp:
481       {
482          if(exp.member.exp)
483             InstDeclPassExpression(exp.member.exp);
484          break;
485       }
486       case typeSizeExp:
487          InstDeclPassTypeName(exp.typeName, false);
488          break;
489       case castExp:
490       {
491          Type type = exp.expType;
492          // Remove casts to simple structs... (Watch out for pointers later...)
493          if(type && type.kind == classType && type._class.registered && type._class.registered.type == structClass)
494          {
495             Expression castExp = exp.cast.exp;
496             Expression prev = exp.prev, next = exp.next;
497             exp.cast.exp = null;
498             FreeExpContents(exp);
499             FreeType(exp.expType);
500             FreeType(exp.destType);
501             *exp = *castExp;
502             delete castExp;
503             exp.prev = prev;
504             exp.next = next;
505             InstDeclPassExpression(exp);
506          }
507          else
508          {
509             InstDeclPassTypeName(exp.cast.typeName, false);
510             if(exp.cast.exp)
511                InstDeclPassExpression(exp.cast.exp);
512          }
513          break;
514       }
515       case conditionExp:
516       {
517          Expression e;
518          InstDeclPassExpression(exp.cond.cond);
519          for(e = exp.cond.exp->first; e; e = e.next)
520             InstDeclPassExpression(e);
521          InstDeclPassExpression(exp.cond.elseExp);
522          break;
523       }
524       case extensionCompoundExp:
525       {
526          InstDeclPassStatement(exp.compound);
527          break;
528       }
529       case vaArgExp:
530       {
531          InstDeclPassExpression(exp.vaArg.exp);
532          break;
533       }
534       case extensionInitializerExp:
535       {
536          InstDeclPassTypeName(exp.initializer.typeName, false);
537          InstDeclPassInitializer(exp.initializer.initializer);
538          break;
539       }
540    }
541 }
542
543 static void InstDeclPassInitializer(Initializer init)
544 {
545    switch(init.type)
546    {
547       case expInitializer:
548          if(init.exp)
549             InstDeclPassExpression(init.exp);
550          break;
551       case listInitializer:
552       {
553          Initializer i;
554          for(i = init.list->first; i; i = i.next)
555             InstDeclPassInitializer(i);
556          break;
557       }
558    }
559 }
560
561 static void InstDeclPassDeclaration(Declaration decl)
562 {
563    switch(decl.type)
564    {
565       case initDeclaration:
566       {
567          if(decl.specifiers)
568          {
569             Specifier spec;
570             for(spec = decl.specifiers->first; spec; spec = spec.next)
571             {
572                int type;
573                if((type = ReplaceClassSpec(decl.specifiers, spec, false)))
574                {
575                   InitDeclarator d;
576                   if(decl.declarators)
577                   {
578                      for(d = decl.declarators->first; d; d = d.next)
579                         ReplaceByInstancePtr(spec, &d.declarator, type);
580                   }
581                }
582                InstDeclPassSpecifier(spec);
583             }
584          }
585          if(decl.declarators)
586          {
587             InitDeclarator d;
588             for(d = decl.declarators->first; d; d = d.next)
589             {
590                InstDeclPassDeclarator(d.declarator);
591                if(d.initializer)
592                   InstDeclPassInitializer(d.initializer);
593             }
594          }
595          break;
596       }
597       case structDeclaration:
598       {
599          if(decl.specifiers)
600          {
601             Specifier spec;
602             for(spec = decl.specifiers->first; spec; spec = spec.next)
603             {
604                int type;
605                if((type = ReplaceClassSpec(decl.specifiers, spec, false)))
606                {
607                   if(decl.declarators)
608                   {
609                      Declarator d;
610                      for(d = decl.declarators->first; d; d = d.next)
611                         ReplaceByInstancePtr(spec, &d, type);
612                   }
613                }
614                InstDeclPassSpecifier(spec);
615             }
616          }
617
618          if(decl.declarators)
619          {
620             Declarator d;
621             for(d = decl.declarators->first; d; d = d.next)
622                InstDeclPassDeclarator(d);
623          }
624          break;
625       }
626       // This should be removed by now?
627       case instDeclaration:
628          // InstDeclPassInstantiation(decl.inst);
629          break;
630    }
631 }
632
633 static void InstDeclPassStatement(Statement stmt)
634 {
635    switch(stmt.type)
636    {
637       case badDeclarationStmt:
638          if(stmt.decl)
639             InstDeclPassDeclaration(stmt.decl);
640          break;
641       case labeledStmt:
642          InstDeclPassStatement(stmt.labeled.stmt);
643          break;
644       case caseStmt:
645          // This expression should be constant...
646          if(stmt.caseStmt.exp)
647             InstDeclPassExpression(stmt.caseStmt.exp);
648          if(stmt.caseStmt.stmt)
649             InstDeclPassStatement(stmt.caseStmt.stmt);
650          break;
651       case compoundStmt:
652       {
653          Declaration decl;
654          Statement s;
655          Context prevContext = curContext;
656
657          if(!stmt.compound.isSwitch)
658             curContext = stmt.compound.context;
659
660          if(stmt.compound.declarations)
661          {
662             for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
663                InstDeclPassDeclaration(decl);
664          }
665          if(stmt.compound.statements)
666          {
667             for(s = stmt.compound.statements->first; s; s = s.next)
668                InstDeclPassStatement(s);
669          }
670          curContext = prevContext;
671          break;
672       }
673       case expressionStmt:
674       {
675          if(stmt.expressions)
676          {
677             Expression exp;
678             for(exp = stmt.expressions->first; exp; exp = exp.next)
679                InstDeclPassExpression(exp);
680          }
681          break;
682       }
683       case ifStmt:
684       {
685          if(stmt.ifStmt.exp)
686          {
687             Expression exp;
688             for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
689                InstDeclPassExpression(exp);
690          }
691          if(stmt.ifStmt.stmt)
692             InstDeclPassStatement(stmt.ifStmt.stmt);
693          if(stmt.ifStmt.elseStmt)
694             InstDeclPassStatement(stmt.ifStmt.elseStmt);
695          break;
696       }
697       case switchStmt:
698       {
699          Expression exp;
700          if(stmt.switchStmt.exp)
701          {
702             for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
703                InstDeclPassExpression(exp);
704          }
705          InstDeclPassStatement(stmt.switchStmt.stmt);
706          break;
707       }
708       case whileStmt:
709       {
710          Expression exp;
711          if(stmt.whileStmt.exp)
712          {
713             for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
714                InstDeclPassExpression(exp);
715          }
716          InstDeclPassStatement(stmt.whileStmt.stmt);
717          break;
718       }
719       case doWhileStmt:
720       {
721          if(stmt.doWhile.exp)
722          {
723             Expression exp;
724             for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
725                InstDeclPassExpression(exp);
726          }
727          if(stmt.doWhile.stmt)
728             InstDeclPassStatement(stmt.doWhile.stmt);
729          break;
730       }
731       case forStmt:
732       {
733          Expression exp;
734          if(stmt.forStmt.init)
735             InstDeclPassStatement(stmt.forStmt.init);
736          if(stmt.forStmt.check)
737             InstDeclPassStatement(stmt.forStmt.check);
738          if(stmt.forStmt.increment)
739          {
740             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
741                InstDeclPassExpression(exp);
742          }
743          if(stmt.forStmt.stmt)
744             InstDeclPassStatement(stmt.forStmt.stmt);
745          break;
746       }
747       case gotoStmt:
748          break;
749       case continueStmt:
750          break;
751       case breakStmt:
752          break;
753       case returnStmt:
754       {
755          Expression exp;
756          if(stmt.expressions)
757          {
758             for(exp = stmt.expressions->first; exp; exp = exp.next)
759                InstDeclPassExpression(exp);
760          }
761          break;
762       }
763       case asmStmt:
764       {
765          AsmField field;
766          if(stmt.asmStmt.inputFields)
767          {
768             for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
769                if(field.expression)
770                   InstDeclPassExpression(field.expression);
771          }
772          if(stmt.asmStmt.outputFields)
773          {
774             for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
775                if(field.expression)
776                   InstDeclPassExpression(field.expression);
777          }
778          if(stmt.asmStmt.clobberedFields)
779          {
780             for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
781                if(field.expression)
782                   InstDeclPassExpression(field.expression);
783          }
784          break;
785       }
786    }
787 }
788
789 public void ProcessInstanceDeclarations()
790 {
791    External external;
792    curContext = globalContext;
793    for(external = ast->first; external; external = external.next)
794    {
795       curExternal = external;
796       if(external.type == functionExternal)
797       {
798          FunctionDefinition func = external.function;
799          if(func.specifiers)
800          {
801             Specifier spec;
802             for(spec = func.specifiers->first; spec; spec = spec.next)
803             {
804                int type;
805                if((type = ReplaceClassSpec(func.specifiers, spec, false)))
806                   ReplaceByInstancePtr(spec, &func.declarator, type);
807                InstDeclPassSpecifier(spec);
808             }
809          }
810          InstDeclPassDeclarator(func.declarator);
811          if(func.body)
812             InstDeclPassStatement(func.body);
813       }
814       else if(external.type == declarationExternal)
815       {
816          if(external.declaration)
817             InstDeclPassDeclaration(external.declaration);
818       }
819    }
820 }