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