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