i18n: (#858) Handling localization for libraries within static executables
[sdk] / compiler / libec / src / ast.ec
index 8482d37..4d5e08f 100644 (file)
@@ -1,7 +1,7 @@
 import "ecdefs"
 
 #define YYLTYPE Location
-#include "grammar.eh"
+#include "grammar.h"
 extern char * yytext;
 
 char * defaultNameSpace;
@@ -12,7 +12,9 @@ bool strictNameSpaces;
 public void SetStrictNameSpaces(bool b) { strictNameSpaces = b; }
 
 AccessMode declMode = privateAccess;
-public void SetDeclMode(AccessMode accessMode) { declMode = accessMode; }
+AccessMode structDeclMode = privateAccess;
+
+public void SetDeclMode(AccessMode accessMode) { structDeclMode = declMode = accessMode; }
 AccessMode defaultDeclMode = privateAccess;
 public void SetDefaultDeclMode(AccessMode accessMode) { defaultDeclMode = accessMode; }
 
@@ -55,7 +57,7 @@ public Identifier MkIdentifier(char * string)
 {
    Identifier id { };
    int c;
-   
+
    id._class = null; // Default class...
 
    if(string)
@@ -81,7 +83,7 @@ public Identifier MkIdentifier(char * string)
          // TODO: Do these better, keep in string?
          if(!strcmp(name, "typed_object"))
          {
-            id._class = MkSpecifierName("class");
+            id._class = MkSpecifierName("typed_object"); //"class");
             id.string = CopyString(namePart);
          }
          else if(!strcmp(name, "property"))
@@ -119,7 +121,7 @@ public Identifier MkIdentifier(char * string)
                else
                   id.string = CopyString(string);
             }
-         }         
+         }
       }
       else if(gotColon)
       {
@@ -139,8 +141,9 @@ public TemplateParameter MkTypeTemplateParameter(Identifier identifier, Template
    if(identifier.string)
    {
       TemplateParameter param { type = TemplateParameterType::type, identifier = identifier, dataType = baseTplDatatype, defaultArgument = defaultArgument };
-      TemplatedType type { key = (uint)identifier.string, param = param };
-      curContext.templateTypes.Add((BTNode)type);
+      TemplatedType type { key = (uintptr)identifier.string, param = param };
+      if(!curContext.templateTypes.Add((BTNode)type))
+         delete type;
       return param;
    }
    return null;
@@ -212,7 +215,8 @@ public Expression MkExpIdentifier(Identifier id)
 
 public Expression MkExpDummy()
 {
-   return { type = dummyExp };
+   Expression exp { type = dummyExp };
+   return exp;
 }
 
 public Expression MkExpConstant(char * string)
@@ -225,6 +229,97 @@ Expression MkExpString(char * string)
    return { type = stringExp, string = CopyString(string) };
 }
 
+// TODO: String is case sensitive..
+//       What should we do about it?
+/*public class CaseSensitiveString : String
+{
+   int OnCompare(CaseSensitiveString string2)
+   {
+      int result = 0;
+      if(this && string2)
+         result = strcmpi(this, string2);
+      else if(!this && string2)
+         result = 1;
+      else if(this && !string2)
+         result = -1;
+      return result;
+   }
+}*/
+
+public struct ContextStringPair
+{
+   String string, context;
+
+   // TODO: Should this be automated somehow?
+   void OnFree()
+   {
+      delete string;
+      delete context;
+   }
+
+   int OnCompare(ContextStringPair b)
+   {
+      int result;
+      result = (string && b.string) ? strcmp(string, b.string) :
+         (!string && b.string) ? 1 : (string && !b.string) ? -1 : 0;
+      if(result) return result;
+
+      result = (context && b.context) ? strcmp(context, b.context) :
+         (!context && b.context) ? 1 : (context && !b.context) ? -1 : 0;
+      // TODO: Support these
+      // result = CaseSensitiveString::OnCompare(string, b.string);
+      // result = ((CaseSensitiveString)string).OnCompare(b.string);
+      return result;
+   }
+};
+
+Map<ContextStringPair, List<Location>> intlStrings { };
+
+Expression MkExpIntlString(char * string, char * context)
+{
+   OldList * list = MkList();
+   if(inCompiler)
+   {
+      ContextStringPair pair { };
+      List<Location> list;
+      int len = strlen(string);
+
+      pair.string = new byte[len-2+1]; memcpy(pair.string, string+1, len-2); pair.string[len-2] = '\0';
+      if(context) { len = strlen(context); pair.context = new byte[len-2+1]; memcpy(pair.context, context+1, len-2); pair.context[len-2] = '\0'; }
+
+      list = intlStrings[pair];
+      if(!list)
+      {
+         list = { };
+         intlStrings[pair] = list;
+      }
+      else
+      {
+         delete pair.string;
+         delete pair.context;
+      }
+      list.Add(yylloc);
+   }
+   //ListAdd(list, QMkExpId("__thisModule"));
+   ListAdd(list, MkExpString(QMkString(i18nModuleName ? i18nModuleName : "")));
+   ListAdd(list, MkExpString(string));
+   if(context)
+   {
+      int lenString = strlen(string), lenContext = strlen(context);
+      char * msgid = new char[lenString-2 + lenContext-2 + 4];
+      msgid[0] = '\"';
+      memcpy(msgid+1, context+1, lenContext-2);
+      msgid[1+lenContext-2] = 4; // EOT
+      memcpy(msgid+1+lenContext-2+1, string+1, lenString-2);
+      memcpy(msgid+1+lenContext-2+1+lenString-2, "\"", 2);
+      ListAdd(list, MkExpString(msgid));
+      delete msgid;
+   }
+   else
+      ListAdd(list, QMkExpId("null"));
+   return MkExpCall(QMkExpId("GetTranslatedString"), list);
+}
+
 Expression MkExpOp(Expression exp1, int op, Expression exp2)
 {
    Expression exp
@@ -282,6 +377,11 @@ Expression MkExpTypeSize(TypeName typeName)
    return { type = typeSizeExp, typeName = typeName };
 }
 
+Expression MkExpTypeAlign(TypeName typeName)
+{
+   return { type = typeAlignExp, typeName = typeName };
+}
+
 Expression MkExpClassSize(Specifier _class)
 {
    return { type = classSizeExp, _class = _class };
@@ -324,7 +424,12 @@ Expression MkExpVaArg(Expression exp, TypeName type)
 
 Specifier MkSpecifier(int specifier)
 {
-   return { type = baseSpecifier, specifier = specifier };
+   if(specifier == _BOOL && (declMode != defaultAccess && defaultDeclMode != defaultAccess))
+      return MkSpecifierName("bool");
+   else if(specifier == _BOOL || specifier == BOOL)
+      return { type = baseSpecifier, specifier = specifier };
+   else
+      return { type = baseSpecifier, specifier = specifier };
 }
 
 Specifier MkSpecifierTypeOf(Expression expression)
@@ -337,14 +442,14 @@ Specifier MkSpecifierSubClass(Specifier _class)
    return { type = subClassSpecifier, _class = _class };
 }
 
-Specifier MkSpecifierExtended(char * name)
+Specifier MkSpecifierExtended(ExtDecl extDecl)
 {
-   return { type = extendedSpecifier, name = CopyString(name) };
+   return { type = extendedSpecifier, extDecl = extDecl /*name = CopyString(name)*/ };
 }
 
 Specifier MkEnum(Identifier id, OldList list)
 {
-   Specifier spec 
+   Specifier spec
    {
       type = enumSpecifier;
       id = id;
@@ -360,13 +465,21 @@ Specifier MkEnum(Identifier id, OldList list)
 
       if(id)
       {
-         curContext.structSymbols.Add((BTNode)Symbol { string = CopyString(id.string), isStruct = true, type = type });
+         Symbol symbol { string = CopyString(id.string), isStruct = true, type = type };
          type.refCount++;
+         if(strstr(symbol.string, "::"))
+            curContext.hasNameSpace = true;
+         if(!curContext.structSymbols.Add((BTNode)symbol))
+            FreeSymbol(symbol);
       }
       for(e = list.first; e; e = e.next)
       {
-         (curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)Symbol { string = CopyString(e.id.string), type = type });
+         Symbol symbol { string = CopyString(e.id.string), type = type };
          type.refCount++;
+         if(strstr(symbol.string, "::"))
+            curContext.hasNameSpace = true;
+         if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
+            FreeSymbol(symbol);
       }
       FreeType(type);
    }
@@ -377,13 +490,16 @@ Specifier MkStructOrUnion(SpecifierType type, Identifier id, OldList definitions
 {
    Specifier spec { type = type, id = id };
    if(id && FindType(curContext, id.string))
-      declMode = defaultAccess;
+      structDeclMode = defaultAccess;
    spec.definitions = definitions;
-   if(definitions && id && !declMode)
+   if(definitions && id && structDeclMode == defaultAccess)
    {
       OldList specs { };
+      Symbol symbol;
       specs.Add(spec);
-      curContext.structSymbols.Add((BTNode)Symbol { string = CopyString(id.string), type = ProcessType(specs, null), isStruct = true });
+      symbol = Symbol { string = CopyString(id.string), type = ProcessType(specs, null), isStruct = true };
+      if(!curContext.structSymbols.Add((BTNode)symbol))
+         FreeSymbol(symbol);
    }
    return spec;
 }
@@ -393,12 +509,37 @@ void AddStructDefinitions(Specifier spec, OldList definitions)
    spec.definitions = definitions;
    if(definitions && spec.id && !declMode)
    {
+      Symbol symbol;
       OldList specs { };
       specs.Add(spec);
-      curContext.parent.structSymbols.Add((BTNode)Symbol { string = CopyString(spec.id.string), type = ProcessType(specs, null), isStruct = true });
+      symbol = Symbol { string = CopyString(spec.id.string), type = ProcessType(specs, null), isStruct = true };
+      if(!curContext.parent.structSymbols.Add((BTNode)symbol))
+         FreeSymbol(symbol);
    }
 }
 
+Attribute MkAttribute(String attr, Expression exp)
+{
+   return { attr = attr, exp = exp };
+}
+
+Attrib MkAttrib(int type, OldList * attribs)
+{
+   return { type = type, attribs = attribs };
+}
+
+ExtDecl MkExtDeclString(String s)
+{
+   return { type = extDeclString, s = s };
+
+}
+
+ExtDecl MkExtDeclAttrib(Attrib attr)
+{
+   return { type = extDeclAttrib, attr = attr };
+}
+
+
 public Declarator MkDeclaratorIdentifier(Identifier id)
 {
    return { type = identifierDeclarator, identifier = id };
@@ -409,12 +550,12 @@ Declarator MkDeclaratorFunction(Declarator declarator, OldList parameters)
    return { type = functionDeclarator, declarator = declarator, function.parameters = parameters };
 }
 
-Declarator MkDeclaratorExtended(char * extended, Declarator declarator)
+Declarator MkDeclaratorExtended(ExtDecl extended, Declarator declarator)
 {
    return { type = extendedDeclarator, declarator = declarator, extended.extended = extended };
 }
 
-Declarator MkDeclaratorExtendedEnd(char * extended, Declarator declarator)
+Declarator MkDeclaratorExtendedEnd(ExtDecl extended, Declarator declarator)
 {
    return { type = extendedDeclaratorEnd, declarator = declarator, extended.extended = extended };
 }
@@ -475,6 +616,91 @@ InitDeclarator MkInitDeclarator(Declarator declarator, Initializer initializer)
 
 public TypeName MkTypeName(OldList qualifiers, Declarator declarator)
 {
+   if(qualifiers != null)
+   {
+      Declarator parentDecl = declarator;
+      Declarator decl = declarator;
+      while(decl && decl.type == arrayDeclarator)
+         decl = decl.declarator;
+      if(decl && decl.type == identifierDeclarator && decl.identifier.string && CheckType(decl.identifier.string) == TYPE_NAME)
+      {
+         Specifier spec;
+         // Check if we're missing a real type specifier here
+         for(spec = qualifiers.first; spec; spec = spec.next)
+         {
+            if(spec.type == baseSpecifier)
+            {
+               if(spec.specifier == CONST || spec.specifier == VOLATILE ||
+                  spec.specifier == EXTERN || spec.specifier == STATIC ||
+                  spec.specifier == AUTO || spec.specifier == REGISTER)
+                  continue;
+               break;
+            }
+            else if(spec.type != extendedSpecifier)
+               break;
+         }
+         if(!spec)
+         {
+            // This is actually a type
+            ListAdd(qualifiers, MkSpecifierName(decl.identifier.string));
+            FreeDeclarator(decl);
+            parentDecl.declarator = null;
+         }
+      }
+   }
+   return { qualifiers = qualifiers, declarator = declarator };
+}
+
+public TypeName MkTypeNameGuessDecl(OldList qualifiers, Declarator declarator)
+{
+   if(qualifiers != null)
+   {
+      bool gotType = false;
+      bool gotFullType = false;
+      Specifier spec, next;
+      for(spec = qualifiers.first; spec; spec = next)
+      {
+         next = spec.next;
+         if(gotType && !declarator && ((spec.type == nameSpecifier && spec.name) || (spec.type == baseSpecifier && gotFullType)))
+         {
+            String s = null;
+            if(spec.type == nameSpecifier)
+            {
+               char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
+               s = colon ? colon + 2 : spec.name;
+            }
+            else if(spec.type == baseSpecifier)
+            {
+               if(spec.specifier == INT64) s = "int64";
+            }
+            if(s)
+            {
+               declarator = MkDeclaratorIdentifier(MkIdentifier(s));
+               qualifiers.Remove(spec);
+               FreeSpecifier(spec);
+               spec = null;
+            }
+         }
+         if(spec && spec.type != extendedSpecifier)
+         {
+            if(spec.type == baseSpecifier)
+            {
+               if(spec.specifier == CONST || spec.specifier == VOLATILE ||
+                  spec.specifier == EXTERN || spec.specifier == STATIC ||
+                  spec.specifier == AUTO || spec.specifier == REGISTER)
+                  continue;
+               else if(spec.specifier != UNSIGNED && spec.specifier != SIGNED && spec.specifier != LONG)
+                  gotFullType = true;
+               gotType = true;
+            }
+            else
+            {
+               gotFullType = true;
+               gotType = true;
+            }
+         }
+      }
+   }
    return { qualifiers = qualifiers, declarator = declarator };
 }
 
@@ -527,7 +753,10 @@ Declaration MkDeclarationInst(Instantiation inst)
       type = MkClassTypeSymbol(inst._class.symbol);
    };
    symbol.idCode = symbol.id = curContext.nextID++;
-   (curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol);
+   if(strstr(symbol.string, "::"))
+      curContext.hasNameSpace = true;
+   if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
+      excludedSymbols->Add(symbol);
    decl.symbol = inst.symbol = symbol;
    return decl;
 }
@@ -569,7 +798,7 @@ Declaration MkDeclarationDefine(Identifier id, Expression exp)
    if(!eSystem_FindDefine(privateModule, id.string))
       eSystem_RegisterDefine(id.string, expString, privateModule, buildingECERECOMModule ? baseSystemAccess : publicAccess);
    else
-      Compiler_Warning("Redefinition of %s ignored\n", id.string);
+      Compiler_Warning($"Redefinition of %s ignored\n", id.string);
    return decl;
 }
 
@@ -577,18 +806,20 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
 {
    Declaration decl { type = initDeclaration, declarators = initDeclarators, specifiers = specifiers, loc = yylloc };
    bool variable = true;
-   
+
    if(specifiers != null)
    {
-      Specifier spec;
-      for(spec = specifiers.first; spec; spec = spec.next)
+      bool gotType = false;
+      Specifier spec, next;
+      for(spec = specifiers.first; spec; spec = next)
       {
+         next = spec.next;
          if(spec.type == baseSpecifier && spec.specifier == TYPEDEF)
          {
             if(initDeclarators != null)
             {
                InitDeclarator d;
-         
+
                for(d = initDeclarators.first; d; d = d.next)
                {
                   if(GetDeclId(d.declarator).string)
@@ -600,34 +831,74 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
                      };
                      type.id = type.idCode = curContext.nextID++;
 
-                     (curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type);
+                     if(!(curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type))
+                        excludedSymbols->Add(type);
                      decl.symbol = d.declarator.symbol = type;
                   }
                }
             }
             else if(spec.next)
             {
-               for(; spec; spec = spec.next)
+               //for(spec = spec.next; spec; spec = spec.next)
+               spec = specifiers.last;
                {
-                  if(spec.type == nameSpecifier && spec.name)
+                  if((spec.type == nameSpecifier && spec.name) || spec.type == baseSpecifier)
                   {
-                     Symbol type
+                     String s = null;
+                     if(spec.type == nameSpecifier)
                      {
-                        string = CopyString(spec.name);
-                        type = ProcessType(specifiers, null);
-                     };
-                     type.id = type.idCode = curContext.nextID++;
-                     (curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type);
-                     decl.symbol = type;
+                        char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
+                        s = colon ? colon + 2 : spec.name;
+                     }
+                     else if(spec.type == baseSpecifier)
+                     {
+                        if(spec.specifier == INT64) s = "int64";
+                     }
+                     if(s)
+                     {
+                        Symbol type { string = CopyString(s), type = ProcessType(specifiers, null) };
+                        type.id = type.idCode = curContext.nextID++;
+                        decl.symbol = type;
+                        decl.declarators = initDeclarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
+                        specifiers.Remove(spec);
+                        FreeSpecifier(spec);
+                        if(!(curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type))
+                           excludedSymbols->Add(type);
+                     }
                   }
                }
             }
             variable = false;
             break;
          }
-         else if(spec.type == baseSpecifier && 
+         else if(spec.type == baseSpecifier &&
             (spec.specifier == STRUCT || spec.specifier == UNION))
             variable = false;
+         else
+         {
+            if(gotType && initDeclarators == null && !spec.next && ((spec.type == nameSpecifier && spec.name) || spec.type == baseSpecifier))
+            {
+               String s = null;
+               if(spec.type == nameSpecifier)
+               {
+                  char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
+                  s = colon ? colon + 2 : spec.name;
+               }
+               else if(spec.type == baseSpecifier)
+               {
+                  if(spec.specifier == INT64) s = "int64";
+               }
+               if(s)
+               {
+                  decl.declarators = initDeclarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
+                  specifiers.Remove(spec);
+                  FreeSpecifier(spec);
+                  spec = null;
+               }
+            }
+         }
+         if(spec && spec.type != extendedSpecifier)
+            gotType = true;
       }
    }
    if(variable && initDeclarators)
@@ -667,45 +938,53 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
                   delete id.string;
                   id.string = CopyString(name);
                }
-               
-               symbol = Symbol { string = CopyString(id.string), type = ProcessType(specifiers, d.declarator) };
-               (curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol);
-               // TODO: Add better support to count declarators
-               if(symbol.type && symbol.type.kind == arrayType && !symbol.type.arraySizeExp && d.initializer)
+
+               // Avoid memory leaks on duplicated symbols (BinaryTree::Add Would Fail)
+               symbol = (Symbol)(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.FindString(id.string);
+               if(!symbol)
                {
-                  if(d.initializer.type == listInitializer)
+                  symbol = Symbol { string = CopyString(id.string), type = ProcessType(specifiers, d.declarator) };
+                  if(strstr(symbol.string, "::"))
+                     curContext.hasNameSpace = true;
+                  if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
+                     excludedSymbols->Add(symbol);
+                  // TODO: Add better support to count declarators
+                  if(symbol.type && symbol.type.kind == arrayType && !symbol.type.arraySizeExp && d.initializer)
                   {
-                     char string[256];
-                     sprintf(string, "%d",d.initializer.list->count);
-                     symbol.type.arraySizeExp = MkExpConstant(string);
-                     symbol.type.freeExp = true;
-                  }
-                  else if(d.initializer.type == expInitializer && d.initializer.exp.type == stringExp && d.initializer.exp.string)
-                  {
-                     char string[256];
-                     int c, count = 0;
-                     char ch;
-                     bool escaped = false;
-                     char * s = d.initializer.exp.string;
-
-                     // MAKE MORE ACCURATE
-                     for(c = 1; (ch = s[c]); c++)
+                     if(d.initializer.type == listInitializer)
+                     {
+                        char string[256];
+                        sprintf(string, "%d",d.initializer.list->count);
+                        symbol.type.arraySizeExp = MkExpConstant(string);
+                        symbol.type.freeExp = true;
+                     }
+                     else if(d.initializer.type == expInitializer && d.initializer.exp.type == stringExp && d.initializer.exp.string)
                      {
-                        if(ch == '\\' && !escaped)
-                           escaped = true;
-                        else
+                        char string[256];
+                        int c, count = 0;
+                        char ch;
+                        bool escaped = false;
+                        char * s = d.initializer.exp.string;
+
+                        // MAKE MORE ACCURATE
+                        for(c = 1; (ch = s[c]); c++)
                         {
-                           count++;
-                           escaped = false;
+                           if(ch == '\\' && !escaped)
+                              escaped = true;
+                           else
+                           {
+                              count++;
+                              escaped = false;
+                           }
                         }
-                     }
 
-                     sprintf(string, "%d", count);
-                     symbol.type.arraySizeExp = MkExpConstant(string);
-                     symbol.type.freeExp = true;
+                        sprintf(string, "%d", count);
+                        symbol.type.arraySizeExp = MkExpConstant(string);
+                        symbol.type.freeExp = true;
+                     }
                   }
+                  symbol.id = symbol.idCode = curContext.nextID++;
                }
-               symbol.id = symbol.idCode = curContext.nextID++;
                decl.symbol = d.declarator.symbol = symbol;
             }
          }
@@ -722,7 +1001,39 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
 
 Declaration MkStructDeclaration(OldList specifiers, OldList declarators, Specifier extStorage)
 {
-   return { type = structDeclaration, declarators = declarators, specifiers = specifiers, extStorage = extStorage, loc = yylloc };
+   Declaration decl { type = structDeclaration, declarators = declarators, specifiers = specifiers, extStorage = extStorage, loc = yylloc };
+   if(specifiers != null)
+   {
+      bool gotType = false;
+      Specifier spec, next;
+      for(spec = specifiers.first; spec; spec = next)
+      {
+         next = spec.next;
+         if(gotType && declarators == null && ((spec.type == nameSpecifier && spec.name) || spec.type == baseSpecifier))
+         {
+            String s = null;
+            if(spec.type == nameSpecifier)
+            {
+               char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
+               s = colon ? colon + 2 : spec.name;
+            }
+            else if(spec.type == baseSpecifier)
+            {
+               if(spec.specifier == INT64) s = "int64";
+            }
+            if(s)
+            {
+               decl.declarators = declarators = MkListOne(MkStructDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
+               specifiers.Remove(spec);
+               FreeSpecifier(spec);
+               spec = null;
+            }
+         }
+         if(spec && spec.type != extendedSpecifier)
+            gotType = true;
+      }
+   }
+   return decl;
 }
 
 Statement MkLabeledStmt(Identifier id, Statement statement)
@@ -805,6 +1116,35 @@ Statement MkReturnStmt(OldList exp)
 
 FunctionDefinition MkFunction(OldList specifiers, Declarator declarator, OldList declarationList)
 {
+   return _MkFunction(specifiers, declarator, declarationList, true);
+}
+
+FunctionDefinition _MkFunction(OldList specifiers, Declarator declarator, OldList declarationList, bool errorOnOmit)
+{
+   if(errorOnOmit)
+   {
+      Declarator funcDecl = GetFuncDecl(declarator);
+      if(funcDecl && funcDecl.function.parameters)
+      {
+         TypeName tn;
+         for(tn = funcDecl.function.parameters->first; tn; tn = tn.next)
+         {
+            if(tn.qualifiers || tn.declarator)
+            {
+               Identifier declID = tn.declarator ? GetDeclId(tn.declarator) : null;
+               if(!declID)
+               {
+                  // Check for (void)
+                  Specifier spec = tn.qualifiers ? tn.qualifiers->first : null;
+                  if(!tn.declarator && !tn.prev && !tn.next && spec && !spec.next && spec.type == baseSpecifier && spec.specifier == VOID);
+                  else
+                     Compiler_Error("parameter name omitted\n");
+                  break;
+               }
+            }
+         }
+      }
+   }
    return { specifiers = specifiers, declarator = declarator, declarations = declarationList };
 }
 
@@ -836,7 +1176,8 @@ void ProcessFunctionBody(FunctionDefinition func, Statement body)
                if(!symbol && id)
                {
                   symbol = Symbol { string = CopyString(id.string), type = ProcessType(param.qualifiers, param.declarator), isParam = true };
-                  context.symbols.Add((BTNode)symbol);
+                  if(!context.symbols.Add((BTNode)symbol))
+                     excludedSymbols->Add(symbol);
 
                   // TODO: Fix this, the parameters' IDs should really be smaller...
                   symbol.id = context.nextID++;
@@ -878,7 +1219,10 @@ void ProcessFunctionBody(FunctionDefinition func, Statement body)
       }
       symbol = Symbol { string = CopyString(id.string), type = ProcessType(func.specifiers, declarator) };
       symbol.idCode = symbol.id = globalContext.nextID++;
-      globalContext.symbols.Add((BTNode)symbol);
+      if(strstr(symbol.string, "::"))
+         globalContext.hasNameSpace = true;
+      if(!globalContext.symbols.Add((BTNode)symbol))
+         excludedSymbols->Add(symbol);
       declarator.symbol = symbol;
    }
    else
@@ -887,7 +1231,10 @@ void ProcessFunctionBody(FunctionDefinition func, Statement body)
       excludedSymbols->Remove(declarator.symbol);
       delete symbol.string;
       symbol.string = CopyString(GetDeclId(declarator).string);
-      globalContext.symbols.Add((BTNode)symbol);
+      if(strstr(symbol.string, "::"))
+         globalContext.hasNameSpace = true;
+      if(!globalContext.symbols.Add((BTNode)symbol))
+         excludedSymbols->Add(symbol);
 
       if(!symbol.type)
          symbol.type = ProcessType(func.specifiers, declarator);
@@ -915,7 +1262,7 @@ External MkExternalFunction(FunctionDefinition function)
       for(spec = function.specifiers->first; spec; spec = spec.next)
          if(spec.type == baseSpecifier && spec.specifier == STATIC)
          {
-            declMode = staticAccess;
+            structDeclMode = declMode = staticAccess;
             break;
          }
    }
@@ -960,12 +1307,12 @@ External MkExternalDeclaration(Declaration declaration)
       for(spec = declaration.specifiers->first; spec; spec = spec.next)
          if(spec.type == baseSpecifier && spec.specifier == TYPEDEF)
          {
-            declMode = defaultAccess;
+            structDeclMode = declMode = defaultAccess;
             break;
          }
          else if(spec.type == baseSpecifier && spec.specifier == STATIC)
          {
-            declMode = staticAccess;
+            structDeclMode = declMode = staticAccess;
             break;
          }
    }
@@ -1021,7 +1368,7 @@ void SetClassTemplateArgs(Specifier spec, OldList templateArgs)
                   fileInput = backFileInput;
                   if(fileInput)
                   {
-                     fileInput.Seek(yylloc.start.pos, start); 
+                     fileInput.Seek(yylloc.start.pos, start);
                      resetScannerPos(&yylloc.start);
                      yychar = -2;
                   }
@@ -1114,7 +1461,7 @@ Specifier _MkSpecifierName(char * name, Symbol symbol, OldList templateArgs)
          }
       }
       else if(symbol)
-         spec.name = CopyString(symbol.string);   
+         spec.name = CopyString(symbol.string);
       else
          spec.name = CopyString(name);
       spec.symbol = symbol;
@@ -1189,7 +1536,8 @@ void ProcessClassFunctionBody(ClassFunction func, Statement body)
 
                   // TODO: Fix this, the parameters' IDs should really be smaller...
                   symbol.idCode = symbol.id = context.nextID++;
-                  context.symbols.Add((BTNode)symbol);
+                  if(!context.symbols.Add((BTNode)symbol))
+                     excludedSymbols->Add(symbol);
 
                   param.declarator.symbol = symbol;
                }
@@ -1200,7 +1548,7 @@ void ProcessClassFunctionBody(ClassFunction func, Statement body)
 
       symbol = Symbol
       {
-         
+
       };
 
       {
@@ -1302,10 +1650,10 @@ Instantiation MkInstantiationNamed(OldList specs, Expression exp, OldList member
          }
 
       FreeList(specs, FreeSpecifier);
-         
+
       if(!spec)
       {
-         Compiler_Error("Expecting class specifier\n");
+         Compiler_Error($"Expecting class specifier\n");
          inst._class = MkSpecifierName /*MkClassName*/("");
          //exit(1);
          //return null;
@@ -1427,7 +1775,7 @@ Symbol _DeclClass(int symbolID, char * name)
       for(classContext = curContext; classContext && !classContext.classDef; classContext = classContext.parent);
       if(classContext)
       {
-         
+
       }
       */
       if(name[0] == ':' && name[1] == ':')
@@ -1437,7 +1785,8 @@ Symbol _DeclClass(int symbolID, char * name)
          string = CopyString(name);
          idCode = symbolID, id = symbolID;
       };
-      globalContext.classes.Add((BTNode)symbol);
+      if(!globalContext.classes.Add((BTNode)symbol))
+         excludedSymbols->Add(symbol);
 
       {
          int start = 0, c;
@@ -1469,18 +1818,19 @@ void SetupBaseSpecs(Symbol symbol, OldList baseSpecs)
       strcpy(name, ((Specifier)baseSpecs.first).name);
       tpl = strchr(name, '<');
       if(tpl) *tpl = 0;
-      
+
       baseClass = FindClass(name);
-      if(baseClass.ctx)
+      if(baseClass && baseClass.ctx)
       {
          TemplatedType copy;
          for(copy = (TemplatedType)baseClass.ctx.templateTypes.first; copy; copy = (TemplatedType)copy.next)
          {
             TemplatedType type { key = copy.key, param = copy.param };
-            curContext.templateTypes.Add((BTNode)type);
+            if(!curContext.templateTypes.Add((BTNode)type))
+               delete type;
          }
       }
-      else if(baseClass.registered)
+      else if(baseClass && baseClass.registered)
       {
          Class sClass;
          for(sClass = baseClass.registered; sClass; sClass = sClass.base)
@@ -1499,12 +1849,13 @@ void SetupBaseSpecs(Symbol symbol, OldList baseSpecs)
                   {
                      p.param = param = TemplateParameter
                      {
-                        identifier = MkIdentifier(p.name), type = p.type, 
+                        identifier = MkIdentifier(p.name), type = p.type,
                         dataTypeString = p.dataTypeString /*, dataType = { specs, decl }*/
                      };
                   }
-                  type = TemplatedType { key = (uint)p.name, param = param };
-                  curContext.templateTypes.Add((BTNode)type);
+                  type = TemplatedType { key = (uintptr)p.name, param = param };
+                  if(!curContext.templateTypes.Add((BTNode)type))
+                     delete type;
                }
             }
          }
@@ -1516,6 +1867,27 @@ ClassDefinition MkClass(Symbol symbol, OldList baseSpecs, OldList definitions)
 {
    ClassDefinition classDef;
    SetupBaseSpecs(symbol, baseSpecs);
+   if(symbol.ctx)
+   {
+      ClassDefinition classDef = symbol.ctx.classDef;
+      if(classDef)
+      {
+         // This can occur if two instances of a class are defined...
+         // To avoid dangling 'parent' Contexts, we free the previous class definition
+         External external;
+         for(external = ast->first; external; external = external.next)
+         {
+            if(external.type == classExternal && external._class == classDef)
+            {
+               ast->Remove(external);
+               FreeExternal(external);
+               break;
+            }
+         }
+      }
+      FreeContext(symbol.ctx);
+      delete symbol.ctx;
+   }
    symbol.ctx = curContext;
    classDef = { symbol = symbol, _class = MkSpecifierName /*MkClassName*/(symbol.string), baseSpecs = baseSpecs, definitions = definitions, nameLoc = symbol.nameLoc };
    curContext.classDef = classDef;
@@ -1547,7 +1919,7 @@ PropertyDef MkProperty(OldList specs, Declarator decl, Identifier id, Statement
    {
       char typeString[1024];
       typeString[0] = '\0';
-      PrintType(type, typeString, false, true);
+      PrintTypeNoConst(type, typeString, false, true);
       id = MkIdentifier(typeString);
       prop.conversion = true;
    }
@@ -1635,7 +2007,13 @@ Symbol FindType(Context ctx, char * name)
    Symbol type = null;
    if(curContext)
    {
+      //char output[8192];
       type = (Symbol)ctx.types.FindString(name);
+      /*if(!strcmp(name, "intptr_t") && !type)
+      {
+         ctx.types.Print(output, depthOrder);
+         puts(output);
+      }*/
       if(!type && ctx.parent)
          type = FindType(ctx.parent, name);
    }
@@ -1657,7 +2035,7 @@ TemplatedType FindTemplateTypeParameter(Context ctx, char * name)
 bool ModuleAccess(Module searchIn, Module searchFor)
 {
    SubModule subModule;
-   
+
    if(searchFor == searchIn)
       return true;
 
@@ -1682,8 +2060,8 @@ ModuleImport FindModule(Module moduleToFind)
          break;
    if(!module)
    {
-      module = ModuleImport 
-      { 
+      module = ModuleImport
+      {
          name = CopyString(moduleToFind.name), importType = moduleToFind.importType,
          importAccess = ModuleAccess(privateModule, moduleToFind) ? publicAccess : privateAccess
       };
@@ -1700,7 +2078,7 @@ static void GetFullClassNameSpace(NameSpace * ns, char * name)
    {
       GetFullClassNameSpace(ns->parent, name);
       strcat(name, ns->name);
-      strcat(name, "::");      
+      strcat(name, "::");
    }
 }
 
@@ -1784,7 +2162,7 @@ public Symbol FindClass(char * name)
          }
          */
          if(cl.shortName && !strcmp(cl.shortName, name))
-            break;            
+            break;
       }
 #ifdef _TIMINGS
       findClassIgnoreNSTotalTime += GetTime() - startTime;
@@ -1818,7 +2196,8 @@ public Symbol FindClass(char * name)
                cl.module = FindModule(_class.module);
             else
                cl.module = mainModule;
-            globalContext.classes.Add((BTNode)cl);
+            if(!globalContext.classes.Add((BTNode)cl))
+               excludedSymbols->Add(cl);
             if(strcmp(name, _class.name))
                cl.shortName = CopyString(_class.name);
          }
@@ -1834,7 +2213,6 @@ void CopyTypeInto(Type type, Type src)
 {
    type = *src;
    type.name = CopyString(src.name);
-   type.enumName = CopyString(src.enumName);
    type.refCount = 1;
 
    if(src.kind == enumType)
@@ -1842,10 +2220,12 @@ void CopyTypeInto(Type type, Type src)
       NamedLink member;
 
       type.members.Clear();
-      for(member = type.members.first; member; member = member.next)
+      // This must have been a mistake: member = **type**.members.first
+      for(member = src.members.first; member; member = member.next)
       {
          type.members.Add(NamedLink { name = CopyString(member.name), data = member.data });
       }
+      type.enumName = CopyString(src.enumName);
    }
    else if(src.kind == structType || src.kind == unionType)
    {
@@ -1853,6 +2233,7 @@ void CopyTypeInto(Type type, Type src)
       // Tricky stuff... will be removed from list only when ref count reaches 0
       for(member = type.members.first; member; member = member.next)
          member.refCount++;
+      type.enumName = CopyString(src.enumName);
    }
    else if(src.kind == functionType)
    {
@@ -1873,638 +2254,465 @@ void CopyTypeInto(Type type, Type src)
    }
 }
 
-public Type ProcessType(OldList specs, Declarator decl)
+static Type ProcessTypeSpecs(OldList specs, bool assumeEllipsis, bool keepTypeName)
 {
-   Type type = null;
-   bool isTypedef = false;
-   if(!specs || specs.first)
+   Type specType { refCount = 1, kind = intType, isSigned = true };
+   if(specs != null)
    {
-      Declarator funcDecl = GetFuncDecl(decl);
-      Type specType { };
-      bool dllExport = false;
-
-      specType.kind = intType;
-      specType.isSigned = true;   
-      specType.refCount = 1;
-
-      type = Type { refCount = 1 };
-
-      while(decl && (decl.type == structDeclarator || decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd))
+      bool isTypedef = false;
+      Specifier spec;
+      bool isLong = false;
+      for(spec = specs.first; spec; spec = spec.next)
       {
-         if(decl.type == structDeclarator && decl.structDecl.exp)
+         if(spec.type == extendedSpecifier)
          {
-            ProcessExpressionType(decl.structDecl.exp);
-            ComputeExpression(decl.structDecl.exp);
-            if(decl.structDecl.exp.type == constantExp)
-               specType.bitFieldCount = strtoul(decl.structDecl.exp.constant, null, 0);
+            ExtDecl extDecl = spec.extDecl;
+            if(extDecl.type == extDeclString)
+            {
+               String s = spec.extDecl.s;
+               if(!strcmp(spec.extDecl.s, "__declspec(dllexport)") || !strcmp(spec.extDecl.s, "dllexport"))
+                  specType.dllExport = true;
+               else if(!strcmp(spec.extDecl.s, "__declspec(stdcall)") || !strcmp(spec.extDecl.s, "stdcall"))
+                  specType.attrStdcall = true;
+            }
+            else if(extDecl.type == extDeclAttrib)
+            {
+               OldList * attribs = extDecl.attr.attribs;
+               if(attribs)
+               {
+                  Attribute attr;
+                  for(attr = attribs->first; attr; attr = attr.next)
+                  {
+                     String s = attr.attr;
+                     if(s)
+                     {
+                        if(!strcmp(s, "dllexport"))
+                           specType.dllExport = true;
+                        else if(!strcmp(s, "stdcall"))
+                           specType.attrStdcall = true;
+                     }
+                  }
+               }
+               specType.keepCast = true;
+            }
          }
-         if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended && 
-            (!strcmp(decl.extended.extended, "__declspec(dllexport)") || !strcmp(decl.extended.extended, "dllexport")))
+
+         if(spec.specifier != CONST && (specType.kind == structType || specType.kind == unionType))
          {
-            dllExport = true;
+            FreeType(specType);
+            specType = { kind = intType, isSigned = true, refCount = 1 };
          }
-         if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended && 
-            (strstr(decl.extended.extended, "__attribute__")))
+
+         if(isTypedef && keepTypeName)
          {
-            specType.keepCast = true;
+            specType.kind = dummyType;
+            return specType;
          }
-         decl = decl.declarator;
-      }
-
-      // If we'll be using the specType
-      if(funcDecl || !decl || decl.type == identifierDeclarator)
-      {
-         Specifier spec;
-         if(specs != null)
+         else if(spec.type == baseSpecifier)
          {
-            bool isLong = false;
-            for(spec = specs.first; spec; spec = spec.next)
+            if(spec.specifier == TYPEDEF)
+               isTypedef = true;
+            else if(spec.specifier == VOID) specType.kind = voidType;
+            else if(spec.specifier == CHAR) specType.kind = charType;
+            else if(spec.specifier == INT) { if(specType.kind != shortType && specType.kind != longType && !isLong) specType.kind = intType; }
+            else if(spec.specifier == _BOOL || spec.specifier == BOOL)
+               specType.kind = _BoolType;
+            else if(spec.specifier == UINT) { if(specType.kind != shortType && specType.kind != longType) specType.kind = intType; specType.isSigned = false; }
+            else if(spec.specifier == INT64) specType.kind = int64Type;
+            else if(spec.specifier == VALIST)
+               specType.kind = vaListType;
+            else if(spec.specifier == SHORT) specType.kind = shortType;
+            else if(spec.specifier == LONG)
             {
-               if(spec.type == extendedSpecifier && (!strcmp(spec.name, "__declspec(dllexport)") || !strcmp(spec.name, "dllexport")))
+               if(isLong || (targetBits == 64 && targetPlatform != win32))
+                  specType.kind = int64Type;
+               else
+                  specType.kind = intType;
+               isLong = true;
+            }
+            else if(spec.specifier == FLOAT) specType.kind = floatType;
+            else if(spec.specifier == DOUBLE) specType.kind = doubleType;
+            else if(spec.specifier == SIGNED) specType.isSigned = true;
+            else if(spec.specifier == UNSIGNED) specType.isSigned = false;
+            else if(spec.specifier == CONST)
+               specType.constant = true;
+            else if(spec.specifier == TYPED_OBJECT || spec.specifier == ANY_OBJECT || spec.specifier == CLASS)
+            {
+               switch(spec.specifier)
                {
-                  dllExport = true;
+                  case TYPED_OBJECT:   specType.classObjectType = typedObject;   break;
+                  case ANY_OBJECT:     specType.classObjectType = anyObject;     break;
+                  case CLASS:          specType.classObjectType = classPointer;  break;
                }
-               if(spec.type == extendedSpecifier && strstr(spec.name, "__attribute__"))
+               specType.kind = classType;
+               specType._class = FindClass("class");
+            }
+            else if(spec.specifier == THISCLASS)
+               specType.kind = thisClassType;
+         }
+         else if(spec.type == nameSpecifier)
+         {
+            if(spec.name && (!strcmp(spec.name, "intptr") || !strcmp(spec.name, "uintptr")))
+            {
+               specType.kind = intPtrType;
+               if(!strcmp(spec.name, "uintptr"))
+                  specType.isSigned = false;
+            }
+            else if(spec.name && (!strcmp(spec.name, "uintsize") || !strcmp(spec.name, "intsize")))
+            {
+               specType.kind = intSizeType;
+               if(!strcmp(spec.name, "uintsize"))
+                  specType.isSigned = false;
+            }
+            else
+            {
+               Symbol symbol = spec.name ? FindType(curContext, spec.name) : null;
+               if(symbol && symbol.type)
                {
-                  specType.keepCast = true;
-               }
+                  // Free Type Contents:
+                  Type dummy { };
+                  *dummy = *specType;
+                  FreeType(dummy);
 
-               if(specType.kind == structType || specType.kind == unionType)
+                  CopyTypeInto(specType, symbol.type);
+                  specType.typeName = CopyString(symbol.type.name);
+               }
+               else if(!isTypedef) // !specType.kind)    // TESTING THIS FOR enum / typedef problem
                {
-                  FreeType(specType);
-                  specType = { kind = intType, isSigned = true, refCount = 1 };
+                  // key.sym enum values need FindClass:
+                  specType._class = spec.name ? FindClass(spec.name) : null;
+                  specType.kind = classType;
+                  if(!specType._class)
+                     specType.kind = intType;
                }
+            }
+         }
+         else if(spec.type == enumSpecifier)
+         {
+            specType.kind = enumType;
+            specType.enumName = spec.id ? CopyString(spec.id.string) : null;
 
-               if(spec.type == baseSpecifier)
+            if(spec.list)
+            {
+               Enumerator e;
+               int nextValue = 0;
+               for(e = spec.list->first; e; e = e.next)
                {
-                  if(spec.specifier == TYPEDEF) isTypedef = true;
-                  else if(spec.specifier == VOID) specType.kind = voidType;
-                  else if(spec.specifier == CHAR) specType.kind = charType;
-                  else if(spec.specifier == INT) { if(specType.kind != shortType && specType.kind != longType) specType.kind = intType; }
-                  else if(spec.specifier == UINT) { if(specType.kind != shortType && specType.kind != longType) specType.kind = intType; specType.isSigned = false; }
-                  else if(spec.specifier == INT64) specType.kind = int64Type;
-                  else if(spec.specifier == VALIST) 
-                     specType.kind = vaListType;
-                  else if(spec.specifier == SHORT) specType.kind = shortType;
-                  else if(spec.specifier == LONG) 
-                  {
-                     if(isLong)
-                        specType.kind = int64Type;
-                     else
-                        specType.kind = intType;
-                     isLong = true;
-                     // specType.kind = longType;
-                  }
-                  else if(spec.specifier == FLOAT) specType.kind = floatType;
-                  else if(spec.specifier == DOUBLE) specType.kind = doubleType;
-                  else if(spec.specifier == SIGNED) specType.isSigned = true;
-                  else if(spec.specifier == UNSIGNED) specType.isSigned = false;
-                  else if(spec.specifier == CONST) specType.constant = true;
-                  else if(spec.specifier == TYPED_OBJECT) 
-                  { 
-                     specType.classObjectType = typedObject; specType.kind = classType; specType._class = FindClass("class"); 
-                  }
-                  else if(spec.specifier == ANY_OBJECT) 
-                  { 
-                     specType.classObjectType = anyObject; specType.kind = classType; specType._class = FindClass("class"); 
-                  }
-                  else if(spec.specifier == CLASS)
-                  {
-                     specType.classObjectType = classPointer; specType.kind = classType; specType._class = FindClass("class");
-                  }
-                  else if(spec.specifier == THISCLASS)
-                     specType.kind = thisClassType;
+                  // TOFIX: NamedItem i { } causes cryptic error, bad .c!
+                  NamedLink i { name = CopyString(e.id.string) };
+                  specType.members.Add(i);
                }
-               else if(spec.type == nameSpecifier)
+            }
+         }
+         else if(spec.type == templateTypeSpecifier)
+         {
+            specType.kind = templateType;
+            specType.templateParameter = spec.templateParameter;
+         }
+         else if(spec.type == structSpecifier || spec.type == unionSpecifier)
+         {
+            Symbol _class = spec.id ? FindClass(spec.id.string) : null;
+            if(_class)
+            {
+               specType.declaredWithStruct = true;
+               if(!_class.registered || _class.registered.type != structClass)
+                  specType.directClassAccess = true;     // TODO: Need to clarify what 'directClassAccess' is about
+               specType._class = _class;
+               specType.kind = classType;
+               break;
+            }
+            specType.members.Clear();
+            if(spec.type == structSpecifier)
+               specType.kind = structType;
+            else if(spec.type == unionSpecifier)
+               specType.kind = unionType;
+            if(spec.id)
+            {
+               // TESTING THIS HERE... Had 0 type size
+               if(!spec.definitions && !isTypedef)
                {
-                  Symbol symbol = spec.name ? FindType(curContext, spec.name) : null;
+                  Symbol symbol = spec.id.string ? FindSymbol(spec.id.string, curContext, globalContext, true, false) : null;
                   if(symbol && symbol.type)
                   {
-                     CopyTypeInto(specType, symbol.type);
-                     specType.typeName = CopyString(symbol.type.name);
-                  }
-                  else if(!isTypedef) // !specType.kind)    // TESTING THIS FOR enum / typedef problem
-                  {
-                     // key.sym enum values need FindClass:
-                     specType._class = spec.name ? FindClass(spec.name) : null;
-                     // specType._class = spec.symbol; 
-                     specType.kind = classType;
-                     if(!specType._class)
-                        specType.kind = intType;
-                  }
-               }
-               else if(spec.type == enumSpecifier)
-               {
+                     specType = *symbol.type;
+                     specType.name = CopyString(symbol.type.name);
+                     specType.typeName = CopyString(spec.name);
+                     specType.enumName = CopyString(symbol.type.enumName);
+                     specType.refCount = 1;
 
-                  specType.kind = enumType;
-                  specType.enumName = spec.id ? CopyString(spec.id.string) : null;
-
-                  if(spec.list)
-                  {
-                     Enumerator e;
-                     int nextValue = 0;
-                     for(e = spec.list->first; e; e = e.next)
+                     if(symbol.type.kind == enumType)
                      {
-                        specType.members.Add(NamedItem { name = CopyString(e.id.string) });
-                        /*
-                        if(e.exp && ComputeExpression(e.exp), e.exp.isConstant && e.exp.expType.kind == intType)
-                           value.data = (void *) nextValue = strtol(e.exp.string, null, 0);
-                        else
-                           value.data = (void *)nextValue++;
-                        */
-                     }
-                  }
-                  /*
-                  if(spec.list)
-                  {
-                     Declaration decl;
-                     for(enumerator = spec.list->first; enumerator; enumerator = enumerator.next)
-                        if(decl.declarators)
+                        NamedLink member;
+
+                        specType.members.Clear();
+                        for(member = symbol.type.members.first; member; member = member.next)
                         {
-                           Declarator d;
-                           for(d = decl.declarators.first; d; d = d.next)
-                           {
-                              Type memberType = ProcessType(decl.specifiers, d);
-                              specType.members.Add(memberType);
-                           }
+                           NamedLink item { name = CopyString(member.name), data = member.data };
+                           specType.members.Add(item);
                         }
-                        else if(decl.specifiers)
+                     }
+                     else if(symbol.type.kind == structType || symbol.type.kind == unionType)
+                     {
+                        Type member;
+                        // Tricky stuff... will be removed from list only when ref count reaches 0
+                        for(member = specType.members.first; member; member = member.next)
+                           member.refCount++;
+                     }
+                     else if(symbol.type.kind == functionType)
+                     {
+                        Type param;
+                        specType.returnType.refCount++;
+                        for(param = specType.params.first; param; param = param.next)
+                           param.refCount++;
+                     }
+                     else if(symbol.type.kind == pointerType || symbol.type.kind == arrayType)
+                     {
+                        specType.type.refCount++;
+                        if(symbol.type.kind == arrayType)
                         {
-                           Type memberType = ProcessType(decl.specifiers, null);
-                           specType.members.Add(memberType);
+                           if(specType.arraySizeExp)
+                              specType.arraySizeExp = CopyExpression(specType.arraySizeExp);
                         }
+
+                     }
                   }
-                  */
-               }
-               else if(spec.type == templateTypeSpecifier)
-               {
-                  /*
-                  printf("spec %x\n", spec);
-                  printf("template param %x\n", spec.templateParameter);
-                  printf("identifier %x\n", spec.templateParameter.identifier);
-                  printf("string %x\n", spec.templateParameter.identifier.string);
-                  */
-                  specType.kind = templateType;
-                  specType.templateParameter = spec.templateParameter;
+                  else
+                     specType.enumName = CopyString(spec.id.string);
                }
-               else if(spec.type == structSpecifier || spec.type == unionSpecifier)
+               else
+                  specType.enumName = CopyString(spec.id.string);
+            }
+
+            if(spec.definitions)
+            {
+               ClassDef def;
+               for(def = spec.definitions->first; def; def = def.next)
                {
-                  Symbol _class = spec.id ? FindClass(spec.id.string) : null;
-                  if(_class)
+                  if(def.type == declarationClassDef && def.decl.type == structDeclaration)
                   {
-                     if(!_class.registered || _class.registered.type != structClass)
-                        specType.directClassAccess = true;
-                     specType._class = _class;
-                     specType.kind = classType;
-                     break;
-                  }
-                  if(spec.type == structSpecifier)
-                     specType.kind = structType;
-                  else if(spec.type == unionSpecifier)
-                     specType.kind = unionType;
-                  if(spec.id)
-                  {
-                     // TESTING THIS HERE... Had 0 type size 
-                     if(!spec.definitions && !isTypedef)
+                     Declaration decl = def.decl;
+                     if(decl.declarators)
                      {
-                        Symbol symbol = spec.id.string ? FindSymbol(spec.id.string, curContext, globalContext, true, false) : null;
-                        if(symbol && symbol.type)
+                        Declarator d;
+                        for(d = decl.declarators->first; d; d = d.next)
                         {
-                           specType = *symbol.type;
-                           specType.name = CopyString(symbol.type.name);
-                           specType.typeName = CopyString(spec.name);
-                           specType.enumName = CopyString(symbol.type.enumName);
-                           specType.refCount = 1;
-
-                           if(symbol.type.kind == enumType)
-                           {
-                              NamedLink member;
-
-                              specType.members.Clear();
-                              for(member = specType.members.first; member; member = member.next)
-                              {
-                                 specType.members.Add(NamedLink { name = CopyString(member.name), data = member.data });
-                              }
-                           }
-                           else if(symbol.type.kind == structType || symbol.type.kind == unionType)
-                           {
-                              Type member;
-                              // Tricky stuff... will be removed from list only when ref count reaches 0
-                              for(member = specType.members.first; member; member = member.next)
-                                 member.refCount++;
-                           }
-                           else if(symbol.type.kind == functionType)
-                           {
-                              Type param;
-                              specType.returnType.refCount++;
-                              for(param = specType.params.first; param; param = param.next)
-                                 param.refCount++;
-                           }
-                           else if(symbol.type.kind == pointerType || symbol.type.kind == arrayType)
-                           {
-                              specType.type.refCount++;
-                              if(symbol.type.kind == arrayType)
-                              {
-                                 if(specType.arraySizeExp)
-                                    specType.arraySizeExp = CopyExpression(specType.arraySizeExp);
-                              }
-
-                           }
+                           Type memberType = ProcessType(decl.specifiers, d);
+                           specType.members.Add(memberType);
                         }
-                        else
-                           specType.enumName = CopyString(spec.id.string);
                      }
-                     else
-                        specType.enumName = CopyString(spec.id.string);
-                  }
-
-                  if(spec.definitions)
-                  {
-                     ClassDef def;
-                     for(def = spec.definitions->first; def; def = def.next)
+                     else if(decl.specifiers)
                      {
-                        if(def.type == declarationClassDef && def.decl.type == structDeclaration)
-                        {
-                           Declaration decl = def.decl;
-                           if(decl.declarators)
-                           {
-                              Declarator d;
-                              for(d = decl.declarators->first; d; d = d.next)
-                              {
-                                 Type memberType = ProcessType(decl.specifiers, d);
-                                 specType.members.Add(memberType);
-                              }
-                           }
-                           else if(decl.specifiers)
-                           {
-                              Type memberType = ProcessType(decl.specifiers, null);
-                              specType.members.Add(memberType);
-                           }
-                        }
+                        Type memberType = ProcessType(decl.specifiers, null);
+                        specType.members.Add(memberType);
                      }
                   }
-                  break;
-               }
-               else if(spec.type == subClassSpecifier)
-               {
-                  specType.kind = specType.kind = subClassType;
-                  specType._class = spec._class.symbol; // FindClass(spec._class.name);
                }
-               /*
-               else if(spec.type == classSpecifier)
-               {
-                  specType._class = FindClass(spec.name);
-                  specType.kind = classType;
-               }
-               */
             }
+            break;
+         }
+         else if(spec.type == subClassSpecifier)
+         {
+            specType.kind = specType.kind = subClassType;
+            specType._class = spec._class.symbol;
          }
-         else if(!decl)
-            specType.kind = ellipsisType;
       }
+   }
+   else if(assumeEllipsis)
+      specType.kind = ellipsisType;
+   return specType;
+}
 
-      if(funcDecl)
+static Type ProcessTypeDecls(OldList specs, Declarator decl, Type parentType)
+{
+   Type type = parentType;
+   Declarator subDecl = decl ? decl.declarator : null;
+   if(!parentType)
+      type = ProcessTypeSpecs(specs, decl == null, (decl && decl.type == extendedDeclaratorEnd) ? true : false);
+   if(decl)
+   {
+      switch(decl.type)
       {
-         Declarator d = funcDecl.declarator;
-         Type funcType { };
-         TypeName param;
-
-         funcType.kind = functionType;
-         funcType.refCount = 1;
-         if(funcDecl.function.parameters)
+         case bracketsDeclarator: break;
+         case extendedDeclarator:
+         case extendedDeclaratorEnd:
          {
-            for(param = funcDecl.function.parameters->first; param; param = param.next)
+            ExtDecl extDecl = decl.extended.extended;
+            if(extDecl)
             {
-               /*
-               if(param.typedObject)
+               switch(extDecl.type)
                {
-                  Type typedObjectType
+                  case extDeclString:
                   {
-                     refCount = 1;
-                     byReference = param.byReference;
-                     kind = TypeTypedObject;
-                  };
-                  funcType.params.Add(typedObjectType);
+                     String s = extDecl.s;
+                     if(s)
+                     {
+                        if(!strcmp(s, "__declspec(dllexport)") || !strcmp(s, "dllexport"))
+                           type.dllExport = true;
+                        else if(!strcmp(s, "__declspec(stdcall)") || !strcmp(s, "stdcall"))
+                           type.attrStdcall = true;
+                     }
+                     break;
+                  }
+                  case extDeclAttrib:
+                  {
+                     OldList * attribs = extDecl.attr.attribs;
+                     if(attribs)
+                     {
+                        Attribute attr;
+                        for(attr = attribs->first; attr; attr = attr.next)
+                        {
+                           String s = attr.attr;
+                           if(s)
+                           {
+                              if(!strcmp(s, "dllexport"))
+                                 type.dllExport = true;
+                              else if(!strcmp(s, "stdcall"))
+                                 type.attrStdcall = true;
+                           }
+                        }
+                     }
+                     type.keepCast = true;
+                     break;
+                  }
                }
-               else*/
-                  funcType.params.Add(ProcessType(param.qualifiers, param.declarator));
             }
+            break;
          }
-
-         // Function returning a pointer...
-         if(decl.type == pointerDeclarator)
+         case structDeclarator:
          {
-            Pointer pointer = decl.pointer.pointer;
-            Type ptrType { };
-            funcType.returnType = ptrType;
-            funcType.returnType.refCount = 1;
-            while(pointer)
+            Expression exp = decl.structDecl.exp;
+            if(exp)
             {
-               ptrType.kind = pointerType;
-               pointer = pointer.pointer;
-               if(pointer)
-               {
-                  ptrType.type = Type { refCount = 1 };
-                  ptrType = ptrType.type;
-               }
+               ProcessExpressionType(exp);
+               ComputeExpression(exp);
+               if(exp.type == constantExp)
+                  type.bitFieldCount = (uint)strtoul(exp.constant, null, 0);
             }
-            ptrType.type = Type { refCount = 1 };
-            *ptrType.type = specType;
-         }
-         else
-         {
-            funcType.returnType = Type { refCount = 1 };
-            *funcType.returnType = specType;
+            break;
          }
-
-         // TESTING: Added extendedDeclarator here
-         while(d && (d.type == bracketsDeclarator || d.type == extendedDeclarator || d.type == extendedDeclaratorEnd))
+         case functionDeclarator:
          {
-            if((d.type == extendedDeclarator || d.type == extendedDeclaratorEnd) && d.extended.extended && 
-               (!strcmp(d.extended.extended, "__declspec(dllexport)") || !strcmp(d.extended.extended, "dllexport")))
+            type = { refCount = 1, kind = functionType, returnType = type, dllExport = type.dllExport, attrStdcall = type.attrStdcall };
+            if(decl.function.parameters)
             {
-               dllExport = true;            
+               TypeName param;
+               for(param = decl.function.parameters->first; param; param = param.next)
+                  type.params.Add(ProcessType(param.qualifiers, param.declarator));
             }
-            d = d.declarator;
+            break;
          }
-
-         funcType.dllExport = dllExport;
-
-         if(d && d.type == pointerDeclarator)
+         case arrayDeclarator:
          {
-            Type ptrType;
-            Identifier id;
-
-            if(d.declarator && d.declarator.type == arrayDeclarator)
+            type = { refCount = 1, kind = arrayType, arraySizeExp = CopyExpression(decl.array.exp), freeExp = true, type = type, dllExport = type.dllExport, attrStdcall = type.attrStdcall };
+            if(decl.array.enumClass)
+               type.enumClass = decl.array.enumClass.symbol;
+            break;
+         }
+         case pointerDeclarator:
+         {
+            Pointer pointer = decl.pointer.pointer;
+            while(pointer)
             {
-               // Arrays of pointers to functions (extremely tricky :()
-               Pointer pointer = d.pointer.pointer;
-
-               // TO WORK ON: Fixed the order for the array...
-               type.kind = arrayType;
-               type.arraySizeExp = CopyExpression(d.declarator.array.exp);
-               type.freeExp = true;
-               if(d.declarator.array.enumClass)
-                  type.enumClass = d.declarator.array.enumClass.symbol; // FindClass(d.declarator.array.enumClass.name);
-               if(d.declarator.declarator && d.declarator.declarator.type == arrayDeclarator)
-               {
-                  Type tmpType = type;
-                  Type inType;
-                  type = ProcessType(null, d.declarator.declarator);
-                  inType = type.type;
-                  type.type = tmpType;
-                  tmpType.type = inType;
-               }
+               OldList * qualifiers = pointer.qualifiers;
+               if(type.classObjectType)
+                  type.byReference = true;
                else
-                  type.type = ProcessType(null, d.declarator.declarator);
-
-               for(ptrType = type.type; ptrType && ptrType.kind && ptrType.type; ptrType = ptrType.type);
-
-               while(pointer)
-               {
-                  ptrType.kind = pointerType;
-                  pointer = pointer.pointer;
-                  if(pointer)
-                  {
-                     ptrType.type = Type { refCount = 1 };
-                     ptrType = ptrType.type;
-                  }
-               }
-               ptrType.type = ProcessType(specs, null);
-            }
-            else
-            {
-               // WARNING: Not caring if this declarator contains a declarator between
-               //          the pointer and the function other than brackets (like in the case of array of pointers to functions)...
-               // *********** Could it ever go in here???  Yes: void (* converters_table[10]) (); ***********
-               Pointer pointer = d.pointer.pointer;
-
-               ptrType = type;
-               while(pointer)
-               {
-                  ptrType.kind = pointerType;
-                  ptrType.type = Type { refCount = 1 };
-                  pointer = pointer.pointer;
-                  if(pointer)
-                     ptrType = ptrType.type;
-               }
-            }
-
-            *ptrType.type = funcType;
-            id = GetDeclId(d);
-            if(id)
-            {
-               if(id._class && !id._class.name)
-                  ptrType.type.staticMethod =  true;
-               else 
+                  type = { refCount = 1, kind = pointerType, type = type, dllExport = type.dllExport, attrStdcall = type.attrStdcall };
+               if(qualifiers)
                {
-                  // TODO : Ensure classSym has been resolved here... (Is this gonna cause problems? Supposed to do this later...)
-                  if(!id.classSym)
-                  {
-                     if(id._class && id._class.name)
-                     {
-                        id.classSym = id._class.symbol; // FindClass(id._class.name);
-                        /* TODO: Name Space Fix ups
-                        if(!id.classSym)
-                           id.nameSpace = eSystem_FindNameSpace(privateModule, id._class.name);
-                        */
-                     }
-                  }
-
-                  ptrType.type.thisClass = id.classSym;
-                  if(ptrType.type.thisClass && strcmp(ptrType.type.thisClass.string, "class"))
-                     ptrType.type.extraParam = true;
-                  else if(id._class && id._class.name && !strcmp(id._class.name, "any_object"))
+                  Specifier spec;
+                  for(spec = qualifiers->first; spec; spec = spec.next)
                   {
-                     ptrType.type.extraParam = true;
-                     ptrType.type.thisClass = FindClass("class");
+                     if(spec.type == baseSpecifier && spec.specifier == CONST)
+                        type.constant = true;
                   }
                }
-
-               type.name = CopyString(id.string);
+               pointer = pointer.pointer;
             }
+            break;
          }
-         else if(!d || d.type == identifierDeclarator)
+         case identifierDeclarator:
          {
-
-            *type = funcType;
-            if(d)
+            Identifier id = decl.identifier;
+            Specifier _class = id._class;
+            delete type.name;
+            type.name = CopyString(id.string);
+            if(_class)
             {
-               if(d.identifier._class && d.identifier._class.type == templateTypeSpecifier)
+               if(_class.type == templateTypeSpecifier)
                {
-                  type.thisClassTemplate = d.identifier._class.templateParameter;
+                  type.thisClassTemplate = _class.templateParameter;
                   type.extraParam = true;
                }
                else
                {
-                  if(d.identifier._class && !d.identifier._class.name)
+                  String name = _class.name;
+                  if(!name)
                      type.staticMethod = true;
                   else
                   {
-                     if(d.identifier._class && d.identifier._class.name && d.identifier._class.name[strlen(d.identifier._class.name)-1] == '&')
+                     if(!id.classSym)
+                        id.classSym = _class.symbol; // FindClass(_class.name);
+                     /* TODO: Name Space Fix ups
+                        id.nameSpace = eSystem_FindNameSpace(privateModule, _class.name);
+                     */
+
+                     if(name[strlen(name)-1] == '&')
                      {
                         type.thisClass = FindClass("class");
                         type.byReference = true;
                      }
                      else
-                        type.thisClass = d.identifier._class ? d.identifier._class.symbol /*FindClass(d.identifier._class.name)*/ : null;
+                        type.thisClass = _class.symbol;
+
                      if(type.thisClass && strcmp(type.thisClass.string, "class"))
+                        type.extraParam = true;
+                     else if(!strcmp(name, "any_object"))
                      {
                         type.extraParam = true;
+                        type.thisClass = FindClass("class");
                      }
-                     else if(d.identifier._class && d.identifier._class.name && !strcmp(d.identifier._class.name, "any_object"))
+                     else if(!strcmp(name, "class"))
                      {
-                        type.extraParam = true;
                         type.thisClass = FindClass("class");
+                        type.classObjectType = classPointer;   // This is used for class properties
                      }
-                     else if(d.identifier._class && d.identifier._class.name && !strcmp(d.identifier._class.name, "class"))
+                     else if(!strcmp(name, "typed_object") || !strcmp(name, "typed_object&"))
                      {
-                        //type.extraParam = true;
                         type.thisClass = FindClass("class");
-                        type.classObjectType = classPointer;
+                        type.classObjectType = typedObject;
                      }
                   }
                }
-               type.name = CopyString(d.identifier.string);
-            }
-         }
-         delete funcType;
-      }
-      else if(decl && decl.type == pointerDeclarator)
-      {
-         if(decl.declarator && decl.declarator.type == arrayDeclarator)
-         {
-            // Arrays of pointers (tricky :))
-            Identifier id;
-            Pointer pointer = decl.pointer.pointer;
-            Type ptrType;
-
-            // TO WORK ON: Fixed the order for the array...
-            type.kind = arrayType;
-            type.arraySizeExp = CopyExpression(decl.declarator.array.exp);
-            type.freeExp = true;
-            if(decl.declarator.array.enumClass)
-               type.enumClass = decl.declarator.array.enumClass.symbol; // FindClass(decl.declarator.array.enumClass.name);
-            if(decl.declarator.declarator && decl.declarator.declarator.type == arrayDeclarator)
-            {
-               Type tmpType = type;
-               Type inType;
-               type = ProcessType(null, decl.declarator.declarator);
-               inType = type.type;
-               type.type = tmpType;
-               tmpType.type = inType;
-            }
-            else
-               type.type = ProcessType(null, decl.declarator.declarator);
-            /*
-            type.type = ProcessType(null, decl.declarator.declarator);
-            type.kind = arrayType;
-            type.arraySizeExp = CopyExpression(decl.declarator.array.exp);
-            type.arraySizeExp.freeExp = true;
-            if(decl.array.enumClass)
-               type.enumClass = FindClass(decl.array.enumClass.name);
-            */
-
-            for(ptrType = type.type; ptrType && ptrType.kind && ptrType.type; ptrType = ptrType.type);
-
-            while(pointer)
-            {
-               ptrType.kind = pointerType;
-               pointer = pointer.pointer;
-               if(pointer)
-               {
-                  ptrType.type = Type { refCount = 1 };
-                  ptrType = ptrType.type;
-               }
-            }
-            ptrType.type = ProcessType(specs, null);
-            id = GetDeclId(decl);
-            if(id) type.name = CopyString(id.string);
-         }
-         else
-         {
-            Identifier id;
-            Pointer pointer = decl.pointer.pointer;
-            Type ptrType = type;
-
-            if(type.classObjectType)
-            {
-               type.byReference = true;
-            }
-            else
-            {
-               while(pointer)
-               {
-                  ptrType.kind = pointerType;
-                  pointer = pointer.pointer;
-                  if(pointer)
-                  {
-                     ptrType.type = Type { refCount = 1 };
-                     ptrType = ptrType.type;
-                  }
-               }
-               ptrType.type = ProcessType(specs, decl.declarator);
-
-               if(type.type.classObjectType)
-               {
-                  Type subType = type.type;
-                  type.classObjectType = subType.classObjectType;
-                  type.kind = subType.kind;
-                  type._class = subType._class;
-                  type.byReference = true;
-
-                  FreeType(subType);
-               }
-               id = GetDeclId(decl);
-               if(id) type.name = CopyString(id.string);
             }
+            break;
          }
+         default:
+            PrintLn("Unhandled Declarator Type: ", decl.type);
       }
-      else if(decl && decl.type == arrayDeclarator)
-      {
-         Identifier id;
-
-         type.kind = arrayType;
-         
-         type.arraySizeExp = CopyExpression(decl.array.exp);
-         type.freeExp = true;
-         if(decl.array.enumClass)
-            type.enumClass = decl.array.enumClass.symbol; // FindClass(decl.array.enumClass.name);
-         id = GetDeclId(decl);
-
-         // TO WORK ON: Fixed the order for the array...
-         if(decl.declarator && decl.declarator.type == arrayDeclarator)
-         {
-            Type tmpType = type;
-            Type inType;
-            type = ProcessType(specs, decl.declarator);
-            inType = type.type;
-            type.type = tmpType;
-            tmpType.type = inType;
-         }
-         else
-            type.type = ProcessType(specs, decl.declarator);
-
-         if(id)
-         {
-            delete type.name;
-            type.name = CopyString(id.string);
-         }
-      }
-      else
+   }
+   if(subDecl)
+   {
+      Type curType = type;
+      type = ProcessTypeDecls(null, subDecl, type);
+      if(curType && type.kind != functionType)
       {
-         if(!decl || decl.type == identifierDeclarator)
-         {
-            *type = specType;
-            delete type.name;
-            type.name = decl ? CopyString(decl.identifier.string) : null;
-         }   
+         curType.thisClassTemplate = type.thisClassTemplate;
+         curType.extraParam = type.extraParam;
+         curType.staticMethod = type.staticMethod;
+         curType.thisClass = type.thisClass;
+         curType.byReference = type.byReference;
+         curType.classObjectType = type.classObjectType;
       }
-      delete specType;
    }
    return type;
 }
 
+public Type ProcessType(OldList specs, Declarator decl)
+{
+   return ProcessTypeDecls(specs, decl, null);
+}
+
 public Type ProcessTypeString(char * string, bool staticMethod)
 {
    OldList * specs = MkList();
@@ -2548,15 +2756,15 @@ public Type MkClassType(char * name)
    return null;
 }
 
-AsmField MkAsmField(char * command, Expression expression)
+AsmField MkAsmField(char * command, Expression expression, Identifier symbolic)
 {
-   return { command = command, expression = expression };
+   return { command = command, expression = expression, symbolic = symbolic };
 }
 
 Statement MkAsmStmt(Specifier spec, char * statements, OldList inputFields, OldList outputFields, OldList clobberedFields)
 {
-   return { type = asmStmt, asmStmt.spec = spec, asmStmt.statements = statements, 
-      asmStmt.inputFields = inputFields, asmStmt.outputFields = outputFields, 
+   return { type = asmStmt, asmStmt.spec = spec, asmStmt.statements = statements,
+      asmStmt.inputFields = inputFields, asmStmt.outputFields = outputFields,
       asmStmt.clobberedFields = clobberedFields };
 }
 
@@ -2684,7 +2892,7 @@ Expression GetTemplateArgExpByName(char * paramName, Class curClass, TemplatePar
          char idString[32];
          char className[1024];
          Expression classExp;
-         
+
          sprintf(idString, "%d", id);
          strcpy(className, "__ecereClass_");
          FullClassNameCat(className, _class.fullName, true);
@@ -2692,14 +2900,82 @@ Expression GetTemplateArgExpByName(char * paramName, Class curClass, TemplatePar
          DeclareClass(FindClass(_class.fullName), className);
 
          argExp = MkExpIndex((/*pointer ? MkExpPointer : */MkExpMember)
-               (MkExpMember(MkExpIdentifier(MkIdentifier("this")), MkIdentifier("_class")) /*MkExpIdentifier(MkIdentifier(className))*/, 
+               (MkExpMember(MkExpIdentifier(MkIdentifier("this")), MkIdentifier("_class")) /*MkExpIdentifier(MkIdentifier(className))*/,
                MkIdentifier("templateArgs")), MkListOne(MkExpConstant(idString)));
       }
    }
-   return argExp; 
+   return argExp;
 }
 
 Expression GetTemplateArgExp(TemplateParameter param, Class curClass, bool pointer)
 {
    return param.identifier ? GetTemplateArgExpByName(param.identifier.string, curClass, type) : null;
 }
+
+/*char * CreateMsgID(char * string, char * context)
+{
+   int lenString = strlen(string), lenContext = strlen(context);
+   char * msgid = new char[lenString + lenContext + 20];
+   memcpy(msgid, string, lenString);
+   memcpy(msgid+lenString, " [msgctxt: ", 11);
+   memcpy(msgid+lenString+11, context, lenContext);
+   memcpy(msgid+lenString+11+lenContext, "]", 2);
+   return msgid;
+}*/
+
+public void OutputIntlStrings()
+{
+   if(intlStrings.count)
+   {
+      char * srcFile = GetSourceFile();
+      char * objFile = GetOutputFile();
+      char srcFileFixed[MAX_LOCATION];
+      char potFile[MAX_LOCATION];
+      File f;
+      ChangeExtension(objFile, "bowl", potFile);
+      f = FileOpen(potFile, write);
+      if(f)
+      {
+         char * filePrefix = "";
+         if(!(srcFile[0] && (srcFile[1] == ':' || srcFile[0] == '/')))
+            filePrefix = "./"; //(GetRuntimePlatform() == win32) ? ".\\" : "./";
+         // GetSystemPathBuffer(srcFileFixed, srcFile);
+         GetSlashPathBuffer(srcFileFixed, srcFile);
+         for(s : intlStrings)
+         {
+            // TOFIX: (#654) ContextStringPair * pair = &s;
+            ContextStringPair pair = &s;
+            for(l : s)
+               f.Printf("#: %s%s:%d\n", filePrefix, srcFileFixed, l.start.line);
+             // PoEdit now preserves and distinguish msgctxt
+            if(pair.context)
+               f.Printf("msgctxt \"%s\"\n", pair.context);
+            f.Printf("msgid \"%s\"\n", pair.string);
+            f.Printf("msgstr \"%s\"\n\n", pair.string);
+         }
+         delete f;
+      }
+      intlStrings.Free();
+   }
+}
+
+default extern OldList * ast;
+default extern int yyparse ();
+default extern int yylex ();
+
+public void SetAST(OldList * list) { ast = list; }
+public OldList * GetAST() { return ast; }
+public void ParseEc()
+{
+   yyparse();
+}
+
+public int LexEc()
+{
+   return yylex();
+}
+
+public const char * GetYYText()
+{
+   return yytext;
+}