summaryrefslogtreecommitdiffstats
path: root/source/slang/check.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-27 10:24:25 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-27 10:24:25 -0700
commit31293d61d3ec80198eab2439ec937d7ba37f6722 (patch)
tree5d58272d219064234c6e90d7271caef5e118a77d /source/slang/check.cpp
parent1716208fb62a7f0a8bbe55e597b582066cb51731 (diff)
Allow for re-export of an `import` declaration
If module `A.slang` contains `__exported __import B;` then any declarations from `B.slang` will be visible to any client code that does `__import A;`. This allows a user to make a single "umbrella" file that encompases a bunch of code files. Note that this really only affects scoping during Slang compilation/checking; at code generation time everything always gets emitted as raw HLSL/GLSL so that names will be visible whether we want them to be or not.
Diffstat (limited to 'source/slang/check.cpp')
-rw-r--r--source/slang/check.cpp47
1 files changed, 31 insertions, 16 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 582f19448..11efb2f7d 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -4893,6 +4893,36 @@ namespace Slang
return expr;
}
+ void importModuleIntoScope(Scope* scope, ProgramSyntaxNode* moduleDecl)
+ {
+ // If we've imported this one already, then
+ // skip the step where we modify the current scope.
+ if (importedModules.Contains(moduleDecl))
+ {
+ return;
+ }
+ importedModules.Add(moduleDecl);
+
+
+ // Create a new sub-scope to wire the module
+ // into our lookup chain.
+ auto subScope = new Scope();
+ subScope->containerDecl = moduleDecl;
+
+ subScope->nextSibling = scope->nextSibling;
+ scope->nextSibling = subScope;
+
+ // Also import any modules from nested `import` declarations
+ // with the `__exported` modifier
+ for (auto importDecl : moduleDecl->getMembersOfType<ImportDecl>())
+ {
+ if (!importDecl->HasModifier<ExportedModifier>())
+ continue;
+
+ importModuleIntoScope(scope, importDecl->importedModuleDecl.Ptr());
+ }
+ }
+
virtual void visitImportDecl(ImportDecl* decl) override
{
if(decl->IsChecked(DeclCheckState::Checked))
@@ -4917,22 +4947,7 @@ 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();
- subScope->containerDecl = importedModuleDecl.Ptr();
-
- subScope->nextSibling = scope->nextSibling;
- scope->nextSibling = subScope;
+ importModuleIntoScope(scope.Ptr(), importedModuleDecl.Ptr());
decl->SetCheckState(DeclCheckState::Checked);
}