compiler/libec: Fixed keeping cast between long/int types
[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 bool inDebugger = false;
187 public void SetInDebugger(bool b) { inDebugger = b; }
188
189 Context curContext;
190 Context globalContext;
191 OldList * excludedSymbols;
192
193 Context topContext;
194 OldList * imports;
195 OldList * defines;
196 Module privateModule;
197 public void SetPrivateModule(Module module) { privateModule = module; }public Module GetPrivateModule() { return privateModule; }
198 ModuleImport mainModule;
199 public void SetMainModule(ModuleImport moduleImport) { mainModule = moduleImport; } public ModuleImport GetMainModule() { return mainModule; }
200 File fileInput;
201 public void SetFileInput(File file) { fileInput = file; }
202 char * symbolsDir = null;
203 public void SetSymbolsDir(const char * s) {
204    delete symbolsDir;
205    symbolsDir = CopyString(s);
206 } public const char * GetSymbolsDir() { return symbolsDir ? symbolsDir : ""; }
207 const char * outputFile;
208 public void SetOutputFile(const char * s) { outputFile = s; } public const char * GetOutputFile() { return outputFile; }
209 const char * sourceFile;
210 public void SetSourceFile(const char * s) { sourceFile = s; } public const char * GetSourceFile() { return sourceFile; }
211 const char * i18nModuleName;
212 public void SetI18nModuleName(const char * s) { i18nModuleName = s; } public const char * GetI18nModuleName() { return i18nModuleName; }
213
214 public void SetGlobalContext(Context context) { globalContext = context; } public Context GetGlobalContext() { return globalContext; }
215 public void SetTopContext(Context context) { topContext = context; } public Context GetTopContext() { return topContext; }
216 public void SetCurrentContext(Context context) { curContext = context; } public Context GetCurrentContext() { return curContext; }
217 public void SetExcludedSymbols(OldList * list) { excludedSymbols = list; }
218 public void SetImports(OldList * list) { imports = list; }
219 public void SetDefines(OldList * list) { defines = list; }
220
221 bool outputLineNumbers = true;
222 public void SetOutputLineNumbers(bool value) { outputLineNumbers = value; }
223
224 public void FixModuleName(char *moduleName)
225 {
226    ChangeCh(moduleName, '.', '_');
227    ChangeCh(moduleName, ' ', '_');
228    ChangeCh(moduleName, '-', '_');
229    ChangeCh(moduleName, '&', '_');
230 }
231
232 // todo support %var% variables for windows and $var for linux?
233 public char * PassArg(char * output, const char * input)
234 {
235 #ifdef __WIN32__
236 //define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
237    const char * escChars = " !\"%&'()+,;=[]^`{}~"; // windowsFileNameCharsNeedEscaping;
238    const char * escCharsQuoted = "\"";
239 #else
240 //define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
241    const char * escChars = " !\"$&'()*:;<=>?[\\`{|"; // linuxFileNameCharsNeedEscaping;
242    const char * escCharsQuoted = "\"()$";
243 #endif
244    bool quoting = false;
245    char *o = output;
246    const char *i = input, *l = input;
247 #ifdef __WIN32__
248    while(*l && !strchr(escChars, *l)) l++;
249    if(*l) quoting = true;
250 #else
251    if(*i == '-')
252    {
253       l++;
254       while(*l && !strchr(escChars, *l)) l++;
255       if(*l) quoting = true;
256       *o++ = *i++;
257    }
258 #endif
259    if(quoting)
260       *o++ = '\"';
261    while(*i)
262    {
263       if(strchr(quoting ? escCharsQuoted : escChars, *i))
264          *o++ = '\\';
265       *o++ = *i++;
266    }
267    if(quoting)
268       *o++ = '\"';
269    *o = '\0';
270    return o;
271 }
272 /*public Module GetPrivateModule()
273 {
274    return privateModule;
275 }*/
276
277 public class GlobalData : BTNode
278 {
279 public:
280    Module module;
281    char * dataTypeString;
282    Type dataType;
283    void * symbol;
284    char * fullName;
285 };
286
287 public class TemplatedType : BTNode
288 {
289 public:
290    TemplateParameter param;
291 };
292
293 class DataRedefinition : struct
294 {
295    DataRedefinition prev, next;
296    char name[1024];
297    char type1[1024], type2[1024];
298 };
299
300 public struct CodePosition
301 {
302 public:
303    int line, charPos, pos;
304    int included;
305
306    void AdjustDelete(BufferLocation start, BufferLocation end)
307    {
308       // Location is before, nothing to do
309       if(line - 1 < start.y || (line - 1 == start.y && charPos - 1 < start.x))
310          return;
311       // Location is inside deleted bytes, point to the start
312       if((line - 1 >= start.y && (line - 1 > start.y || charPos - 1 >= start.x)) &&
313          (line - 1 >= end.y && (line - 1 > end.y || charPos - 1 >= end.x)))
314       {
315          // Location is after
316          if(line - 1 >= end.y)
317          {
318             // Location is on another line
319             if(line - 1 > end.y)
320                line -= end.y - start.y;
321             // Location is the last touched line
322             else
323             {
324                if(charPos - 1 >= end.x)
325                {
326                   line = start.y + 1;
327                   //if(start.line == end.line)
328                      charPos -= end.x - start.x;
329                }
330             }
331          }
332       }
333       else
334       {
335          line = start.y + 1;
336          charPos = start.x + 1;
337       }
338    }
339
340    // Assuming no carriage return before first character ???? fixed?
341    void AdjustAdd(BufferLocation start, BufferLocation end)
342    {
343       int numLines = end.y - start.y;
344       if(line - 1 >= start.y)
345       {
346          if(line - 1 > start.y)
347             line += numLines;
348          else
349          {
350             if(charPos - 1 > start.x || (charPos - 1 == start.x /*&& (numLines ? true : false)*/))
351             {
352                line += numLines;
353                //charPos - 1 += numLines ? end.x : (end.x - start.x);
354                charPos += end.x - start.x;
355             }
356          }
357       }
358    }
359 };
360
361 public struct Location
362 {
363 public:
364    CodePosition start, end;
365
366    bool Inside(int line, int charPos)
367    {
368       return (start.line < line || (start.line == line && start.charPos <= charPos)) &&
369              (end.line > line || (end.line == line && end.charPos >= charPos));
370    }
371 };
372
373 public enum DefinitionType { moduleDefinition, classDefinition, defineDefinition, functionDefinition, dataDefinition };
374
375 public class Definition : struct
376 {
377 public:
378    Definition prev, next;
379    char * name;
380    DefinitionType type;
381 };
382
383 public class ImportedModule : struct
384 {
385 public:
386    ImportedModule prev, next;
387    char * name;
388    DefinitionType type;
389    ImportType importType;
390    bool globalInstance;
391    bool dllOnly;
392    AccessMode importAccess;
393 };
394
395 public class Identifier : struct
396 {
397 public:
398    Identifier prev, next;
399    Location loc;
400    // TODO: NameSpace * nameSpace;
401    Symbol classSym;
402    Specifier _class;
403    char * string;
404    Identifier badID;
405 };
406
407 public enum ExpressionType
408 {
409    identifierExp, instanceExp, constantExp, stringExp, opExp,
410    bracketsExp, indexExp, callExp, memberExp, pointerExp, typeSizeExp,
411    castExp, conditionExp, newExp, renewExp, classSizeExp,
412    dummyExp, dereferenceErrorExp, symbolErrorExp,
413    memberSymbolErrorExp, memoryErrorExp, unknownErrorExp,
414    noDebuggerErrorExp,
415    extensionCompoundExp, classExp, classDataExp, new0Exp, renew0Exp,
416    dbopenExp, dbfieldExp, dbtableExp, dbindexExp, extensionExpressionExp, extensionInitializerExp,
417    vaArgExp, arrayExp, typeAlignExp,
418    memberPropertyErrorExp, functionCallErrorExp, divideBy0ErrorExp
419 };
420
421 public enum MemberType
422 {
423    unresolvedMember, propertyMember, methodMember, dataMember, reverseConversionMember, classPropertyMember
424 };
425
426 public class ExpUsage
427 {
428 public:
429    bool usageGet:1, usageSet:1, usageArg:1, usageCall:1, usageMember:1, usageDeepGet:1, usageRef:1, usageDelete:1;
430 };
431
432 public class TemplateParameter : struct
433 {
434 public:
435    TemplateParameter prev, next;
436    Location loc;
437
438    TemplateParameterType type;
439    Identifier identifier;
440    union
441    {
442       TemplateDatatype dataType; // For both base datatype (type) and data type (expression)
443       TemplateMemberType memberType;   // For identifier
444    };
445    TemplateArgument defaultArgument;
446
447    // For type parameters
448    const char * dataTypeString;
449    Type baseType;
450 }
451
452 public class TemplateDatatype : struct
453 {
454 public:
455    OldList * specifiers;
456    Declarator decl;
457 }
458
459 public class TemplateArgument : struct
460 {
461 public:
462    TemplateArgument prev, next;
463    Location loc;
464
465    Identifier name;
466    TemplateParameterType type;
467    union
468    {
469       Expression expression;
470       Identifier identifier;
471       TemplateDatatype templateDatatype;
472    };
473 }
474
475 public enum SpecifierType
476 {
477    baseSpecifier, nameSpecifier, enumSpecifier, structSpecifier, unionSpecifier, /*classSpecifier,*/
478    extendedSpecifier, typeOfSpecifier, subClassSpecifier, templateTypeSpecifier
479 };
480
481 public class Specifier : struct
482 {
483 public:
484    Specifier prev, next;
485    Location loc;
486    SpecifierType type;
487    union
488    {
489       int specifier;
490       struct
491       {
492          ExtDecl extDecl;
493          char * name;
494          Symbol symbol;
495          OldList/*<TemplateArgument>*/ * templateArgs;
496          Specifier nsSpec;
497       };
498       struct
499       {
500          Identifier id;
501          OldList/*<Enumerator>*/ * list;
502          OldList/*<Specifier>*/ * baseSpecs;
503          OldList/*<ClassDef>*/ * definitions;
504          bool addNameSpace;
505          Context ctx;
506          ExtDecl extDeclStruct;
507       };
508       Expression expression;
509       Specifier _class;
510       TemplateParameter templateParameter;
511    };
512 };
513
514 public class Attribute : struct
515 {
516 public:
517    Attribute prev, next;
518    Location loc;
519    String attr;
520    Expression exp;
521 }
522
523 public class Attrib : struct
524 {
525 public:
526    Location loc;
527    int type;
528    OldList * attribs;
529 }
530
531 public class ExtDecl : struct
532 {
533 public:
534    Location loc;
535    ExtDeclType type;
536    union
537    {
538       String s;
539       Attrib attr;
540    };
541 }
542
543 public enum ExtDeclType
544 {
545    extDeclString, extDeclAttrib
546 };
547
548 public class Expression : struct
549 {
550 public:
551    Expression prev, next;
552    Location loc;
553    ExpressionType type;
554    union
555    {
556       struct
557       {
558          char * constant;
559          Identifier identifier;
560       };
561       Statement compound;
562       Instantiation instance;
563       struct
564       {
565          char * string;
566          bool intlString;
567          bool wideString;
568       };
569       OldList * list;
570       struct
571       {
572          OldList * specifiers;
573          Declarator decl;
574       } _classExp;
575       struct
576       {
577          Identifier id;
578       } classData;
579       struct
580       {
581          Expression exp;
582          OldList * arguments;
583          Location argLoc;
584       } call;
585       struct
586       {
587          Expression exp;
588          OldList * index;
589       } index;
590       struct
591       {
592          Expression exp;
593          Identifier member;
594
595          MemberType memberType;
596          bool thisPtr;
597       } member;
598       struct
599       {
600          int op;
601          Expression exp1, exp2;
602       } op;
603       TypeName typeName;
604       Specifier _class;
605       struct
606       {
607          TypeName typeName;
608          Expression exp;
609       } cast;
610       struct
611       {
612          Expression cond;
613          OldList * exp;
614          Expression elseExp;
615       } cond;
616       struct
617       {
618          TypeName typeName;
619          Expression size;
620       } _new;
621       struct
622       {
623          TypeName typeName;
624          Expression size;
625          Expression exp;
626       } _renew;
627       struct
628       {
629          char * table;
630          Identifier id;
631       } db;
632       struct
633       {
634          Expression ds;
635          Expression name;
636       } dbopen;
637       struct
638       {
639          TypeName typeName;
640          Initializer initializer;
641       } initializer;
642       struct
643       {
644          Expression exp;
645          TypeName typeName;
646       } vaArg;
647    };
648
649    bool debugValue;
650
651    DataValue val;
652
653    uint64 address;
654    bool hasAddress;
655
656    // *** COMPILING DATA ***
657    Type expType;
658    Type destType;
659
660    ExpUsage usage;
661    int tempCount;
662    bool byReference;
663    bool isConstant;
664    bool addedThis;
665    bool needCast;
666    bool thisPtr;
667    bool opDestType;
668    uint needTemplateCast;
669
670    void Clear()
671    {
672       debugValue = false;
673       val = { 0 };
674       address = 0;
675       hasAddress = false;
676
677       expType = null;
678       destType = null;
679
680       usage = 0;
681       tempCount = 0;
682       byReference = false;
683       isConstant = false;
684       addedThis = false;
685       needCast = false;
686       thisPtr = false;
687       opDestType = false;
688       needTemplateCast = 0;
689    }
690 };
691
692 public class Enumerator : struct
693 {
694 public:
695    Enumerator prev, next;
696    Location loc;
697    Identifier id;
698    Expression exp;
699 };
700
701 class Pointer : struct
702 {
703    Pointer prev, next;
704    Location loc;
705    OldList * qualifiers;
706    Pointer pointer;
707 };
708
709 public enum DeclaratorType
710 {
711    structDeclarator, identifierDeclarator, bracketsDeclarator, arrayDeclarator,
712    functionDeclarator, pointerDeclarator, extendedDeclarator, extendedDeclaratorEnd
713 };
714
715 public class Declarator : struct
716 {
717 public:
718    Declarator prev, next;
719    Location loc;
720    DeclaratorType type;
721    Symbol symbol;//, propSymbol;
722    Declarator declarator;
723    union
724    {
725       Identifier identifier;
726       struct
727       {
728          Expression exp;
729          Expression posExp;
730          Attrib attrib;
731       } structDecl;
732       struct
733       {
734          Expression exp;
735          Specifier enumClass;
736       } array;
737       struct
738       {
739          OldList * parameters;
740       } function;
741       struct
742       {
743          Pointer pointer;
744       } pointer;
745       struct
746       {
747          ExtDecl extended;
748       } extended;
749    };
750 };
751
752 public enum InitializerType { expInitializer, listInitializer };
753
754 public class Initializer : struct
755 {
756 public:
757    Initializer prev, next;
758    Location loc;
759    InitializerType type;
760    union
761    {
762       Expression exp;
763       OldList * list;
764    };
765    bool isConstant;
766    Identifier id;
767 };
768
769 public class InitDeclarator : struct
770 {
771 public:
772    InitDeclarator prev, next;
773    Location loc;
774    Declarator declarator;
775    Initializer initializer;
776 };
777
778 public enum ClassObjectType
779 {
780    none,
781    classPointer,
782    typedObject,
783    anyObject
784 };
785
786 public class TypeName : struct
787 {
788 public:
789    TypeName prev, next;
790    Location loc;
791    OldList * qualifiers;
792    Declarator declarator;
793    //bool /*typedObject, */byReference;
794    //bool anyObject;
795    ClassObjectType classObjectType;
796    Expression bitCount;
797 };
798
799 class AsmField : struct
800 {
801    AsmField prev, next;
802    Location loc;
803    char * command;
804    Expression expression;
805    Identifier symbolic;
806 };
807
808 public enum StmtType { labeledStmt, caseStmt, compoundStmt,
809                expressionStmt, ifStmt, switchStmt, whileStmt, doWhileStmt,
810                forStmt, gotoStmt, continueStmt, breakStmt, returnStmt, asmStmt, badDeclarationStmt,
811                fireWatchersStmt, stopWatchingStmt, watchStmt, forEachStmt
812              };
813
814 public class Statement : struct
815 {
816 public:
817    Statement prev, next;
818    Location loc;
819    StmtType type;
820    union
821    {
822       OldList * expressions;
823       struct
824       {
825          Identifier id;
826          Statement stmt;
827       } labeled;
828       struct
829       {
830          Expression exp;
831          Statement stmt;
832       } caseStmt;
833       struct
834       {
835          OldList * declarations;
836          OldList * statements;
837          Context context;
838          bool isSwitch;
839       } compound;
840       struct
841       {
842          OldList * exp;
843          Statement stmt;
844          Statement elseStmt;
845       } ifStmt;
846       struct
847       {
848          OldList * exp;
849          Statement stmt;
850       } switchStmt;
851       struct
852       {
853          OldList * exp;
854          Statement stmt;
855       } whileStmt;
856       struct
857       {
858          OldList * exp;
859          Statement stmt;
860       } doWhile;
861       struct
862       {
863          Statement init;
864          Statement check;
865          OldList * increment;
866          Statement stmt;
867       } forStmt;
868       struct
869       {
870          Identifier id;
871       } gotoStmt;
872       struct
873       {
874          Specifier spec;
875          char * statements;
876          OldList * inputFields;
877          OldList * outputFields;
878          OldList * clobberedFields;
879       } asmStmt;
880       struct
881       {
882          Expression watcher, object;
883          OldList * watches;   // OldList of PropertyWatch for a StmtWatch, list of property identifiers for firewatches, stopwatching
884       } _watch;
885       struct
886       {
887          Identifier id;
888          OldList * exp;
889          OldList * filter;
890          Statement stmt;
891       } forEachStmt;
892       Declaration decl;
893    };
894 };
895
896 public enum DeclarationType { structDeclaration, initDeclaration, instDeclaration, defineDeclaration };
897
898 public class Declaration : struct
899 {
900 public:
901    Declaration prev, next;
902    Location loc;
903    DeclarationType type;
904    union
905    {
906       struct
907       {
908          OldList * specifiers;
909          OldList * declarators;
910       };
911       Instantiation inst;
912       struct
913       {
914          Identifier id;
915          Expression exp;
916       };
917    };
918    Specifier extStorage;
919    Symbol symbol;
920    AccessMode declMode;
921 };
922
923 public class Instantiation : struct
924 {
925 public:
926    Instantiation prev, next;
927    Location loc;
928    Specifier _class;
929    Expression exp;
930    OldList * members;
931    Symbol symbol;
932    bool fullSet;
933    bool isConstant;
934    byte * data;
935    Location nameLoc, insideLoc;
936    bool built;
937 };
938
939 public enum MembersInitType { dataMembersInit, methodMembersInit };
940
941 public class FunctionDefinition : struct
942 {
943 public:
944    FunctionDefinition prev, next;
945    Location loc;
946    OldList * specifiers;
947    Declarator declarator;
948    OldList * declarations;
949    Statement body;
950    Class _class;
951    OldList attached;    // For IDE
952    AccessMode declMode;
953
954    Type type;
955    Symbol propSet;
956
957    int tempCount;
958    bool propertyNoThis; // Not used yet; might use to support both this = and return syntax for conversion properties
959 };
960
961 public class ClassFunction : struct
962 {
963 public:
964    ClassFunction prev, next;
965    Location loc;
966    OldList * specifiers;
967    Declarator declarator;
968    OldList * declarations;
969    Statement body;
970    Class _class;
971    OldList attached;    // For IDE
972    AccessMode declMode;
973
974    // COMPILING DATA
975    Type type;
976    Symbol propSet;
977
978    bool isVirtual;
979    bool isConstructor, isDestructor;
980    bool dontMangle;
981    int id, idCode;
982 };
983
984 public class MembersInit : struct
985 {
986 public:
987    MembersInit prev, next;
988    Location loc;
989    MembersInitType type;
990    union
991    {
992       OldList * dataMembers;
993       ClassFunction function;
994    };
995    //bool coloned;
996 };
997
998 public class MemberInit : struct
999 {
1000 public:
1001    MemberInit prev, next;
1002    Location loc;
1003    Location realLoc;
1004    OldList * identifiers;
1005    // Expression exp;
1006    Initializer initializer;
1007
1008    // COMPILE DATA
1009    bool used;
1010    bool variable;
1011    bool takeOutExp;
1012 };
1013
1014 public class ClassDefinition : struct
1015 {
1016 public:
1017    ClassDefinition prev, next;
1018    Location loc;
1019    Specifier _class;
1020    // Specifier base;
1021    OldList * baseSpecs;
1022    OldList * definitions;
1023    Symbol symbol;
1024    Location blockStart;
1025    Location nameLoc;
1026    AccessMode declMode;
1027    bool deleteWatchable;
1028 };
1029
1030 public class PropertyWatch : struct
1031 {
1032 public:
1033    PropertyWatch prev, next;
1034    Location loc;
1035    Statement compound;
1036    OldList * properties;
1037    bool deleteWatch;
1038 };
1039
1040 public enum ClassDefType
1041 {
1042    functionClassDef, defaultPropertiesClassDef, declarationClassDef, propertyClassDef,
1043    propertyWatchClassDef, classDesignerClassDef, classNoExpansionClassDef, classFixedClassDef,
1044    designerDefaultPropertyClassDef, classDataClassDef, classPropertyClassDef, classPropertyValueClassDef,
1045    memberAccessClassDef, accessOverrideClassDef
1046 };
1047
1048 public class PropertyDef : struct
1049 {
1050 public:
1051    PropertyDef prev, next;
1052    Location loc;
1053    OldList * specifiers;
1054    Declarator declarator;
1055    Identifier id;
1056    Statement getStmt;
1057    Statement setStmt;
1058    Statement issetStmt;
1059    Symbol symbol;
1060    Expression category;
1061    struct
1062    {
1063       bool conversion:1;
1064       bool isWatchable:1;
1065       bool isDBProp:1;
1066    };
1067 };
1068
1069 public class ClassDef : struct
1070 {
1071 public:
1072    ClassDef prev, next;
1073    Location loc;
1074    ClassDefType type;
1075    union
1076    {
1077       Declaration decl;
1078       ClassFunction function;
1079       OldList * defProperties;
1080       PropertyDef propertyDef;
1081       PropertyWatch propertyWatch;
1082       char * designer;
1083       Identifier defaultProperty;
1084       struct
1085       {
1086          Identifier id;
1087          Initializer initializer;
1088       };
1089    };
1090    AccessMode memberAccess;
1091
1092    // IDE
1093    void * object;
1094 };
1095
1096 // An 'edge from' is a 'dependency on'
1097 class TopoEdge : struct
1098 {
1099    public LinkElement<TopoEdge> in, out;
1100    External from, to;
1101    bool breakable;
1102 };
1103
1104 public enum ExternalType { functionExternal, declarationExternal, classExternal, importExternal, nameSpaceExternal, dbtableExternal };
1105
1106 public class External : struct
1107 {
1108 public:
1109    External prev, next;
1110    Location loc;
1111    ExternalType type;
1112    Symbol symbol;
1113    union
1114    {
1115       FunctionDefinition function;
1116       ClassDefinition _class;
1117       Declaration declaration;
1118       char * importString;
1119       Identifier id;
1120       DBTableDef table;
1121    };
1122    ImportType importType;
1123
1124    // For the TopoSort
1125    External fwdDecl;
1126    LinkList<TopoEdge, link = out> outgoing { };
1127    LinkList<TopoEdge, link = in> incoming { };
1128    int nonBreakableIncoming;
1129
1130    void CreateUniqueEdge(External from, bool soft)
1131    {
1132       for(i : from.outgoing; i.to == this)
1133       {
1134          if(i.breakable && !soft)
1135          {
1136 #ifdef _DEBUG
1137             if(from == this)
1138                PrintLn("bug: self-dependency");
1139 #endif
1140             i.breakable = false;
1141             nonBreakableIncoming++;
1142          }
1143          return;
1144       }
1145       CreateEdge(from, soft);
1146    }
1147
1148    void CreateEdge(External from, bool soft)
1149    {
1150       TopoEdge e { from = from, to = this, breakable = soft };
1151
1152 #ifdef _DEBUG
1153       if(from == this && !soft)
1154          PrintLn("bug: self-dependency");
1155
1156       /*for(i : from.outgoing)
1157       {
1158          if(i.to == this)
1159             PrintLn("Warning: adding a duplicate edge");
1160       }*/
1161 #endif
1162
1163       from.outgoing.Add(e);
1164       incoming.Add(e);
1165       if(!soft)
1166          nonBreakableIncoming++;
1167    }
1168
1169    External ForwardDeclare()
1170    {
1171       External f = null;
1172       Context tmpContext = curContext;
1173
1174       switch(type)
1175       {
1176          case declarationExternal:
1177          {
1178             if(declaration.type == initDeclaration)
1179             {
1180                OldList * specs = declaration.specifiers;
1181                if(specs)
1182                {
1183                   Specifier s;
1184                   for(s = specs->first; s; s = s.next)
1185                   {
1186                      if(s.type == structSpecifier || s.type == unionSpecifier)
1187                         break;
1188                   }
1189                   if(s)
1190                   {
1191                      curContext = null;
1192                      f = MkExternalDeclaration(MkDeclaration(MkListOne(MkStructOrUnion(s.type, CopyIdentifier(s.id), null)), null));
1193                      curContext = tmpContext;
1194                   }
1195                }
1196             }
1197             break;
1198          }
1199          case functionExternal:
1200          {
1201             curContext = null;
1202             f = MkExternalDeclaration(MkDeclaration(CopyList(function.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(CopyDeclarator(function.declarator), null))));
1203             curContext = tmpContext;
1204             f.symbol = symbol;
1205
1206             DeclareTypeForwardDeclare(f, symbol.type, false, false);
1207             break;
1208          }
1209       }
1210
1211       /*
1212       for(i : m.protoDepsExternal)
1213       {
1214          // If the edge is already added, don't bother
1215          if(i.incoming.count)
1216             CreateEdge(f, i.fwdDecl ? i.fwdDecl : i, i.fwdDecl ? false : true);
1217       }
1218       */
1219
1220       fwdDecl = f;
1221
1222       if(!f)
1223          PrintLn("warning: unhandled forward declaration requested");
1224       return f;
1225    }
1226 };
1227
1228 public class Context : struct
1229 {
1230 public:
1231    Context parent;
1232    BinaryTree types { CompareKey = (void *)BinaryTree::CompareString };
1233    BinaryTree classes { CompareKey = (void *)BinaryTree::CompareString };
1234    BinaryTree symbols { CompareKey = (void *)BinaryTree::CompareString };
1235    BinaryTree structSymbols { CompareKey = (void *)BinaryTree::CompareString };
1236    int nextID;
1237    int simpleID;
1238    BinaryTree templateTypes { CompareKey = (void *)BinaryTree::CompareString };
1239    ClassDefinition classDef;
1240    bool templateTypesOnly;
1241    bool hasNameSpace;
1242 };
1243
1244 /*************** Compiling passes symbols ***************/
1245
1246 public class Symbol : struct
1247 {
1248 public:
1249    char * string;
1250    Symbol parent, left, right;   // Reusing left, right as prev, next when in excludedSymbols
1251    int depth;
1252
1253    Type type;
1254    union
1255    {
1256       Method method;
1257       Property _property;
1258       Class registered;
1259    };
1260    bool notYetDeclared;
1261    union
1262    {
1263       struct
1264       {
1265          External pointerExternal;  // external declaration for the pointer to the Class:    e.g. __ecereClass___ecereNameSpace__ecere__com__Class
1266          External structExternal;   // external declaration for the actual class members structure: e.g. __ecereNameSpace__ecere__com__Class
1267       };
1268       struct
1269       {
1270          External externalGet;
1271          External externalSet;
1272          External externalPtr;    // Property pointer for watchers
1273          External externalIsSet;
1274       };
1275       struct
1276       {
1277          External methodExternal;
1278          External methodCodeExternal;
1279       };
1280    };
1281    bool imported, declaredStructSym;
1282    Class _class; // for properties only...
1283
1284    // Only used for classes right now...
1285    bool declaredStruct;
1286    bool needConstructor, needDestructor;
1287    char * constructorName, * structName, * className, * destructorName;
1288
1289    ModuleImport module;
1290    ClassImport _import;
1291    Location nameLoc;
1292    bool isParam;
1293    bool isRemote;
1294    bool isStruct;
1295    bool fireWatchersDone;
1296    int declaring;
1297    bool classData;
1298    bool isStatic;
1299    char * shortName;
1300    OldList * templateParams;     // Review the necessity for this
1301    OldList templatedClasses;
1302    Context ctx;
1303    int isIterator;
1304    Expression propCategory;
1305    bool mustRegister;   // Must register the class within the RegisterClass (also used to check whether this class is declared in this module)
1306 };
1307
1308 // For the .imp file:
1309 public class ClassImport : struct
1310 {
1311 public:
1312    ClassImport prev, next;
1313    char * name;
1314    OldList methods;
1315    OldList properties;
1316    bool itself;
1317    int isRemote;
1318 };
1319
1320 public class FunctionImport : struct
1321 {
1322 public:
1323    FunctionImport prev, next;
1324    char * name;
1325 };
1326
1327 public class ModuleImport : struct
1328 {
1329 public:
1330    ModuleImport prev, next;
1331    char * name;
1332    OldList classes;
1333    OldList functions;
1334    ImportType importType;
1335    AccessMode importAccess;
1336 };
1337
1338 public class PropertyImport : struct
1339 {
1340 public:
1341    PropertyImport prev, next;
1342    char * name;
1343    bool isVirtual;
1344    bool hasSet, hasGet;
1345 };
1346
1347 public class MethodImport : struct
1348 {
1349 public:
1350    MethodImport prev, next;
1351    char * name;
1352    bool isVirtual;
1353 };
1354
1355 // For the .sym file:
1356 public enum TypeKind
1357 {
1358    voidType, charType, shortType, intType, int64Type, longType, floatType,
1359    doubleType, classType, structType, unionType, functionType, arrayType, pointerType,
1360    ellipsisType, enumType, methodType, vaListType, /*typedObjectType, anyObjectType, classPointerType, */ dummyType,
1361    subClassType, templateType, thisClassType, intPtrType, intSizeType, _BoolType
1362 };
1363
1364 public class Type : struct
1365 {
1366 public:
1367    Type prev, next;
1368    int refCount;
1369    union
1370    {
1371       Symbol _class;
1372       struct
1373       {
1374          OldList members;
1375          char * enumName;
1376       };
1377       // For a function:
1378       struct
1379       {
1380          Type returnType;
1381          OldList params;
1382          Symbol thisClass;
1383          bool staticMethod;
1384          TemplateParameter thisClassTemplate;
1385       };
1386       // For a method
1387       struct
1388       {
1389          Method method;
1390          Class methodClass;      // Clarify what this is!
1391          Class usedClass;
1392       };
1393
1394       // For an array:
1395       struct
1396       {
1397          Type arrayType;
1398          int arraySize;
1399          Expression arraySizeExp;
1400          bool freeExp;
1401          Symbol enumClass;
1402       };
1403       // For a pointer:
1404       Type type;
1405       TemplateParameter templateParameter;
1406    };
1407    TypeKind kind;
1408    uint size;
1409    char * name;
1410    char * typeName;
1411    Class thisClassFrom;
1412
1413    ClassObjectType classObjectType;
1414    int alignment;
1415    uint offset;
1416    int bitFieldCount;
1417    int count;  // This is used to avoid outputting warnings when non-zero
1418
1419    bool isSigned:1;
1420    bool constant:1;
1421    bool truth:1;
1422    bool byReference:1;
1423    bool extraParam:1;      // Clarify this... One thing it is used for is adaptive method with their own type explicitly specified
1424    bool directClassAccess:1;     // Need to clarify this if this had the same intended purpose as declaredWithStruct
1425    bool computing:1;
1426    bool keepCast:1;
1427    bool passAsTemplate:1;
1428    bool dllExport:1;
1429    bool attrStdcall:1;
1430    bool declaredWithStruct:1;
1431    bool typedByReference:1;      // Originally typed by reference, regardless of class type
1432    bool casted:1;
1433    bool pointerAlignment:1; // true if the alignment is the pointer size
1434    bool isLong:1;    // true if this is truly a long set as a int/int64 (need to improve long support)
1435    // bool wasThisClass:1;
1436    // TODO: Add _Complex & _Imaginary support
1437    // bool complex:1, imaginary:1;
1438
1439    const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
1440    {
1441       Type type = (Type)this;
1442       tempString[0] = '\0';
1443       if(type)
1444          PrintType(type, tempString, false, true);
1445       return tempString;
1446    }
1447
1448    void OnFree()
1449    {
1450
1451    }
1452
1453    property bool specConst
1454    {
1455       get
1456       {
1457          Type t = this;
1458          while((t.kind == pointerType || t.kind == arrayType) && t.type) t = t.type;
1459          return t.constant;
1460       }
1461    }
1462
1463    // Used for generating calls to eClass_AddDataMember (differs slightly from 'isPointerType' below), meant to return true where ComputeTypeSize returns targetBits / 8
1464    property bool isPointerTypeSize
1465    {
1466       get
1467       {
1468          bool result = false;
1469          if(this)
1470          {
1471             switch(kind)
1472             {
1473                case classType:
1474                {
1475                   Class _class = this._class ? this._class.registered : null;
1476                   if(!_class || (_class.type != structClass && _class.type != unitClass && _class.type != enumClass && _class.type != bitClass))
1477                      result = true;
1478                   break;
1479                }
1480                case pointerType:
1481                case subClassType:
1482                case thisClassType:
1483                case intPtrType:
1484                case intSizeType:
1485                   result = true;
1486                   break;
1487                case templateType:
1488                {
1489                   TemplateParameter param = templateParameter;
1490                   Type baseType = ProcessTemplateParameterType(param);
1491                   if(baseType)
1492                      result = baseType.isPointerTypeSize;
1493                   break;
1494                }
1495             }
1496          }
1497          return result;
1498       }
1499    }
1500
1501    property bool isPointerType
1502    {
1503       get
1504       {
1505          if(this)
1506          {
1507             if(kind == pointerType || kind == methodType || kind == functionType || kind == arrayType || kind == subClassType)
1508                return true;
1509             else if(kind == classType)
1510             {
1511                if(_class && _class.registered)
1512                {
1513                   Class c = _class.registered;
1514                   if(c.type == bitClass || c.type == unitClass || c.type == enumClass || c.type == systemClass)
1515                      return false;
1516                   else if(c.type == structClass && !byReference)
1517                      return false;
1518                }
1519                return true;
1520             }
1521             else if(kind == templateType)
1522             {
1523                if(passAsTemplate) return false;
1524                if(templateParameter)
1525                {
1526                   if(templateParameter.dataType)
1527                   {
1528                      Specifier spec = templateParameter.dataType.specifiers ? templateParameter.dataType.specifiers->first : null;
1529                      if(templateParameter.dataType.decl && templateParameter.dataType.decl.type == pointerDeclarator)
1530                         return true;
1531                      if(spec && spec.type == nameSpecifier && strcmp(spec.name, "uint64"))
1532                         return true;
1533                   }
1534                   if(templateParameter.dataTypeString)
1535                      return true;
1536                }
1537             }
1538             else
1539                return false;
1540          }
1541          return false;
1542       }
1543    }
1544 };
1545
1546 public struct Operand
1547 {
1548 public:
1549    TypeKind kind;
1550    Type type;
1551    unsigned int ptrSize;
1552    union    // Promote to using data value
1553    {
1554       char c;
1555       unsigned char uc;
1556       short s;
1557       unsigned short us;
1558       int i;
1559       unsigned int ui;
1560       float f;
1561       double d;
1562       // unsigned char * p; // Now always storing addresses in ui64
1563       int64 i64;
1564       uint64 ui64;
1565       // intptr iptr;
1566       // uintptr uiptr;
1567    };
1568    OpTable ops;
1569 };
1570
1571 public struct OpTable
1572 {
1573 public:
1574    // binary arithmetic
1575    bool (* Add)(Expression, Operand, Operand);
1576    bool (* Sub)(Expression, Operand, Operand);
1577    bool (* Mul)(Expression, Operand, Operand);
1578    bool (* Div)(Expression, Operand, Operand);
1579    bool (* Mod)(Expression, Operand, Operand);
1580
1581    // unary arithmetic
1582    bool (* Neg)(Expression, Operand);
1583
1584    // unary arithmetic increment and decrement
1585    bool (* Inc)(Expression, Operand);
1586    bool (* Dec)(Expression, Operand);
1587
1588    // binary arithmetic assignment
1589    bool (* Asign)(Expression, Operand, Operand);
1590    bool (* AddAsign)(Expression, Operand, Operand);
1591    bool (* SubAsign)(Expression, Operand, Operand);
1592    bool (* MulAsign)(Expression, Operand, Operand);
1593    bool (* DivAsign)(Expression, Operand, Operand);
1594    bool (* ModAsign)(Expression, Operand, Operand);
1595
1596    // binary bitwise
1597    bool (* BitAnd)(Expression, Operand, Operand);
1598    bool (* BitOr)(Expression, Operand, Operand);
1599    bool (* BitXor)(Expression, Operand, Operand);
1600    bool (* LShift)(Expression, Operand, Operand);
1601    bool (* RShift)(Expression, Operand, Operand);
1602    bool (* BitNot)(Expression, Operand);
1603
1604    // binary bitwise assignment
1605    bool (* AndAsign)(Expression, Operand, Operand);
1606    bool (* OrAsign)(Expression, Operand, Operand);
1607    bool (* XorAsign)(Expression, Operand, Operand);
1608    bool (* LShiftAsign)(Expression, Operand, Operand);
1609    bool (* RShiftAsign)(Expression, Operand, Operand);
1610
1611    // unary logical negation
1612    bool (* Not)(Expression, Operand);
1613
1614    // binary logical equality
1615    bool (* Equ)(Expression, Operand, Operand);
1616    bool (* Nqu)(Expression, Operand, Operand);
1617
1618    // binary logical
1619    bool (* And)(Expression, Operand, Operand);
1620    bool (* Or)(Expression, Operand, Operand);
1621
1622    // binary logical relational
1623    bool (* Grt)(Expression, Operand, Operand);
1624    bool (* Sma)(Expression, Operand, Operand);
1625    bool (* GrtEqu)(Expression, Operand, Operand);
1626    bool (* SmaEqu)(Expression, Operand, Operand);
1627
1628    bool (* Cond)(Expression, Operand, Operand, Operand);
1629 };
1630
1631 define MAX_INCLUDE_DEPTH = 30;
1632
1633 #include <stdarg.h>
1634
1635 void Compiler_Error(const char * format, ...)
1636 {
1637    if(inCompiler)
1638    {
1639       if(!parsingType)
1640       {
1641          va_list args;
1642          char string[10000];
1643
1644          if(yylloc.start.included)
1645          {
1646             GetWorkingDir(string, sizeof(string));
1647             PathCat(string, GetIncludeFileFromID(yylloc.start.included));
1648          }
1649          else
1650          {
1651             GetWorkingDir(string, sizeof(string));
1652             PathCat(string, sourceFile);
1653          }
1654          printf("%s", string);
1655
1656          /*
1657          yylloc.start.col = yylloc.end.col = 1;
1658          yylloc.start.line = yylloc.end.line = 1;
1659          yylloc.start.pos = yylloc.end.pos = 0;
1660          */
1661 #ifdef _DEBUG
1662          if(!yylloc.start.line)
1663             printf("no line");
1664 #endif
1665
1666          //printf("(%d, %d) : error: ", yylloc.start.line, yylloc.start.charPos);
1667          printf($":%d:%d: error: ", yylloc.start.line, yylloc.start.charPos);
1668          //printf(":%d: error: ", yylloc.start.line);
1669          va_start(args, format);
1670          vsnprintf(string, sizeof(string), format, args);
1671          string[sizeof(string)-1] = 0;
1672          va_end(args);
1673          fputs(string, stdout);
1674          fflush(stdout);
1675          __thisModule.application.exitCode = 1;
1676       }
1677       else
1678       {
1679          // Error parsing type
1680          parseTypeError = true;
1681       }
1682    }
1683 }
1684
1685 int numWarnings;
1686 public int GetNumWarnings() { return numWarnings; }
1687
1688 void Compiler_Warning(const char * format, ...)
1689 {
1690    if(inCompiler)
1691    {
1692       va_list args;
1693       char string[10000];
1694       char fileName[MAX_FILENAME];
1695
1696       if(yylloc.start.included)
1697       {
1698          String include = GetIncludeFileFromID(yylloc.start.included);
1699          GetWorkingDir(string, sizeof(string));
1700          PathCat(string, include);
1701       }
1702       else
1703       {
1704          GetWorkingDir(string, sizeof(string));
1705          PathCat(string, sourceFile);
1706       }
1707
1708       // Skip these warnings from MinGW-w64 GCC 4.8 in intrin-impl.h
1709       GetLastDirectory(string, fileName);
1710       if(!strcmp(fileName, "intrin-impl.h")) return;
1711
1712       printf("%s", string);
1713
1714       //printf("(%d, %d) : warning: ", yylloc.start.line, yylloc.start.charPos);
1715       printf($":%d:%d: warning: ", yylloc.start.line, yylloc.start.charPos);
1716       //printf(":%d: warning: ", yylloc.start.line);
1717       va_start(args, format);
1718       vsnprintf(string, sizeof(string), format, args);
1719       string[sizeof(string)-1] = 0;
1720       va_end(args);
1721       fputs(string, stdout);
1722       fflush(stdout);
1723       numWarnings++;
1724    }
1725 }
1726 bool parseError;
1727 bool skipErrors;
1728
1729 int yyerror()
1730 {
1731    if(!skipErrors)
1732    {
1733         //fflush(stdout);
1734         //printf("\n%*s\n%*s\n", column, "^", column, s);
1735       parseError = true;
1736       Compiler_Error($"syntax error\n");
1737    }
1738    return 0;
1739 }
1740
1741 Platform targetPlatform;
1742
1743 public int GetHostBits()
1744 {
1745    // Default to runtime platform in case we fail to determine host
1746    int hostBits = (sizeof(uintptr) == 8) ? 64 : 32;
1747    String hostType = getenv("HOSTTYPE");
1748    char host[256];
1749    if(!hostType)
1750    {
1751       DualPipe f = DualPipeOpen({ output = true }, "uname -m");
1752       if(f)
1753       {
1754          if(f.GetLine(host, sizeof(host)))
1755             hostType = host;
1756          delete f;
1757       }
1758    }
1759    if(hostType)
1760    {
1761       if(!strcmp(hostType, "x86_64"))
1762          hostBits = 64;
1763       else if(!strcmp(hostType, "i386") || !strcmp(hostType, "i686"))
1764          hostBits = 32;
1765    }
1766    return hostBits;
1767 }
1768
1769 public void SetTargetPlatform(Platform platform) { targetPlatform = platform; };
1770
1771 int targetBits;
1772
1773 public void SetTargetBits(int bits) { targetBits = bits; };
1774 public int GetTargetBits() { return targetBits; };