compiler: (WIP) Fixes for MinGW/GCC 5
[sdk] / compiler / libec / src / ast.ec
index 0d58a1b..12d21a6 100644 (file)
@@ -399,6 +399,11 @@ Expression MkExpTypeAlign(TypeName typeName)
    return { type = typeAlignExp, typeName = typeName, loc = yylloc };
 }
 
+Expression MkExpOffsetOf(TypeName typeName, Identifier id)
+{
+   return { type = offsetOfExp, offset.typeName = typeName, offset.id = id, loc = yylloc };
+}
+
 Expression MkExpClassSize(Specifier _class)
 {
    return { type = classSizeExp, _class = _class, loc = yylloc };
@@ -689,6 +694,7 @@ public TypeName MkTypeNameGuessDecl(OldList qualifiers, Declarator declarator)
             else if(spec.type == baseSpecifier)
             {
                if(spec.specifier == INT64) s = "int64";
+               else if(spec.specifier == INT128) s = "__int128";
             }
             if(s)
             {
@@ -868,6 +874,7 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
                      else if(spec.type == baseSpecifier)
                      {
                         if(spec.specifier == INT64) s = "int64";
+                        else if(spec.specifier == INT128) s = "__int128";
                      }
                      if(s)
                      {
@@ -901,6 +908,7 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
                else if(spec.type == baseSpecifier)
                {
                   if(spec.specifier == INT64) s = "int64";
+                  else if(spec.specifier == INT128) s = "__int128";
                }
                if(s)
                {
@@ -955,7 +963,7 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
 
                // Avoid memory leaks on duplicated symbols (BinaryTree::Add Would Fail)
                symbol = (Symbol)(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.FindString(id.string);
-               if(!symbol)
+               if(!symbol && strcmp(id.string, "strlen")) // Avoid overriding our definition of strlen or our 'uintsize' warning override won't take effect
                {
                   symbol = Symbol { string = CopyString(id.string), type = ProcessType(specifiers, d.declarator) };
                   if(strstr(symbol.string, "::"))
@@ -979,6 +987,7 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
                         char ch;
                         bool escaped = false;
                         char * s = d.initializer.exp.string;
+                        if(s[0] == 'L') s++;
 
                         // MAKE MORE ACCURATE
                         for(c = 1; (ch = s[c]); c++)
@@ -1032,6 +1041,7 @@ Declaration MkStructDeclaration(OldList specifiers, OldList declarators, Specifi
             else if(spec.type == baseSpecifier)
             {
                if(spec.specifier == INT64) s = "int64";
+               else if(spec.specifier == INT128) s = "__int128";
             }
             if(s)
             {
@@ -1424,7 +1434,7 @@ void SetClassTemplateArgs(Specifier spec, OldList templateArgs)
          if(!symbol && spec.symbol)
          {
             // If class was only decl'ed, invoke DeclClass on this templated class as well
-            symbol = _DeclClass(templateString);
+            symbol = _DeclClass(null, templateString);
             symbol.notYetDeclared = true;
          }
          // Add a reference to all templated class to the basic class
@@ -1470,7 +1480,22 @@ Specifier _MkSpecifierName(const char * name, Symbol symbol, OldList templateArg
          }
       }
       else if(symbol)
+      {
+         char nameSpace[1024];
+         char * c = strstr(name, symbol.string);
          spec.name = CopyString(symbol.string);
+         if(c && c >= name + 2 && c[-1] == ':' && c[-2] == ':')
+         {
+            if(c > name + 2)
+            {
+               memcpy(nameSpace, name, c - name - 2);
+               nameSpace[c-name] = 0;
+               spec.nsSpec = _MkSpecifierName(nameSpace, null, null);
+            }
+            else
+               spec.nsSpec = _MkSpecifierName(null, null, null);
+         }
+      }
       else
          spec.name = CopyString(name);
       spec.symbol = symbol;
@@ -1734,12 +1759,12 @@ ClassDef MkClassDefFunction(ClassFunction function)
    return def;
 }
 
-Symbol DeclClassAddNameSpace(const char * className)
+Symbol DeclClassAddNameSpace(Specifier _class, const char * className)
 {
    char name[1024];
    int len = 0, stringLen;
    name[0] = '\0';
-   if((currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
+   if(className[0] != ':' && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess && (!_class || _class.name))
    {
       if(defaultNameSpace)
       {
@@ -1760,20 +1785,30 @@ Symbol DeclClassAddNameSpace(const char * className)
    memcpy(name + len, className, stringLen);
    len += stringLen;
    name[len] = 0;
-   return _DeclClass(name);
+   return _DeclClass(_class, name);
 }
 
-Symbol DeclClass(const char * name)
+Symbol DeclClass(Specifier _class, const char * name)
 {
-   if(strchr(name, ':'))
-      return _DeclClass(name);
+   if(_class || strchr(name, ':'))
+      return _DeclClass(_class, name);
    else
-      return DeclClassAddNameSpace(name);
+      return DeclClassAddNameSpace(_class, name);
 }
 
-Symbol _DeclClass(const char * name)
+Symbol _DeclClass(Specifier _class, const char * name)
 {
-   Symbol symbol = FindClass(name);
+   Symbol symbol;
+   char nameBuffer[1024];
+   if(_class)
+   {
+      strcpy(nameBuffer,  _class.name ? _class.name : "");
+      strcat(nameBuffer, "::");
+      strcat(nameBuffer, name);
+      name = nameBuffer;
+   }
+
+   symbol = FindClass(name);
    if(!symbol)
    {
       /*
@@ -1789,7 +1824,7 @@ Symbol _DeclClass(const char * name)
       symbol = Symbol
       {
          string = CopyString(name);
-         // notYetDeclared = true;
+         notYetDeclared = true;
       };
       if(!globalContext.classes.Add((BTNode)symbol))
          excludedSymbols->Add(symbol);
@@ -1959,6 +1994,16 @@ int CheckType(const char * text)
 #ifdef _TIMINGS
    Time startTime = GetTime();
 #endif
+
+   if(inIDE)
+   {
+      // Help out the Debugger with Windows files until we improve the parser
+      if(!strcmp(text, "WINAPI"))
+         return EXT_DECL;
+      else if(!strcmp(text, "BOOL") || !strcmp(text, "WINUSERAPI"))
+         return TYPE_NAME;
+   }
+
    if(FindTemplateTypeParameter(curContext, text))
    {
 #ifdef _TIMINGS
@@ -2224,6 +2269,7 @@ public Symbol FindClass(const char * name)
 void CopyTypeInto(Type type, Type src)
 {
    type = *src;
+
    type.name = CopyString(src.name);
    type.typeName = CopyString(src.typeName);
    type.refCount = 1;
@@ -2301,6 +2347,8 @@ static Type ProcessTypeSpecs(OldList specs, bool assumeEllipsis, bool keepTypeNa
                            specType.dllExport = true;
                         else if(!strcmp(s, "stdcall"))
                            specType.attrStdcall = true;
+                        else if(!strcmp(s, "__vector_size__"))
+                           specType.isVector = true;
                      }
                   }
                }
@@ -2330,6 +2378,7 @@ static Type ProcessTypeSpecs(OldList specs, bool assumeEllipsis, bool keepTypeNa
                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 == INT128) specType.kind = int128Type;
             else if(spec.specifier == VALIST)
                specType.kind = vaListType;
             else if(spec.specifier == SHORT) specType.kind = shortType;
@@ -2339,6 +2388,7 @@ static Type ProcessTypeSpecs(OldList specs, bool assumeEllipsis, bool keepTypeNa
                   specType.kind = int64Type;
                else
                   specType.kind = intType;
+               specType.isLong = true;
                isLong = true;
             }
             else if(spec.specifier == FLOAT) specType.kind = floatType;
@@ -2389,6 +2439,7 @@ static Type ProcessTypeSpecs(OldList specs, bool assumeEllipsis, bool keepTypeNa
 
                   CopyTypeInto(specType, symbol.type);
                   specType.constant = isConstant;
+                  delete specType.typeName;
                   specType.typeName = CopyString(symbol.type.name);
                }
                else if(!isTypedef) // !specType.kind)    // TESTING THIS FOR enum / typedef problem
@@ -2540,8 +2591,29 @@ static Type ProcessTypeDecls(OldList specs, Declarator decl, Type parentType)
 {
    Type type = parentType;
    Declarator subDecl = decl ? decl.declarator : null;
+   bool isVector = false;
+   if(decl && (decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd))
+   {
+      ExtDecl extDecl = decl.extended.extended;
+      if(extDecl && 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, "__vector_size__"))
+                     isVector = true;
+            }
+         }
+      }
+   }
+
    if(!parentType)
-      type = ProcessTypeSpecs(specs, decl == null, (decl && decl.type == extendedDeclaratorEnd) ? true : false);
+      type = ProcessTypeSpecs(specs, decl == null, (decl && decl.type == extendedDeclaratorEnd && !isVector) ? true : false);
    if(decl)
    {
       switch(decl.type)
@@ -2582,6 +2654,16 @@ static Type ProcessTypeDecls(OldList specs, Declarator decl, Type parentType)
                                  type.dllExport = true;
                               else if(!strcmp(s, "stdcall"))
                                  type.attrStdcall = true;
+                              else if(!strcmp(s, "__vector_size__"))
+                              {
+                                 type.isVector = true;
+                                 /*
+                                 Expression exp = attr.exp;
+                                 while(exp.type == bracketsExp)
+                                    exp = exp.list ? exp.list->last : null;
+                                 type.vectorSize = CopyExpression(exp);
+                                 */
+                              }
                            }
                         }
                      }