diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-06-26 13:47:08 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-06-26 13:47:08 -0700 |
| commit | 0259ddb0a72d3b12278404847f6e30b63e97cfc3 (patch) | |
| tree | d73c230a8b2ddc06e0fa978945aa8a838b189236 | |
| parent | 3f316dcbd9274efc74f817cf36f17a511ff2e21e (diff) | |
| parent | f6cb66feab3439f41ca87cb307f69b49654883ab (diff) | |
Merge pull request #43 from tfoleyNV/import-macros
Add support for `#import`
| -rw-r--r-- | slang.h | 10 | ||||
| -rw-r--r-- | source/slang/check.cpp | 17 | ||||
| -rw-r--r-- | source/slang/compiler.h | 24 | ||||
| -rw-r--r-- | source/slang/diagnostic-defs.h | 1 | ||||
| -rw-r--r-- | source/slang/options.cpp | 8 | ||||
| -rw-r--r-- | source/slang/parser.cpp | 8 | ||||
| -rw-r--r-- | source/slang/preprocessor.cpp | 237 | ||||
| -rw-r--r-- | source/slang/preprocessor.h | 10 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 101 | ||||
| -rw-r--r-- | source/slang/token-defs.h | 2 | ||||
| -rw-r--r-- | tests/preprocessor/import.hlsl | 18 | ||||
| -rw-r--r-- | tests/preprocessor/import.slang.h | 12 | ||||
| -rw-r--r-- | tests/render/pound-import.hlsl (renamed from tests/render/auto-import.hlsl) | 4 | ||||
| -rw-r--r-- | tests/render/pound-import.slang.h (renamed from tests/render/auto-import.slang.h) | 0 |
14 files changed, 270 insertions, 182 deletions
@@ -204,16 +204,6 @@ extern "C" const char* searchDir); /*! - @brief Add a path to use when searching for referenced files, that automatically treats `#include` as `__import` - This behaves just like `spAddSearchPath()` except that any `#include` file found through this path - will be treated as if it was referenced with `__import`. - @param ctx The compilation context. - @param searchDir The additional search directory. - */ - SLANG_API void spAddAutoImportPath( - SlangCompileRequest* request, - const char* searchDir); - /*! @brief Add a macro definition to be used during preprocessing. @param key The name of the macro to define. @param value The value of the macro to define. diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 463052bc8..582f19448 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -52,6 +52,14 @@ namespace Slang // lexical outer statements List<StatementSyntaxNode*> outerStmts; + + // We need to track what has been `import`ed, + // to avoid importing the same thing more than once + // + // TODO: a smarter approach might be to filter + // out duplicate references during lookup. + HashSet<ProgramSyntaxNode*> importedModules; + public: SemanticsVisitor( DiagnosticSink * pErr, @@ -4909,6 +4917,15 @@ namespace Slang // it later during code generation. decl->importedModuleDecl = importedModuleDecl; + // If we've imported this one already, then + // skip the step where we modify the current scope. + if (importedModules.Contains(importedModuleDecl.Ptr())) + { + return; + } + importedModules.Add(importedModuleDecl.Ptr()); + + // Create a new sub-scope to wire the module // into our lookup chain. auto subScope = new Scope(); diff --git a/source/slang/compiler.h b/source/slang/compiler.h index 3f45ea5c7..a6f3eee0e 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -150,21 +150,13 @@ namespace Slang // A directory to be searched when looking for files (e.g., `#include`) struct SearchDirectory { - enum Kind - { - Default, - AutoImport, - }; - SearchDirectory() = default; SearchDirectory(SearchDirectory const& other) = default; - SearchDirectory(String const& path, Kind kind) + SearchDirectory(String const& path) : path(path) - , kind(kind) {} String path; - Kind kind; }; class Session; @@ -211,9 +203,16 @@ namespace Slang RefPtr<ProgramLayout> layout; // Modules that have been dynamically loaded via `import` - Dictionary<String, RefPtr<ProgramSyntaxNode>> loadedModulesMap; + // + // This is a list of unique modules loaded, in the order they were encountered. List<RefPtr<ProgramSyntaxNode> > loadedModulesList; + // Map from the logical name of a module to its definition + Dictionary<String, RefPtr<ProgramSyntaxNode>> mapPathToLoadedModule; + + // Map from the path of a module file to its definition + Dictionary<String, RefPtr<ProgramSyntaxNode>> mapNameToLoadedModules; + CompileRequest(Session* session) : mSession(session) @@ -255,10 +254,9 @@ namespace Slang String const& source, CodePosition const& loc); - String autoImportModule( + void handlePoundImport( String const& path, - String const& source, - CodePosition const& loc); + TokenList const& tokens); RefPtr<ProgramSyntaxNode> findOrImportModule( String const& name, diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h index ff93e51fb..f92f43ddb 100644 --- a/source/slang/diagnostic-defs.h +++ b/source/slang/diagnostic-defs.h @@ -92,6 +92,7 @@ DIAGNOSTIC(-1, Note, seeOpeningToken, "see opening '$0'") // 153xx - #include DIAGNOSTIC(15300, Error, includeFailed, "failed to find include file '$0'") +DIAGNOSTIC(15301, Error, importFailed, "failed to find imported file '$0'") DIAGNOSTIC(-1, Error, noIncludeHandlerSpecified, "no `#include` handler was specified") // 154xx - macro definition diff --git a/source/slang/options.cpp b/source/slang/options.cpp index 81b893d66..62b45e025 100644 --- a/source/slang/options.cpp +++ b/source/slang/options.cpp @@ -375,14 +375,6 @@ struct OptionsParser compileRequest, String(includeDirStr).begin()); } - else if (argStr == "-auto-import-dir") - { - char const* importDirStr = tryReadCommandLineArgumentRaw(arg, &argCursor, argEnd); - - spAddAutoImportPath( - compileRequest, - String(importDirStr).begin()); - } else if (argStr == "--") { // The `--` option causes us to stop trying to parse options, diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index 0598e67a7..61d7b225d 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -805,10 +805,10 @@ namespace Slang return decl; } - static RefPtr<Decl> parseAutoImportDecl( + static RefPtr<Decl> parsePoundImportDecl( Parser* parser) { - Token importToken = parser->ReadToken(TokenType::AutoImport); + Token importToken = parser->ReadToken(TokenType::PoundImport); auto decl = new ImportDecl(); decl->nameToken = importToken; @@ -2186,8 +2186,8 @@ namespace Slang decl = parseModifierDecl(parser); else if(parser->LookAheadToken("__import")) decl = parseImportDecl(parser); - else if(parser->LookAheadToken(TokenType::AutoImport)) - decl = parseAutoImportDecl(parser); + else if(parser->LookAheadToken(TokenType::PoundImport)) + decl = parsePoundImportDecl(parser); else if (AdvanceIf(parser, TokenType::Semicolon)) { decl = new EmptyDecl(); diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp index 00abb3fe5..084f518fb 100644 --- a/source/slang/preprocessor.cpp +++ b/source/slang/preprocessor.cpp @@ -1,12 +1,11 @@ -// Preprocessor.cpp -#include "Preprocessor.h" +// preprocessor.cpp +#include "preprocessor.h" -#include "Diagnostics.h" -#include "Lexer.h" - -// Needed so that we can construct modifier syntax -// to represent GLSL directives -#include "Syntax.h" +#include "compiler.h" +#include "diagnostics.h" +#include "lexer.h" +// Needed so that we can construct modifier syntax to represent GLSL directives +#include "syntax.h" #include <assert.h> @@ -18,15 +17,6 @@ namespace Slang { -// Forward declaration for code provided in `slang.cpp` -// -// TODO: Need an appropriate header for this. -String autoImportModule( - CompileRequest* request, - String const& path, - String const& source, - CodePosition const& loc); - // State of a preprocessor conditional, which can change when // we encounter directives like `#elif` or `#endif` enum class PreprocessorConditionalState @@ -177,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; + + TranslationUnitRequest* getTranslationUnit() + { + return translationUnit; + } + + ProgramSyntaxNode* getSyntax() + { + return getTranslationUnit()->SyntaxNode.Ptr(); + } - // The over-arching compile request taht is invoking us - CompileRequest* compileRequest; + CompileRequest* getCompileRequest() + { + return getTranslationUnit()->compileRequest; + } }; // Convenience routine to access the diagnostic sink @@ -315,11 +317,6 @@ static Token AdvanceRawToken(Preprocessor* preprocessor) EndInputStream(preprocessor, inputStream); continue; } - else - { - // HACK(tfoley): A place to fall into debugger... - int f = 0; - } } // Everything worked, so read a token from the top-most stream @@ -351,11 +348,6 @@ static Token PeekRawToken(Preprocessor* preprocessor) inputStream = inputStream->parent; continue; } - else - { - // HACK(tfoley): A place to fall into debugger... - int f = 0; - } } // Everything worked, so the token we just peeked is fine. @@ -1489,6 +1481,8 @@ static void expectEndOfDirective(PreprocessorDirectiveContext* context) AdvanceRawToken(context->preprocessor); } +// Handle a `#import` directive +static void HandleImportDirective(PreprocessorDirectiveContext* context); // Handle a `#include` directive static void HandleIncludeDirective(PreprocessorDirectiveContext* context) @@ -1520,7 +1514,7 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context) GetSink(context)->diagnose(pathToken.Position, Diagnostics::includeFailed, path); return; - case IncludeResult::FoundIncludeFile: + case IncludeResult::Found: break; } @@ -1529,50 +1523,12 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context) // a switch of input stream expectEndOfDirective(context); - switch( includeResult ) - { - case IncludeResult::FoundIncludeFile: - { - // Push the new file onto our stack of input streams - // TODO(tfoley): check if we have made our include stack too deep - PreprocessorInputStream* inputStream = CreateInputStreamForSource(context->preprocessor, foundSource, foundPath); - inputStream->parent = context->preprocessor->inputStream; - context->preprocessor->inputStream = inputStream; - } - break; - - case IncludeResult::FoundAutoImportFile: - { - // - - String autoImportName = autoImportModule( - context->preprocessor->compileRequest, - foundPath, - foundSource, - GetDirectiveLoc(context)); - - SourceTextInputStream* inputStream = new SourceTextInputStream(); - - Token token; - token.Type = TokenType::AutoImport; - token.Position = GetDirectiveLoc(context); - token.flags = 0; - token.Content = autoImportName; - - inputStream->lexedTokens.mTokens.Add(token); - - token.Type = TokenType::EndOfFile; - token.flags = TokenFlag::AfterWhitespace | TokenFlag::AtStartOfLine; - inputStream->lexedTokens.mTokens.Add(token); - - inputStream->tokenReader = TokenReader(inputStream->lexedTokens); - - inputStream->parent = context->preprocessor->inputStream; - context->preprocessor->inputStream = inputStream; - } - break; - } - } + // Push the new file onto our stack of input streams + // TODO(tfoley): check if we have made our include stack too deep + PreprocessorInputStream* inputStream = CreateInputStreamForSource(context->preprocessor, foundSource, foundPath); + inputStream->parent = context->preprocessor->inputStream; + context->preprocessor->inputStream = inputStream; +} // Handle a `#define` directive static void HandleDefineDirective(PreprocessorDirectiveContext* context) @@ -1789,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); } @@ -1833,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); } @@ -1878,6 +1834,7 @@ static const PreprocessorDirective kDirectives[] = { "elif", &HandleElifDirective, ProcessWhenSkipping }, { "endif", &HandleEndIfDirective, ProcessWhenSkipping }, + { "import", &HandleImportDirective, 0 }, { "include", &HandleIncludeDirective, 0 }, { "define", &HandleDefineDirective, 0 }, { "undef", &HandleUndefDirective, 0 }, @@ -2084,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) @@ -2129,4 +2084,120 @@ TokenList preprocessSource( return tokens; } +// + +// Handle a `#import` directive +static void HandleImportDirective(PreprocessorDirectiveContext* context) +{ + Token pathToken; + if(!Expect(context, TokenType::StringLiterial, Diagnostics::expectedTokenInPreprocessorDirective, &pathToken)) + return; + + String path = getFileNameTokenValue(pathToken); + + // TODO(tfoley): make this robust in presence of `#line` + String pathIncludedFrom = GetDirectiveLoc(context).FileName; + String foundPath; + String foundSource; + + IncludeHandler* includeHandler = context->preprocessor->includeHandler; + if (!includeHandler) + { + GetSink(context)->diagnose(pathToken.Position, Diagnostics::importFailed, path); + GetSink(context)->diagnose(pathToken.Position, Diagnostics::noIncludeHandlerSpecified); + return; + } + auto includeResult = includeHandler->TryToFindIncludeFile(path, pathIncludedFrom, &foundPath, &foundSource); + + switch (includeResult) + { + case IncludeResult::NotFound: + case IncludeResult::Error: + GetSink(context)->diagnose(pathToken.Position, Diagnostics::importFailed, path); + return; + + case IncludeResult::Found: + break; + } + + // Do all checking related to the end of this directive before we push a new stream, + // just to avoid complications where that check would need to deal with + // a switch of input stream + expectEndOfDirective(context); + + // TODO: may want to have some kind of canonicalization step here + 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 translationUnit = context->preprocessor->translationUnit; + auto request = translationUnit->compileRequest; + + + // Have we already loaded a module matching this name? + if (request->mapPathToLoadedModule.TryGetValue(moduleKey)) + { + // 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 + { + // We are going to preprocess the file using the *same* preprocessor + // state that is already active. The main alternative would be + // to construct a fresh preprocessor and use that. The current + // choice is made so that macros defined in the imported file + // will be made visible to the importer, rather than disappear + // when a sub-preprocessor gets finalized. + auto preprocessor = context->preprocessor; + + // We need to save/restore the input stream, so that we can + // re-use the preprocessor + PreprocessorInputStream* savedStream = preprocessor->inputStream; + + // Create an input stream for reading from the imported file + PreprocessorInputStream* subInputStream = CreateInputStreamForSource(preprocessor, foundSource, foundPath); + + // Now preprocess that stream + preprocessor->inputStream = subInputStream; + TokenList subTokens = ReadAllTokens(preprocessor); + + // Restore the previous input stream + preprocessor->inputStream = savedStream; + + // Now we need to do something with those tokens we read + request->handlePoundImport( + moduleKey, + subTokens); + } + } + + // Now create a dummy token stream to represent the import request, + // so that it can be manifest in the user's program + SourceTextInputStream* inputStream = new SourceTextInputStream(); + + Token token; + token.Type = TokenType::PoundImport; + token.Position = GetDirectiveLoc(context); + token.flags = 0; + token.Content = foundPath; + + inputStream->lexedTokens.mTokens.Add(token); + + token.Type = TokenType::EndOfFile; + token.flags = TokenFlag::AfterWhitespace | TokenFlag::AtStartOfLine; + inputStream->lexedTokens.mTokens.Add(token); + + inputStream->tokenReader = TokenReader(inputStream->lexedTokens); + + inputStream->parent = context->preprocessor->inputStream; + context->preprocessor->inputStream = inputStream; +} + + + } diff --git a/source/slang/preprocessor.h b/source/slang/preprocessor.h index 0c7848bb4..d23b19773 100644 --- a/source/slang/preprocessor.h +++ b/source/slang/preprocessor.h @@ -7,16 +7,15 @@ namespace Slang { -class CompileRequest; class DiagnosticSink; class ProgramSyntaxNode; +class TranslationUnitRequest; enum class IncludeResult { Error, NotFound, - FoundIncludeFile, - FoundAutoImportFile, + Found, }; // Callback interface for the preprocessor to use when looking @@ -36,9 +35,8 @@ TokenList preprocessSource( String const& fileName, DiagnosticSink* sink, IncludeHandler* includeHandler, - Dictionary<String, String> defines, - ProgramSyntaxNode* syntax, - CompileRequest* compileRequest); + Dictionary<String, String> defines, + TranslationUnitRequest* translationUnit); } // namespace Slang diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index fc18ea1cf..cd48a4152 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -103,21 +103,7 @@ struct IncludeHandlerImpl : IncludeHandler request->mDependencyFilePaths.Add(path); - // HACK(tfoley): We might have found the file in the same directory, - // but what if this is also inside an auto-import path? - for (auto & dir : request->searchDirectories) - { - // Only consider auto-import paths - if(dir.kind != SearchDirectory::Kind::AutoImport) - continue; - - String otherPath = Path::Combine(dir.path, pathToInclude); - - if(otherPath == path) - return IncludeResult::FoundAutoImportFile; - } - - return IncludeResult::FoundIncludeFile; + return IncludeResult::Found; } for (auto & dir : request->searchDirectories) @@ -130,14 +116,7 @@ struct IncludeHandlerImpl : IncludeHandler request->mDependencyFilePaths.Add(path); - switch( dir.kind ) - { - case SearchDirectory::Kind::Default: - return IncludeResult::FoundIncludeFile; - - case SearchDirectory::Kind::AutoImport: - return IncludeResult::FoundAutoImportFile; - } + return IncludeResult::Found; } } return IncludeResult::NotFound; @@ -188,8 +167,7 @@ void CompileRequest::parseTranslationUnit( &mSink, &includeHandler, combinedPreprocessorDefinitions, - translationUnitSyntax.Ptr(), - this); + translationUnit); parseSourceFile( translationUnit, @@ -419,28 +397,52 @@ RefPtr<ProgramSyntaxNode> CompileRequest::loadModule( RefPtr<ProgramSyntaxNode> moduleDecl = translationUnit->SyntaxNode; - loadedModulesMap.Add(name, moduleDecl); + mapPathToLoadedModule.Add(path, moduleDecl); + mapNameToLoadedModules.Add(name, moduleDecl); loadedModulesList.Add(moduleDecl); return moduleDecl; } -String CompileRequest::autoImportModule( +void CompileRequest::handlePoundImport( String const& path, - String const& source, - CodePosition const& loc) + TokenList const& tokens) { - // TODO: may want to have some kind of canonicalization step here - String name = path; + RefPtr<TranslationUnitRequest> translationUnit = new TranslationUnitRequest(); + translationUnit->compileRequest = this; - // Have we already loaded a module matching this name? - if (loadedModulesMap.TryGetValue(name)) - return name; + // Imported code is always native Slang code + RefPtr<Scope> languageScope = mSession->slangLanguageScope; + + RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode(); + translationUnit->SyntaxNode = translationUnitSyntax; + + parseSourceFile( + translationUnit.Ptr(), + tokens, + &mSink, + path, + languageScope); + + // TODO: handle errors + + checkTranslationUnit(translationUnit.Ptr()); - loadModule(name, path, source, loc); + // Skip code generation + + // + + RefPtr<ProgramSyntaxNode> moduleDecl = translationUnit->SyntaxNode; + + // 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); - return name; + mapPathToLoadedModule.Add(path, moduleDecl); + loadedModulesList.Add(moduleDecl); } RefPtr<ProgramSyntaxNode> CompileRequest::findOrImportModule( @@ -450,7 +452,7 @@ RefPtr<ProgramSyntaxNode> CompileRequest::findOrImportModule( // Have we already loaded a module matching this name? // If so, return it. RefPtr<ProgramSyntaxNode> moduleDecl; - if (loadedModulesMap.TryGetValue(name, moduleDecl)) + if (mapNameToLoadedModules.TryGetValue(name, moduleDecl)) return moduleDecl; // Derive a file name for the module, by taking the given @@ -489,7 +491,7 @@ RefPtr<ProgramSyntaxNode> CompileRequest::findOrImportModule( { this->mSink.diagnose(loc, Diagnostics::cannotFindFile, fileName); - loadedModulesMap[name] = nullptr; + mapNameToLoadedModules[name] = nullptr; return nullptr; } break; @@ -498,6 +500,11 @@ RefPtr<ProgramSyntaxNode> 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( @@ -515,15 +522,6 @@ RefPtr<ProgramSyntaxNode> findOrImportModule( return request->findOrImportModule(name, loc); } -String autoImportModule( - CompileRequest* request, - String const& path, - String const& source, - CodePosition const& loc) -{ - return request->autoImportModule(path, source, loc); -} - void Session::addBuiltinSource( RefPtr<Scope> const& scope, String const& path, @@ -674,14 +672,7 @@ SLANG_API void spAddSearchPath( SlangCompileRequest* request, const char* path) { - REQ(request)->searchDirectories.Add(Slang::SearchDirectory(path, Slang::SearchDirectory::Kind::Default)); -} - -SLANG_API void spAddAutoImportPath( - SlangCompileRequest* request, - const char* path) -{ - REQ(request)->searchDirectories.Add(Slang::SearchDirectory(path, Slang::SearchDirectory::Kind::AutoImport)); + REQ(request)->searchDirectories.Add(Slang::SearchDirectory(path)); } SLANG_API void spAddPreprocessorDefine( diff --git a/source/slang/token-defs.h b/source/slang/token-defs.h index f7800de55..0fe833e36 100644 --- a/source/slang/token-defs.h +++ b/source/slang/token-defs.h @@ -30,7 +30,7 @@ TOKEN(NewLine, "newline") TOKEN(LineComment, "line comment") TOKEN(BlockComment, "block comment") -TOKEN(AutoImport, "automatic import directive") +TOKEN(PoundImport, "'#import'") #define PUNCTUATION(id, text) \ TOKEN(id, "'" text "'") diff --git a/tests/preprocessor/import.hlsl b/tests/preprocessor/import.hlsl new file mode 100644 index 000000000..486023678 --- /dev/null +++ b/tests/preprocessor/import.hlsl @@ -0,0 +1,18 @@ +//TEST:SIMPLE:-profile vs_5_0 + +// Confirm that `#import` interacts with preprocessor as expected + +// Here is a macro that flows from parent to child file +#define FOO float + +// Here we import the child file +#import "import.slang.h" + +// Here we use a macro that flows the other way (child->parent) +BAR g( FOO x ) { return f(x); } + +// Here we confirm that importing the file again is a no-op +#import "import.slang.h" + +void main() +{} diff --git a/tests/preprocessor/import.slang.h b/tests/preprocessor/import.slang.h new file mode 100644 index 000000000..a97a199f0 --- /dev/null +++ b/tests/preprocessor/import.slang.h @@ -0,0 +1,12 @@ +// Confirm that `#import` interacts with preprocessor as expected + +// We add a guard to ensure that this file isn't imported more than once +#ifdef BAR +#error File imported more than one! +#endif + +// Here we use a macro from the parent file +FOO f( FOO y ) { return y; } + +// Here is a macro that flows from child to parent +#define BAR float diff --git a/tests/render/auto-import.hlsl b/tests/render/pound-import.hlsl index 588ebc612..a9b625fb6 100644 --- a/tests/render/auto-import.hlsl +++ b/tests/render/pound-import.hlsl @@ -1,4 +1,4 @@ -//TEST(smoke,render):COMPARE_HLSL_GLSL_RENDER: -xslang -auto-import-dir -xslang tests/render/ +//TEST(smoke,render):COMPARE_HLSL_GLSL_RENDER: // This is a basic test case for cross-compilation behavior. // @@ -8,7 +8,7 @@ // Pull in Spire code depdendency using extended syntax: -#include "auto-import.slang.h" +#import "pound-import.slang.h" #if defined(__HLSL__) diff --git a/tests/render/auto-import.slang.h b/tests/render/pound-import.slang.h index d53005688..d53005688 100644 --- a/tests/render/auto-import.slang.h +++ b/tests/render/pound-import.slang.h |
