compiler/libec: Fixed improper usage of GCC compound statement expressions that would...
[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 bool 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 true;
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 true;
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 /*Class*/ || spec.type == subClassSpecifier)
64    {
65       Symbol classSym = spec.symbol; // FindClass(spec.name);
66       if(spec.type == subClassSpecifier)
67       {
68          classSym = FindClass("ecere::com::Class");
69       }
70
71       if(classSym)
72       {
73          Class _class = classSym.registered;
74          spec.type = nameSpecifier;
75
76          if(spec.templateArgs)
77          {
78             FreeList(spec.templateArgs, FreeTemplateArgument);
79             spec.templateArgs = null;
80          }
81
82          if(_class && _class.type == structClass)
83          {
84             //Externalexternal;
85             char name[1024];
86             name[0] = 0;
87             FullClassNameCat(name, _class.fullName, false);
88             //spec.name = CopyString(name);
89             delete spec.name;
90             spec.type = structSpecifier;
91             spec.id = MkIdentifier(name);
92             spec.list = null;
93             spec.definitions = null;
94
95             /*
96             external = DeclareStruct(_class.fullName, false);
97             // If this declaration created something, we gotta pass it through
98             if(external)
99             {
100                Context ctx = curContext;
101                curContext = globalContext;
102                InstDeclPassDeclaration(external.declaration);
103                curContext = ctx;
104             }
105             */
106          }
107          else if(_class && _class.type == noHeadClass)
108          {
109             /*
110             delete spec.name;
111             spec.name = CopyString("void");
112             */
113
114             char name[1024] = "";
115             FullClassNameCat(name, _class.fullName, false);
116             delete spec.name;
117             spec.type = structSpecifier;
118             spec.id = MkIdentifier(name);
119             spec.list = null;
120             spec.definitions = null;
121          }
122          else if(_class)
123          {
124             if((_class.type != systemClass ||
125                !strcmp(_class.fullName, "enum") ||
126                !strcmp(_class.fullName, "ecere::com::Instance") ||
127                (_class.dataTypeString && !strcmp(_class.dataTypeString, "char *")) ||
128                //strcmp(_class.fullName, "bool") &&
129                !strcmp(_class.fullName, "uint64") ||
130                !strcmp(_class.fullName, "uint32") ||
131                !strcmp(_class.fullName, "uint16") ||
132                !strcmp(_class.fullName, "uint") ||
133                !strcmp(_class.fullName, "byte")))
134             {
135                delete spec.name;
136                if(_class.dataTypeString)
137                {
138                   if(!strcmp(_class.dataTypeString, "uint64") ||
139                      !strcmp(_class.dataTypeString, "uint32") ||
140                      !strcmp(_class.dataTypeString, "uint16") ||
141                      !strcmp(_class.dataTypeString, "uint") ||
142                      !strcmp(_class.dataTypeString, "byte"))
143                   {
144                      if(!_class.dataType)
145                         _class.dataType = ProcessTypeString(_class.dataTypeString, false);
146                      if(_class.dataType && _class.dataType.kind == classType) 
147                         classSym = _class.dataType._class;
148                      else
149                         classSym = FindClass(_class.dataTypeString);
150                      _class = classSym ? classSym.registered : null;
151                   }
152
153                   if(!strcmp(_class.dataTypeString, "char *"))
154                      spec.name = CopyString("char");
155                   else
156                      spec.name = CopyString(_class.dataTypeString);
157                   spec.symbol = null;
158                }
159                else
160                {
161                   spec.name = CopyString(null);
162                   spec.symbol = null;
163                }
164             }
165             else if(!_class.base)
166             {
167                delete spec.name;
168                spec.type = baseSpecifier;
169                spec.specifier = VOID;
170                return true;
171             }
172          }
173          else
174          {
175             delete spec.name;
176             spec.type = structSpecifier;
177             spec.id = MkIdentifier("__ecereNameSpace__ecere__com__Instance");
178             spec.list = null;
179             spec.definitions = null;
180          }
181
182          if(_class && _class.dataTypeString && !strcmp(_class.dataTypeString /*fullName*/, "char *"))
183             return true; //false;
184          if(!_class || _class.type == normalClass || _class.type == noHeadClass || !strcmp(_class.fullName, "ecere::com::Instance"))
185             return true;
186          else if(param && _class.type == structClass)
187             return 2;
188       }
189    }
190    else if(spec.type == baseSpecifier)
191    {
192       if(spec.specifier == ANY_OBJECT)
193       {
194          spec.specifier = VOID;
195          return true;
196       }
197    }
198    return false;
199 }
200
201 static void ReplaceByInstancePtr(Specifier spec, Declarator * declPtr, int type)
202 {
203    Declarator decl = *declPtr;
204    if(decl && decl.type == pointerDeclarator)
205    {
206       // Pointers to simple classes shouldn't be added pointers
207       if(type == 2);
208       else
209       // Add pointer
210          decl.pointer.pointer = MkPointer(null, decl.pointer.pointer);
211    }
212    else
213    {
214       Declarator newDecl { };
215       if(decl)
216       {
217          *newDecl = *decl;
218          decl.declarator = newDecl;
219       }
220       else
221          decl = newDecl;
222       decl.type = pointerDeclarator;
223       decl.pointer.pointer = MkPointer(null, null);      
224       *declPtr = decl;
225    }
226 }
227
228 static void InstDeclPassSpecifier(Specifier spec)
229 {
230    switch(spec.type)
231    {
232       case baseSpecifier:
233          if(spec.specifier == TYPED_OBJECT)
234          {
235             spec.type = extendedSpecifier;
236             spec.name = CopyString("struct __ecereNameSpace__ecere__com__Class * class, void *");
237          }
238          break;
239       case nameSpecifier:
240          break;
241       case enumSpecifier:
242       {
243          Enumerator e;
244          if(spec.list)
245          {
246             for(e = spec.list->first; e; e = e.next)
247             {
248             
249             }
250          }
251          break;
252       }
253       case structSpecifier:
254       case unionSpecifier:
255       {
256          if(spec.definitions)
257          {
258             ClassDef def;
259             for(def = spec.definitions->first; def; def = def.next)
260                if(def.decl)
261                   InstDeclPassDeclaration(def.decl);
262          }
263          if(spec.id)
264             InstDeclPassIdentifier(spec.id);
265          break;
266       }
267       case extendedSpecifier:
268          if(!strcmp(spec.name, "dllexport"))
269          {
270             Specifier prevSpec;
271             delete spec.name;
272             for(prevSpec = spec.prev; prevSpec; prevSpec = prevSpec.prev)
273                if(prevSpec.type == baseSpecifier && prevSpec.specifier == EXTERN)
274                   break;
275             if(prevSpec)
276             {
277                if(targetPlatform == win32)
278                   spec.name = CopyString("__declspec(dllexport)");
279                else
280                   spec.name = CopyString("__attribute__ ((visibility(\"default\")))");
281             }
282             else
283             {
284                if(targetPlatform == win32)
285                   spec.name = CopyString("extern __declspec(dllexport)");
286                else
287                   spec.name = CopyString("extern __attribute__ ((visibility(\"default\")))");
288             }
289          }
290          break;
291
292       /*case classSpecifier:
293          break;*/
294    }
295 }
296
297 static void InstDeclPassDeclarator(Declarator decl)
298 {
299    switch(decl.type)
300    {
301       case structDeclarator:
302          if(decl.declarator)
303             InstDeclPassDeclarator(decl.declarator);
304          break;
305       case identifierDeclarator:
306       {
307          if(decl.identifier)
308             InstDeclPassIdentifier(decl.identifier);
309          break;
310       }
311       case bracketsDeclarator:
312          if(decl.declarator)
313             InstDeclPassDeclarator(decl.declarator);
314          break;
315       case arrayDeclarator:
316          if(decl.declarator)
317             InstDeclPassDeclarator(decl.declarator);
318          break;
319       case functionDeclarator:
320       {
321          if(decl.declarator)
322             InstDeclPassDeclarator(decl.declarator);
323          if(decl.function.parameters)
324          {
325             TypeName type;
326             if(decl.declarator)
327                InstDeclPassDeclarator(decl.declarator);
328             for(type = decl.function.parameters->first; type; type = type.next)
329             {
330                bool typedObject = false;
331                Specifier spec = null;
332                if(type.qualifiers)
333                {
334                   spec = (Specifier)type.qualifiers->first;
335                   if(spec && spec.type == nameSpecifier && !strcmp(spec.name, "class"))
336                      typedObject = true;
337                }
338
339                InstDeclPassTypeName(type, true);
340                if(typedObject)
341                {
342                   TypeName _class
343                   {
344                      qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
345                      declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
346                   };
347                   decl.function.parameters->Insert(spec.prev, _class);
348                }
349             }
350          }
351          break;
352       }
353       case pointerDeclarator:
354       case extendedDeclarator:
355       case extendedDeclaratorEnd:
356          if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended)
357          {
358             if(!strcmp(decl.extended.extended, "dllexport"))
359             {
360                delete decl.extended.extended;
361                if(targetPlatform == win32)
362                   decl.extended.extended = CopyString("extern __declspec(dllexport)");
363                else
364                   decl.extended.extended = CopyString("extern __attribute__ ((visibility(\"default\")))");
365             }
366             else if(!strcmp(decl.extended.extended, "stdcall") || !strcmp(decl.extended.extended, "_stdcall") || 
367                !strcmp(decl.extended.extended, "__stdcall") || !strcmp(decl.extended.extended, "__stdcall__"))
368             {
369                delete decl.extended.extended;
370                if(targetPlatform == win32)
371                   decl.extended.extended = CopyString("__attribute__((__stdcall__))");
372                else
373                   decl.extended.extended = CopyString("");
374             }
375          }
376          if(decl.declarator)
377             InstDeclPassDeclarator(decl.declarator);
378          break;
379    }
380 }
381
382 /*static */void InstDeclPassTypeName(TypeName type, bool param)
383 {
384    if(type.qualifiers)
385    {
386       Specifier spec;
387       for(spec = type.qualifiers->first; spec; spec = spec.next)
388       {
389          int result;
390          if((result = ReplaceClassSpec(type.qualifiers, spec, param)))
391             ReplaceByInstancePtr(spec, &type.declarator, result);
392          else
393          {
394             Symbol classSym = (spec.type == nameSpecifier) ? spec.symbol /*FindClass(spec.name)*/ : null;
395             if(type.classObjectType && (!classSym || (classSym && classSym.registered && 
396                (classSym.registered.type == enumClass || classSym.registered.type == bitClass || classSym.registered.type == unitClass || 
397                (classSym.registered.type == systemClass && strcmp(classSym.string, "ecere::com::Instance") && strcmp(classSym.string, "ecere::com::Class"))))))
398                ReplaceByInstancePtr(spec, &type.declarator, 2);
399          }
400          InstDeclPassSpecifier(spec);
401       }
402    }
403    if(type.declarator)
404       InstDeclPassDeclarator(type.declarator);
405 }
406
407 static void InstDeclPassIdentifier(Identifier id)
408 {
409    if(strchr(id.string, ':'))
410    {
411       char newID[1024];
412       int c;
413       char ch;
414       int len;
415       strcpy(newID, "__ecereNameSpace__");
416       len = strlen(newID);
417
418       for(c = 0; (ch = id.string[c]); c++)
419       {
420          if(ch == ':') ch = '_';
421
422          newID[len++] = ch;
423       }
424       newID[len] = 0;
425       delete id.string;
426       id.string = CopyString(newID);
427    }
428 }
429
430 static void InstDeclPassExpression(Expression exp)
431 {
432    switch(exp.type)
433    {
434       case identifierExp:
435       {
436          if(exp.identifier)
437             InstDeclPassIdentifier(exp.identifier);
438          break;
439       }
440       case constantExp:
441          break;
442       case stringExp:
443          break;
444       case opExp:
445          if(exp.op.exp1)
446             InstDeclPassExpression(exp.op.exp1);
447          if(exp.op.exp2)
448             InstDeclPassExpression(exp.op.exp2);
449          break;
450       case extensionExpressionExp:
451       case bracketsExp:
452       {
453          Expression e;
454          for(e = exp.list->first; e; e = e.next)
455             InstDeclPassExpression(e);
456          break;
457       }
458       case indexExp:
459       {
460          Expression e;
461          InstDeclPassExpression(exp.index.exp);
462          for(e = exp.index.index->first; e; e = e.next)
463             InstDeclPassExpression(e);
464          break;
465       }
466       case callExp:
467       {
468          Expression e;
469          InstDeclPassExpression(exp.call.exp);
470          if(exp.call.arguments)
471          {
472             for(e = exp.call.arguments->first; e; e = e.next)
473                InstDeclPassExpression(e);
474          }
475          break;
476       }
477       case memberExp:
478       {
479          InstDeclPassExpression(exp.member.exp);
480          break;
481       }
482       case pointerExp:
483       {
484          InstDeclPassExpression(exp.member.exp);
485          break;
486       }
487       case typeSizeExp:
488          InstDeclPassTypeName(exp.typeName, false);
489          break;
490       case castExp:
491       {
492          Type type = exp.expType;
493          // Remove casts to simple structs... (Watch out for pointers later...)
494          if(type && type.kind == classType && type._class.registered && type._class.registered.type == structClass)
495          {
496             Expression castExp = exp.cast.exp;
497             Expression prev = exp.prev, next = exp.next;
498             exp.cast.exp = null;
499             FreeExpContents(exp);
500             FreeType(exp.expType);
501             FreeType(exp.destType);
502             *exp = *castExp;
503             delete castExp;
504             exp.prev = prev;
505             exp.next = next;
506             InstDeclPassExpression(exp);
507          }
508          else
509          {
510             InstDeclPassTypeName(exp.cast.typeName, false);
511             if(exp.cast.exp)
512                InstDeclPassExpression(exp.cast.exp);
513          }
514          break;
515       }
516       case conditionExp:
517       {
518          Expression e;
519          InstDeclPassExpression(exp.cond.cond);
520          for(e = exp.cond.exp->first; e; e = e.next)
521             InstDeclPassExpression(e);
522          InstDeclPassExpression(exp.cond.elseExp);
523          break;
524       }
525       case extensionCompoundExp:
526       {
527          InstDeclPassStatement(exp.compound);
528          break;
529       }
530       case vaArgExp:
531       {
532          InstDeclPassExpression(exp.vaArg.exp);
533          break;
534       }
535       case extensionInitializerExp:
536       {
537          InstDeclPassTypeName(exp.initializer.typeName, false);
538          InstDeclPassInitializer(exp.initializer.initializer);
539          break;
540       }
541    }
542 }
543
544 static void InstDeclPassInitializer(Initializer init)
545 {
546    switch(init.type)
547    {
548       case expInitializer:
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 labeledStmt:
638          InstDeclPassStatement(stmt.labeled.stmt);
639          break;
640       case caseStmt:
641          // This expression should be constant...
642          if(stmt.caseStmt.exp)
643             InstDeclPassExpression(stmt.caseStmt.exp);
644          if(stmt.caseStmt.stmt)
645             InstDeclPassStatement(stmt.caseStmt.stmt);
646          break;
647       case compoundStmt:
648       {
649          Declaration decl;
650          Statement s;
651          Context prevContext = curContext;
652
653          if(!stmt.compound.isSwitch)
654             curContext = stmt.compound.context;
655          
656          if(stmt.compound.declarations)
657          {
658             for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
659                InstDeclPassDeclaration(decl);
660          }
661          if(stmt.compound.statements)
662          {
663             for(s = stmt.compound.statements->first; s; s = s.next)
664                InstDeclPassStatement(s);
665          }
666          curContext = prevContext;
667          break;
668       }
669       case expressionStmt:
670       {
671          if(stmt.expressions)
672          {
673             Expression exp;
674             for(exp = stmt.expressions->first; exp; exp = exp.next)
675                InstDeclPassExpression(exp);
676          }
677          break;
678       }
679       case ifStmt:
680       {
681          if(stmt.ifStmt.exp)
682          {
683             Expression exp;
684             for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
685                InstDeclPassExpression(exp);
686          }
687          if(stmt.ifStmt.stmt)
688             InstDeclPassStatement(stmt.ifStmt.stmt);
689          if(stmt.ifStmt.elseStmt)
690             InstDeclPassStatement(stmt.ifStmt.elseStmt);
691          break;
692       }
693       case switchStmt:
694       {
695          Expression exp;
696          for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
697             InstDeclPassExpression(exp);
698          InstDeclPassStatement(stmt.switchStmt.stmt);
699          break;
700       }
701       case whileStmt:
702       {
703          Expression exp;
704          for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
705             InstDeclPassExpression(exp);
706          InstDeclPassStatement(stmt.whileStmt.stmt);
707          break;
708       }
709       case doWhileStmt:
710       {
711          if(stmt.doWhile.exp)
712          {
713             Expression exp;
714             for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
715                InstDeclPassExpression(exp);
716          }
717          if(stmt.doWhile.stmt)
718             InstDeclPassStatement(stmt.doWhile.stmt);
719          break;
720       }
721       case forStmt:
722       {
723          Expression exp;
724          if(stmt.forStmt.init)
725             InstDeclPassStatement(stmt.forStmt.init);
726          if(stmt.forStmt.check)
727             InstDeclPassStatement(stmt.forStmt.check);
728          if(stmt.forStmt.increment)
729          {
730             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
731                InstDeclPassExpression(exp);
732          }
733          if(stmt.forStmt.stmt)
734             InstDeclPassStatement(stmt.forStmt.stmt);
735          break;
736       }
737       case gotoStmt:
738          break;
739       case continueStmt:
740          break;
741       case breakStmt:
742          break;
743       case returnStmt:
744       {
745          Expression exp;
746          if(stmt.expressions)
747          {
748             for(exp = stmt.expressions->first; exp; exp = exp.next)
749                InstDeclPassExpression(exp);
750          }
751          break;
752       }
753       case asmStmt:
754       {
755          AsmField field;
756          if(stmt.asmStmt.inputFields)
757          {
758             for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
759                if(field.expression)
760                   InstDeclPassExpression(field.expression);
761          }
762          if(stmt.asmStmt.outputFields)
763          {
764             for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
765                if(field.expression)
766                   InstDeclPassExpression(field.expression);
767          }
768          if(stmt.asmStmt.clobberedFields)
769          {
770             for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
771                if(field.expression)
772                   InstDeclPassExpression(field.expression);
773          }
774          break;
775       }
776    }
777 }
778
779 public void ProcessInstanceDeclarations()
780 {
781    External external;
782    curContext = globalContext;
783    for(external = ast->first; external; external = external.next)
784    {
785       curExternal = external;
786       if(external.type == functionExternal)
787       {
788          FunctionDefinition func = external.function;
789          if(func.specifiers)
790          {
791             Specifier spec;
792             for(spec = func.specifiers->first; spec; spec = spec.next)
793             {
794                int type;
795                if((type = ReplaceClassSpec(func.specifiers, spec, false)))
796                   ReplaceByInstancePtr(spec, &func.declarator, type);
797                InstDeclPassSpecifier(spec);
798             }
799          }
800          InstDeclPassDeclarator(func.declarator);
801          if(func.body)
802             InstDeclPassStatement(func.body);
803       }
804       else if(external.type == declarationExternal)
805       {
806          if(external.declaration)
807             InstDeclPassDeclaration(external.declaration);         
808       }
809    }
810 }