compiler/libec: Fix for thisclass related warnings in Map.ec
[sdk] / compiler / libec / src / ecdefs.ec
index 4d56a41..595a121 100644 (file)
@@ -21,6 +21,129 @@ import "dbpass"
 
 #include <stdio.h>
 
+#define yylloc _yylloc
+#include "grammar.h"
+#undef yylloc
+
+public enum TokenType
+{
+  identifier = IDENTIFIER,
+  constant = CONSTANT,
+  stringLiteral = STRING_LITERAL,
+  sizeOf = SIZEOF,
+  ptrOp = PTR_OP,
+  incOp = INC_OP,
+  decOp = DEC_OP,
+  leftOp = LEFT_OP,
+  rightOp = RIGHT_OP,
+  leOp = LE_OP,
+  geOp = GE_OP,
+  eqOp = EQ_OP,
+  neOp = NE_OP,
+  andOp = AND_OP,
+  orOp = OR_OP,
+  mulAssign = MUL_ASSIGN,
+  divAssign = DIV_ASSIGN,
+  modAssign = MOD_ASSIGN,
+  addAssign = ADD_ASSIGN,
+  subAssign = SUB_ASSIGN,
+  leftAssign = LEFT_ASSIGN,
+  rightAssign = RIGHT_ASSIGN,
+  andAssign = AND_ASSIGN,
+  xorAssign = XOR_ASSIGN,
+  orAssign = OR_ASSIGN,
+  typeName = TYPE_NAME,
+  _typedef = TYPEDEF,
+  _extern = EXTERN,
+  _static = STATIC,
+  _auto = AUTO,
+  _register = REGISTER,
+  _char = CHAR,
+  _short = SHORT,
+  _int = INT,
+  _uint = UINT,
+  _int64 = INT64,
+  _long = LONG,
+  _signed = SIGNED,
+  _unsigned = UNSIGNED,
+  _float = FLOAT,
+  _double = DOUBLE,
+  _const = CONST,
+  _volatile = VOLATILE,
+  _void = VOID,
+  _valist = VALIST,
+  _struct = STRUCT,
+  _union = UNION,
+  _enum = ENUM,
+  ellipsis = ELLIPSIS,
+  _case = CASE,
+  _default = DEFAULT,
+  _if = IF,
+  _switch = SWITCH,
+  _whilte = WHILE,
+  _do = DO,
+  _for = FOR,
+  _goto = GOTO,
+  _continue = CONTINUE,
+  _break = BREAK,
+  _return = RETURN,
+  ifx = IFX,
+  _else = ELSE,
+  _class = CLASS,
+  thisClass = THISCLASS,
+  className = CLASS_NAME,
+  _property = PROPERTY,
+  setProp = SETPROP,
+  getProp = GETPROP,
+  newOp = NEWOP,
+  _renew = RENEW,
+  _delete = DELETE,
+  _extDecl = EXT_DECL,
+  _extStorage = EXT_STORAGE,
+  _import = IMPORT,
+  _define = DEFINE,
+  _virtual = VIRTUAL,
+  attrib = ATTRIB,
+  _public = PUBLIC,
+  _priate = PRIVATE,
+  typedObject = TYPED_OBJECT,
+  anyObject = ANY_OBJECT,
+  _incref = _INCREF,
+  extension = EXTENSION,
+  ___asm = ASM,
+  _typeof = TYPEOF,
+  _watch = WATCH,
+  stopWatching = STOPWATCHING,
+  fireWatchers = FIREWATCHERS,
+  _watchable = WATCHABLE,
+  classDesigner = CLASS_DESIGNER,
+  classNoExpansion = CLASS_NO_EXPANSION,
+  classFixed = CLASS_FIXED,
+  isPropSet = ISPROPSET,
+  classDefaultProperty = CLASS_DEFAULT_PROPERTY,
+  propertyCategory = PROPERTY_CATEGORY,
+  classData = CLASS_DATA,
+  classProperty = CLASS_PROPERTY,
+  subClass = SUBCLASS,
+  nameSpace = NAMESPACE,
+  new0Op = NEW0OP,
+  renew0Op = RENEW0,
+  vaArg = VAARG,
+  dbTable = DBTABLE,
+  dbField = DBFIELD,
+  dbIndex = DBINDEX,
+  databaseOpen = DATABASE_OPEN,
+  alignOf = ALIGNOF,
+  attribDep = ATTRIB_DEP,
+  _attrib = __ATTRIB,
+  BOOL = BOOL,
+  _BOOL = _BOOL,
+  complex = _COMPLEX,
+  imaginary = _IMAGINARY,
+  _restrict = RESTRICT,
+  _thread = THREAD
+};
+
 enum Order { ascending, descending };
 
 public class DBTableDef : struct
@@ -28,7 +151,7 @@ public class DBTableDef : struct
 public:
    char * name;
    Symbol symbol;
-   OldList * definitions;   
+   OldList * definitions;
    AccessMode declMode;
 }
 
@@ -60,6 +183,9 @@ class DBIndexItem : struct
 bool inCompiler = false;
 public void SetInCompiler(bool b) { inCompiler = b; }
 
+bool inDebugger = false;
+public void SetInDebugger(bool b) { inDebugger = b; }
+
 Context curContext;
 Context globalContext;
 OldList * excludedSymbols;
@@ -74,14 +200,16 @@ public void SetMainModule(ModuleImport moduleImport) { mainModule = moduleImport
 File fileInput;
 public void SetFileInput(File file) { fileInput = file; }
 char * symbolsDir = null;
-public void SetSymbolsDir(char * s) { 
+public void SetSymbolsDir(const char * s) {
    delete symbolsDir;
    symbolsDir = CopyString(s);
-} public char * GetSymbolsDir() { return symbolsDir ? symbolsDir : ""; }
-char * outputFile;
-public void SetOutputFile(char * s) { outputFile = s; } public char * GetOutputFile() { return outputFile; }
-char * sourceFile;
-public void SetSourceFile(char * s) { sourceFile = s; } public char * GetSourceFile() { return sourceFile; }
+} public const char * GetSymbolsDir() { return symbolsDir ? symbolsDir : ""; }
+const char * outputFile;
+public void SetOutputFile(const char * s) { outputFile = s; } public const char * GetOutputFile() { return outputFile; }
+const char * sourceFile;
+public void SetSourceFile(const char * s) { sourceFile = s; } public const char * GetSourceFile() { return sourceFile; }
+const char * i18nModuleName;
+public void SetI18nModuleName(const char * s) { i18nModuleName = s; } public const char * GetI18nModuleName() { return i18nModuleName; }
 
 public void SetGlobalContext(Context context) { globalContext = context; } public Context GetGlobalContext() { return globalContext; }
 public void SetTopContext(Context context) { topContext = context; } public Context GetTopContext() { return topContext; }
@@ -93,6 +221,54 @@ public void SetDefines(OldList * list) { defines = list; }
 bool outputLineNumbers = true;
 public void SetOutputLineNumbers(bool value) { outputLineNumbers = value; }
 
+public void FixModuleName(char *moduleName)
+{
+   ChangeCh(moduleName, '.', '_');
+   ChangeCh(moduleName, ' ', '_');
+   ChangeCh(moduleName, '-', '_');
+   ChangeCh(moduleName, '&', '_');
+}
+
+// todo support %var% variables for windows and $var for linux?
+public char * PassArg(char * output, const char * input)
+{
+#ifdef __WIN32__
+//define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
+   const char * escChars = " !\"%&'()+,;=[]^`{}~"; // windowsFileNameCharsNeedEscaping;
+   const char * escCharsQuoted = "\"";
+#else
+//define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
+   const char * escChars = " !\"$&'()*:;<=>?[\\`{|"; // linuxFileNameCharsNeedEscaping;
+   const char * escCharsQuoted = "\"()$";
+#endif
+   bool quoting = false;
+   char *o = output;
+   const char *i = input, *l = input;
+#ifdef __WIN32__
+   while(*l && !strchr(escChars, *l)) l++;
+   if(*l) quoting = true;
+#else
+   if(*i == '-')
+   {
+      l++;
+      while(*l && !strchr(escChars, *l)) l++;
+      if(*l) quoting = true;
+      *o++ = *i++;
+   }
+#endif
+   if(quoting)
+      *o++ = '\"';
+   while(*i)
+   {
+      if(strchr(quoting ? escCharsQuoted : escChars, *i))
+         *o++ = '\\';
+      *o++ = *i++;
+   }
+   if(quoting)
+      *o++ = '\"';
+   *o = '\0';
+   return o;
+}
 /*public Module GetPrivateModule()
 {
    return privateModule;
@@ -125,7 +301,7 @@ public struct CodePosition
 {
 public:
    int line, charPos, pos;
-   bool included;
+   int included;
 
    void AdjustDelete(BufferLocation start, BufferLocation end)
    {
@@ -143,7 +319,7 @@ public:
             if(line - 1 > end.y)
                line -= end.y - start.y;
             // Location is the last touched line
-            else 
+            else
             {
                if(charPos - 1 >= end.x)
                {
@@ -174,7 +350,7 @@ public:
             if(charPos - 1 > start.x || (charPos - 1 == start.x /*&& (numLines ? true : false)*/))
             {
                line += numLines;
-               //charPos - 1 += numLines ? end.x : (end.x - start.x);            
+               //charPos - 1 += numLines ? end.x : (end.x - start.x);
                charPos += end.x - start.x;
             }
          }
@@ -189,7 +365,7 @@ public:
 
    bool Inside(int line, int charPos)
    {
-      return (start.line < line || (start.line == line && start.charPos <= charPos)) && 
+      return (start.line < line || (start.line == line && start.charPos <= charPos)) &&
              (end.line > line || (end.line == line && end.charPos >= charPos));
    }
 };
@@ -229,16 +405,17 @@ public:
 };
 
 public enum ExpressionType
-{ 
+{
    identifierExp, instanceExp, constantExp, stringExp, opExp,
    bracketsExp, indexExp, callExp, memberExp, pointerExp, typeSizeExp,
    castExp, conditionExp, newExp, renewExp, classSizeExp,
-   dummyExp, dereferenceErrorExp, symbolErrorExp, classMemberSymbolErrorExp,
-   structMemberSymbolErrorExp, memoryErrorExp, unknownErrorExp,
-   noDebuggerErrorExp, debugStateErrorExp,
+   dummyExp, dereferenceErrorExp, symbolErrorExp,
+   memberSymbolErrorExp, memoryErrorExp, unknownErrorExp,
+   noDebuggerErrorExp,
    extensionCompoundExp, classExp, classDataExp, new0Exp, renew0Exp,
    dbopenExp, dbfieldExp, dbtableExp, dbindexExp, extensionExpressionExp, extensionInitializerExp,
-   vaArgExp, arrayExp
+   vaArgExp, arrayExp, typeAlignExp,
+   memberPropertyErrorExp, functionCallErrorExp, divideBy0ErrorExp
 };
 
 public enum MemberType
@@ -257,7 +434,7 @@ public class TemplateParameter : struct
 public:
    TemplateParameter prev, next;
    Location loc;
-   
+
    TemplateParameterType type;
    Identifier identifier;
    union
@@ -266,9 +443,9 @@ public:
       TemplateMemberType memberType;   // For identifier
    };
    TemplateArgument defaultArgument;
-    
+
    // For type parameters
-   char * dataTypeString;
+   const char * dataTypeString;
    Type baseType;
 }
 
@@ -284,7 +461,7 @@ public class TemplateArgument : struct
 public:
    TemplateArgument prev, next;
    Location loc;
-   
+
    Identifier name;
    TemplateParameterType type;
    union
@@ -312,18 +489,20 @@ public:
       int specifier;
       struct
       {
+         ExtDecl extDecl;
          char * name;
          Symbol symbol;
-         OldList * templateArgs;
+         OldList/*<TemplateArgument>*/ * templateArgs;
       };
       struct
       {
          Identifier id;
-         OldList * list;
-         OldList * baseSpecs;
-         OldList * definitions;
+         OldList/*<Enumerator>*/ * list;
+         OldList/*<Specifier>*/ * baseSpecs;
+         OldList/*<ClassDef>*/ * definitions;
          bool addNameSpace;
          Context ctx;
+         ExtDecl extDeclStruct;
       };
       Expression expression;
       Specifier _class;
@@ -331,6 +510,40 @@ public:
    };
 };
 
+public class Attribute : struct
+{
+public:
+   Attribute prev, next;
+   Location loc;
+   String attr;
+   Expression exp;
+}
+
+public class Attrib : struct
+{
+public:
+   Location loc;
+   int type;
+   OldList * attribs;
+}
+
+public class ExtDecl : struct
+{
+public:
+   Location loc;
+   ExtDeclType type;
+   union
+   {
+      String s;
+      Attrib attr;
+   };
+}
+
+public enum ExtDeclType
+{
+   extDeclString, extDeclAttrib
+};
+
 public class Expression : struct
 {
 public:
@@ -346,7 +559,12 @@ public:
       };
       Statement compound;
       Instantiation instance;
-      char * string;
+      struct
+      {
+         char * string;
+         bool intlString;
+         bool wideString;
+      };
       OldList * list;
       struct
       {
@@ -431,7 +649,7 @@ public:
 
    DataValue val;
 
-   uint address;
+   uint64 address;
    bool hasAddress;
 
    // *** COMPILING DATA ***
@@ -445,6 +663,8 @@ public:
    bool addedThis;
    bool needCast;
    bool thisPtr;
+   bool opDestType;
+   uint needTemplateCast;
 
    void Clear()
    {
@@ -463,6 +683,8 @@ public:
       addedThis = false;
       needCast = false;
       thisPtr = false;
+      opDestType = false;
+      needTemplateCast = 0;
    }
 };
 
@@ -485,7 +707,7 @@ class Pointer : struct
 
 public enum DeclaratorType
 {
-   structDeclarator, identifierDeclarator, bracketsDeclarator, arrayDeclarator, 
+   structDeclarator, identifierDeclarator, bracketsDeclarator, arrayDeclarator,
    functionDeclarator, pointerDeclarator, extendedDeclarator, extendedDeclaratorEnd
 };
 
@@ -504,7 +726,7 @@ public:
       {
          Expression exp;
          Expression posExp;
-         char * attrib;
+         Attrib attrib;
       } structDecl;
       struct
       {
@@ -521,7 +743,7 @@ public:
       } pointer;
       struct
       {
-         char * extended;
+         ExtDecl extended;
       } extended;
    };
 };
@@ -540,6 +762,7 @@ public:
       OldList * list;
    };
    bool isConstant;
+   Identifier id;
 };
 
 public class InitDeclarator : struct
@@ -578,10 +801,11 @@ class AsmField : struct
    Location loc;
    char * command;
    Expression expression;
+   Identifier symbolic;
 };
 
 public enum StmtType { labeledStmt, caseStmt, compoundStmt,
-               expressionStmt, ifStmt, switchStmt, whileStmt, doWhileStmt, 
+               expressionStmt, ifStmt, switchStmt, whileStmt, doWhileStmt,
                forStmt, gotoStmt, continueStmt, breakStmt, returnStmt, asmStmt, badDeclarationStmt,
                fireWatchersStmt, stopWatchingStmt, watchStmt, forEachStmt
              };
@@ -616,7 +840,7 @@ public:
       {
          OldList * exp;
          Statement stmt;
-         Statement elseStmt;                  
+         Statement elseStmt;
       } ifStmt;
       struct
       {
@@ -745,7 +969,7 @@ public:
    Class _class;
    OldList attached;    // For IDE
    AccessMode declMode;
-   
+
    // COMPILING DATA
    Type type;
    Symbol propSet;
@@ -798,7 +1022,6 @@ public:
    Symbol symbol;
    Location blockStart;
    Location nameLoc;
-   int endid;
    AccessMode declMode;
    bool deleteWatchable;
 };
@@ -814,7 +1037,7 @@ public:
 };
 
 public enum ClassDefType
-{ 
+{
    functionClassDef, defaultPropertiesClassDef, declarationClassDef, propertyClassDef,
    propertyWatchClassDef, classDesignerClassDef, classNoExpansionClassDef, classFixedClassDef,
    designerDefaultPropertyClassDef, classDataClassDef, classPropertyClassDef, classPropertyValueClassDef,
@@ -833,9 +1056,13 @@ public:
    Statement setStmt;
    Statement issetStmt;
    Symbol symbol;
-   bool conversion;
-   bool isWatchable;
-   char * category;
+   Expression category;
+   struct
+   {
+      bool conversion:1;
+      bool isWatchable:1;
+      bool isDBProp:1;
+   };
 };
 
 public class ClassDef : struct
@@ -865,6 +1092,14 @@ public:
    void * object;
 };
 
+// An 'edge from' is a 'dependency on'
+class TopoEdge : struct
+{
+   public LinkElement<TopoEdge> in, out;
+   External from, to;
+   bool breakable;
+};
+
 public enum ExternalType { functionExternal, declarationExternal, classExternal, importExternal, nameSpaceExternal, dbtableExternal };
 
 public class External : struct
@@ -884,6 +1119,109 @@ public:
       DBTableDef table;
    };
    ImportType importType;
+
+   // For the TopoSort
+   External fwdDecl;
+   LinkList<TopoEdge, link = out> outgoing { };
+   LinkList<TopoEdge, link = in> incoming { };
+   int nonBreakableIncoming;
+
+   void CreateUniqueEdge(External from, bool soft)
+   {
+      for(i : from.outgoing; i.to == this)
+      {
+         if(i.breakable && !soft)
+         {
+#ifdef _DEBUG
+            if(from == this)
+               PrintLn("bug: self-dependency");
+#endif
+            i.breakable = false;
+            nonBreakableIncoming++;
+         }
+         return;
+      }
+      CreateEdge(from, soft);
+   }
+
+   void CreateEdge(External from, bool soft)
+   {
+      TopoEdge e { from = from, to = this, breakable = soft };
+
+#ifdef _DEBUG
+      if(from == this && !soft)
+         PrintLn("bug: self-dependency");
+
+      /*for(i : from.outgoing)
+      {
+         if(i.to == this)
+            PrintLn("Warning: adding a duplicate edge");
+      }*/
+#endif
+
+      from.outgoing.Add(e);
+      incoming.Add(e);
+      if(!soft)
+         nonBreakableIncoming++;
+   }
+
+   External ForwardDeclare()
+   {
+      External f = null;
+      Context tmpContext = curContext;
+
+      switch(type)
+      {
+         case declarationExternal:
+         {
+            if(declaration.type == initDeclaration)
+            {
+               OldList * specs = declaration.specifiers;
+               if(specs)
+               {
+                  Specifier s;
+                  for(s = specs->first; s; s = s.next)
+                  {
+                     if(s.type == structSpecifier || s.type == unionSpecifier)
+                        break;
+                  }
+                  if(s)
+                  {
+                     curContext = null;
+                     f = MkExternalDeclaration(MkDeclaration(MkListOne(MkStructOrUnion(s.type, CopyIdentifier(s.id), null)), null));
+                     curContext = tmpContext;
+                  }
+               }
+            }
+            break;
+         }
+         case functionExternal:
+         {
+            curContext = null;
+            f = MkExternalDeclaration(MkDeclaration(CopyList(function.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(CopyDeclarator(function.declarator), null))));
+            curContext = tmpContext;
+            f.symbol = symbol;
+
+            DeclareTypeForwardDeclare(f, symbol.type, false, false);
+            break;
+         }
+      }
+
+      /*
+      for(i : m.protoDepsExternal)
+      {
+         // If the edge is already added, don't bother
+         if(i.incoming.count)
+            CreateEdge(f, i.fwdDecl ? i.fwdDecl : i, i.fwdDecl ? false : true);
+      }
+      */
+
+      fwdDecl = f;
+
+      if(!f)
+         PrintLn("warning: unhandled forward declaration requested");
+      return f;
+   }
 };
 
 public class Context : struct
@@ -899,6 +1237,7 @@ public:
    BinaryTree templateTypes { CompareKey = (void *)BinaryTree::CompareString };
    ClassDefinition classDef;
    bool templateTypesOnly;
+   bool hasNameSpace;
 };
 
 /*************** Compiling passes symbols ***************/
@@ -917,7 +1256,7 @@ public:
       Property _property;
       Class registered;
    };
-   int id, idCode;
+   bool notYetDeclared;
    union
    {
       struct
@@ -947,7 +1286,7 @@ public:
    char * constructorName, * structName, * className, * destructorName;
 
    ModuleImport module;
-   ClassImport _import;  
+   ClassImport _import;
    Location nameLoc;
    bool isParam;
    bool isRemote;
@@ -961,6 +1300,7 @@ public:
    OldList templatedClasses;
    Context ctx;
    int isIterator;
+   Expression propCategory;
 };
 
 // For the .imp file:
@@ -972,7 +1312,7 @@ public:
    OldList methods;
    OldList properties;
    bool itself;
-   bool isRemote;
+   int isRemote;
 };
 
 public class FunctionImport : struct
@@ -1012,11 +1352,11 @@ public:
 
 // For the .sym file:
 public enum TypeKind
-{ 
+{
    voidType, charType, shortType, intType, int64Type, longType, floatType,
    doubleType, classType, structType, unionType, functionType, arrayType, pointerType,
    ellipsisType, enumType, methodType, vaListType, /*typedObjectType, anyObjectType, classPointerType, */ dummyType,
-   subClassType, templateType, thisClassType
+   subClassType, templateType, thisClassType, intPtrType, intSizeType, _BoolType
 };
 
 public class Type : struct
@@ -1045,7 +1385,7 @@ public:
       struct
       {
          Method method;
-         Class methodClass;
+         Class methodClass;      // Clarify what this is!
          Class usedClass;
       };
 
@@ -1062,29 +1402,38 @@ public:
       Type type;
       TemplateParameter templateParameter;
    };
-   bool isSigned;
    TypeKind kind;
-   bool constant;
    uint size;
    char * name;
    char * typeName;
-   bool count;
-   bool truth;
+   Class thisClassFrom;
 
    ClassObjectType classObjectType;
-   bool byReference;
-
-   bool extraParam;
    int alignment;
-   bool directClassAccess;
-   bool computing;
-   bool dllExport;
    uint offset;
-   bool keepCast;
-   bool passAsTemplate;
    int bitFieldCount;
-
-   char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+   int count;  // This is used to avoid outputting warnings when non-zero
+
+   bool isSigned:1;
+   bool constant:1;
+   bool truth:1;
+   bool byReference:1;
+   bool extraParam:1;      // Clarify this... One thing it is used for is adaptive method with their own type explicitly specified
+   bool directClassAccess:1;     // Need to clarify this if this had the same intended purpose as declaredWithStruct
+   bool computing:1;
+   bool keepCast:1;
+   bool passAsTemplate:1;
+   bool dllExport:1;
+   bool attrStdcall:1;
+   bool declaredWithStruct:1;
+   bool typedByReference:1;      // Originally typed by reference, regardless of class type
+   bool casted:1;
+   bool pointerAlignment:1; // true if the alignment is the pointer size
+   // bool wasThisClass:1;
+   // TODO: Add _Complex & _Imaginary support
+   // bool complex:1, imaginary:1;
+
+   const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
    {
       Type type = (Type)this;
       tempString[0] = '\0';
@@ -1095,9 +1444,101 @@ public:
 
    void OnFree()
    {
-      
+
+   }
+
+   property bool specConst
+   {
+      get
+      {
+         Type t = this;
+         while((t.kind == pointerType || t.kind == arrayType) && t.type) t = t.type;
+         return t.constant;
+      }
+   }
+
+   // Used for generating calls to eClass_AddDataMember (differs slightly from 'isPointerType' below), meant to return true where ComputeTypeSize returns targetBits / 8
+   property bool isPointerTypeSize
+   {
+      get
+      {
+         bool result = false;
+         if(this)
+         {
+            switch(kind)
+            {
+               case classType:
+               {
+                  Class _class = this._class ? this._class.registered : null;
+                  if(!_class || (_class.type != structClass && _class.type != unitClass && _class.type != enumClass && _class.type != bitClass))
+                     result = true;
+                  break;
+               }
+               case pointerType:
+               case subClassType:
+               case thisClassType:
+               case intPtrType:
+               case intSizeType:
+                  result = true;
+                  break;
+               case templateType:
+               {
+                  TemplateParameter param = templateParameter;
+                  Type baseType = ProcessTemplateParameterType(param);
+                  if(baseType)
+                     result = baseType.isPointerTypeSize;
+                  break;
+               }
+            }
+         }
+         return result;
+      }
+   }
+
+   property bool isPointerType
+   {
+      get
+      {
+         if(this)
+         {
+            if(kind == pointerType || kind == methodType || kind == functionType || kind == arrayType || kind == subClassType)
+               return true;
+            else if(kind == classType)
+            {
+               if(_class && _class.registered)
+               {
+                  Class c = _class.registered;
+                  if(c.type == bitClass || c.type == unitClass || c.type == enumClass || c.type == systemClass)
+                     return false;
+                  else if(c.type == structClass && !byReference)
+                     return false;
+               }
+               return true;
+            }
+            else if(kind == templateType)
+            {
+               if(passAsTemplate) return false;
+               if(templateParameter)
+               {
+                  if(templateParameter.dataType)
+                  {
+                     Specifier spec = templateParameter.dataType.specifiers ? templateParameter.dataType.specifiers->first : null;
+                     if(templateParameter.dataType.decl && templateParameter.dataType.decl.type == pointerDeclarator)
+                        return true;
+                     if(spec && spec.type == nameSpecifier && strcmp(spec.name, "uint64"))
+                        return true;
+                  }
+                  if(templateParameter.dataTypeString)
+                     return true;
+               }
+            }
+            else
+               return false;
+         }
+         return false;
+      }
    }
-};            
+};
 
 public struct Operand
 {
@@ -1115,9 +1556,11 @@ public:
       unsigned int ui;
       float f;
       double d;
-      unsigned char * p;
+      // unsigned char * p; // Now always storing addresses in ui64
       int64 i64;
       uint64 ui64;
+      // intptr iptr;
+      // uintptr uiptr;
    };
    OpTable ops;
 };
@@ -1131,14 +1574,14 @@ public:
    bool (* Mul)(Expression, Operand, Operand);
    bool (* Div)(Expression, Operand, Operand);
    bool (* Mod)(Expression, Operand, Operand);
-   
+
    // unary arithmetic
    bool (* Neg)(Expression, Operand);
-   
+
    // unary arithmetic increment and decrement
    bool (* Inc)(Expression, Operand);
    bool (* Dec)(Expression, Operand);
-   
+
    // binary arithmetic assignment
    bool (* Asign)(Expression, Operand, Operand);
    bool (* AddAsign)(Expression, Operand, Operand);
@@ -1146,7 +1589,7 @@ public:
    bool (* MulAsign)(Expression, Operand, Operand);
    bool (* DivAsign)(Expression, Operand, Operand);
    bool (* ModAsign)(Expression, Operand, Operand);
-   
+
    // binary bitwise
    bool (* BitAnd)(Expression, Operand, Operand);
    bool (* BitOr)(Expression, Operand, Operand);
@@ -1154,39 +1597,39 @@ public:
    bool (* LShift)(Expression, Operand, Operand);
    bool (* RShift)(Expression, Operand, Operand);
    bool (* BitNot)(Expression, Operand);
-   
+
    // binary bitwise assignment
    bool (* AndAsign)(Expression, Operand, Operand);
    bool (* OrAsign)(Expression, Operand, Operand);
    bool (* XorAsign)(Expression, Operand, Operand);
    bool (* LShiftAsign)(Expression, Operand, Operand);
    bool (* RShiftAsign)(Expression, Operand, Operand);
-   
+
    // unary logical negation
    bool (* Not)(Expression, Operand);
-   
+
    // binary logical equality
    bool (* Equ)(Expression, Operand, Operand);
    bool (* Nqu)(Expression, Operand, Operand);
-   
+
    // binary logical
    bool (* And)(Expression, Operand, Operand);
    bool (* Or)(Expression, Operand, Operand);
-   
+
    // binary logical relational
    bool (* Grt)(Expression, Operand, Operand);
    bool (* Sma)(Expression, Operand, Operand);
    bool (* GrtEqu)(Expression, Operand, Operand);
    bool (* SmaEqu)(Expression, Operand, Operand);
-   
+
    bool (* Cond)(Expression, Operand, Operand, Operand);
 };
 
-define MAX_INCLUDE_DEPTH = 10;
+define MAX_INCLUDE_DEPTH = 30;
 
 #include <stdarg.h>
 
-void Compiler_Error(char * format, ...)
+void Compiler_Error(const char * format, ...)
 {
    if(inCompiler)
    {
@@ -1205,7 +1648,7 @@ void Compiler_Error(char * format, ...)
             GetWorkingDir(string, sizeof(string));
             PathCat(string, sourceFile);
          }
-         printf(string);
+         printf("%s", string);
 
          /*
          yylloc.start.col = yylloc.end.col = 1;
@@ -1214,16 +1657,18 @@ void Compiler_Error(char * format, ...)
          */
 #ifdef _DEBUG
          if(!yylloc.start.line)
-            printf("");
+            printf("no line");
 #endif
 
          //printf("(%d, %d) : error: ", yylloc.start.line, yylloc.start.charPos);
-         printf(":%d:%d: error: ", yylloc.start.line, yylloc.start.charPos);
+         printf($":%d:%d: error: ", yylloc.start.line, yylloc.start.charPos);
          //printf(":%d: error: ", yylloc.start.line);
          va_start(args, format);
-         vsprintf(string,format,args);
+         vsnprintf(string, sizeof(string), format, args);
+         string[sizeof(string)-1] = 0;
          va_end(args);
          fputs(string, stdout);
+         fflush(stdout);
          __thisModule.application.exitCode = 1;
       }
       else
@@ -1237,51 +1682,90 @@ void Compiler_Error(char * format, ...)
 int numWarnings;
 public int GetNumWarnings() { return numWarnings; }
 
-void Compiler_Warning(char * format, ...)
+void Compiler_Warning(const char * format, ...)
 {
    if(inCompiler)
    {
       va_list args;
       char string[10000];
+      char fileName[MAX_FILENAME];
 
       if(yylloc.start.included)
       {
+         String include = GetIncludeFileFromID(yylloc.start.included);
          GetWorkingDir(string, sizeof(string));
-         PathCat(string, GetIncludeFileFromID(yylloc.start.included));
+         PathCat(string, include);
       }
       else
       {
          GetWorkingDir(string, sizeof(string));
          PathCat(string, sourceFile);
       }
-      
-      printf(string);
+
+      // Skip these warnings from MinGW-w64 GCC 4.8 in intrin-impl.h
+      GetLastDirectory(string, fileName);
+      if(!strcmp(fileName, "intrin-impl.h")) return;
+
+      printf("%s", string);
 
       //printf("(%d, %d) : warning: ", yylloc.start.line, yylloc.start.charPos);
-      printf(":%d:%d: warning: ", yylloc.start.line, yylloc.start.charPos);
+      printf($":%d:%d: warning: ", yylloc.start.line, yylloc.start.charPos);
       //printf(":%d: warning: ", yylloc.start.line);
       va_start(args, format);
-      vsprintf(string,format,args);
+      vsnprintf(string, sizeof(string), format, args);
+      string[sizeof(string)-1] = 0;
       va_end(args);
       fputs(string, stdout);
+      fflush(stdout);
       numWarnings++;
    }
 }
 bool parseError;
 bool skipErrors;
 
-int yyerror(char * s)
+int yyerror()
 {
    if(!skipErrors)
    {
        //fflush(stdout);
        //printf("\n%*s\n%*s\n", column, "^", column, s);
       parseError = true;
-      Compiler_Error("syntax error\n");
+      Compiler_Error($"syntax error\n");
    }
    return 0;
 }
 
 Platform targetPlatform;
 
+public int GetHostBits()
+{
+   // Default to runtime platform in case we fail to determine host
+   int hostBits = (sizeof(uintptr) == 8) ? 64 : 32;
+   String hostType = getenv("HOSTTYPE");
+   char host[256];
+   if(!hostType)
+   {
+      DualPipe f = DualPipeOpen({ output = true }, "uname -m");
+      if(f)
+      {
+         if(f.GetLine(host, sizeof(host)))
+            hostType = host;
+         delete f;
+      }
+   }
+   if(hostType)
+   {
+      if(!strcmp(hostType, "x86_64"))
+         hostBits = 64;
+      else if(!strcmp(hostType, "i386") || !strcmp(hostType, "i686"))
+         hostBits = 32;
+   }
+   return hostBits;
+}
+
 public void SetTargetPlatform(Platform platform) { targetPlatform = platform; };
+
+int targetBits;
+
+public void SetTargetBits(int bits) { targetBits = bits; };
+public int GetTargetBits() { return targetBits; };