compiler/libec: Improved error messages
[sdk] / compiler / libec / src / loadSymbols.ec
index f53e9ed..90ec83b 100644 (file)
@@ -1,4 +1,5 @@
 import "ecdefs"
+import "lexer"
 
 extern int yychar;
 
@@ -7,7 +8,7 @@ public void SetGlobalData(NameSpace * nameSpace) { globalData = nameSpace; }
 
 OldList dataRedefinitions;
 
-#define MAX_INCLUDE_DEPTH 10
+// #define MAX_INCLUDE_DEPTH 30
 
 extern char sourceFileStack[MAX_INCLUDE_DEPTH][MAX_LOCATION];
 extern int include_stack_ptr;
@@ -33,10 +34,14 @@ bool ecereImported;
 public void SetEcereImported(bool b) { ecereImported = b; } public bool GetEcereImported() { return ecereImported; }
 bool inPreCompiler = false;
 public void SetInPreCompiler(bool b) {inPreCompiler = b; }
+bool inSymbolGen = false;
+public void SetInSymbolGen(bool b) {inSymbolGen = b; }
+bool inDocumentor = false;
+public void SetInDocumentor(bool b) { inDocumentor = b; }
 OldList * precompDefines;
 public void SetPrecompDefines(OldList * list) { precompDefines = list; }
 
-bool DummyMethod()
+public bool DummyMethod()
 {
    return true;
 }
@@ -79,19 +84,22 @@ static void ReadDataMembers(Class regClass, DataMember member, File f)
             if(member)
             {
                if(!eMember_AddDataMember(member, name, line[0] ? line : 0, 0, 0 /*size *//*type->size*/, memberAccess))
-                  ;//Compiler_Error("Member with same name already exists %s in member %s\n", name, member->name);
+                  ;//Compiler_Error($"Member with same name (%s) already exists in member %s\n", name, member->name);
             }
             else if(regClass && regClass.type == bitClass)
             {
                //eClass_AddBitMember(regClass, name, line[0] ? line : 0, size, bitPos);
                BitMember member = eClass_AddBitMember(regClass, name, line[0] ? line : 0, 0, 0, memberAccess);
-               member.size = size;
-               member.pos = bitPos;
+               if(member)
+               {
+                  member.size = size;
+                  member.pos = bitPos;
+               }
             }
             else if(regClass)
             {
                if(!eClass_AddDataMember(regClass, name, line[0] ? line : 0, 0, 0 /*size *//*type->size*/, memberAccess))
-                  ;//Compiler_Error("Member with same name already exists %s in class %s\n", name, regClass.fullName);
+                  ;//Compiler_Error($"Member with same name (%s) already exists in class %s\n", name, regClass.fullName);
             }
          }
          else if(!strcmp(line, "[Struct]") || !strcmp(line, "[Union]"))
@@ -101,12 +109,12 @@ static void ReadDataMembers(Class regClass, DataMember member, File f)
             if(member)
             {
                if(!eMember_AddMember(member, dataMember))
-                  ;//Compiler_Error("Member with same name already exists %s in member %s\n", name, member->name);
+                  ;//Compiler_Error($"Member with same name (%s) already exists in member %s\n", name, member->name);
             }
             else if(regClass)
             {
                if(!eClass_AddMember(regClass, dataMember))
-                  ;//Compiler_Error("Member with same name already exists %s in class %s\n", name, regClass.name);
+                  ;//Compiler_Error($"Member with same name (%s) already exists in class %s\n", name, regClass.name);
             }
          }
       }
@@ -122,7 +130,7 @@ static void ReadDataMembers(Class regClass, DataMember member, File f)
 
 // This should register the stuff only...
 // But also call ImportModule
-public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly)
+public bool LoadSymbols(const char * fileName, ImportType importType, bool loadDllOnly)
 {
    File f = FileOpenBuffered(fileName, read);
    bool globalInstance = false;
@@ -202,19 +210,19 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                         TrimLSpaces(line, line);
 
                         if(importType == preDeclImport)
-                           DeclClass(0, name);
+                           DeclClass(null, name);
                         if(isStatic || loadDllOnly || importType == preDeclImport || importType == comCheckImport)
                           regClass = null;
                         else if(regClass = eSystem_FindClass(privateModule, name), !regClass || regClass.internalDecl || regClass.isRemote)
                         {
                            Symbol existingClass = FindClass(name);
-                           char * baseName = (classType == normalClass && importType == remoteImport && isRemote) ? "DCOMClientObject" : (!strcmp(line, "[None]") ? null : line);
+                           const char * baseName = (classType == normalClass && importType == remoteImport && isRemote) ? "DCOMClientObject" : (!strcmp(line, "[None]") ? null : line);
                            //Symbol baseSymbol = baseName ? FindClass(baseName) : null;
                            //if(baseSymbol && !baseSymbol->registered)
                            /*if(classType != unitClass && classType != bitClass && classType != enumClass && baseName && !eSystem_FindClass(privateModule, baseName))
                            {
-                              Compiler_Error("Base class %s undefined\n", baseName);
-                              DeclClass(0, name);
+                              Compiler_Error($"Base class %s undefined\n", baseName);
+                              DeclClass(name);
                               regClass = null;
                               continue;
                            }
@@ -234,7 +242,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                     char className[1024] = "DCOMClient_";
                                     strcat(className, name);
                                     if(!existingClass)
-                                       existingClass = DeclClass(0, name);
+                                       existingClass = DeclClass(null, name);
                                     regClass = eSystem_RegisterClass(classType, className, baseName, 0, 0, null, null, privateModule, ecereCOMModule ? baseSystemAccess : publicAccess, inheritanceAccess);
                                  }
                                  if(regClass)
@@ -263,13 +271,11 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                  regClass.structSize = regClass.offset;    // THIS COULD PROBABLY BENEFIT FROM SOME EXPLANATIONS...
                               }
 
-                              // Added this
                               if(regClass && existingClass)
                               {
                                  existingClass.registered = regClass;
-                                 regClass.symbol = existingClass; // TESTING THIS
-                                 existingClass.id = MAXINT;
-                                 existingClass.idCode = MAXINT;
+                                 regClass.symbol = existingClass;
+                                 existingClass.notYetDeclared = true;
                                  existingClass.imported = true;
                                  if(regClass.module)
                                     existingClass.module = FindModule(regClass.module);
@@ -292,7 +298,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                         for(;;)
                         {
                            char * equal;
-                           
+
                            if(!f.GetLine(line, sizeof(line))) break;
                            TrimLSpaces(line, line);
                            if(!strcmp(line, ".")) break;
@@ -307,7 +313,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                  name[equal - line] = '\0';
                                  TrimLSpaces(name, name);
                                  TrimRSpaces(name, name);
-                                 eEnum_AddFixedValue(regClass, name, atoi(equal + 1));
+                                 eEnum_AddFixedValue(regClass, name, strtoll(equal + 1, null, 0));
                               }
                               else
                               {
@@ -349,7 +355,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                            }
                            else
                            {
-                              strcpy(name, line);                              
+                              strcpy(name, line);
                               isVirtual = false;
                               memberAccess = publicAccess;
                            }
@@ -375,7 +381,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                  TrimLSpaces(line, line);
                                  if(regClass)
                                  {
-                                    Property prop = eClass_AddProperty(regClass, conversion ? null : name, line[0] ? line : 0, (void *)setStmt, (void *)getStmt, memberAccess);
+                                    Property prop = eClass_AddProperty(regClass, conversion ? null : name, line[0] ? line : 0, (void *)(uintptr)setStmt, (void *)(uintptr)getStmt, memberAccess);
                                     if(prop)
                                     {
                                        prop.compiled = false;
@@ -429,7 +435,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                  TrimLSpaces(line, line);
                                  if(regClass)
                                  {
-                                    eClass_AddClassProperty(regClass, name, line, (void *)setStmt, (void *)getStmt);
+                                    eClass_AddClassProperty(regClass, name, line, (void *)(uintptr)setStmt, (void *)(uintptr)getStmt);
                                  }
                               }
                               else if(!strcmp(line, "[Set]"))
@@ -494,33 +500,24 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                  f.GetLine(line, sizeof(line)); TrimLSpaces(line, line);
                                  if(regClass && strcmp(line, "[None]"))
                                  {
+                                    LexerBackup backup = pushLexer();   // We currently don't have a separate Lexer instance for TU/Type/Expression
                                     Operand op;
                                     Expression exp;
-                                    Location oldLocation = yylloc;
-
-                                    File backFileInput = fileInput;
-                                    declMode = 0;
-                                    resetScanner();
 
+                                    skipErrors = true;
                                     exp = ParseExpressionString(line);
-                                    if(info)
-                                       exp.destType = ProcessTypeString(info, false);
-                                    ProcessExpressionType(exp);
-                                    ComputeExpression(exp);
-                                    op = GetOperand(exp);
-                                    defaultArg.expression.ui64 = op.ui64;
-                                    FreeExpression(exp);
-
-                                    // TESTING THIS SCANNER RESUME STUFF
-                                    resetScanner();
-                                    yylloc = oldLocation;
-                                    fileInput = backFileInput;
-                                    if(fileInput)
+                                    if(exp)
                                     {
-                                       fileInput.Seek(yylloc.start.pos, start); 
-                                       resetScannerPos(&yylloc.start);
-                                       yychar = -2;
+                                       if(info)
+                                          exp.destType = ProcessTypeString(info, false);
+                                       ProcessExpressionType(exp);
+                                       ComputeExpression(exp);
+                                       op = GetOperand(exp);
+                                       defaultArg.expression.ui64 = op.ui64;
+                                       FreeExpression(exp);
                                     }
+                                    skipErrors = false;
+                                    popLexer(backup);
                                  }
                                  break;
                               case identifier:
@@ -541,7 +538,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                            if(type == TemplateParameterType::type || type == TemplateParameterType::expression)
                               delete info;
                            if(type == TemplateParameterType::type || type == TemplateParameterType::identifier)
-                              delete defaultArg.dataTypeString;                           
+                              delete (void *)defaultArg.dataTypeString;
                         }
                         if(regClass)
                            eClass_DoneAddingTemplateParameters(regClass);
@@ -565,7 +562,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                   if(!f.GetLine(line, sizeof(line))) break;
                   TrimLSpaces(line, line);
                   if(!strcmp(line, ".")) break;
-                  if(!strcmp(line, "[Value]")) 
+                  if(!strcmp(line, "[Value]"))
                   {
                      f.GetLine(line, sizeof(line));
                      TrimLSpaces(line, line);
@@ -586,7 +583,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                   if(!f.GetLine(line, sizeof(line))) break;
                   TrimLSpaces(line, line);
                   if(!strcmp(line, ".")) break;
-                  if(!strcmp(line, "[Type]")) 
+                  if(!strcmp(line, "[Type]"))
                   {
                      f.GetLine(line, sizeof(line));
                      TrimLSpaces(line, line);
@@ -607,7 +604,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                   if(!f.GetLine(line, sizeof(line))) break;
                   TrimLSpaces(line, line);
                   if(!strcmp(line, ".")) break;
-                  if(!strcmp(line, "[Type]")) 
+                  if(!strcmp(line, "[Type]"))
                   {
                      f.GetLine(line, sizeof(line));
                      TrimLSpaces(line, line);
@@ -645,14 +642,14 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                  delete spaceName;
                               nameSpace = newSpace;
                               if(name[c] == ':') c++;
-                              start = c+1;         
+                              start = c+1;
                            }
                         }
                         if(c - start)
                         {
                            // TOFIX:
                            //if(!(data = (GlobalData)nameSpace->functions.FindString(name)))
-                           data = (GlobalData)nameSpace->functions.FindString(name);
+                           data = (GlobalData)nameSpace->functions.FindString(name + start);
                            if(!data)
                            {
                               data = GlobalData
@@ -661,7 +658,7 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
                                  dataTypeString = CopyString(line),
                                  module = privateModule
                               };
-                              data.key = (uint)(data.fullName + start);
+                              data.key = (uintptr)(data.fullName + start);
                               // Reusing functions here...
                               nameSpace->functions.Add((BTNode)data);
                            }
@@ -713,24 +710,38 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
    }
    else if(importType != comCheckImport)
    {
-      Compiler_Error("Couldn't open %s\n", fileName);
+      char sysFileName[MAX_LOCATION];
+      GetSystemPathBuffer(sysFileName, fileName);
+      Compiler_Error($"Couldn't open %s\n", sysFileName);
    }
    return globalInstance;
 }
 
+Map<String, List<Module> > loadedModules { };
+
 // (Same function as in actual compiler)
-public void ImportModule(char * name, ImportType importType, AccessMode importAccess, bool loadDllOnly)
+public void ImportModule(const char * name, ImportType importType, AccessMode importAccess, bool loadDllOnly)
 {
    ImportedModule module = null;
-   char moduleName[MAX_FILENAME];
+   char moduleName[MAX_LOCATION];
+   bool isSourceModule = false;
+   if(sourceFile)
+   {
+      char sourceFileModule[MAX_FILENAME];
+      GetLastDirectory(sourceFile, sourceFileModule);
+      StripExtension(sourceFileModule);
+      if(!strcmpi(sourceFileModule, name))
+         isSourceModule = true;
+   }
 
-   strncpy(moduleName, name, MAX_FILENAME-1);
-   moduleName[MAX_FILENAME-1] = 0;
+   strncpy(moduleName, name, MAX_LOCATION-1);
+   moduleName[MAX_LOCATION-1] = 0;
    StripExtension(moduleName);
 
    for(module = defines->first; module; module = module.next)
    {
-      if(module.type == moduleDefinition && !strcmpi(module.name, moduleName))
+      if(module.type == moduleDefinition && !strcmpi(module.name, moduleName) &&
+         ((importType == remoteImport) == (module.importType == remoteImport) || isSourceModule))
          break;
    }
    if((!module || (module.dllOnly && !loadDllOnly)) && strlen(name) < MAX_FILENAME)
@@ -746,7 +757,7 @@ public void ImportModule(char * name, ImportType importType, AccessMode importAc
       PathCat(symFile, name);
       ChangeExtension(symFile, "sym", symFile);
 
-      if(!strcmp(ext, "dll") || !strcmp(ext, "dll") || !ext[0])
+      if(!strcmp(ext, "dll") || !strcmp(ext, "so") || !strcmp(ext, "dylib") || !ext[0])
       {
          if(importType != comCheckImport)
          {
@@ -776,15 +787,49 @@ public void ImportModule(char * name, ImportType importType, AccessMode importAc
 
             if(ext[0] || !FileExists(symFile))
             {
-               char file[MAX_FILENAME];
+               bool skipLoad = false;
+               List<Module> list = null;
+               /*
+               char file[MAX_LOCATION];
                strcpy(file, name);
                StripExtension(file);
+               */
+
+               // Load an extra instance of any shared module to ensure freeing up a
+               // module loaded in another file will not invalidate our objects.
+
+               // Don't do this for Documentor, because files are loaded with full paths
+               // and won't be recognized as the same libecere that Documentor is actually using,
+               // and since this is loaded from the Documentor app module, it will invalidate classes in use.
+               // We only load one component app at a time for Documentor, so we do not need this trick.
+               if(!inCompiler && !inPreCompiler && !inSymbolGen && !inDocumentor)
+               {
+                  MapIterator<String, List<Module> > it { map = loadedModules };
+                  if(!it.Index(name /*file*/, false))
+                  {
+                     Module firstModule = eModule_LoadStrict(__thisModule.application, name /*file*/, importAccess);
+                     if(firstModule)
+                     {
+                        list = { };
+                        list.Add(firstModule);
+                        loadedModules[name /*file*/] = list;
+                     }
+                     else
+                        skipLoad = true;
+                  }
+                  else
+                     list = it.data;
+               }
 
-               loadedModule = eModule_LoadStrict(privateModule, file, importAccess);
-               if(loadedModule)
+               if(!skipLoad)
                {
-                  loadedModule.importType = importType;
-                  module.dllOnly = false;    // If this is truly a dll, no need to reload it again...
+                  loadedModule = eModule_LoadStrict(privateModule, name /*file*/, importAccess);
+                  if(loadedModule)
+                  {
+                     loadedModule.importType = importType;
+                     module.dllOnly = false;    // If this is truly a dll, no need to reload it again...
+                     if(list) list.Add(loadedModule);
+                  }
                }
             }
          }
@@ -828,7 +873,7 @@ public void ImportModule(char * name, ImportType importType, AccessMode importAc
                   strcpy(symFile, dir);
                   // PathCat(symFile, "Debug");
                   PathCat(symFile, "obj");
-                  sprintf(configDir, "debug.%s", (GetRuntimePlatform() == win32) ? "win32" : "linux");
+                  sprintf(configDir, "debug.%s", (__runtimePlatform == win32) ? "win32" : (__runtimePlatform == apple) ? "apple" : "linux");
                   PathCat(symFile, configDir);
 
                   PathCat(symFile, name);
@@ -865,7 +910,7 @@ int FindIncludeFileID(char * includeFile)
 int GetIncludeFileID(char * includeFile)
 {
    int found = FindIncludeFileID(includeFile);
-   if(found) 
+   if(found)
       return found;
 
    includes = renew includes char *[numIncludes+1];
@@ -905,7 +950,7 @@ File OpenIncludeFile(char * includeFile)
                break;
          }
       }
-      if(sysIncludeDirs)
+      if(!file && sysIncludeDirs)
       {
          for(includeDir = sysIncludeDirs->first; includeDir; includeDir = includeDir.next)
          {
@@ -938,7 +983,7 @@ public void FreeGlobalData(NameSpace globalDataList)
    {
       FreeGlobalData(ns);
       globalDataList.nameSpaces.Remove((BTNode)ns);
-      delete ns->name;
+      delete (void *)ns->name;
       delete ns;
    }
    for(;(data = (GlobalData)globalDataList.functions.root);)
@@ -967,7 +1012,7 @@ public void CheckDataRedefinitions()
       PrintType(type1, type1String, false, true);
       PrintType(type2, type2String, false, true);
       if(strcmp(type1String, type2String))
-         Compiler_Warning("Redefinition of %s (defining as %s, already defined as %s)\n", redefinition.name, type1String, type2String);
+         Compiler_Warning($"Redefinition of %s (defining as %s, already defined as %s)\n", redefinition.name, type1String, type2String);
       FreeType(type1);
       FreeType(type2);
    }