diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-26 10:52:31 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-26 12:17:49 -0700 |
| commit | f6cb66feab3439f41ca87cb307f69b49654883ab (patch) | |
| tree | d73c230a8b2ddc06e0fa978945aa8a838b189236 /source/slang/preprocessor.cpp | |
| parent | 6e99b81c98f8c76444563d959536073befc7d8ca (diff) | |
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.
Diffstat (limited to 'source/slang/preprocessor.cpp')
| -rw-r--r-- | source/slang/preprocessor.cpp | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp index c3cc8cb0a..084f518fb 100644 --- a/source/slang/preprocessor.cpp +++ b/source/slang/preprocessor.cpp @@ -167,11 +167,23 @@ struct Preprocessor // represent end-of-input situations. Token endOfFileToken; - // Syntax for the program we are trying to parse - ProgramSyntaxNode* syntax; + // The translation unit that is being parsed + TranslationUnitRequest* translationUnit; - // The over-arching compile request taht is invoking us - CompileRequest* compileRequest; + TranslationUnitRequest* getTranslationUnit() + { + return translationUnit; + } + + ProgramSyntaxNode* getSyntax() + { + return getTranslationUnit()->SyntaxNode.Ptr(); + } + + CompileRequest* getCompileRequest() + { + return getTranslationUnit()->compileRequest; + } }; // Convenience routine to access the diagnostic sink @@ -1733,7 +1745,7 @@ static void handleGLSLVersionDirective(PreprocessorDirectiveContext* context) // Attach the modifier to the program we are parsing! addModifier( - context->preprocessor->syntax, + context->preprocessor->getSyntax(), modifier); } @@ -1777,7 +1789,7 @@ static void handleGLSLExtensionDirective(PreprocessorDirectiveContext* context) // Attach the modifier to the program we are parsing! addModifier( - context->preprocessor->syntax, + context->preprocessor->getSyntax(), modifier); } @@ -2029,14 +2041,12 @@ TokenList preprocessSource( String const& fileName, DiagnosticSink* sink, IncludeHandler* includeHandler, - Dictionary<String, String> defines, - ProgramSyntaxNode* syntax, - CompileRequest* compileRequest) + Dictionary<String, String> defines, + TranslationUnitRequest* translationUnit) { Preprocessor preprocessor; InitializePreprocessor(&preprocessor, sink); - preprocessor.syntax = syntax; - preprocessor.compileRequest = compileRequest; + preprocessor.translationUnit = translationUnit; preprocessor.includeHandler = includeHandler; for (auto p : defines) @@ -2116,21 +2126,24 @@ static void HandleImportDirective(PreprocessorDirectiveContext* context) expectEndOfDirective(context); // TODO: may want to have some kind of canonicalization step here - String moduleName = foundPath; + String moduleKey = foundPath; // Import code from the chosen file, if needed. We only // need to import on the first `#import` directive, and // after that we ignore additional `#import`s for the same file. { - auto request = context->preprocessor->compileRequest; + auto translationUnit = context->preprocessor->translationUnit; + auto request = translationUnit->compileRequest; // Have we already loaded a module matching this name? - if (request->loadedModulesMap.TryGetValue(moduleName)) + if (request->mapPathToLoadedModule.TryGetValue(moduleKey)) { - // The module has already been loaded, so we bail out - // and leave *nothing* in the input stream. - return; + // The module has already been loaded, so we don't need to + // actually tokenize the code here. But note that we *do* + // go on to insert tokens for an `import` operation into + // the stream, so it is up to downstream code to avoid + // re-importing the same thing twice. } else { @@ -2158,8 +2171,7 @@ static void HandleImportDirective(PreprocessorDirectiveContext* context) // Now we need to do something with those tokens we read request->handlePoundImport( - moduleName, - foundPath, + moduleKey, subTokens); } } @@ -2172,7 +2184,7 @@ static void HandleImportDirective(PreprocessorDirectiveContext* context) token.Type = TokenType::PoundImport; token.Position = GetDirectiveLoc(context); token.flags = 0; - token.Content = moduleName; + token.Content = foundPath; inputStream->lexedTokens.mTokens.Add(token); |
