compiler/libec: Fixed passing of typed objects in ellipsis functions; Fixed string...
[sdk] / compiler / libec / src / pass15.ec
index 291508e..1d32137 100644 (file)
@@ -9,7 +9,7 @@ import "ecdefs"
    (_class ? ((void *)(((char *)_class.data) + baseClass.offsetClass)) : null)
 
 #define YYLTYPE Location
-#include "grammar.eh"
+#include "grammar.h"
 
 extern OldList * ast;
 extern int returnCode;
@@ -34,6 +34,8 @@ static char * thisNameSpace;
 /*static */Class containerClass;
 bool thisClassParams = true;
 
+uint internalValueCounter;
+
 #ifdef _DEBUG
 Time findSymbolTotalTime;
 #endif
@@ -56,117 +58,6 @@ Time findSymbolTotalTime;
    }
 }
 
-int64 _strtoi64(char * string, char ** endString, int base)
-{
-   int64 value = 0;
-   int sign = 1;
-   int c;
-   char ch;
-   for(c = 0; (ch = string[c]) && isspace(ch); c++);
-   if(ch =='+') c++;
-   else if(ch == '-') { sign = -1; c++; };
-   if(!base)
-   {
-      if(ch == 0 && string[c+1] == 'x')
-      {
-         base = 16;
-         c+=2;
-      }
-      else if(ch == '0')
-      {
-         base = 8;
-         c++;
-      }
-      else
-         base = 10;
-   }
-   for( ;(ch = string[c]); c++)
-   {
-      if(ch == '0')
-         ch = 0;
-      else if(ch >= '1' && ch <= '9')
-         ch -= '1';
-      else if(ch >= 'a' && ch <= 'z') 
-         ch -= 'a'; 
-      else if(ch >= 'A' && ch <= 'Z') 
-         ch -= 'A';
-      else
-      {
-         *endString = string + c;
-         // Invalid character
-         break;
-      }
-      if(ch < base)
-      {
-         value *= base;
-         value += ch;
-      }
-      else
-      {
-         *endString = string + c;
-         // Invalid character
-         break;
-      }
-   }
-   return sign*value;
-}
-
-uint64 _strtoui64(char * string, char ** endString, int base)
-{
-   uint64 value = 0;
-   int sign = 1;
-   int c;
-   char ch;
-   for(c = 0; (ch = string[c]) && isspace(ch); c++);
-   if(ch =='+') c++;
-   else if(ch == '-') { sign = -1; c++; };
-   if(!base)
-   {
-      if(ch == 0 && string[c+1] == 'x')
-      {
-         base = 16;
-         c+=2;
-      }
-      else if(ch == '0')
-      {
-         base = 8;
-         c++;
-      }
-      else
-         base = 10;
-   }
-   for( ;(ch = string[c]); c++)
-   {
-      if(ch == '0')
-         ch = 0;
-      else if(ch >= '1' && ch <= '9')
-         ch -= '1';
-      else if(ch >= 'a' && ch <= 'z') 
-         ch -= 'a'; 
-      else if(ch >= 'A' && ch <= 'Z') 
-         ch -= 'A';
-      else
-      {
-         if(endString) *endString = string + c;
-         // Invalid character
-         break;
-      }
-      if(ch < base)
-      {
-         value *= base;
-         value += ch;
-      }
-      else
-      {
-         if(endString)
-            *endString = string + c;
-         // Invalid character
-         break;
-      }
-   }
-   return sign*value;
-}
-
 Type ProcessTemplateParameterType(TemplateParameter param)
 {
    if(param && param.type == TemplateParameterType::type && (param.dataType || param.dataTypeString))
@@ -201,6 +92,8 @@ bool NeedCast(Type type1, Type type2)
          case shortType:
          case intType:
          case int64Type:
+         case intPtrType:
+         case intSizeType:
             if(type1.passAsTemplate && !type2.passAsTemplate)
                return true;
             return type1.isSigned != type2.isSigned;
@@ -238,7 +131,7 @@ static void ReplaceClassMembers(Expression exp, Class _class)
          Property prop = eClass_FindProperty(_class, id.string, privateModule);
          Method method = null;
          DataMember member = null;
-         ClassProperty classProp;
+         ClassProperty classProp = null;
          if(!prop)
          {
             method = eClass_FindMethod(_class, id.string, privateModule);
@@ -402,14 +295,14 @@ public char * PrintUChar(unsigned char result)
 
 public char * PrintFloat(float result)
 {
-   char temp[100];
+   char temp[350];
    sprintf(temp, "%.16ff", result);
    return CopyString(temp);
 }
 
 public char * PrintDouble(double result)
 {
-   char temp[100];
+   char temp[350];
    sprintf(temp, "%.16f", result);
    return CopyString(temp);
 }
@@ -425,30 +318,41 @@ public char * PrintDouble(double result)
       Operand op2 = GetOperand(exp);                        \
       if(op2.kind == intType && op2.type.isSigned) *value2 = (t) op2.i; \
       else if(op2.kind == intType) *value2 = (t) op2.ui;                 \
-      if(op2.kind == int64Type && op2.type.isSigned) *value2 = (t) op2.i64; \
+      else if(op2.kind == int64Type && op2.type.isSigned) *value2 = (t) op2.i64; \
       else if(op2.kind == int64Type) *value2 = (t) op2.ui64;                 \
+      else if(op2.kind == intSizeType && op2.type.isSigned) *value2 = (t) op2.i64; \
+      else if(op2.kind == intSizeType) *value2 = (t) op2.ui64; \
+      else if(op2.kind == intPtrType && op2.type.isSigned) *value2 = (t) op2.i64; \
+      else if(op2.kind == intPtrType) *value2 = (t) op2.ui64;                 \
       else if(op2.kind == shortType && op2.type.isSigned) *value2 = (t) op2.s;   \
       else if(op2.kind == shortType) *value2 = (t) op2.us;                        \
       else if(op2.kind == charType && op2.type.isSigned) *value2 = (t) op2.c;    \
       else if(op2.kind == charType) *value2 = (t) op2.uc;                         \
       else if(op2.kind == floatType) *value2 = (t) op2.f;                         \
       else if(op2.kind == doubleType) *value2 = (t) op2.d;                        \
-      else if(op2.kind == pointerType) *value2 = (t) op2.ui;                        \
+      else if(op2.kind == pointerType) *value2 = (t) op2.ui64;                    \
       else                                                                          \
          return false;                                                              \
       return true;                                                                  \
    }
 
-GETVALUE(Int, int);
-GETVALUE(UInt, unsigned int);
-GETVALUE(Int64, int64);
-GETVALUE(UInt64, uint64);
-GETVALUE(Short, short);
-GETVALUE(UShort, unsigned short);
-GETVALUE(Char, char);
-GETVALUE(UChar, unsigned char);
-GETVALUE(Float, float);
-GETVALUE(Double, double);
+// To help the deubugger currently not preprocessing...
+#define HELP(x) x
+
+GETVALUE(Int, HELP(int));
+GETVALUE(UInt, HELP(unsigned int));
+GETVALUE(Int64, HELP(int64));
+GETVALUE(UInt64, HELP(uint64));
+GETVALUE(IntPtr, HELP(intptr));
+GETVALUE(UIntPtr, HELP(uintptr));
+GETVALUE(IntSize, HELP(intsize));
+GETVALUE(UIntSize, HELP(uintsize));
+GETVALUE(Short, HELP(short));
+GETVALUE(UShort, HELP(unsigned short));
+GETVALUE(Char, HELP(char));
+GETVALUE(UChar, HELP(unsigned char));
+GETVALUE(Float, HELP(float));
+GETVALUE(Double, HELP(double));
 
 void ComputeExpression(Expression exp);
 
@@ -457,12 +361,30 @@ void ComputeClassMembers(Class _class, bool isMember)
    DataMember member = isMember ? (DataMember) _class : null;
    Context context = isMember ? null : SetupTemplatesContext(_class);
    if(member || ((_class.type == bitClass || _class.type == normalClass || _class.type == structClass || _class.type == noHeadClass) && 
-                 (_class.type == bitClass || _class.structSize == _class.offset) && _class.computeSize))
+                 (_class.type == bitClass || (!_class.structSize || _class.structSize == _class.offset)) && _class.computeSize))
    {
       int c;
       int unionMemberOffset = 0;
       int bitFields = 0;
 
+      /*
+      if(!member && (_class.type == structClass || _class.type == normalClass || _class.type == noHeadClass) && _class.memberOffset && _class.memberOffset > _class.base.structSize)
+         _class.memberOffset = (_class.base && _class.base.type != systemClass) ? _class.base.structSize : 0;
+      */
+
+      if(member)
+      {
+         member.memberOffset = 0;
+         if(targetBits < sizeof(void *) * 8)
+            member.structAlignment = 0;
+      }
+      else if(targetBits < sizeof(void *) * 8)
+         _class.structAlignment = 0;
+
+      // Confusion here: non struct classes seem to have their memberOffset restart at 0 at each hierarchy level
+      if(!member && ((_class.type == normalClass || _class.type == noHeadClass) || (_class.type == structClass && _class.memberOffset && _class.memberOffset > _class.base.structSize)))
+         _class.memberOffset = (_class.base && _class.type == structClass) ? _class.base.structSize : 0;
+
       if(!member && _class.destructionWatchOffset)
          _class.memberOffset += sizeof(OldList);
 
@@ -477,8 +399,6 @@ void ComputeClassMembers(Class _class, bool isMember)
             {
                if(dataMember.type == normalMember && dataMember.dataTypeString && !dataMember.dataType)
                {
-                  /*if(dataMember.dataType)
-                     printf("");*/
                   dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
                   /*if(!dataMember.dataType)
                      dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
@@ -575,12 +495,6 @@ void ComputeClassMembers(Class _class, bool isMember)
                      alignment = dataMember.dataType.alignment;
                   }
 
-#ifdef _DEBUG
-                  if(!size)
-                  {
-                     // printf("");
-                  }
-#endif
                   if(isMember)
                   {
                      // TESTING THIS PADDING CODE
@@ -617,12 +531,20 @@ void ComputeClassMembers(Class _class, bool isMember)
                }
                else
                {
+                  int alignment;
+
                   ComputeClassMembers((Class)dataMember, true);
+                  alignment = dataMember.structAlignment;
 
                   if(isMember)
                   {
-                     // THERE WASN'T A MAX HERE ? member.structAlignment = dataMember.structAlignment;
-                     member.structAlignment = Max(member.structAlignment, dataMember.structAlignment);
+                     if(alignment)
+                     {
+                        if(member.memberOffset % alignment)
+                           member.memberOffset += alignment - (member.memberOffset % alignment);
+
+                        member.structAlignment = Max(member.structAlignment, alignment);
+                     }
                      dataMember.offset = member.memberOffset;
                      if(member.type == unionMember)
                         unionMemberOffset = Max(unionMemberOffset, dataMember.memberOffset);
@@ -631,7 +553,12 @@ void ComputeClassMembers(Class _class, bool isMember)
                   }
                   else
                   {
-                     _class.structAlignment = Max(_class.structAlignment, dataMember.structAlignment);
+                     if(alignment)
+                     {
+                        if(_class.memberOffset % alignment)
+                           _class.memberOffset += alignment - (_class.memberOffset % alignment);
+                        _class.structAlignment = Max(_class.structAlignment, alignment);
+                     }
                      dataMember.offset = _class.memberOffset;
                      _class.memberOffset += dataMember.memberOffset;
                   }
@@ -690,7 +617,13 @@ void ComputeClassMembers(Class _class, bool isMember)
 
          if(_class.type != bitClass)
          {
-            _class.structSize = (_class.base ? (_class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize) : 0) + _class.memberOffset;
+            int extra = 0;
+            if(_class.structAlignment)
+            {
+               if(_class.memberOffset % _class.structAlignment)
+                  extra += _class.structAlignment - (_class.memberOffset % _class.structAlignment);
+            }
+            _class.structSize = (_class.base ? (_class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize) : 0) + _class.memberOffset + extra;
             if(!member)
             {
                Property prop;
@@ -754,6 +687,8 @@ public int ComputeTypeSize(Type type)
          case charType: type.alignment = size = sizeof(char); break;
          case intType: type.alignment = size = sizeof(int); break;
          case int64Type: type.alignment = size = sizeof(int64); break;
+         case intPtrType: type.alignment = size = targetBits / 8; break;
+         case intSizeType: type.alignment = size = targetBits / 8; break;
          case longType: type.alignment = size = sizeof(long); break;
          case shortType: type.alignment = size = sizeof(short); break;
          case floatType: type.alignment = size = sizeof(float); break;
@@ -781,10 +716,10 @@ public int ComputeTypeSize(Type type)
                size = type.alignment = ComputeTypeSize(_class.dataType);
             }
             else
-               size = type.alignment = sizeof(Instance *);
+               size = type.alignment = targetBits / 8; // sizeof(Instance *);
             break;
          }
-         case pointerType: case subClassType: size = type.alignment = sizeof(void *); break;
+         case pointerType: case subClassType: size = type.alignment = targetBits / 8; /*sizeof(void *); */break;
          case arrayType: 
             if(type.arraySizeExp)
             {
@@ -801,22 +736,16 @@ public int ComputeTypeSize(Type type)
                   yylloc = type.arraySizeExp.loc;
                   if(inCompiler)
                      PrintExpression(type.arraySizeExp, expression);
-                  Compiler_Error("Array size not constant int (%s)\n", expression);
+                  Compiler_Error($"Array size not constant int (%s)\n", expression);
                   yylloc = oldLoc;
                }
                GetInt(type.arraySizeExp, &type.arraySize);
-#ifdef _DEBUG
-               if(!type.arraySize)
-               {
-                  printf("");
-               }
-#endif
             }
             else if(type.enumClass)
             {
                if(type.enumClass && type.enumClass.registered && type.enumClass.registered.type == enumClass)
                {
-                  type.arraySize = eClass_GetProperty(type.enumClass.registered, "enumSize");
+                  type.arraySize = (int)eClass_GetProperty(type.enumClass.registered, "enumSize");
                }
                else
                   type.arraySize = 0;
@@ -874,19 +803,22 @@ public int ComputeTypeSize(Type type)
             TemplateParameter param = type.templateParameter;
             Type baseType = ProcessTemplateParameterType(param);
             if(baseType)
+            {
                size = ComputeTypeSize(baseType);
+               type.alignment = baseType.alignment;
+            }
             else
-               size = sizeof(uint64);
+               type.alignment = size = sizeof(uint64);
             break;
          }
          case enumType:
          {
-            size = sizeof(enum { test });
+            type.alignment = size = sizeof(enum { test });
             break;
          }
          case thisClassType:
          {
-            size = sizeof(void *);
+            type.alignment = size = targetBits / 8; //sizeof(void *);
             break;
          }
       }
@@ -897,7 +829,7 @@ public int ComputeTypeSize(Type type)
 }
 
 
-/*static */int AddMembers(OldList * declarations, Class _class, bool isMember, uint * retSize, Class topClass)
+/*static */int AddMembers(OldList * declarations, Class _class, bool isMember, uint * retSize, Class topClass, bool *addedPadding)
 {
    // This function is in need of a major review when implementing private members etc.
    DataMember topMember = isMember ? (DataMember) _class : null;
@@ -906,6 +838,8 @@ public int ComputeTypeSize(Type type)
    int alignment, size;
    DataMember member;
    Context context = isMember ? null : SetupTemplatesContext(_class);
+   if(addedPadding)
+      *addedPadding = false;
 
    if(!isMember && _class.base)
    {
@@ -914,7 +848,7 @@ public int ComputeTypeSize(Type type)
       {
          // DANGER: Testing this noHeadClass here...
          if(_class.type == structClass || _class.type == noHeadClass)
-            /*totalSize = */AddMembers(declarations, _class.base, false, &totalSize, topClass);
+            /*totalSize = */AddMembers(declarations, _class.base, false, &totalSize, topClass, null);
          else
             maxSize -= _class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize;
       }
@@ -973,7 +907,7 @@ public int ComputeTypeSize(Type type)
                OldList * specs = MkList(), * list = MkList();
                
                size = 0;
-               AddMembers(list, (Class)member, true, &size, topClass);
+               AddMembers(list, (Class)member, true, &size, topClass, null);
                ListAdd(specs, 
                   MkStructOrUnion((member.type == unionMember)?unionSpecifier:structSpecifier, null, list));
                ListAdd(declarations, MkClassDefDeclaration(MkStructDeclaration(specs, null, null)));
@@ -999,11 +933,19 @@ public int ComputeTypeSize(Type type)
    }
    else if(totalSize < maxSize && _class.type != systemClass)
    {
-      char sizeString[50];
-      sprintf(sizeString, "%d", maxSize - totalSize);
-      ListAdd(declarations, 
-         MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(CHAR)), 
-         MkListOne(MkDeclaratorArray(MkDeclaratorIdentifier(MkIdentifier("__ecere_padding")), MkExpConstant(sizeString))), null)));
+      int autoPadding = 0;
+      if(!isMember && _class.structAlignment && totalSize % _class.structAlignment)
+         autoPadding = _class.structAlignment - (totalSize % _class.structAlignment);
+      if(totalSize + autoPadding < maxSize)
+      {
+         char sizeString[50];
+         sprintf(sizeString, "%d", maxSize - totalSize);
+         ListAdd(declarations, 
+            MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(CHAR)), 
+            MkListOne(MkDeclaratorArray(MkDeclaratorIdentifier(MkIdentifier("__ecere_padding")), MkExpConstant(sizeString))), null)));
+         if(addedPadding)
+            *addedPadding = true;
+      }
    }
    if(context)
       FinishTemplatesContext(context);
@@ -1059,12 +1001,12 @@ void DeclareStruct(char * name, bool skipNoHead)
    External external = null;
    Symbol classSym = FindClass(name);
 
-   if(!inCompiler || !classSym) return null;
+   if(!inCompiler || !classSym) return;
 
    // We don't need any declaration for bit classes...
    if(classSym.registered && 
       (classSym.registered.type == bitClass || classSym.registered.type == unitClass || classSym.registered.type == enumClass))
-      return null;
+      return;
 
    /*if(classSym.registered.templateClass)
       return DeclareStruct(classSym.registered.templateClass.fullName, skipNoHead);
@@ -1092,7 +1034,7 @@ void DeclareStruct(char * name, bool skipNoHead)
             DeclareStruct(classSym.registered.templateClass.fullName, skipNoHead);
             classSym.declaring--;
          }
-         return null;
+         return;
       }
       
       //if(!skipNoHead)
@@ -1106,18 +1048,19 @@ void DeclareStruct(char * name, bool skipNoHead)
 
       if(!skipNoHead)
       {
+         bool addedPadding = false;
          classSym.declaredStructSym = true;
 
          declarations = MkList();
 
-         AddMembers(declarations, classSym.registered, false, null, classSym.registered);
+         AddMembers(declarations, classSym.registered, false, null, classSym.registered, &addedPadding);
 
          //ListAdd(specifiers, MkSpecifier(TYPEDEF));
          //ListAdd(specifiers, MkStructOrUnion(structSpecifier, null, declarations));
 
-         if(!declarations->count)
+         if(!declarations->count || (declarations->count == 1 && addedPadding))
          {
-            FreeList(declarations, null);
+            FreeList(declarations, FreeClassDef);
             declarations = null;
          }
       }
@@ -1564,7 +1507,7 @@ public Type Dereference(Type source)
          source.refCount++;
       }
       else
-         Compiler_Error("cannot dereference type\n");
+         Compiler_Error($"cannot dereference type\n");
    }
    return type;
 }
@@ -1694,7 +1637,7 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
       if(type && type.kind == templateType && type.templateParameter.type == TemplateParameterType::type && _class.templateArgs /* TODO: Watch out for these _class.templateClass*/)
       {
          int id = 0;
-         ClassTemplateParameter curParam;
+         ClassTemplateParameter curParam = null;
          Class sClass;
          for(sClass = _class; sClass; sClass = sClass.base)
          {
@@ -1882,13 +1825,13 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
                expString[0] = '\0';
                PrintExpression(member.initializer.exp, expString);
                ChangeCh(expString, '\n', ' ');
-               Compiler_Error("unresolved symbol used as an instance method %s\n", expString);
+               Compiler_Error($"unresolved symbol used as an instance method %s\n", expString);
             }
          }
          //else if(!MatchTypes(member.exp.expType, type, null, _class, null, true, true, false, false))
          else if(!MatchTypes(member.initializer.exp.expType, type, null, null, _class, true, true, false, false))
          {
-            Compiler_Error("incompatible instance method %s\n", ident.string);
+            Compiler_Error($"incompatible instance method %s\n", ident.string);
          }
       }
       else if(member.initializer)
@@ -1932,17 +1875,17 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
          {
             if(method)
             {
-               Compiler_Error("couldn't find virtual method %s in class %s\n", ident.string, _class.fullName);
+               Compiler_Error($"couldn't find virtual method %s in class %s\n", ident.string, _class.fullName);
             }
             else if(_class)
             {
-               Compiler_Error("couldn't find member %s in class %s\n", ident.string, _class.fullName);
+               Compiler_Error($"couldn't find member %s in class %s\n", ident.string, _class.fullName);
                if(inCompiler)
                   eClass_AddDataMember(_class, ident.string, "int", 0, 0, publicAccess);
             }
          }
          else if(_class)
-            Compiler_Error("too many initializers for instantiation of class %s\n", _class.fullName);
+            Compiler_Error($"too many initializers for instantiation of class %s\n", _class.fullName);
       }
    }
 }
@@ -2041,7 +1984,7 @@ void ProcessInstantiationType(Instantiation inst)
                      }
                      else if(classSym)
                      {
-                        Compiler_Error("couldn't find virtual method %s in class %s\n",
+                        Compiler_Error($"couldn't find virtual method %s in class %s\n",
                            unmangled, classSym.string);
                      }
                   }
@@ -2094,6 +2037,9 @@ void ProcessInstantiationType(Instantiation inst)
                         printf("TOCHECK: Will this ever be in a list? Yes.\n");
                         excludedSymbols->Remove(declarator.symbol);
                         globalContext.symbols.Add((BTNode)declarator.symbol);
+                        if(strstr(declarator.symbol.string), "::")
+                           globalContext.hasNameSpace = true;
+
                      }
                      */
                   
@@ -2215,7 +2161,7 @@ ClassTemplateArgument * FindTemplateArg(Class _class, TemplateParameter param)
 {
    ClassTemplateArgument * arg = null;
    int id = 0;
-   ClassTemplateParameter curParam;
+   ClassTemplateParameter curParam = null;
    Class sClass;
    for(sClass = _class; sClass; sClass = sClass.base)
    {
@@ -2256,7 +2202,7 @@ public Context SetupTemplatesContext(Class _class)
       {
          if(param.type == type && param.identifier)
          {
-            TemplatedType type { key = (uint)param.identifier.string, param = param };
+            TemplatedType type { key = (uintptr)param.identifier.string, param = param };
             curContext.templateTypes.Add((BTNode)type);
          }
       }
@@ -2285,7 +2231,7 @@ public Context SetupTemplatesContext(Class _class)
                      dataTypeString = p.dataTypeString /*, dataType = { specs, decl }*/
                   };
                }
-               type = TemplatedType { key = (uint)p.name, param = param };
+               type = TemplatedType { key = (uintptr)p.name, param = param };
                curContext.templateTypes.Add((BTNode)type);
             }
          }
@@ -2777,7 +2723,7 @@ bool DeclareFunction(GlobalFunction function, char * name)
             {
                Specifier spec;
                for(spec = specifiers->first; spec; spec = spec.next)
-                  if(spec.type == extendedSpecifier && !strcmp(spec.name, "dllexport"))
+                  if(spec.type == extendedSpecifier && spec.extDecl && spec.extDecl.type == extDeclString && !strcmp(spec.extDecl.s, "dllexport"))
                   {
                      specifiers->Remove(spec);
                      FreeSpecifier(spec);
@@ -2943,7 +2889,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
 
          /*source.kind != voidType && source.kind != structType && source.kind != unionType  */
       
-         /*&& (source.kind != classType /*|| source._class.registered.type != structClass)*/)
+         /*&& (source.kind != classType /-*|| source._class.registered.type != structClass)*/)
          return true;
       if(!isConversionExploration && source.kind == pointerType && source.type.kind == voidType &&
          ((dest.kind == classType && (!dest._class || !dest._class.registered || dest._class.registered.type == structClass || dest._class.registered.type == normalClass || dest._class.registered.type == noHeadClass || dest._class.registered.type == systemClass))
@@ -3167,15 +3113,19 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          return true;
       else if(dest.kind == shortType && source.kind == charType)
          return true;
-      else if(dest.kind == intType && (source.kind == shortType || source.kind == charType))
+      else if(dest.kind == intType && (source.kind == shortType || source.kind == charType || source.kind == intSizeType /* Exception here for size_t */))
+         return true;
+      else if(dest.kind == int64Type && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == intPtrType || source.kind == intSizeType))
+         return true;
+      else if(dest.kind == intPtrType && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == intSizeType || source.kind == int64Type))
          return true;
-      else if(dest.kind == int64Type && (source.kind == shortType || source.kind == charType || source.kind == intType))
+      else if(dest.kind == intSizeType && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == int64Type || source.kind == intPtrType))
          return true;
       else if(source.kind == enumType &&
-         (dest.kind == intType || dest.kind == shortType || dest.kind == charType || dest.kind == longType || dest.kind == int64Type))
+         (dest.kind == intType || dest.kind == shortType || dest.kind == charType || dest.kind == longType || dest.kind == int64Type || dest.kind == intPtrType || dest.kind == intSizeType))
           return true;
       else if(dest.kind == enumType &&
-         (source.kind == intType || source.kind == shortType || source.kind == charType || source.kind == longType || dest.kind == int64Type))
+         (source.kind == intType || source.kind == shortType || source.kind == charType || source.kind == longType || source.kind == int64Type || source.kind == intPtrType || source.kind == intSizeType))
           return true;
       else if((dest.kind == functionType || (dest.kind == pointerType && dest.type.kind == functionType) || dest.kind == methodType) && 
               ((source.kind == functionType || (source.kind == pointerType && source.type.kind == functionType) || source.kind == methodType)))
@@ -3208,9 +3158,9 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                !eClass_IsDerived(source.thisClass ? source.thisClass.registered : owningClassSource,paramDest._class.registered))))
             {
                if(paramDest && paramDest.kind == classType)
-                  Compiler_Error("method class must be derived from %s\n", paramDest._class.string);
+                  Compiler_Error($"method class must be derived from %s\n", paramDest._class.string);
                else
-                  Compiler_Error("method class should not take an object\n");
+                  Compiler_Error($"method class should not take an object\n");
                return false;
             }
             paramDest = paramDest.next;
@@ -3223,7 +3173,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                {
                   if(!paramSource || paramSource.kind != classType || !eClass_IsDerived(paramSource._class.registered,dest.thisClass.registered))
                   {
-                     Compiler_Error("method class must be derived from %s\n", dest.thisClass.string);
+                     Compiler_Error($"method class must be derived from %s\n", dest.thisClass.string);
                      return false;
                   }
                }
@@ -3234,9 +3184,9 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                   if(!paramSource || paramSource.kind != classType || (owningClassDest && !eClass_IsDerived(paramSource._class.registered, owningClassDest)))
                   {
                      if(owningClassDest)
-                       Compiler_Error("%s expected to be derived from method class\n", owningClassDest.fullName);
+                       Compiler_Error($"%s expected to be derived from method class\n", owningClassDest.fullName);
                      else
-                        Compiler_Error("overriding class expected to be derived from method class\n");      
+                        Compiler_Error($"overriding class expected to be derived from method class\n");      
                      return false;
                   }
                }
@@ -3249,7 +3199,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                   // Source thisClass must be derived from destination thisClass
                   if(!eClass_IsDerived(source.thisClass ? source.thisClass.registered : owningClassSource, dest.thisClass.registered))
                   {
-                     Compiler_Error("method class must be derived from %s\n", dest.thisClass.string);
+                     Compiler_Error($"method class must be derived from %s\n", dest.thisClass.string);
                      return false;
                   }
                }
@@ -3260,9 +3210,9 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                   if(source.thisClass && source.thisClass.registered && owningClassDest && !eClass_IsDerived(source.thisClass.registered, owningClassDest))
                   {
                      //if(owningClass)
-                        Compiler_Error("%s expected to be derived from method class\n", /*owningClass.name*/ source.thisClass.registered.fullName);
+                        Compiler_Error($"%s expected to be derived from method class\n", /*owningClass.name*/ source.thisClass.registered.fullName);
                      //else
-                        //Compiler_Error("overriding class expected to be derived from method class\n");      
+                        //Compiler_Error($"overriding class expected to be derived from method class\n");      
                      return false;
                   }
                }
@@ -3273,7 +3223,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          // Source return type must be derived from destination return type
          if(!MatchTypes(source.returnType, dest.returnType, null, null, null, true, true, false, false))
          {
-            Compiler_Warning("incompatible return type for function\n");
+            Compiler_Warning($"incompatible return type for function\n");
             return false;
          }
 
@@ -3283,8 +3233,8 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          {
             if(!paramSource)
             {
-               //Compiler_Warning("not enough parameters\n");
-               Compiler_Error("not enough parameters\n");
+               //Compiler_Warning($"not enough parameters\n");
+               Compiler_Error($"not enough parameters\n");
                return false;
             }
             {
@@ -3297,7 +3247,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                   paramSource.kind != templateType)
                {
                   int id = 0;
-                  ClassTemplateParameter curParam;
+                  ClassTemplateParameter curParam = null;
                   Class sClass;
                   for(sClass = owningClassSource; sClass; sClass = sClass.base)
                   {
@@ -3333,7 +3283,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                   char type[1024];
                   type[0] = 0;
                   PrintType(paramDest, type, false, true);
-                  Compiler_Warning("incompatible parameter %s (expected %s)\n", paramSource.name, type);
+                  Compiler_Warning($"incompatible parameter %s (expected %s)\n", paramSource.name, type);
                   
                   if(paramDestType != paramDest)
                      FreeType(paramDestType);
@@ -3347,7 +3297,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          }
          if(paramSource)
          {
-            Compiler_Error("too many parameters\n");
+            Compiler_Error($"too many parameters\n");
             return false;
          }
          return true;
@@ -3488,6 +3438,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 {
    Type source = sourceExp.expType;
    Type realDest = dest;
+   Type backupSourceExpType = null;
 
    if(dest.kind == pointerType && sourceExp.type == constantExp && !strtoul(sourceExp.constant, null, 0))
       return true;
@@ -3564,9 +3515,9 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                if(tempType._class)
                   MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false);
 
-               FreeType(sourceExp.expType);
+               // NOTE: To handle bad warnings on int64 vs 32 bit eda::Id incompatibilities
+               backupSourceExpType = sourceExp.expType;
                sourceExp.expType = dest; dest.refCount++;
-
                //sourceExp.expType = MkClassType(_class.fullName);
                flag = true;            
 
@@ -3632,6 +3583,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 
             FreeType(source);
             FreeType(dest);
+            if(backupSourceExpType) FreeType(backupSourceExpType);
             return true;
          }
       }
@@ -3768,6 +3720,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                FreeType(source);
                if(inCompiler) FreeType(dest);
 
+               if(backupSourceExpType) FreeType(backupSourceExpType);
                return true;
             }
 
@@ -3823,6 +3776,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          {
             FreeType(source);
             FreeType(dest);
+            if(backupSourceExpType)
+            {
+               // Failed to convert: revert previous exp type
+               if(sourceExp.expType) FreeType(sourceExp.expType);
+               sourceExp.expType = backupSourceExpType;
+            }
             return false;
          }
       }
@@ -3872,6 +3831,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       {
          FreeType(source);
          FreeType(dest);
+         if(backupSourceExpType)
+         {
+            // Failed to convert: revert previous exp type
+            if(sourceExp.expType) FreeType(sourceExp.expType);
+            sourceExp.expType = backupSourceExpType;
+         }
          return false;
       }
 
@@ -3908,6 +3873,8 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 
       FreeType(dest);
       FreeType(source);
+      if(backupSourceExpType) FreeType(backupSourceExpType);
+
       return true;
    }
    else
@@ -4251,6 +4218,32 @@ public Operand GetOperand(Expression exp)
                }
                op.kind = intType;
                break;
+            case intPtrType:
+               if(type.isSigned)
+               {
+                  op.i64 = (int64)_strtoi64(exp.constant, null, 0);
+                  op.ops = intOps;
+               }
+               else
+               {
+                  op.ui64 = (uint64)_strtoui64(exp.constant, null, 0);
+                  op.ops = uintOps;
+               }
+               op.kind = intType;
+               break;
+            case intSizeType:
+               if(type.isSigned)
+               {
+                  op.i64 = (int64)_strtoi64(exp.constant, null, 0);
+                  op.ops = intOps;
+               }
+               else
+               {
+                  op.ui64 = (uint64)_strtoui64(exp.constant, null, 0);
+                  op.ops = uintOps;
+               }
+               op.kind = intType;
+               break;
             case floatType:
                op.f = (float)strtod(exp.constant, null);
                op.ops = floatOps;
@@ -4265,7 +4258,7 @@ public Operand GetOperand(Expression exp)
             case arrayType:
             case pointerType:
             case classType:
-               op.p = (unsigned char *)strtoul(exp.constant, null, 0);
+               op.ui64 = _strtoui64(exp.constant, null, 0);
                op.kind = pointerType;
                op.ops = uintOps;
                // op.ptrSize = 
@@ -4375,8 +4368,24 @@ static void PopulateInstanceProcessMember(Instantiation inst, OldList * memberLi
                   exp.type = constantExp;
                   break;
                }
+               case intPtrType:
+               {
+                  FreeExpContents(exp);
+                  // TODO: This should probably use proper type
+                  exp.constant = PrintInt64((int64)*(intptr*)ptr);
+                  exp.type = constantExp;
+                  break;
+               }
+               case intSizeType:
+               {
+                  FreeExpContents(exp);
+                  // TODO: This should probably use proper type
+                  exp.constant = PrintInt64((int64)*(intptr*)ptr);
+                  exp.type = constantExp;
+                  break;
+               }
                default:
-                  printf("error: unhandled type populating instance\n");
+                  Compiler_Error($"Unhandled type populating instance\n");
             }
          }
          ListAdd(memberList, member);
@@ -4476,8 +4485,14 @@ void PopulateInstance(Instantiation inst)
                      exp.type = constantExp;
                      break;
                   }
+                  case intPtrType:
+                  {
+                     exp.constant = PrintInt64((int64)*(intptr*)ptr);
+                     exp.type = constantExp;
+                     break;
+                  }
                   default:
-                     printf("error: unhandled type populating instance\n");
+                     Compiler_Error($"Unhandled type populating instance\n");
                }
             }
             ListAdd(memberList, member);
@@ -4672,6 +4687,16 @@ void ComputeInstantiation(Expression exp)
                                        GetInt64(value, (int64*)ptr);
                                        break;
                                     }
+                                    case intPtrType:
+                                    {
+                                       GetIntPtr(value, (intptr*)ptr);
+                                       break;
+                                    }
+                                    case intSizeType:
+                                    {
+                                       GetIntSize(value, (intsize*)ptr);
+                                       break;
+                                    }
                                     case floatType:
                                     {
                                        GetFloat(value, (float*)ptr);
@@ -4734,13 +4759,25 @@ void ComputeInstantiation(Expression exp)
                                        Set(inst.data, _strtoi64(value.constant, null, 0));
                                        break;
                                     }
+                                    case intPtrType:
+                                    {
+                                       void (*Set)(void *, intptr) = (void *)prop.Set;
+                                       Set(inst.data, (intptr)_strtoi64(value.constant, null, 0));
+                                       break;
+                                    }
+                                    case intSizeType:
+                                    {
+                                       void (*Set)(void *, intsize) = (void *)prop.Set;
+                                       Set(inst.data, (intsize)_strtoi64(value.constant, null, 0));
+                                       break;
+                                    }
                                  }
                               }
                               else if(value.type == stringExp)
                               {
                                  char temp[1024];
                                  ReadString(temp, value.string);
-                                 prop.Set(inst.data, temp);
+                                 ((void (*)(void *, void *))(void *)prop.Set)(inst.data, temp);
                               }
                            }
                         }
@@ -4845,6 +4882,26 @@ void ComputeInstantiation(Expression exp)
                                     else
                                        bits |= ((uint64)part << bitMember.pos);
                                     break;
+                                 case intPtrType:
+                                    if(type.isSigned)
+                                    {
+                                       bits |= ((intptr)part << bitMember.pos);
+                                    }
+                                    else
+                                    {
+                                       bits |= ((uintptr)part << bitMember.pos);
+                                    }
+                                    break;
+                                 case intSizeType:
+                                    if(type.isSigned)
+                                    {
+                                       bits |= ((ssize_t)(intsize)part << bitMember.pos);
+                                    }
+                                    else
+                                    {
+                                       bits |= ((size_t) (uintsize)part << bitMember.pos);
+                                    }
+                                    break;
                               }
                            }
                         }
@@ -5446,6 +5503,42 @@ void ComputeExpression(Expression exp)
                                  PopulateInstance(exp.instance);
                                  break;
                               }
+                              case intPtrType:
+                              {
+                                 // TOFIX:
+                                 intptr intValue;
+                                 void (*Set)(void *, intptr) = (void *)prop.Set;
+
+                                 exp.instance = Instantiation { };
+                                 exp.instance.data = new0 byte[_class.structSize];
+                                 exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+                                 exp.instance.loc = exp.loc;
+                                 exp.type = instanceExp;
+                              
+                                 GetIntPtr(value, &intValue);
+
+                                 Set(exp.instance.data, intValue);
+                                 PopulateInstance(exp.instance);
+                                 break;
+                              }
+                              case intSizeType:
+                              {
+                                 // TOFIX:
+                                 intsize intValue;
+                                 void (*Set)(void *, intsize) = (void *)prop.Set;
+
+                                 exp.instance = Instantiation { };
+                                 exp.instance.data = new0 byte[_class.structSize];
+                                 exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+                                 exp.instance.loc = exp.loc;
+                                 exp.type = instanceExp;
+
+                                 GetIntSize(value, &intValue);
+
+                                 Set(exp.instance.data, intValue);
+                                 PopulateInstance(exp.instance);
+                                 break;
+                              }
                               case doubleType:
                               {
                                  double doubleValue;
@@ -5735,6 +5828,42 @@ void ComputeExpression(Expression exp)
                      exp.type = constantExp;
                   }
                   break;
+               case intPtrType:
+                  if(type.isSigned)
+                  {
+                     intptr value;
+                     GetIntPtr(e, &value);
+                     FreeExpContents(exp);
+                     exp.constant = PrintInt64((int64)value);
+                     exp.type = constantExp;
+                  }
+                  else
+                  {
+                     uintptr value;
+                     GetUIntPtr(e, &value);
+                     FreeExpContents(exp);
+                     exp.constant = PrintUInt64((uint64)value);
+                     exp.type = constantExp;
+                  }
+                  break;
+               case intSizeType:
+                  if(type.isSigned)
+                  {
+                     intsize value;
+                     GetIntSize(e, &value);
+                     FreeExpContents(exp);
+                     exp.constant = PrintInt64((int64)value);
+                     exp.type = constantExp;
+                  }
+                  else
+                  {
+                     uintsize value;
+                     GetUIntSize(e, &value);
+                     FreeExpContents(exp);
+                     exp.constant = PrintUInt64((uint64)value);
+                     exp.type = constantExp;
+                  }
+                  break;
                case floatType:
                {
                   float value;
@@ -5938,17 +6067,31 @@ void CheckTemplateTypes(Expression exp)
       switch(exp.expType.kind)
       {
          case doubleType:
-            exp.type = opExp;
-            exp.op.exp1 = null;
-            context = PushContext();               
-            exp.op.exp2 = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)), 
-               MkExpExtensionCompound(compound = MkCompoundStmt(
-                  MkListOne(MkDeclaration(MkListOne(MkSpecifier(DOUBLE)), 
-                     MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal")), MkInitializerAssignment(newExp))))),
-                  MkListOne(MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internal")))))))));
-            compound.compound.context = context;
-            PopContext(context);
-            exp.op.op = '*';
+            if(exp.destType.classObjectType)
+            {
+               // We need to pass the address, just pass it along (Undo what was done above)
+               if(exp.destType) exp.destType.refCount--;
+               if(exp.expType)  exp.expType.refCount--;
+               delete newExp;
+            }
+            else
+            {
+               // If we're looking for value:
+               // ({ union { double d; uint64 i; } u; u.i = [newExp]; u.d; })
+               OldList * specs;
+               OldList * unionDefs = MkList();
+               OldList * statements = MkList();
+               context = PushContext();
+               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(DOUBLE)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("d"))), null))); 
+               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifierName("uint64")), MkListOne(MkDeclaratorIdentifier(MkIdentifier("i"))), null)));
+               specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
+               exp.type = extensionCompoundExp;
+               exp.compound = MkCompoundStmt(MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_union")), null)))),statements);
+               ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("d")), '=', newExp))));
+               ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("i")))));
+               exp.compound.compound.context = context;
+               PopContext(context);
+            }
             break;
          default:
             exp.type = castExp;
@@ -5971,18 +6114,31 @@ void CheckTemplateTypes(Expression exp)
       switch(exp.expType.kind)
       {
          case doubleType:
-            exp.type = opExp;
-            exp.op.exp1 = null;
-            context = PushContext();               
-            exp.op.exp2 = MkExpCast(MkTypeName(MkListOne(MkSpecifier(DOUBLE)), MkDeclaratorPointer(MkPointer(null, null), null)), 
-               MkExpExtensionCompound(compound = MkCompoundStmt(
-                  MkListOne(MkDeclaration(MkListOne(MkSpecifierName("uint64")), 
-                     MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal")), MkInitializerAssignment(newExp))))),
-                  MkListOne(MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internal")))))))));
-            compound.compound.context = context;
-            PopContext(context);
-            exp.op.op = '*';
-            ProcessExpressionType(exp.op.exp2);
+            if(exp.destType.classObjectType)
+            {
+               // We need to pass the address, just pass it along (Undo what was done above)
+               if(exp.destType) exp.destType.refCount--;
+               if(exp.expType)  exp.expType.refCount--;
+               delete newExp;
+            }
+            else
+            {
+               // If we're looking for value:
+               // ({ union { double d; uint64 i; } u; u.i = [newExp]; u.d; })
+               OldList * specs;
+               OldList * unionDefs = MkList();
+               OldList * statements = MkList();
+               context = PushContext();
+               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(DOUBLE)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("d"))), null))); 
+               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifierName("uint64")), MkListOne(MkDeclaratorIdentifier(MkIdentifier("i"))), null)));
+               specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
+               exp.type = extensionCompoundExp;
+               exp.compound = MkCompoundStmt(MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_union")), null)))),statements);
+               ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("i")), '=', newExp))));
+               ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("d")))));
+               exp.compound.compound.context = context;
+               PopContext(context);
+            }
             break;
          case classType:
          {
@@ -6044,28 +6200,37 @@ void CheckTemplateTypes(Expression exp)
       }
    }
 }
+// TODO: The Symbol tree should be reorganized by namespaces
+// Name Space:
+//    - Tree of all symbols within (stored without namespace)
+//    - Tree of sub-namespaces
 
 static Symbol ScanWithNameSpace(BinaryTree tree, char * nameSpace, char * name)
 {
-   Symbol symbol;
    int nsLen = strlen(nameSpace);
-   for(symbol = (Symbol)tree.first; symbol; symbol = (Symbol)((BTNode)symbol).next)
+   Symbol symbol;
+   // Start at the name space prefix
+   for(symbol = (Symbol)tree.FindPrefix(nameSpace); symbol; symbol = (Symbol)((BTNode)symbol).next)
    {
-      if(!strncmp(symbol.string, nameSpace, nsLen))
+      char * s = symbol.string;
+      if(!strncmp(s, nameSpace, nsLen))
       {
+         // This supports e.g. matching ecere::Socket to ecere::net::Socket
          int c;
          char * namePart;
-         for(c = strlen(symbol.string)-1; c >= 0; c--)
-            if(symbol.string[c] == ':')
+         for(c = strlen(s)-1; c >= 0; c--)
+            if(s[c] == ':')
                break;
 
-         namePart = symbol.string+c+1;
+         namePart = s+c+1;
          if(!strcmp(namePart, name))
          {
             // TODO: Error on ambiguity
             return symbol;
          }
       }
+      else
+         break;
    }
    return null;
 }
@@ -6089,17 +6254,31 @@ static Symbol FindWithNameSpace(BinaryTree tree, char * name)
    while(c >= 0 && name[c] == ':') c--;
    if(c >= 0)
    {
+      // Try an exact match first
+      Symbol symbol = (Symbol)tree.FindString(name);
+      if(symbol)
+         return symbol;
+
+      // Namespace specified
       memcpy(nameSpace, name, c + 1);
       nameSpace[c+1] = 0;
+
       return ScanWithNameSpace(tree, nameSpace, namePart);
    }
    else if(gotColon)
    {
+      // Looking for a global symbol, e.g. ::Sleep()
       Symbol symbol = (Symbol)tree.FindString(namePart);
       return symbol;
    }
    else
+   {
+      // Name only (no namespace specified)
+      Symbol symbol = (Symbol)tree.FindString(namePart);
+      if(symbol)
+         return symbol;
       return ScanWithNameSpace(tree, "", namePart);
+   }
    return null;
 }
 
@@ -6118,7 +6297,7 @@ static void ProcessDeclaration(Declaration decl);
 
    for(ctx = startContext; ctx /*!= topContext.parent */&& !symbol; ctx = ctx.parent)
    {
-      if(ctx == globalContext && !globalNameSpace)
+      if(ctx == globalContext && !globalNameSpace && ctx.hasNameSpace)
       {
          symbol = null;
          if(thisNameSpace)
@@ -6127,15 +6306,14 @@ static void ProcessDeclaration(Declaration decl);
             strcpy(curName, thisNameSpace);
             strcat(curName, "::");
             strcat(curName, name);
+            // Try to resolve in current namespace first
             symbol = FindWithNameSpace(isStruct ? ctx.structSymbols : ctx.symbols, curName);
          }
          if(!symbol)
             symbol = FindWithNameSpace(isStruct ? ctx.structSymbols : ctx.symbols, name);
       }
-      else if(isStruct)
-         symbol = (Symbol)ctx.structSymbols.FindString(name);
       else
-         symbol = (Symbol)ctx.symbols.FindString(name);
+         symbol = (Symbol)(isStruct ? ctx.structSymbols : ctx.symbols).FindString(name);
 
       if(symbol || ctx == endContext) break;
    }
@@ -6175,7 +6353,7 @@ static void ProcessDeclaration(Declaration decl);
 
 static void GetTypeSpecs(Type type, OldList * specs)
 {
-   if(!type.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
+   if(!type.isSigned && type.kind != intPtrType && type.kind != intSizeType) ListAdd(specs, MkSpecifier(UNSIGNED));
    switch(type.kind)
    {
       case classType: 
@@ -6193,6 +6371,8 @@ static void GetTypeSpecs(Type type, OldList * specs)
       case charType: ListAdd(specs, MkSpecifier(CHAR)); break;
       case shortType: ListAdd(specs, MkSpecifier(SHORT)); break;
       case int64Type: ListAdd(specs, MkSpecifier(INT64)); break;
+      case intPtrType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intptr" : "uintptr")); break;
+      case intSizeType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intsize" : "uintsize")); break;
       case intType: 
       default:
          ListAdd(specs, MkSpecifier(INT)); break;
@@ -6262,6 +6442,8 @@ static void _PrintType(Type type, char * string, bool printName, bool printFunct
          case voidType: strcat(string, "void"); break;
          case intType:  strcat(string, type.isSigned ? "int" : "uint"); break;
          case int64Type:  strcat(string, type.isSigned ? "int64" : "uint64"); break;
+         case intPtrType:  strcat(string, type.isSigned ? "intptr" : "uintptr"); break;
+         case intSizeType:  strcat(string, type.isSigned ? "intsize" : "uintsize"); break;
          case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
          case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
          case floatType: strcat(string, "float"); break;
@@ -6345,12 +6527,6 @@ static void _PrintType(Type type, char * string, bool printName, bool printFunct
                      strcat(string, name);
                   }
                }
-#ifdef _DEBUG
-               else
-               {
-                  printf("");
-               }
-#endif
             }
 
             if(printFunction)
@@ -6454,10 +6630,6 @@ static void _PrintType(Type type, char * string, bool printName, bool printFunct
          case vaListType:
          strcat(string, "__builtin_va_list");
             break;
-#ifdef _DEBUG
-         default:
-            printf("");
-#endif
       }
       if(type.name && printName && type.kind != functionType && (type.kind != pointerType || type.type.kind != functionType))
       {
@@ -6467,6 +6639,9 @@ static void _PrintType(Type type, char * string, bool printName, bool printFunct
    }
 }
 
+// *****
+// TODO: Add a max buffer size to avoid overflows. This function is used with static size char arrays.
+// *****
 void PrintType(Type type, char * string, bool printName, bool fullName)
 {
    Type funcType;
@@ -6480,14 +6655,7 @@ void PrintType(Type type, char * string, bool printName, bool fullName)
       strcat(string, "(");
       _PrintType(type, string, printName, false, fullName);
       strcat(string, ")");
-      /*
-      if(type.name)
-         strcat(string, type.name);
-      else
-      {
-         printf("");
-      }
-      */
+
       strcat(string, "(");
       for(param = funcType.params.first; param; param = param.next)
       {
@@ -6658,7 +6826,7 @@ static bool ResolveIdWithClass(Expression exp, Class _class, bool skipIDClassChe
          {
             char constant[256];
             exp.type = constantExp;
-            sprintf(constant, "%d",classProp.Get(_class));
+            sprintf(constant, "%d", (int)classProp.Get(_class));
             exp.constant = CopyString(constant);
          }
       }
@@ -6849,11 +7017,30 @@ void ApplyAnyObjectLogic(Expression e)
 
                         curContext = context;
                         e.type = extensionCompoundExp;
+
+                        // We need a current compound for this
+                        if(curCompound)
+                        {
+                           char name[100];
+                           OldList * stmts = MkList();
+                           sprintf(name, "__internalValue%03X", internalValueCounter++);
+                           if(!curCompound.compound.declarations)
+                              curCompound.compound.declarations = MkList();
+                           curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
+                           ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
+                           ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
+                           e.compound = MkCompoundStmt(null, stmts);
+                        }
+                        else
+                           printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
+
+                        /*
                         e.compound = MkCompoundStmt(
                            MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(
                               MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))), 
 
                            MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
+                        */
                         
                         {
                            Type type = e.destType;
@@ -6964,7 +7151,7 @@ void ApplyAnyObjectLogic(Expression e)
    {
       if(destType.kind == ellipsisType)
       {
-         Compiler_Error("Unspecified type\n");
+         Compiler_Error($"Unspecified type\n");
       }
       else if(!(destType.truth && e.expType.kind == classType && e.expType._class && e.expType._class.registered && e.expType._class.registered.type == structClass))
       {
@@ -7228,7 +7415,7 @@ void ProcessExpressionType(Expression exp)
                   {
                      if(inCompiler)
                      {
-                        Compiler_Error("Recursion in defined expression %s\n", id.string);
+                        Compiler_Error($"Recursion in defined expression %s\n", id.string);
                      }
                   }
                }
@@ -7312,12 +7499,6 @@ void ProcessExpressionType(Expression exp)
             {
                exp.instance._class = MkSpecifierName(exp.destType._class.string);
             }
-#ifdef _DEBUG
-            else 
-            {
-               printf("");               
-            }
-#endif
          }
 
          //classSym = FindClass(exp.instance._class.fullName);
@@ -7620,7 +7801,7 @@ void ProcessExpressionType(Expression exp)
                {
                   if(exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN ||exp.op.op == MOD_ASSIGN ||exp.op.op == LEFT_ASSIGN ||exp.op.op == RIGHT_ASSIGN ||
                      exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN)
-                     Compiler_Error("operator %s illegal on pointer\n", exp.op.op);
+                     Compiler_Error($"operator %s illegal on pointer\n", exp.op.op);
                   else if(exp.op.op == '=')
                   {
                      if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
@@ -7678,10 +7859,10 @@ void ProcessExpressionType(Expression exp)
 
             if(assign && type1 && type1.kind == pointerType && exp.op.exp2.expType)
             {
-               if(exp.op.exp2.expType.kind == int64Type || exp.op.exp2.expType.kind == intType || exp.op.exp2.expType.kind == shortType || exp.op.exp2.expType.kind == charType)
+               if(exp.op.exp2.expType.kind == intSizeType || exp.op.exp2.expType.kind == intPtrType || exp.op.exp2.expType.kind == int64Type || exp.op.exp2.expType.kind == intType || exp.op.exp2.expType.kind == shortType || exp.op.exp2.expType.kind == charType)
                {
                   if(exp.op.op != '=' && type1.type.kind == voidType) 
-                     Compiler_Error("void *: unknown size\n");
+                     Compiler_Error($"void *: unknown size\n");
                }
                else if(exp.op.exp2.expType.kind == pointerType || exp.op.exp2.expType.kind == arrayType || exp.op.exp2.expType.kind == functionType || exp.op.exp2.expType.kind == methodType|| 
                            (type1.type.kind == voidType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class.registered &&
@@ -7690,13 +7871,13 @@ void ProcessExpressionType(Expression exp)
                               exp.op.exp2.expType._class.registered.type == noHeadClass)))
                {
                   if(exp.op.op == ADD_ASSIGN)
-                     Compiler_Error("cannot add two pointers\n");                   
+                     Compiler_Error($"cannot add two pointers\n");                   
                }
                else if((exp.op.exp2.expType.kind == classType && type1.kind == pointerType && type1.type.kind == classType && 
                   type1.type._class == exp.op.exp2.expType._class && exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass))
                {
                   if(exp.op.op == ADD_ASSIGN)
-                     Compiler_Error("cannot add two pointers\n");                   
+                     Compiler_Error($"cannot add two pointers\n");                   
                }
                else if(inCompiler)
                {
@@ -7708,7 +7889,7 @@ void ProcessExpressionType(Expression exp)
                   PrintType(exp.op.exp2.expType, type1String, false, true);
                   PrintType(type1, type2String, false, true);
                   ChangeCh(expString, '\n', ' ');
-                  Compiler_Warning("incompatible expression %s (%s); expected %s\n", expString, type1String, type2String);
+                  Compiler_Warning($"incompatible expression %s (%s); expected %s\n", expString, type1String, type2String);
                }
             }
 
@@ -7782,7 +7963,7 @@ void ProcessExpressionType(Expression exp)
             {
                if(type1 && type2 &&
                   // If either both are class or both are not class
-                  ((type1.kind == classType && strcmp(type1._class.string, "String")) == (type2.kind == classType && strcmp(type2._class.string, "String"))))
+                  ((type1.kind == classType && type1._class && strcmp(type1._class.string, "String")) == (type2.kind == classType && type2._class && strcmp(type2._class.string, "String"))))
                {
                   if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
                   exp.op.exp2.destType = type1;
@@ -7795,7 +7976,7 @@ void ProcessExpressionType(Expression exp)
                      type1._class.registered && type1._class.registered.type == unitClass && 
                      type2._class.registered && type2._class.registered.type == unitClass && 
                      type1._class.registered != type2._class.registered)
-                     Compiler_Warning("operating on %s and %s with an untyped result, assuming %s\n",
+                     Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n",
                         type1._class.string, type2._class.string, type1._class.string);
 
                   if(type1.kind == pointerType && type1.type.kind == templateType && type2.kind != pointerType)
@@ -7835,24 +8016,24 @@ void ProcessExpressionType(Expression exp)
                      }
                   }
                   
-                  if(!boolResult && ((type1.kind == pointerType || type1.kind == arrayType || (type1.kind == classType && !strcmp(type1._class.string, "String"))) && (type2.kind == int64Type || type2.kind == intType || type2.kind == shortType || type2.kind == charType)))
+                  if(!boolResult && ((type1.kind == pointerType || type1.kind == arrayType || (type1.kind == classType && !strcmp(type1._class.string, "String"))) && (type2.kind == intSizeType || type2.kind == intPtrType || type2.kind == int64Type || type2.kind == intType || type2.kind == shortType || type2.kind == charType)))
                   {
                      if(type1.kind != classType && type1.type.kind == voidType) 
-                        Compiler_Error("void *: unknown size\n");
+                        Compiler_Error($"void *: unknown size\n");
                      exp.expType = type1;
                      if(type1) type1.refCount++;
                   }
-                  else if(!boolResult && ((type2.kind == pointerType || type2.kind == arrayType || (type2.kind == classType && !strcmp(type2._class.string, "String"))) && (type1.kind == int64Type || type1.kind == intType || type1.kind == shortType || type1.kind == charType)))
+                  else if(!boolResult && ((type2.kind == pointerType || type2.kind == arrayType || (type2.kind == classType && !strcmp(type2._class.string, "String"))) && (type1.kind == intSizeType || type1.kind == intPtrType || type1.kind == int64Type || type1.kind == intType || type1.kind == shortType || type1.kind == charType)))
                   {
                      if(type2.kind != classType && type2.type.kind == voidType) 
-                        Compiler_Error("void *: unknown size\n");
+                        Compiler_Error($"void *: unknown size\n");
                      exp.expType = type2;
                      if(type2) type2.refCount++;
                   }
                   else if((type1.kind == pointerType && type2.kind != pointerType && type2.kind != arrayType && type2.kind != functionType && type2.kind != methodType && type2.kind != classType && type2.kind != subClassType) ||
                           (type2.kind == pointerType && type1.kind != pointerType && type1.kind != arrayType && type1.kind != functionType && type1.kind != methodType && type1.kind != classType && type1.kind != subClassType))
                   {
-                     Compiler_Warning("different levels of indirection\n");
+                     Compiler_Warning($"different levels of indirection\n");
                   }
                   else 
                   {
@@ -7860,7 +8041,7 @@ void ProcessExpressionType(Expression exp)
                      if(type1.kind == pointerType && type2.kind == pointerType)
                      {
                         if(exp.op.op == '+')
-                           Compiler_Error("cannot add two pointers\n");
+                           Compiler_Error($"cannot add two pointers\n");
                         else if(exp.op.op == '-')
                         {
                            // Pointer Subtraction gives integer
@@ -7969,7 +8150,7 @@ void ProcessExpressionType(Expression exp)
                            PrintType(exp.op.exp2.expType, type2, false, true);
                         }
 
-                        Compiler_Warning("incompatible expressions %s (%s) and %s (%s)\n", expString1, type1, expString2, type2);
+                        Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1, expString2, type2);
                      }
                   }
                }
@@ -8129,7 +8310,7 @@ void ProcessExpressionType(Expression exp)
                            PrintType(exp.op.exp2.expType, type2String, false, true);
                         }
 
-                        Compiler_Warning("incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String);
+                        Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String);
 
                         if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass)
                         {
@@ -8237,7 +8418,7 @@ void ProcessExpressionType(Expression exp)
                ChangeCh(expString, '\n', ' ');
             }
             if(expString[0])
-               Compiler_Error("couldn't determine type of %s\n", expString);
+               Compiler_Error($"couldn't determine type of %s\n", expString);
          }
          if(exp.op.exp2 && !exp.op.exp2.expType)
          {
@@ -8249,7 +8430,7 @@ void ProcessExpressionType(Expression exp)
                ChangeCh(expString, '\n', ' ');
             }
             if(expString[0])
-               Compiler_Error("couldn't determine type of %s\n", expString);
+               Compiler_Error($"couldn't determine type of %s\n", expString);
          }
 
          if(boolResult)
@@ -8391,7 +8572,14 @@ void ProcessExpressionType(Expression exp)
          {
             Expression idExp = exp.call.exp;
             Identifier id = idExp.identifier;
-            if(!strcmp(id.string, "__ENDIAN_PAD"))
+            if(!strcmp(id.string, "__builtin_frame_address"))
+            {
+               exp.expType = ProcessTypeString("void *", true);
+               if(exp.call.arguments && exp.call.arguments->first)
+                  ProcessExpressionType(exp.call.arguments->first);
+               break;
+            }
+            else if(!strcmp(id.string, "__ENDIAN_PAD"))
             {
                exp.expType = ProcessTypeString("int", true);
                if(exp.call.arguments && exp.call.arguments->first)
@@ -8601,7 +8789,7 @@ void ProcessExpressionType(Expression exp)
          }
          if(functionType && functionType.kind != TypeKind::functionType)
          {
-            Compiler_Error("called object %s is not a function\n", name);
+            Compiler_Error($"called object %s is not a function\n", name);
          }
          else if(functionType)
          {
@@ -8615,7 +8803,7 @@ void ProcessExpressionType(Expression exp)
             if(!type) emptyParams = true;
 
             // WORKING ON THIS:
-            if(functionType.extraParam && e)
+            if(functionType.extraParam && e && functionType.thisClass)
             {
                e.destType = MkClassType(functionType.thisClass.string);
                e = e.next;
@@ -8665,11 +8853,11 @@ void ProcessExpressionType(Expression exp)
                {
                   yylloc = e.loc;
                   if(methodType && methodType.methodClass)
-                     Compiler_Error("too many arguments for method %s::%s (%d given, expected %d)\n",
+                     Compiler_Error($"too many arguments for method %s::%s (%d given, expected %d)\n",
                         methodType.methodClass.fullName, methodType.method.name, exp.call.arguments->count,
                         noParams ? 0 : functionType.params.count);
                   else
-                     Compiler_Error("too many arguments for function %s (%d given, expected %d)\n",
+                     Compiler_Error($"too many arguments for function %s (%d given, expected %d)\n",
                         name /*exp.call.exp.identifier.string*/, exp.call.arguments->count,
                         noParams ? 0 : functionType.params.count);
                   break;
@@ -8731,8 +8919,16 @@ void ProcessExpressionType(Expression exp)
                }
                else
                {
-                  e.destType = type;
-                  if(type) type.refCount++;
+                  if(type && type.kind == ellipsisType && type.prev && type.prev.kind == classType && type.prev.classObjectType)
+                  {
+                     e.destType = type.prev;
+                     e.destType.refCount++;
+                  }
+                  else
+                  {
+                     e.destType = type;
+                     if(type) type.refCount++;
+                  }
                }
                // Don't reach the end for the ellipsis
                if(type && type.kind != ellipsisType)
@@ -8746,11 +8942,11 @@ void ProcessExpressionType(Expression exp)
             if(type && type.kind != ellipsisType)
             {
                if(methodType && methodType.methodClass)
-                  Compiler_Warning("not enough arguments for method %s::%s (%d given, expected %d)\n",
+                  Compiler_Warning($"not enough arguments for method %s::%s (%d given, expected %d)\n",
                      methodType.methodClass.fullName, methodType.method.name, exp.call.arguments ? exp.call.arguments->count : 0,
                      functionType.params.count + extra);
                else
-                  Compiler_Warning("not enough arguments for function %s (%d given, expected %d)\n",
+                  Compiler_Warning($"not enough arguments for function %s (%d given, expected %d)\n",
                      name /*exp.call.exp.identifier.string*/, exp.call.arguments ? exp.call.arguments->count : 0,
                      functionType.params.count + extra);
             }
@@ -8776,20 +8972,22 @@ void ProcessExpressionType(Expression exp)
                   yylloc = exp.call.exp.identifier.loc;
                   if(strstr(string, "__builtin_") == string);
                   else
-                     Compiler_Warning("%s undefined; assuming extern returning int\n", string);
+                     Compiler_Warning($"%s undefined; assuming extern returning int\n", string);
                   symbol = Symbol { string = CopyString(string), type = ProcessTypeString("int()", true) };
                   globalContext.symbols.Add((BTNode)symbol);
+                  if(strstr(symbol.string, "::"))
+                     globalContext.hasNameSpace = true;
 
                   yylloc = oldyylloc;
                }
             }
             else if(exp.call.exp.type == memberExp)
             {
-               /*Compiler_Warning("%s undefined; assuming returning int\n",
+               /*Compiler_Warning($"%s undefined; assuming returning int\n",
                   exp.call.exp.member.member.string);*/
             }
             else
-               Compiler_Warning("callable object undefined; extern assuming returning int\n");
+               Compiler_Warning($"callable object undefined; extern assuming returning int\n");
 
             if(!functionType.returnType)
             {
@@ -8858,7 +9056,7 @@ void ProcessExpressionType(Expression exp)
             {
                for(param = _class.templateParams.first; param; param = param.next)
                {
-                  if(param.type == identifier && !strcmp(param.name, exp.member.member.string))
+                  if(param.type == identifier && exp.member.member && exp.member.member.string && !strcmp(param.name, exp.member.member.string))
                      break;
                }
             }
@@ -9068,7 +9266,7 @@ void ProcessExpressionType(Expression exp)
                   exp.member.memberType = propertyMember;
 
                if(id && id._class && type._class && !eClass_IsDerived(type._class.registered, _class))
-                  Compiler_Error("invalid class specifier %s for object of class %s\n", _class.fullName, type._class.string);
+                  Compiler_Error($"invalid class specifier %s for object of class %s\n", _class.fullName, type._class.string);
 
                if(typeKind != subClassType)
                {
@@ -9254,7 +9452,7 @@ void ProcessExpressionType(Expression exp)
                      return;
                   }
                   yylloc = exp.member.member.loc;
-                  Compiler_Error("couldn't find member %s in class %s\n", id.string, _class.fullName);
+                  Compiler_Error($"couldn't find member %s in class %s\n", id.string, _class.fullName);
                   if(inCompiler)
                      eClass_AddDataMember(_class, id.string, "int", 0, 0, publicAccess);
                }
@@ -9269,7 +9467,7 @@ void ProcessExpressionType(Expression exp)
                   if(tClass && exp.expType.kind == templateType && exp.expType.templateParameter.type == TemplateParameterType::type)
                   {
                      int id = 0;
-                     ClassTemplateParameter curParam;
+                     ClassTemplateParameter curParam = null;
                      Class sClass;
 
                      for(sClass = tClass; sClass; sClass = sClass.base)
@@ -9327,7 +9525,7 @@ void ProcessExpressionType(Expression exp)
                   else if(tClass && exp.expType.kind == pointerType && exp.expType.type && exp.expType.type.kind == templateType && exp.expType.type.templateParameter.type == TemplateParameterType::type)
                   {
                      int id = 0;
-                     ClassTemplateParameter curParam;
+                     ClassTemplateParameter curParam = null;
                      Class sClass;
 
                      for(sClass = tClass; sClass; sClass = sClass.base)
@@ -9521,7 +9719,7 @@ void ProcessExpressionType(Expression exp)
                }
             }
             else
-               Compiler_Error("undefined class %s\n", (id && (!id._class || id._class.name))? (id.classSym ? id.classSym.string : (type._class ? type._class.string : null)) : "(null)");
+               Compiler_Error($"undefined class %s\n", (id && (!id._class || id._class.name))? (id.classSym ? id.classSym.string : (type._class ? type._class.string : null)) : "(null)");
          }
          else if(type && (type.kind == structType || type.kind == unionType))
          {
@@ -9538,7 +9736,7 @@ void ProcessExpressionType(Expression exp)
             char expString[10240];
             expString[0] = '\0';
             if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
-            Compiler_Error("member operator on non-structure type expression %s\n", expString);
+            Compiler_Error($"member operator on non-structure type expression %s\n", expString);
          }
 
          if(exp.expType && exp.expType.kind == thisClassType && (!exp.destType || exp.destType.kind != thisClassType))
@@ -9696,6 +9894,8 @@ void ProcessExpressionType(Expression exp)
       {
          Type type = ProcessType(exp.initializer.typeName.qualifiers, exp.initializer.typeName.declarator);
          type.refCount++;
+
+         // We have yet to support this... ( { } initializers are currently processed inside ProcessDeclaration()'s initDeclaration case statement
          // ProcessInitializer(exp.initializer.initializer, type);
          exp.expType = type;
          break;
@@ -9882,49 +10082,27 @@ void ProcessExpressionType(Expression exp)
          if(typeString)
          {
             /*
-            (Container)(__extension__( { 
-               int __arrayMembers[] = { 1, 7, 3, 4, 5 };
-               BuiltInContainer __baseContainer
-               {
-                  data = __arrayMembers,
-                  count = 5,
-                  type = class(int),
-                  _vTbl = class(BuiltInContainer)._vTbl,
-                  _class = class(BuiltInContainer) };
-               &__baseContainer;
-             }))
+            (Container)& (struct BuiltInContainer)
+            {
+               ._vTbl = class(BuiltInContainer)._vTbl,
+               ._class = class(BuiltInContainer),
+               .refCount = 0,
+               .data = (int[]){ 1, 7, 3, 4, 5 },
+               .count = 5,
+               .type = class(int),
+            }
             */
-            
             char templateString[1024];
-            OldList * declarations = MkList();
-            OldList * instMembers = MkList();
-            OldList * specs = MkList();
             OldList * initializers = MkList();
-            char count[128];
-            Expression e;
+            OldList * structInitializers = MkList();
+            OldList * specs = MkList();
             Expression expExt;
             Declarator decl = SpecDeclFromString(typeString, specs, null);
-            Context context = PushContext();
-
-            // sprintf(templateString, "Container<%s >", typeString);
             sprintf(templateString, "Container<%s>", typeString);
-   
-            ListAdd(instMembers, MkMemberInit(MkListOne(MkIdentifier("data")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier("__internalList")))));
-
-            sprintf(count, "%d", exp.list->count);
-            ListAdd(instMembers, MkMemberInit(MkListOne(MkIdentifier("count")), MkInitializerAssignment(MkExpConstant(count))));
-
-            ListAdd(instMembers, MkMemberInit(MkListOne(MkIdentifier("type")), MkInitializerAssignment(MkExpClass(CopyList(specs, CopySpecifier), 
-               CopyDeclarator(decl)))));
-
-            ListAdd(instMembers, MkMemberInit(MkListOne(MkIdentifier("_vTbl")), MkInitializerAssignment(MkExpMember(
-               MkExpClass(MkListOne(MkSpecifierName("BuiltInContainer")), null), MkIdentifier("_vTbl")))));
-
-            ListAdd(instMembers, MkMemberInit(MkListOne(MkIdentifier("_class")), MkInitializerAssignment(
-               MkExpClass(MkListOne(MkSpecifierName("BuiltInContainer")), null))));
 
             if(exp.list)
             {
+               Expression e;
                type = ProcessTypeString(typeString, false);
                while(e = exp.list->first)
                {
@@ -9938,25 +10116,34 @@ void ProcessExpressionType(Expression exp)
                delete exp.list;
             }
             
-            ListAdd(declarations, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorArray(PlugDeclarator(decl, 
-               MkDeclaratorIdentifier(MkIdentifier("__internalList"))), null),
-               MkInitializerList(initializers)))));
-            ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName("BuiltInContainer")),
-               MkExpIdentifier(MkIdentifier("__internalContainer")), MkListOne(MkMembersInitList(instMembers)))));
-
+            DeclareStruct("ecere::com::BuiltInContainer", false);
+
+            ListAdd(structInitializers, /*MkIdentifier("_vTbl")*/    MkInitializerAssignment(MkExpMember(MkExpClass(MkListOne(MkSpecifierName("BuiltInContainer")), null), MkIdentifier("_vTbl"))));
+               ProcessExpressionType(((Initializer)structInitializers->last).exp);
+            ListAdd(structInitializers, /*MkIdentifier("_class")*/   MkInitializerAssignment(MkExpClass(MkListOne(MkSpecifierName("BuiltInContainer")), null)));
+               ProcessExpressionType(((Initializer)structInitializers->last).exp);
+            ListAdd(structInitializers, /*MkIdentifier("_refCount")*/MkInitializerAssignment(MkExpConstant("0")));
+               ProcessExpressionType(((Initializer)structInitializers->last).exp);
+            ListAdd(structInitializers, /*MkIdentifier("data")*/     MkInitializerAssignment(MkExpExtensionInitializer(
+               MkTypeName(specs, MkDeclaratorArray(decl, null)),
+               MkInitializerList(initializers))));
+               ProcessExpressionType(((Initializer)structInitializers->last).exp);
+            ListAdd(structInitializers, /*MkIdentifier("count")*/    MkInitializerAssignment({ type = constantExp, constant = PrintString(initializers->count) }));
+               ProcessExpressionType(((Initializer)structInitializers->last).exp);
+            ListAdd(structInitializers, /*MkIdentifier("type")*/     MkInitializerAssignment(MkExpClass(CopyList(specs, CopySpecifier), CopyDeclarator(decl))));
+               ProcessExpressionType(((Initializer)structInitializers->last).exp);
             exp.expType = ProcessTypeString(templateString, false);
             exp.type = bracketsExp;
             exp.list = MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName(templateString)), null),
-               (expExt = MkExpExtensionCompound(MkCompoundStmt(
-                  declarations, MkListOne(MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalContainer")))))))))));
-            expExt.compound.compound.context = context;
-            PopContext(context);
+               MkExpOp(null, '&',
+               expExt = MkExpExtensionInitializer(MkTypeName(MkListOne(MkSpecifierName("BuiltInContainer")), null),
+                  MkInitializerList(structInitializers)))));
             ProcessExpressionType(expExt);
          }
          else
          {
             exp.expType = ProcessTypeString("Container", false);
-            Compiler_Error("Couldn't determine type of array elements\n");
+            Compiler_Error($"Couldn't determine type of array elements\n");
          }
          break;
       }
@@ -9978,6 +10165,17 @@ void ProcessExpressionType(Expression exp)
          if(exp.expType.kind != enumType)
          {
             Type member;
+            String enumName = CopyString(exp.expType.enumName);
+
+            // Fixed a memory leak on self-referencing C structs typedefs
+            // by instantiating a new type rather than simply copying members
+            // into exp.expType
+            FreeType(exp.expType);
+            exp.expType = Type { };
+            exp.expType.kind = symbol.type.kind;
+            exp.expType.refCount++;
+            exp.expType.enumName = enumName;
+
             exp.expType.members = symbol.type.members;
             for(member = symbol.type.members.first; member; member = member.next)
                member.refCount++;
@@ -10018,9 +10216,9 @@ void ProcessExpressionType(Expression exp)
 
                      if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
                      if(unresolved)
-                        Compiler_Error("unresolved identifier %s; expected %s\n", expString, type2);
+                        Compiler_Error($"unresolved identifier %s; expected %s\n", expString, type2);
                      else if(exp.type != dummyExp)
-                        Compiler_Error("couldn't determine type of %s; expected %s\n", expString, type2);
+                        Compiler_Error($"couldn't determine type of %s; expected %s\n", expString, type2);
                   }
                }
                else
@@ -10030,9 +10228,9 @@ void ProcessExpressionType(Expression exp)
                   if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
 
                   if(unresolved)
-                     Compiler_Error("unresolved identifier %s\n", expString);
+                     Compiler_Error($"unresolved identifier %s\n", expString);
                   else if(exp.type != dummyExp)
-                     Compiler_Error("couldn't determine type of %s\n", expString);
+                     Compiler_Error($"couldn't determine type of %s\n", expString);
                }
             }
             else
@@ -10061,7 +10259,9 @@ void ProcessExpressionType(Expression exp)
 #ifdef _DEBUG
                   CheckExpressionType(exp, exp.destType, false);
 #endif
-                  Compiler_Warning("incompatible expression %s (%s); expected %s\n", expString, type1, type2);
+                  // Flex & Bison generate code that triggers this, so we ignore it for a quiet sdk build:
+                  if(!sourceFile || (strcmp(sourceFile, "src\\lexer.ec") && strcmp(sourceFile, "src/lexer.ec") && strcmp(sourceFile, "src\\grammar.ec") && strcmp(sourceFile, "src/grammar.ec")))
+                     Compiler_Warning($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
 
                   // TO CHECK: FORCING HERE TO HELP DEBUGGER
                   FreeType(exp.expType);
@@ -10097,16 +10297,16 @@ void ProcessExpressionType(Expression exp)
    else if(unresolved)
    {
       if(exp.identifier._class && exp.identifier._class.name)
-         Compiler_Error("unresolved identifier %s::%s\n", exp.identifier._class.name, exp.identifier.string);
+         Compiler_Error($"unresolved identifier %s::%s\n", exp.identifier._class.name, exp.identifier.string);
       else if(exp.identifier.string && exp.identifier.string[0])
-         Compiler_Error("unresolved identifier %s\n", exp.identifier.string);
+         Compiler_Error($"unresolved identifier %s\n", exp.identifier.string);
    }
    else if(!exp.expType && exp.type != dummyExp)
    {
       char expString[10240];
       expString[0] = '\0';
       if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
-      Compiler_Error("couldn't determine type of %s\n", expString);
+      Compiler_Error($"couldn't determine type of %s\n", expString);
    }
 
    // Let's try to support any_object & typed_object here:
@@ -10279,7 +10479,7 @@ static void ProcessInitializer(Initializer init, Type type)
 
          if(type && type.kind != arrayType && type.kind != structType && type.kind != unionType && (type.kind != classType || !type._class.registered || type._class.registered.type != structClass))
          {
-            Compiler_Error("Assigning list initializer to non list\n");
+            Compiler_Error($"Assigning list initializer to non list\n");
          }
          break;
       }
@@ -10990,7 +11190,7 @@ static void ProcessStatement(Statement stmt)
                else
                {
                   arrayExp.expType = ProcessTypeString("Container", false);
-                  Compiler_Error("Couldn't determine type of array elements\n");
+                  Compiler_Error($"Couldn't determine type of array elements\n");
                }
 
                /*
@@ -11148,7 +11348,7 @@ static void ProcessStatement(Statement stmt)
          }
          else
          {
-            Compiler_Error("Expression is not a container\n");
+            Compiler_Error($"Expression is not a container\n");
          }
          break;
       }
@@ -11325,12 +11525,12 @@ static void ProcessStatement(Statement stmt)
                               ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_Watch")), args));
                            }
                            else
-                              Compiler_Error("Property %s not found in class %s\n", prop.name, _class.fullName);
+                              Compiler_Error($"Property %s not found in class %s\n", prop.name, _class.fullName);
                         }
                      }
                   }
                   else
-                     Compiler_Error("Invalid watched object\n");
+                     Compiler_Error($"Invalid watched object\n");
                }
 
                curExternal = external;
@@ -11343,7 +11543,7 @@ static void ProcessStatement(Statement stmt)
                FreeList(watches, FreePropertyWatch);
             }
             else
-               Compiler_Error("No observer specified and not inside a _class\n");
+               Compiler_Error($"No observer specified and not inside a _class\n");
          }
          else
          {
@@ -11385,7 +11585,7 @@ static void ProcessStatement(Statement stmt)
                }
                else if(!watches)
                {
-                  //Compiler_Error("No property specified and not inside a property set\n");
+                  //Compiler_Error($"No property specified and not inside a property set\n");
                }
                if(watches)
                {
@@ -11397,7 +11597,7 @@ static void ProcessStatement(Statement stmt)
                         CreateFireWatcher(prop, object, stmt);
                      }
                      else
-                        Compiler_Error("Property %s not found in class %s\n", propID.string, _class.fullName);
+                        Compiler_Error($"Property %s not found in class %s\n", propID.string, _class.fullName);
                   }
                }
                else
@@ -11422,7 +11622,7 @@ static void ProcessStatement(Statement stmt)
                FreeList(watches, FreeIdentifier);
             }
             else
-               Compiler_Error("Invalid object specified and not inside a class\n");
+               Compiler_Error($"Invalid object specified and not inside a class\n");
          }
          break;
       }
@@ -11486,7 +11686,7 @@ static void ProcessStatement(Statement stmt)
                            ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_StopWatching")), args));
                         }
                         else
-                           Compiler_Error("Property %s not found in class %s\n", prop.name, _class.fullName);
+                           Compiler_Error($"Property %s not found in class %s\n", prop.name, _class.fullName);
                      }
                   }
 
@@ -11497,10 +11697,10 @@ static void ProcessStatement(Statement stmt)
                   FreeList(watches, FreeIdentifier);
                }
                else
-                  Compiler_Error("Invalid object specified and not inside a class\n");
+                  Compiler_Error($"Invalid object specified and not inside a class\n");
             }
             else
-               Compiler_Error("No observer specified and not inside a class\n");
+               Compiler_Error($"No observer specified and not inside a class\n");
          }
          break;
       }
@@ -11979,22 +12179,72 @@ static void ProcessClass(OldList definitions, Symbol symbol)
    }
 }
 
+void DeclareFunctionUtil(String s)
+{
+   GlobalFunction function = eSystem_FindFunction(privateModule, s);
+   if(function)
+   {
+      char name[1024];
+      name[0] = 0;
+      if(function.module.importType != staticImport && (!function.dataType || !function.dataType.dllExport))
+         strcpy(name, "__ecereFunction_");
+      FullClassNameCat(name, s, false); // Why is this using FullClassNameCat ?
+      DeclareFunction(function, name);
+   }
+}
+
 void ComputeDataTypes()
 {
    External external;
    External temp { };
+   External after = null;
+
    currentClass = null;
 
    containerClass = eSystem_FindClass(GetPrivateModule(), "Container");
 
-   temp.symbol = Symbol { id = -1000, idCode = -1000 };
-
-   // WHERE SHOULD THIS GO?
-   // curExternal = ast->first;
-   ast->Insert(null, temp);
+   for(external = ast->first; external; external = external.next)
+   {
+      if(external.type == declarationExternal)
+      {
+         Declaration decl = external.declaration;
+         if(decl)
+         {
+            OldList * decls = decl.declarators;
+            if(decls)
+            {
+               InitDeclarator initDecl = decls->first;
+               if(initDecl)
+               {
+                  Declarator declarator = initDecl.declarator;
+                  if(declarator && declarator.type == identifierDeclarator)
+                  {
+                     Identifier id = declarator.identifier;
+                     if(id && id.string)
+                     {
+                        if(!strcmp(id.string, "uintptr_t") || !strcmp(id.string, "intptr_t") || !strcmp(id.string, "size_t") || !strcmp(id.string, "ssize_t"))
+                        {
+                           external.symbol.id = -1001, external.symbol.idCode = -1001;
+                           after = external;
+                        }
+                     }
+                  }
+               }
+            }
+         }
+       }
+   }
 
+   temp.symbol = Symbol { id = -1000, idCode = -1000 };
+   ast->Insert(after, temp);
    curExternal = temp;
 
+   DeclareFunctionUtil("eSystem_New");
+   DeclareFunctionUtil("eSystem_New0");
+   DeclareFunctionUtil("eSystem_Renew");
+   DeclareFunctionUtil("eSystem_Renew0");
+   DeclareFunctionUtil("eClass_GetProperty");
+
    DeclareStruct("ecere::com::Class", false);
    DeclareStruct("ecere::com::Instance", false);
    DeclareStruct("ecere::com::Property", false);