summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-20 13:57:46 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-20 13:57:46 -0700
commitd852ad9fedb71f23b3aa70db0c7b43f6d6fd10e2 (patch)
tree90e3852bd59d99ac875010b371172139ed6cd021 /source
parent4313db822ca468e33c765170c924bf031e5e66a5 (diff)
Only emit each `import`ed module once.
If the user imports a module along more than one path, we need to make sure we don't emit the code twice. I handle this by keeping a set of already-emitted modules. Down the line, a more robust code generation strategy for non-"rewriter" use cases would be handling this at the per-declaration level, and this logic wouldn't really be needed.
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp26
1 files changed, 18 insertions, 8 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 21704f6ff..c531a0a77 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -34,6 +34,8 @@ struct EmitContext
// instead.
Dictionary<String, int> mapGLSLSourcePathToID;
int glslSourceIDCount = 0;
+
+ HashSet<ProgramSyntaxNode*> modulesAlreadyEmitted;
};
//
@@ -2662,16 +2664,24 @@ static void EmitDeclImpl(EmitContext* context, RefPtr<Decl> decl, RefPtr<VarLayo
// When in "rewriter" mode, we need to emit the code of the imported
// module in-place at the `import` site.
- auto moduleDecl = importDecl->importedModuleDecl;
+ auto moduleDecl = importDecl->importedModuleDecl.Ptr();
- // TODO: do we need to modify the code generation environment at
- // all when doing this recursive emit?
- //
- // TODO: what if we import the same module along two different
- // paths? Probably need logic to avoid emitting the same
- // module more than once.
+ // We might import the same module along two different paths,
+ // so we need to be careful to only emit each module once
+ // per output.
+ if(!context->modulesAlreadyEmitted.Contains(moduleDecl))
+ {
+ // Add the module to our set before emitting it, just
+ // in case a circular reference would lead us to
+ // infinite recursion (but that shouldn't be allowed
+ // in the first place).
+ context->modulesAlreadyEmitted.Add(moduleDecl);
- EmitDeclsInContainer(context, moduleDecl);
+ // TODO: do we need to modify the code generation environment at
+ // all when doing this recursive emit?
+
+ EmitDeclsInContainer(context, moduleDecl);
+ }
return;
}