compiler/libec: Improvements to struct and class:struct casts
[sdk] / compiler / libec / src / ecdefs.ec
1 #ifdef ECERE_STATIC
2 public import static "ecere"
3 #else
4 public import "ecere"
5 #endif
6
7 import "ast"
8 import "freeAst"
9 import "firstPass"
10 import "pass0"
11 import "pass1"
12 import "pass15"
13 import "pass16"
14 import "pass2"
15 import "pass3"
16 import "loadSymbols"
17 import "copy"
18 import "shortcuts"
19 import "output"
20 import "dbpass"
21
22 #include <stdio.h>
23
24 #define yylloc _yylloc
25 #include "grammar.h"
26 #undef yylloc
27
28 public enum TokenType
29 {
30   identifier = IDENTIFIER,
31   constant = CONSTANT,
32   stringLiteral = STRING_LITERAL,
33   sizeOf = SIZEOF,
34   ptrOp = PTR_OP,
35   incOp = INC_OP,
36   decOp = DEC_OP,
37   leftOp = LEFT_OP,
38   rightOp = RIGHT_OP,
39   leOp = LE_OP,
40   geOp = GE_OP,
41   eqOp = EQ_OP,
42   neOp = NE_OP,
43   andOp = AND_OP,
44   orOp = OR_OP,
45   mulAssign = MUL_ASSIGN,
46   divAssign = DIV_ASSIGN,
47   modAssign = MOD_ASSIGN,
48   addAssign = ADD_ASSIGN,
49   subAssign = SUB_ASSIGN,
50   leftAssign = LEFT_ASSIGN,
51   rightAssign = RIGHT_ASSIGN,
52   andAssign = AND_ASSIGN,
53   xorAssign = XOR_ASSIGN,
54   orAssign = OR_ASSIGN,
55   typeName = TYPE_NAME,
56   _typedef = TYPEDEF,
57   _extern = EXTERN,
58   _static = STATIC,
59   _auto = AUTO,
60   _register = REGISTER,
61   _char = CHAR,
62   _short = SHORT,
63   _int = INT,
64   _uint = UINT,
65   _int64 = INT64,
66   _long = LONG,
67   _signed = SIGNED,
68   _unsigned = UNSIGNED,
69   _float = FLOAT,
70   _double = DOUBLE,
71   _const = CONST,
72   _volatile = VOLATILE,
73   _void = VOID,
74   _valist = VALIST,
75   _struct = STRUCT,
76   _union = UNION,
77   _enum = ENUM,
78   ellipsis = ELLIPSIS,
79   _case = CASE,
80   _default = DEFAULT,
81   _if = IF,
82   _switch = SWITCH,
83   _whilte = WHILE,
84   _do = DO,
85   _for = FOR,
86   _goto = GOTO,
87   _continue = CONTINUE,
88   _break = BREAK,
89   _return = RETURN,
90   ifx = IFX,
91   _else = ELSE,
92   _class = CLASS,
93   thisClass = THISCLASS,
94   className = CLASS_NAME,
95   _property = PROPERTY,
96   setProp = SETPROP,
97   getProp = GETPROP,
98   newOp = NEWOP,
99   _renew = RENEW,
100   _delete = DELETE,
101   _extDecl = EXT_DECL,
102   _extStorage = EXT_STORAGE,
103   _import = IMPORT,
104   _define = DEFINE,
105   _virtual = VIRTUAL,
106   attrib = ATTRIB,
107   _public = PUBLIC,
108   _priate = PRIVATE,
109   typedObject = TYPED_OBJECT,
110   anyObject = ANY_OBJECT,
111   _incref = _INCREF,
112   extension = EXTENSION,
113   ___asm = ASM,
114   _typeof = TYPEOF,
115   _watch = WATCH,
116   stopWatching = STOPWATCHING,
117   fireWatchers = FIREWATCHERS,
118   _watchable = WATCHABLE,
119   classDesigner = CLASS_DESIGNER,
120   classNoExpansion = CLASS_NO_EXPANSION,
121   classFixed = CLASS_FIXED,
122   isPropSet = ISPROPSET,
123   classDefaultProperty = CLASS_DEFAULT_PROPERTY,
124   propertyCategory = PROPERTY_CATEGORY,
125   classData = CLASS_DATA,
126   classProperty = CLASS_PROPERTY,
127   subClass = SUBCLASS,
128   nameSpace = NAMESPACE,
129   new0Op = NEW0OP,
130   renew0Op = RENEW0,
131   vaArg = VAARG,
132   dbTable = DBTABLE,
133   dbField = DBFIELD,
134   dbIndex = DBINDEX,
135   databaseOpen = DATABASE_OPEN,
136   alignOf = ALIGNOF,
137   attribDep = ATTRIB_DEP,
138   _attrib = __ATTRIB,
139   BOOL = BOOL,
140   _BOOL = _BOOL,
141   complex = _COMPLEX,
142   imaginary = _IMAGINARY,
143   _restrict = RESTRICT,
144   _thread = THREAD
145 };
146
147 enum Order { ascending, descending };
148
149 public class DBTableDef : struct
150 {
151 public:
152    char * name;
153    Symbol symbol;
154    OldList * definitions;
155    AccessMode declMode;
156 }
157
158 enum DBTableEntryType { fieldEntry, indexEntry };
159
160 class DBTableEntry : struct
161 {
162    DBTableEntry prev, next;
163    DBTableEntryType type;
164    Identifier id;
165    union
166    {
167       struct
168       {
169          TypeName dataType;
170          char * name;
171       };
172       OldList * items;
173    };
174 };
175
176 class DBIndexItem : struct
177 {
178    DBIndexItem prev, next;
179    Identifier id;
180    Order order;
181 };
182
183 bool inCompiler = false;
184 public void SetInCompiler(bool b) { inCompiler = b; }
185
186 Context curContext;
187 Context globalContext;
188 OldList * excludedSymbols;
189
190 Context topContext;
191 OldList * imports;
192 OldList * defines;
193 Module privateModule;
194 public void SetPrivateModule(Module module) { privateModule = module; }public Module GetPrivateModule() { return privateModule; }
195 ModuleImport mainModule;
196 public void SetMainModule(ModuleImport moduleImport) { mainModule = moduleImport; } public ModuleImport GetMainModule() { return mainModule; }
197 File fileInput;
198 public void SetFileInput(File file) { fileInput = file; }
199 char * symbolsDir = null;
200 public void SetSymbolsDir(const char * s) {
201    delete symbolsDir;
202    symbolsDir = CopyString(s);
203 } public const char * GetSymbolsDir() { return symbolsDir ? symbolsDir : ""; }
204 const char * outputFile;
205 public void SetOutputFile(const char * s) { outputFile = s; } public const char * GetOutputFile() { return outputFile; }
206 const char * sourceFile;
207 public void SetSourceFile(const char * s) { sourceFile = s; } public const char * GetSourceFile() { return sourceFile; }
208 const char * i18nModuleName;
209 public void SetI18nModuleName(const char * s) { i18nModuleName = s; } public const char * GetI18nModuleName() { return i18nModuleName; }
210
211 public void SetGlobalContext(Context context) { globalContext = context; } public Context GetGlobalContext() { return globalContext; }
212 public void SetTopContext(Context context) { topContext = context; } public Context GetTopContext() { return topContext; }
213 public void SetCurrentContext(Context context) { curContext = context; } public Context GetCurrentContext() { return curContext; }
214 public void SetExcludedSymbols(OldList * list) { excludedSymbols = list; }
215 public void SetImports(OldList * list) { imports = list; }
216 public void SetDefines(OldList * list) { defines = list; }
217
218 bool outputLineNumbers = true;
219 public void SetOutputLineNumbers(bool value) { outputLineNumbers = value; }
220
221 public void FixModuleName(char *moduleName)
222 {
223    ChangeCh(moduleName, '.', '_');
224    ChangeCh(moduleName, ' ', '_');
225    ChangeCh(moduleName, '-', '_');
226    ChangeCh(moduleName, '&', '_');
227 }
228
229 // todo support %var% variables for windows and $var for linux?
230 public char * PassArg(char * output, const char * input)
231 {
232 #ifdef __WIN32__
233 //define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
234    const char * escChars = " !\"%&'()+,;=[]^`{}~"; // windowsFileNameCharsNeedEscaping;
235    const char * escCharsQuoted = "\"";
236 #else
237 //define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
238    const char * escChars = " !\"$&'()*:;<=>?[\\`{|"; // linuxFileNameCharsNeedEscaping;
239    const char * escCharsQuoted = "\"()$";
240 #endif
241    bool quoting = false;
242    char *o = output;
243    const char *i = input, *l = input;
244 #ifdef __WIN32__
245    while(*l && !strchr(escChars, *l)) l++;
246    if(*l) quoting = true;
247 #else
248    if(*i == '-')
249    {
250       l++;
251       while(*l && !strchr(escChars, *l)) l++;
252       if(*l) quoting = true;
253       *o++ = *i++;
254    }
255 #endif
256    if(quoting)
257       *o++ = '\"';
258    while(*i)
259    {
260       if(strchr(quoting ? escCharsQuoted : escChars, *i))
261          *o++ = '\\';
262       *o++ = *i++;
263    }
264    if(quoting)
265       *o++ = '\"';
266    *o = '\0';
267    return o;
268 }
269 /*public Module GetPrivateModule()
270 {
271    return privateModule;
272 }*/
273
274 public class GlobalData : BTNode
275 {
276 public:
277    Module module;
278    char * dataTypeString;
279    Type dataType;
280    void * symbol;
281    char * fullName;
282 };
283
284 public class TemplatedType : BTNode
285 {
286 public:
287    TemplateParameter param;
288 };
289
290 class DataRedefinition : struct
291 {
292    DataRedefinition prev, next;
293    char name[1024];
294    char type1[1024], type2[1024];
295 };
296
297 public struct CodePosition
298 {
299 public:
300    int line, charPos, pos;
301    int included;
302
303    void AdjustDelete(BufferLocation start, BufferLocation end)
304    {
305       // Location is before, nothing to do
306       if(line - 1 < start.y || (line - 1 == start.y && charPos - 1 < start.x))
307          return;
308       // Location is inside deleted bytes, point to the start
309       if((line - 1 >= start.y && (line - 1 > start.y || charPos - 1 >= start.x)) &&
310          (line - 1 >= end.y && (line - 1 > end.y || charPos - 1 >= end.x)))
311       {
312          // Location is after
313          if(line - 1 >= end.y)
314          {
315             // Location is on another line
316             if(line - 1 > end.y)
317                line -= end.y - start.y;
318             // Location is the last touched line
319             else
320             {
321                if(charPos - 1 >= end.x)
322                {
323                   line = start.y + 1;
324                   //if(start.line == end.line)
325                      charPos -= end.x - start.x;
326                }
327             }
328          }
329       }
330       else
331       {
332          line = start.y + 1;
333          charPos = start.x + 1;
334       }
335    }
336
337    // Assuming no carriage return before first character ???? fixed?
338    void AdjustAdd(BufferLocation start, BufferLocation end)
339    {
340       int numLines = end.y - start.y;
341       if(line - 1 >= start.y)
342       {
343          if(line - 1 > start.y)
344             line += numLines;
345          else
346          {
347             if(charPos - 1 > start.x || (charPos - 1 == start.x /*&& (numLines ? true : false)*/))
348             {
349                line += numLines;
350                //charPos - 1 += numLines ? end.x : (end.x - start.x);
351                charPos += end.x - start.x;
352             }
353          }
354       }
355    }
356 };
357
358 public struct Location
359 {
360 public:
361    CodePosition start, end;
362
363    bool Inside(int line, int charPos)
364    {
365       return (start.line < line || (start.line == line && start.charPos <= charPos)) &&
366              (end.line > line || (end.line == line && end.charPos >= charPos));
367    }
368 };
369
370 public enum DefinitionType { moduleDefinition, classDefinition, defineDefinition, functionDefinition, dataDefinition };
371
372 public class Definition : struct
373 {
374 public:
375    Definition prev, next;
376    char * name;
377    DefinitionType type;
378 };
379
380 public class ImportedModule : struct
381 {
382 public:
383    ImportedModule prev, next;
384    char * name;
385    DefinitionType type;
386    ImportType importType;
387    bool globalInstance;
388    bool dllOnly;
389    AccessMode importAccess;
390 };
391
392 public class Identifier : struct
393 {
394 public:
395    Identifier prev, next;
396    Location loc;
397    // TODO: NameSpace * nameSpace;
398    Symbol classSym;
399    Specifier _class;
400    char * string;
401    Identifier badID;
402 };
403
404 public enum ExpressionType
405 {
406    identifierExp, instanceExp, constantExp, stringExp, opExp,
407    bracketsExp, indexExp, callExp, memberExp, pointerExp, typeSizeExp,
408    castExp, conditionExp, newExp, renewExp, classSizeExp,
409    dummyExp, dereferenceErrorExp, symbolErrorExp,
410    memberSymbolErrorExp, memoryErrorExp, unknownErrorExp,
411    noDebuggerErrorExp,
412    extensionCompoundExp, classExp, classDataExp, new0Exp, renew0Exp,
413    dbopenExp, dbfieldExp, dbtableExp, dbindexExp, extensionExpressionExp, extensionInitializerExp,
414    vaArgExp, arrayExp, typeAlignExp,
415    memberPropertyErrorExp, functionCallErrorExp, divideBy0ErrorExp
416 };
417
418 public enum MemberType
419 {
420    unresolvedMember, propertyMember, methodMember, dataMember, reverseConversionMember, classPropertyMember
421 };
422
423 public class ExpUsage
424 {
425 public:
426    bool usageGet:1, usageSet:1, usageArg:1, usageCall:1, usageMember:1, usageDeepGet:1, usageRef:1, usageDelete:1;
427 };
428
429 public class TemplateParameter : struct
430 {
431 public:
432    TemplateParameter prev, next;
433    Location loc;
434
435    TemplateParameterType type;
436    Identifier identifier;
437    union
438    {
439       TemplateDatatype dataType; // For both base datatype (type) and data type (expression)
440       TemplateMemberType memberType;   // For identifier
441    };
442    TemplateArgument defaultArgument;
443
444    // For type parameters
445    const char * dataTypeString;
446    Type baseType;
447 }
448
449 public class TemplateDatatype : struct
450 {
451 public:
452    OldList * specifiers;
453    Declarator decl;
454 }
455
456 public class TemplateArgument : struct
457 {
458 public:
459    TemplateArgument prev, next;
460    Location loc;
461
462    Identifier name;
463    TemplateParameterType type;
464    union
465    {
466       Expression expression;
467       Identifier identifier;
468       TemplateDatatype templateDatatype;
469    };
470 }
471
472 public enum SpecifierType
473 {
474    baseSpecifier, nameSpecifier, enumSpecifier, structSpecifier, unionSpecifier, /*classSpecifier,*/
475    extendedSpecifier, typeOfSpecifier, subClassSpecifier, templateTypeSpecifier
476 };
477
478 public class Specifier : struct
479 {
480 public:
481    Specifier prev, next;
482    Location loc;
483    SpecifierType type;
484    union
485    {
486       int specifier;
487       struct
488       {
489          ExtDecl extDecl;
490          char * name;
491          Symbol symbol;
492          OldList/*<TemplateArgument>*/ * templateArgs;
493       };
494       struct
495       {
496          Identifier id;
497          OldList/*<Enumerator>*/ * list;
498          OldList/*<Specifier>*/ * baseSpecs;
499          OldList/*<ClassDef>*/ * definitions;
500          bool addNameSpace;
501          Context ctx;
502          ExtDecl extDeclStruct;
503       };
504       Expression expression;
505       Specifier _class;
506       TemplateParameter templateParameter;
507    };
508 };
509
510 public class Attribute : struct
511 {
512 public:
513    Attribute prev, next;
514    Location loc;
515    String attr;
516    Expression exp;
517 }
518
519 public class Attrib : struct
520 {
521 public:
522    Location loc;
523    int type;
524    OldList * attribs;
525 }
526
527 public class ExtDecl : struct
528 {
529 public:
530    Location loc;
531    ExtDeclType type;
532    union
533    {
534       String s;
535       Attrib attr;
536    };
537 }
538
539 public enum ExtDeclType
540 {
541    extDeclString, extDeclAttrib
542 };
543
544 public class Expression : struct
545 {
546 public:
547    Expression prev, next;
548    Location loc;
549    ExpressionType type;
550    union
551    {
552       struct
553       {
554          char * constant;
555          Identifier identifier;
556       };
557       Statement compound;
558       Instantiation instance;
559       struct
560       {
561          char * string;
562          bool intlString;
563       };
564       OldList * list;
565       struct
566       {
567          OldList * specifiers;
568          Declarator decl;
569       } _classExp;
570       struct
571       {
572          Identifier id;
573       } classData;
574       struct
575       {
576          Expression exp;
577          OldList * arguments;
578          Location argLoc;
579       } call;
580       struct
581       {
582          Expression exp;
583          OldList * index;
584       } index;
585       struct
586       {
587          Expression exp;
588          Identifier member;
589
590          MemberType memberType;
591          bool thisPtr;
592       } member;
593       struct
594       {
595          int op;
596          Expression exp1, exp2;
597       } op;
598       TypeName typeName;
599       Specifier _class;
600       struct
601       {
602          TypeName typeName;
603          Expression exp;
604       } cast;
605       struct
606       {
607          Expression cond;
608          OldList * exp;
609          Expression elseExp;
610       } cond;
611       struct
612       {
613          TypeName typeName;
614          Expression size;
615       } _new;
616       struct
617       {
618          TypeName typeName;
619          Expression size;
620          Expression exp;
621       } _renew;
622       struct
623       {
624          char * table;
625          Identifier id;
626       } db;
627       struct
628       {
629          Expression ds;
630          Expression name;
631       } dbopen;
632       struct
633       {
634          TypeName typeName;
635          Initializer initializer;
636       } initializer;
637       struct
638       {
639          Expression exp;
640          TypeName typeName;
641       } vaArg;
642    };
643
644    bool debugValue;
645
646    DataValue val;
647
648    uint64 address;
649    bool hasAddress;
650
651    // *** COMPILING DATA ***
652    Type expType;
653    Type destType;
654
655    ExpUsage usage;
656    int tempCount;
657    bool byReference;
658    bool isConstant;
659    bool addedThis;
660    bool needCast;
661    bool thisPtr;
662    bool opDestType;
663    uint needTemplateCast;
664
665    void Clear()
666    {
667       debugValue = false;
668       val = { 0 };
669       address = 0;
670       hasAddress = false;
671
672       expType = null;
673       destType = null;
674
675       usage = 0;
676       tempCount = 0;
677       byReference = false;
678       isConstant = false;
679       addedThis = false;
680       needCast = false;
681       thisPtr = false;
682       opDestType = false;
683       needTemplateCast = 0;
684    }
685 };
686
687 public class Enumerator : struct
688 {
689 public:
690    Enumerator prev, next;
691    Location loc;
692    Identifier id;
693    Expression exp;
694 };
695
696 class Pointer : struct
697 {
698    Pointer prev, next;
699    Location loc;
700    OldList * qualifiers;
701    Pointer pointer;
702 };
703
704 public enum DeclaratorType
705 {
706    structDeclarator, identifierDeclarator, bracketsDeclarator, arrayDeclarator,
707    functionDeclarator, pointerDeclarator, extendedDeclarator, extendedDeclaratorEnd
708 };
709
710 public class Declarator : struct
711 {
712 public:
713    Declarator prev, next;
714    Location loc;
715    DeclaratorType type;
716    Symbol symbol;//, propSymbol;
717    Declarator declarator;
718    union
719    {
720       Identifier identifier;
721       struct
722       {
723          Expression exp;
724          Expression posExp;
725          Attrib attrib;
726       } structDecl;
727       struct
728       {
729          Expression exp;
730          Specifier enumClass;
731       } array;
732       struct
733       {
734          OldList * parameters;
735       } function;
736       struct
737       {
738          Pointer pointer;
739       } pointer;
740       struct
741       {
742          ExtDecl extended;
743       } extended;
744    };
745 };
746
747 public enum InitializerType { expInitializer, listInitializer };
748
749 public class Initializer : struct
750 {
751 public:
752    Initializer prev, next;
753    Location loc;
754    InitializerType type;
755    union
756    {
757       Expression exp;
758       OldList * list;
759    };
760    bool isConstant;
761    Identifier id;
762 };
763
764 public class InitDeclarator : struct
765 {
766 public:
767    InitDeclarator prev, next;
768    Location loc;
769    Declarator declarator;
770    Initializer initializer;
771 };
772
773 public enum ClassObjectType
774 {
775    none,
776    classPointer,
777    typedObject,
778    anyObject
779 };
780
781 public class TypeName : struct
782 {
783 public:
784    TypeName prev, next;
785    Location loc;
786    OldList * qualifiers;
787    Declarator declarator;
788    //bool /*typedObject, */byReference;
789    //bool anyObject;
790    ClassObjectType classObjectType;
791    Expression bitCount;
792 };
793
794 class AsmField : struct
795 {
796    AsmField prev, next;
797    Location loc;
798    char * command;
799    Expression expression;
800    Identifier symbolic;
801 };
802
803 public enum StmtType { labeledStmt, caseStmt, compoundStmt,
804                expressionStmt, ifStmt, switchStmt, whileStmt, doWhileStmt,
805                forStmt, gotoStmt, continueStmt, breakStmt, returnStmt, asmStmt, badDeclarationStmt,
806                fireWatchersStmt, stopWatchingStmt, watchStmt, forEachStmt
807              };
808
809 public class Statement : struct
810 {
811 public:
812    Statement prev, next;
813    Location loc;
814    StmtType type;
815    union
816    {
817       OldList * expressions;
818       struct
819       {
820          Identifier id;
821          Statement stmt;
822       } labeled;
823       struct
824       {
825          Expression exp;
826          Statement stmt;
827       } caseStmt;
828       struct
829       {
830          OldList * declarations;
831          OldList * statements;
832          Context context;
833          bool isSwitch;
834       } compound;
835       struct
836       {
837          OldList * exp;
838          Statement stmt;
839          Statement elseStmt;
840       } ifStmt;
841       struct
842       {
843          OldList * exp;
844          Statement stmt;
845       } switchStmt;
846       struct
847       {
848          OldList * exp;
849          Statement stmt;
850       } whileStmt;
851       struct
852       {
853          OldList * exp;
854          Statement stmt;
855       } doWhile;
856       struct
857       {
858          Statement init;
859          Statement check;
860          OldList * increment;
861          Statement stmt;
862       } forStmt;
863       struct
864       {
865          Identifier id;
866       } gotoStmt;
867       struct
868       {
869          Specifier spec;
870          char * statements;
871          OldList * inputFields;
872          OldList * outputFields;
873          OldList * clobberedFields;
874       } asmStmt;
875       struct
876       {
877          Expression watcher, object;
878          OldList * watches;   // OldList of PropertyWatch for a StmtWatch, list of property identifiers for firewatches, stopwatching
879       } _watch;
880       struct
881       {
882          Identifier id;
883          OldList * exp;
884          OldList * filter;
885          Statement stmt;
886       } forEachStmt;
887       Declaration decl;
888    };
889 };
890
891 public enum DeclarationType { structDeclaration, initDeclaration, instDeclaration, defineDeclaration };
892
893 public class Declaration : struct
894 {
895 public:
896    Declaration prev, next;
897    Location loc;
898    DeclarationType type;
899    union
900    {
901       struct
902       {
903          OldList * specifiers;
904          OldList * declarators;
905       };
906       Instantiation inst;
907       struct
908       {
909          Identifier id;
910          Expression exp;
911       };
912    };
913    Specifier extStorage;
914    Symbol symbol;
915    AccessMode declMode;
916 };
917
918 public class Instantiation : struct
919 {
920 public:
921    Instantiation prev, next;
922    Location loc;
923    Specifier _class;
924    Expression exp;
925    OldList * members;
926    Symbol symbol;
927    bool fullSet;
928    bool isConstant;
929    byte * data;
930    Location nameLoc, insideLoc;
931    bool built;
932 };
933
934 public enum MembersInitType { dataMembersInit, methodMembersInit };
935
936 public class FunctionDefinition : struct
937 {
938 public:
939    FunctionDefinition prev, next;
940    Location loc;
941    OldList * specifiers;
942    Declarator declarator;
943    OldList * declarations;
944    Statement body;
945    Class _class;
946    OldList attached;    // For IDE
947    AccessMode declMode;
948
949    Type type;
950    Symbol propSet;
951
952    int tempCount;
953    bool propertyNoThis; // Not used yet; might use to support both this = and return syntax for conversion properties
954 };
955
956 public class ClassFunction : struct
957 {
958 public:
959    ClassFunction prev, next;
960    Location loc;
961    OldList * specifiers;
962    Declarator declarator;
963    OldList * declarations;
964    Statement body;
965    Class _class;
966    OldList attached;    // For IDE
967    AccessMode declMode;
968
969    // COMPILING DATA
970    Type type;
971    Symbol propSet;
972
973    bool isVirtual;
974    bool isConstructor, isDestructor;
975    bool dontMangle;
976    int id, idCode;
977 };
978
979 public class MembersInit : struct
980 {
981 public:
982    MembersInit prev, next;
983    Location loc;
984    MembersInitType type;
985    union
986    {
987       OldList * dataMembers;
988       ClassFunction function;
989    };
990    //bool coloned;
991 };
992
993 public class MemberInit : struct
994 {
995 public:
996    MemberInit prev, next;
997    Location loc;
998    Location realLoc;
999    OldList * identifiers;
1000    // Expression exp;
1001    Initializer initializer;
1002
1003    // COMPILE DATA
1004    bool used;
1005    bool variable;
1006    bool takeOutExp;
1007 };
1008
1009 public class ClassDefinition : struct
1010 {
1011 public:
1012    ClassDefinition prev, next;
1013    Location loc;
1014    Specifier _class;
1015    // Specifier base;
1016    OldList * baseSpecs;
1017    OldList * definitions;
1018    Symbol symbol;
1019    Location blockStart;
1020    Location nameLoc;
1021    int endid;
1022    AccessMode declMode;
1023    bool deleteWatchable;
1024 };
1025
1026 public class PropertyWatch : struct
1027 {
1028 public:
1029    PropertyWatch prev, next;
1030    Location loc;
1031    Statement compound;
1032    OldList * properties;
1033    bool deleteWatch;
1034 };
1035
1036 public enum ClassDefType
1037 {
1038    functionClassDef, defaultPropertiesClassDef, declarationClassDef, propertyClassDef,
1039    propertyWatchClassDef, classDesignerClassDef, classNoExpansionClassDef, classFixedClassDef,
1040    designerDefaultPropertyClassDef, classDataClassDef, classPropertyClassDef, classPropertyValueClassDef,
1041    memberAccessClassDef, accessOverrideClassDef
1042 };
1043
1044 public class PropertyDef : struct
1045 {
1046 public:
1047    PropertyDef prev, next;
1048    Location loc;
1049    OldList * specifiers;
1050    Declarator declarator;
1051    Identifier id;
1052    Statement getStmt;
1053    Statement setStmt;
1054    Statement issetStmt;
1055    Symbol symbol;
1056    Expression category;
1057    struct
1058    {
1059       bool conversion:1;
1060       bool isWatchable:1;
1061       bool isDBProp:1;
1062    };
1063 };
1064
1065 public class ClassDef : struct
1066 {
1067 public:
1068    ClassDef prev, next;
1069    Location loc;
1070    ClassDefType type;
1071    union
1072    {
1073       Declaration decl;
1074       ClassFunction function;
1075       OldList * defProperties;
1076       PropertyDef propertyDef;
1077       PropertyWatch propertyWatch;
1078       char * designer;
1079       Identifier defaultProperty;
1080       struct
1081       {
1082          Identifier id;
1083          Initializer initializer;
1084       };
1085    };
1086    AccessMode memberAccess;
1087
1088    // IDE
1089    void * object;
1090 };
1091
1092 public enum ExternalType { functionExternal, declarationExternal, classExternal, importExternal, nameSpaceExternal, dbtableExternal };
1093
1094 public class External : struct
1095 {
1096 public:
1097    External prev, next;
1098    Location loc;
1099    ExternalType type;
1100    Symbol symbol;
1101    union
1102    {
1103       FunctionDefinition function;
1104       ClassDefinition _class;
1105       Declaration declaration;
1106       char * importString;
1107       Identifier id;
1108       DBTableDef table;
1109    };
1110    ImportType importType;
1111 };
1112
1113 public class Context : struct
1114 {
1115 public:
1116    Context parent;
1117    BinaryTree types { CompareKey = (void *)BinaryTree::CompareString };
1118    BinaryTree classes { CompareKey = (void *)BinaryTree::CompareString };
1119    BinaryTree symbols { CompareKey = (void *)BinaryTree::CompareString };
1120    BinaryTree structSymbols { CompareKey = (void *)BinaryTree::CompareString };
1121    int nextID;
1122    int simpleID;
1123    BinaryTree templateTypes { CompareKey = (void *)BinaryTree::CompareString };
1124    ClassDefinition classDef;
1125    bool templateTypesOnly;
1126    bool hasNameSpace;
1127 };
1128
1129 /*************** Compiling passes symbols ***************/
1130
1131 public class Symbol : struct
1132 {
1133 public:
1134    char * string;
1135    Symbol parent, left, right;   // Reusing left, right as prev, next when in excludedSymbols
1136    int depth;
1137
1138    Type type;
1139    union
1140    {
1141       Method method;
1142       Property _property;
1143       Class registered;
1144    };
1145    int id, idCode;
1146    union
1147    {
1148       struct
1149       {
1150          External pointerExternal;  // external declaration for the pointer to the Class:    e.g. __ecereClass___ecereNameSpace__ecere__com__Class
1151          External structExternal;   // external declaration for the actual class members structure: e.g. __ecereNameSpace__ecere__com__Class
1152       };
1153       struct
1154       {
1155          External externalGet;
1156          External externalSet;
1157          External externalPtr;    // Property pointer for watchers
1158          External externalIsSet;
1159       };
1160       struct
1161       {
1162          External methodExternal;
1163          External methodCodeExternal;
1164       };
1165    };
1166    bool imported, declaredStructSym;
1167    Class _class; // for properties only...
1168
1169    // Only used for classes right now...
1170    bool declaredStruct;
1171    bool needConstructor, needDestructor;
1172    char * constructorName, * structName, * className, * destructorName;
1173
1174    ModuleImport module;
1175    ClassImport _import;
1176    Location nameLoc;
1177    bool isParam;
1178    bool isRemote;
1179    bool isStruct;
1180    bool fireWatchersDone;
1181    int declaring;
1182    bool classData;
1183    bool isStatic;
1184    char * shortName;
1185    OldList * templateParams;     // Review the necessity for this
1186    OldList templatedClasses;
1187    Context ctx;
1188    int isIterator;
1189    Expression propCategory;
1190 };
1191
1192 // For the .imp file:
1193 public class ClassImport : struct
1194 {
1195 public:
1196    ClassImport prev, next;
1197    char * name;
1198    OldList methods;
1199    OldList properties;
1200    bool itself;
1201    int isRemote;
1202 };
1203
1204 public class FunctionImport : struct
1205 {
1206 public:
1207    FunctionImport prev, next;
1208    char * name;
1209 };
1210
1211 public class ModuleImport : struct
1212 {
1213 public:
1214    ModuleImport prev, next;
1215    char * name;
1216    OldList classes;
1217    OldList functions;
1218    ImportType importType;
1219    AccessMode importAccess;
1220 };
1221
1222 public class PropertyImport : struct
1223 {
1224 public:
1225    PropertyImport prev, next;
1226    char * name;
1227    bool isVirtual;
1228    bool hasSet, hasGet;
1229 };
1230
1231 public class MethodImport : struct
1232 {
1233 public:
1234    MethodImport prev, next;
1235    char * name;
1236    bool isVirtual;
1237 };
1238
1239 // For the .sym file:
1240 public enum TypeKind
1241 {
1242    voidType, charType, shortType, intType, int64Type, longType, floatType,
1243    doubleType, classType, structType, unionType, functionType, arrayType, pointerType,
1244    ellipsisType, enumType, methodType, vaListType, /*typedObjectType, anyObjectType, classPointerType, */ dummyType,
1245    subClassType, templateType, thisClassType, intPtrType, intSizeType, _BoolType
1246 };
1247
1248 public class Type : struct
1249 {
1250 public:
1251    Type prev, next;
1252    int refCount;
1253    union
1254    {
1255       Symbol _class;
1256       struct
1257       {
1258          OldList members;
1259          char * enumName;
1260       };
1261       // For a function:
1262       struct
1263       {
1264          Type returnType;
1265          OldList params;
1266          Symbol thisClass;
1267          bool staticMethod;
1268          TemplateParameter thisClassTemplate;
1269       };
1270       // For a method
1271       struct
1272       {
1273          Method method;
1274          Class methodClass;      // Clarify what this is!
1275          Class usedClass;
1276       };
1277
1278       // For an array:
1279       struct
1280       {
1281          Type arrayType;
1282          int arraySize;
1283          Expression arraySizeExp;
1284          bool freeExp;
1285          Symbol enumClass;
1286       };
1287       // For a pointer:
1288       Type type;
1289       TemplateParameter templateParameter;
1290    };
1291    TypeKind kind;
1292    uint size;
1293    char * name;
1294    char * typeName;
1295
1296    ClassObjectType classObjectType;
1297    int alignment;
1298    uint offset;
1299    int bitFieldCount;
1300    int count;
1301
1302    bool isSigned:1;
1303    bool constant:1;
1304    bool truth:1;
1305    bool byReference:1;
1306    bool extraParam:1;      // Clarify this... One thing it is used for is adaptive method with their own type explicitly specified
1307    bool directClassAccess:1;     // Need to clarify this if this had the same intended purpose as declaredWithStruct
1308    bool computing:1;
1309    bool keepCast:1;
1310    bool passAsTemplate:1;
1311    bool dllExport:1;
1312    bool attrStdcall:1;
1313    bool declaredWithStruct:1;
1314    bool typedByReference:1;      // Originally typed by reference, regardless of class type
1315    bool casted:1;
1316    // bool wasThisClass:1;
1317    // TODO: Add _Complex & _Imaginary support
1318    // bool complex:1, imaginary:1;
1319
1320    const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
1321    {
1322       Type type = (Type)this;
1323       tempString[0] = '\0';
1324       if(type)
1325          PrintType(type, tempString, false, true);
1326       return tempString;
1327    }
1328
1329    void OnFree()
1330    {
1331
1332    }
1333
1334    property bool specConst
1335    {
1336       get
1337       {
1338          Type t = this;
1339          while((t.kind == pointerType || t.kind == arrayType) && t.type) t = t.type;
1340          return t.constant;
1341       }
1342    }
1343 };
1344
1345 public struct Operand
1346 {
1347 public:
1348    TypeKind kind;
1349    Type type;
1350    unsigned int ptrSize;
1351    union    // Promote to using data value
1352    {
1353       char c;
1354       unsigned char uc;
1355       short s;
1356       unsigned short us;
1357       int i;
1358       unsigned int ui;
1359       float f;
1360       double d;
1361       // unsigned char * p; // Now always storing addresses in ui64
1362       int64 i64;
1363       uint64 ui64;
1364       // intptr iptr;
1365       // uintptr uiptr;
1366    };
1367    OpTable ops;
1368 };
1369
1370 public struct OpTable
1371 {
1372 public:
1373    // binary arithmetic
1374    bool (* Add)(Expression, Operand, Operand);
1375    bool (* Sub)(Expression, Operand, Operand);
1376    bool (* Mul)(Expression, Operand, Operand);
1377    bool (* Div)(Expression, Operand, Operand);
1378    bool (* Mod)(Expression, Operand, Operand);
1379
1380    // unary arithmetic
1381    bool (* Neg)(Expression, Operand);
1382
1383    // unary arithmetic increment and decrement
1384    bool (* Inc)(Expression, Operand);
1385    bool (* Dec)(Expression, Operand);
1386
1387    // binary arithmetic assignment
1388    bool (* Asign)(Expression, Operand, Operand);
1389    bool (* AddAsign)(Expression, Operand, Operand);
1390    bool (* SubAsign)(Expression, Operand, Operand);
1391    bool (* MulAsign)(Expression, Operand, Operand);
1392    bool (* DivAsign)(Expression, Operand, Operand);
1393    bool (* ModAsign)(Expression, Operand, Operand);
1394
1395    // binary bitwise
1396    bool (* BitAnd)(Expression, Operand, Operand);
1397    bool (* BitOr)(Expression, Operand, Operand);
1398    bool (* BitXor)(Expression, Operand, Operand);
1399    bool (* LShift)(Expression, Operand, Operand);
1400    bool (* RShift)(Expression, Operand, Operand);
1401    bool (* BitNot)(Expression, Operand);
1402
1403    // binary bitwise assignment
1404    bool (* AndAsign)(Expression, Operand, Operand);
1405    bool (* OrAsign)(Expression, Operand, Operand);
1406    bool (* XorAsign)(Expression, Operand, Operand);
1407    bool (* LShiftAsign)(Expression, Operand, Operand);
1408    bool (* RShiftAsign)(Expression, Operand, Operand);
1409
1410    // unary logical negation
1411    bool (* Not)(Expression, Operand);
1412
1413    // binary logical equality
1414    bool (* Equ)(Expression, Operand, Operand);
1415    bool (* Nqu)(Expression, Operand, Operand);
1416
1417    // binary logical
1418    bool (* And)(Expression, Operand, Operand);
1419    bool (* Or)(Expression, Operand, Operand);
1420
1421    // binary logical relational
1422    bool (* Grt)(Expression, Operand, Operand);
1423    bool (* Sma)(Expression, Operand, Operand);
1424    bool (* GrtEqu)(Expression, Operand, Operand);
1425    bool (* SmaEqu)(Expression, Operand, Operand);
1426
1427    bool (* Cond)(Expression, Operand, Operand, Operand);
1428 };
1429
1430 define MAX_INCLUDE_DEPTH = 30;
1431
1432 #include <stdarg.h>
1433
1434 void Compiler_Error(const char * format, ...)
1435 {
1436    if(inCompiler)
1437    {
1438       if(!parsingType)
1439       {
1440          va_list args;
1441          char string[10000];
1442
1443          if(yylloc.start.included)
1444          {
1445             GetWorkingDir(string, sizeof(string));
1446             PathCat(string, GetIncludeFileFromID(yylloc.start.included));
1447          }
1448          else
1449          {
1450             GetWorkingDir(string, sizeof(string));
1451             PathCat(string, sourceFile);
1452          }
1453          printf("%s", string);
1454
1455          /*
1456          yylloc.start.col = yylloc.end.col = 1;
1457          yylloc.start.line = yylloc.end.line = 1;
1458          yylloc.start.pos = yylloc.end.pos = 0;
1459          */
1460 #ifdef _DEBUG
1461          if(!yylloc.start.line)
1462             printf("no line");
1463 #endif
1464
1465          //printf("(%d, %d) : error: ", yylloc.start.line, yylloc.start.charPos);
1466          printf($":%d:%d: error: ", yylloc.start.line, yylloc.start.charPos);
1467          //printf(":%d: error: ", yylloc.start.line);
1468          va_start(args, format);
1469          vsnprintf(string, sizeof(string), format, args);
1470          string[sizeof(string)-1] = 0;
1471          va_end(args);
1472          fputs(string, stdout);
1473          __thisModule.application.exitCode = 1;
1474       }
1475       else
1476       {
1477          // Error parsing type
1478          parseTypeError = true;
1479       }
1480    }
1481 }
1482
1483 int numWarnings;
1484 public int GetNumWarnings() { return numWarnings; }
1485
1486 void Compiler_Warning(const char * format, ...)
1487 {
1488    if(inCompiler)
1489    {
1490       va_list args;
1491       char string[10000];
1492       char fileName[MAX_FILENAME];
1493
1494       if(yylloc.start.included)
1495       {
1496          String include = GetIncludeFileFromID(yylloc.start.included);
1497          GetWorkingDir(string, sizeof(string));
1498          PathCat(string, include);
1499       }
1500       else
1501       {
1502          GetWorkingDir(string, sizeof(string));
1503          PathCat(string, sourceFile);
1504       }
1505
1506       // Skip these warnings from MinGW-w64 GCC 4.8 in intrin-impl.h
1507       GetLastDirectory(string, fileName);
1508       if(!strcmp(fileName, "intrin-impl.h")) return;
1509
1510       printf("%s", string);
1511
1512       //printf("(%d, %d) : warning: ", yylloc.start.line, yylloc.start.charPos);
1513       printf($":%d:%d: warning: ", yylloc.start.line, yylloc.start.charPos);
1514       //printf(":%d: warning: ", yylloc.start.line);
1515       va_start(args, format);
1516       vsnprintf(string, sizeof(string), format, args);
1517       string[sizeof(string)-1] = 0;
1518       va_end(args);
1519       fputs(string, stdout);
1520       numWarnings++;
1521    }
1522 }
1523 bool parseError;
1524 bool skipErrors;
1525
1526 int yyerror()
1527 {
1528    if(!skipErrors)
1529    {
1530         //fflush(stdout);
1531         //printf("\n%*s\n%*s\n", column, "^", column, s);
1532       parseError = true;
1533       Compiler_Error($"syntax error\n");
1534    }
1535    return 0;
1536 }
1537
1538 Platform targetPlatform;
1539
1540 public int GetHostBits()
1541 {
1542    // Default to runtime platform in case we fail to determine host
1543    int hostBits = (sizeof(uintptr) == 8) ? 64 : 32;
1544    String hostType = getenv("HOSTTYPE");
1545    char host[256];
1546    if(!hostType)
1547    {
1548       DualPipe f = DualPipeOpen({ output = true }, "uname -m");
1549       if(f)
1550       {
1551          if(f.GetLine(host, sizeof(host)))
1552             hostType = host;
1553          delete f;
1554       }
1555    }
1556    if(hostType)
1557    {
1558       if(!strcmp(hostType, "x86_64"))
1559          hostBits = 64;
1560       else if(!strcmp(hostType, "i386") || !strcmp(hostType, "i686"))
1561          hostBits = 32;
1562    }
1563    return hostBits;
1564 }
1565
1566 public void SetTargetPlatform(Platform platform) { targetPlatform = platform; };
1567
1568 int targetBits;
1569
1570 public void SetTargetBits(int bits) { targetBits = bits; };
1571 public int GetTargetBits() { return targetBits; };