compiler/libec: Fix for thisclass related warnings in Map.ec
[sdk] / compiler / libec / src / ecdefs.ec
index 2041214..595a121 100644 (file)
@@ -183,6 +183,9 @@ class DBIndexItem : struct
 bool inCompiler = false;
 public void SetInCompiler(bool b) { inCompiler = b; }
 
+bool inDebugger = false;
+public void SetInDebugger(bool b) { inDebugger = b; }
+
 Context curContext;
 Context globalContext;
 OldList * excludedSymbols;
@@ -560,6 +563,7 @@ public:
       {
          char * string;
          bool intlString;
+         bool wideString;
       };
       OldList * list;
       struct
@@ -1018,7 +1022,6 @@ public:
    Symbol symbol;
    Location blockStart;
    Location nameLoc;
-   int endid;
    AccessMode declMode;
    bool deleteWatchable;
 };
@@ -1089,6 +1092,14 @@ public:
    void * object;
 };
 
+// An 'edge from' is a 'dependency on'
+class TopoEdge : struct
+{
+   public LinkElement<TopoEdge> in, out;
+   External from, to;
+   bool breakable;
+};
+
 public enum ExternalType { functionExternal, declarationExternal, classExternal, importExternal, nameSpaceExternal, dbtableExternal };
 
 public class External : struct
@@ -1108,6 +1119,109 @@ public:
       DBTableDef table;
    };
    ImportType importType;
+
+   // For the TopoSort
+   External fwdDecl;
+   LinkList<TopoEdge, link = out> outgoing { };
+   LinkList<TopoEdge, link = in> incoming { };
+   int nonBreakableIncoming;
+
+   void CreateUniqueEdge(External from, bool soft)
+   {
+      for(i : from.outgoing; i.to == this)
+      {
+         if(i.breakable && !soft)
+         {
+#ifdef _DEBUG
+            if(from == this)
+               PrintLn("bug: self-dependency");
+#endif
+            i.breakable = false;
+            nonBreakableIncoming++;
+         }
+         return;
+      }
+      CreateEdge(from, soft);
+   }
+
+   void CreateEdge(External from, bool soft)
+   {
+      TopoEdge e { from = from, to = this, breakable = soft };
+
+#ifdef _DEBUG
+      if(from == this && !soft)
+         PrintLn("bug: self-dependency");
+
+      /*for(i : from.outgoing)
+      {
+         if(i.to == this)
+            PrintLn("Warning: adding a duplicate edge");
+      }*/
+#endif
+
+      from.outgoing.Add(e);
+      incoming.Add(e);
+      if(!soft)
+         nonBreakableIncoming++;
+   }
+
+   External ForwardDeclare()
+   {
+      External f = null;
+      Context tmpContext = curContext;
+
+      switch(type)
+      {
+         case declarationExternal:
+         {
+            if(declaration.type == initDeclaration)
+            {
+               OldList * specs = declaration.specifiers;
+               if(specs)
+               {
+                  Specifier s;
+                  for(s = specs->first; s; s = s.next)
+                  {
+                     if(s.type == structSpecifier || s.type == unionSpecifier)
+                        break;
+                  }
+                  if(s)
+                  {
+                     curContext = null;
+                     f = MkExternalDeclaration(MkDeclaration(MkListOne(MkStructOrUnion(s.type, CopyIdentifier(s.id), null)), null));
+                     curContext = tmpContext;
+                  }
+               }
+            }
+            break;
+         }
+         case functionExternal:
+         {
+            curContext = null;
+            f = MkExternalDeclaration(MkDeclaration(CopyList(function.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(CopyDeclarator(function.declarator), null))));
+            curContext = tmpContext;
+            f.symbol = symbol;
+
+            DeclareTypeForwardDeclare(f, symbol.type, false, false);
+            break;
+         }
+      }
+
+      /*
+      for(i : m.protoDepsExternal)
+      {
+         // If the edge is already added, don't bother
+         if(i.incoming.count)
+            CreateEdge(f, i.fwdDecl ? i.fwdDecl : i, i.fwdDecl ? false : true);
+      }
+      */
+
+      fwdDecl = f;
+
+      if(!f)
+         PrintLn("warning: unhandled forward declaration requested");
+      return f;
+   }
 };
 
 public class Context : struct
@@ -1142,7 +1256,7 @@ public:
       Property _property;
       Class registered;
    };
-   int id, idCode;
+   bool notYetDeclared;
    union
    {
       struct
@@ -1292,12 +1406,13 @@ public:
    uint size;
    char * name;
    char * typeName;
+   Class thisClassFrom;
 
    ClassObjectType classObjectType;
    int alignment;
    uint offset;
    int bitFieldCount;
-   int count;
+   int count;  // This is used to avoid outputting warnings when non-zero
 
    bool isSigned:1;
    bool constant:1;
@@ -1313,6 +1428,7 @@ public:
    bool declaredWithStruct:1;
    bool typedByReference:1;      // Originally typed by reference, regardless of class type
    bool casted:1;
+   bool pointerAlignment:1; // true if the alignment is the pointer size
    // bool wasThisClass:1;
    // TODO: Add _Complex & _Imaginary support
    // bool complex:1, imaginary:1;
@@ -1340,6 +1456,88 @@ public:
          return t.constant;
       }
    }
+
+   // Used for generating calls to eClass_AddDataMember (differs slightly from 'isPointerType' below), meant to return true where ComputeTypeSize returns targetBits / 8
+   property bool isPointerTypeSize
+   {
+      get
+      {
+         bool result = false;
+         if(this)
+         {
+            switch(kind)
+            {
+               case classType:
+               {
+                  Class _class = this._class ? this._class.registered : null;
+                  if(!_class || (_class.type != structClass && _class.type != unitClass && _class.type != enumClass && _class.type != bitClass))
+                     result = true;
+                  break;
+               }
+               case pointerType:
+               case subClassType:
+               case thisClassType:
+               case intPtrType:
+               case intSizeType:
+                  result = true;
+                  break;
+               case templateType:
+               {
+                  TemplateParameter param = templateParameter;
+                  Type baseType = ProcessTemplateParameterType(param);
+                  if(baseType)
+                     result = baseType.isPointerTypeSize;
+                  break;
+               }
+            }
+         }
+         return result;
+      }
+   }
+
+   property bool isPointerType
+   {
+      get
+      {
+         if(this)
+         {
+            if(kind == pointerType || kind == methodType || kind == functionType || kind == arrayType || kind == subClassType)
+               return true;
+            else if(kind == classType)
+            {
+               if(_class && _class.registered)
+               {
+                  Class c = _class.registered;
+                  if(c.type == bitClass || c.type == unitClass || c.type == enumClass || c.type == systemClass)
+                     return false;
+                  else if(c.type == structClass && !byReference)
+                     return false;
+               }
+               return true;
+            }
+            else if(kind == templateType)
+            {
+               if(passAsTemplate) return false;
+               if(templateParameter)
+               {
+                  if(templateParameter.dataType)
+                  {
+                     Specifier spec = templateParameter.dataType.specifiers ? templateParameter.dataType.specifiers->first : null;
+                     if(templateParameter.dataType.decl && templateParameter.dataType.decl.type == pointerDeclarator)
+                        return true;
+                     if(spec && spec.type == nameSpecifier && strcmp(spec.name, "uint64"))
+                        return true;
+                  }
+                  if(templateParameter.dataTypeString)
+                     return true;
+               }
+            }
+            else
+               return false;
+         }
+         return false;
+      }
+   }
 };
 
 public struct Operand
@@ -1470,6 +1668,7 @@ void Compiler_Error(const char * format, ...)
          string[sizeof(string)-1] = 0;
          va_end(args);
          fputs(string, stdout);
+         fflush(stdout);
          __thisModule.application.exitCode = 1;
       }
       else
@@ -1517,6 +1716,7 @@ void Compiler_Warning(const char * format, ...)
       string[sizeof(string)-1] = 0;
       va_end(args);
       fputs(string, stdout);
+      fflush(stdout);
       numWarnings++;
    }
 }