diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-01-26 15:30:23 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-01-26 15:30:23 -0800 |
| commit | 06f0effb848c6b938e03da8a61e44b3d032380e8 (patch) | |
| tree | e575c83fa7a6b277edc069e4f82f910b74ad56db /source/slang/slang.cpp | |
| parent | a050f4a144d5ab36c93cd0a443767340301fb32e (diff) | |
Fix handling of errors in imported modules (#387)
* Fix handling of errors in imported modules
- If a semantic error is detected in an imported module, then don't try to generate IR code for it
- Also, if a module (transitively) imports itself, then report that as an error
- The way I'm checking for this is a bit hacky (I'm adding the module to the map of loaded modules, but in an "unfinished" state, and then using that unfinished state to detect the import of a module already being imported).
This isn't a 100% complete solution for any of the related problems, but it improves the user experience for the common case.
* Remove #import test.
The feature is slated to be removed, so it isn't worth fixing up this test case.
Diffstat (limited to 'source/slang/slang.cpp')
| -rw-r--r-- | source/slang/slang.cpp | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index e4bf251fc..773b1dd09 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -499,16 +499,31 @@ void CompileRequest::loadParsedModule( Name* name, String const& path) { + // Note: we add the loaded module to our name->module listing + // before doing semantic checking, so that if it tries to + // recursively `import` itself, we can detect it. + RefPtr<LoadedModule> loadedModule = new LoadedModule(); + mapPathToLoadedModule.Add(path, loadedModule); + mapNameToLoadedModules.Add(name, loadedModule); + + int errorCountBefore = mSink.GetErrorCount(); checkTranslationUnit(translationUnit.Ptr()); + int errorCountAfter = mSink.GetErrorCount(); RefPtr<ModuleDecl> moduleDecl = translationUnit->SyntaxNode; - - RefPtr<LoadedModule> loadedModule = new LoadedModule(); loadedModule->moduleDecl = moduleDecl; - loadedModule->irModule = generateIRForTranslationUnit(translationUnit); - mapPathToLoadedModule.Add(path, loadedModule); - mapNameToLoadedModules.Add(name, loadedModule); + if (errorCountAfter != errorCountBefore) + { + // There must have been an error in the loaded module. + } + else + { + // If we didn't run into any errors, then try to generate + // IR code for the imported module. + loadedModule->irModule = generateIRForTranslationUnit(translationUnit); + } + loadedModulesList.Add(loadedModule); } @@ -591,7 +606,16 @@ RefPtr<ModuleDecl> CompileRequest::findOrImportModule( // If so, return it. RefPtr<LoadedModule> loadedModule; if (mapNameToLoadedModules.TryGetValue(name, loadedModule)) - return loadedModule->moduleDecl; + { + if (!loadedModule) + return nullptr; + + if (!loadedModule->moduleDecl) + { + // We seem to be in the middle of loading this module + mSink.diagnose(loc, Diagnostics::recursiveModuleImport, name); + } + } // Derive a file name for the module, by taking the given // identifier, replacing all occurences of `_` with `-`, |
