From f6cb66feab3439f41ca87cb307f69b49654883ab Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 26 Jun 2017 10:52:31 -0700 Subject: Check for re-import at translation-unit level Previously the code checked for a duplicate `#import` using a data structure attached to the compile request, but this would fail for nested imports. It also wouldn't work for a combination of `#import` and `__import`. This change makes it so that we instead track a set of already-imported modules in the semantic checking visitor, which is instantiated once per translation unit. We also key this set on the actual module (AST) imported, rather than on path/name/whatever, so hopefully it will be robust to the same thing getting imported multiple ways. --- source/slang/slang.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'source/slang/slang.cpp') diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 5e80dabf5..cd48a4152 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -167,8 +167,7 @@ void CompileRequest::parseTranslationUnit( &mSink, &includeHandler, combinedPreprocessorDefinitions, - translationUnitSyntax.Ptr(), - this); + translationUnit); parseSourceFile( translationUnit, @@ -398,7 +397,8 @@ RefPtr CompileRequest::loadModule( RefPtr moduleDecl = translationUnit->SyntaxNode; - loadedModulesMap.Add(name, moduleDecl); + mapPathToLoadedModule.Add(path, moduleDecl); + mapNameToLoadedModules.Add(name, moduleDecl); loadedModulesList.Add(moduleDecl); return moduleDecl; @@ -406,7 +406,6 @@ RefPtr CompileRequest::loadModule( } void CompileRequest::handlePoundImport( - String const& name, String const& path, TokenList const& tokens) { @@ -436,7 +435,13 @@ void CompileRequest::handlePoundImport( RefPtr moduleDecl = translationUnit->SyntaxNode; - loadedModulesMap.Add(name, moduleDecl); + // TODO: It is a bit broken here that we use the module path, + // as the "name" when registering things, but this saves + // us the trouble of trying to special-case things when + // checking an `import` down the road. + mapNameToLoadedModules.Add(path, moduleDecl); + + mapPathToLoadedModule.Add(path, moduleDecl); loadedModulesList.Add(moduleDecl); } @@ -447,7 +452,7 @@ RefPtr CompileRequest::findOrImportModule( // Have we already loaded a module matching this name? // If so, return it. RefPtr moduleDecl; - if (loadedModulesMap.TryGetValue(name, moduleDecl)) + if (mapNameToLoadedModules.TryGetValue(name, moduleDecl)) return moduleDecl; // Derive a file name for the module, by taking the given @@ -486,7 +491,7 @@ RefPtr CompileRequest::findOrImportModule( { this->mSink.diagnose(loc, Diagnostics::cannotFindFile, fileName); - loadedModulesMap[name] = nullptr; + mapNameToLoadedModules[name] = nullptr; return nullptr; } break; @@ -495,6 +500,11 @@ RefPtr CompileRequest::findOrImportModule( break; } + // Maybe this was loaded previously via `#import` + if (mapPathToLoadedModule.TryGetValue(foundPath, moduleDecl)) + return moduleDecl; + + // We've found a file that we can load for the given module, so // go ahead and perform the module-load action return loadModule( -- cgit v1.2.3