summaryrefslogtreecommitdiffstats
path: root/source/slang/slang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang.cpp')
-rw-r--r--source/slang/slang.cpp792
1 files changed, 485 insertions, 307 deletions
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 2f37981c5..1de94bb14 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -2,9 +2,11 @@
#include "../core/slang-io.h"
#include "../slang/slang-stdlib.h"
+#include "parameter-binding.h"
#include "../slang/parser.h"
#include "../slang/preprocessor.h"
#include "../slang/reflection.h"
+#include "syntax-visitors.h"
#include "../slang/type-layout.h"
#ifdef _WIN32
@@ -19,128 +21,142 @@ using namespace CoreLib::Basic;
using namespace CoreLib::IO;
using namespace Slang::Compiler;
-namespace SlangLib
+namespace Slang {
+namespace Compiler {
+
+static void stdlibDiagnosticCallback(
+ char const* message,
+ void* userData)
{
- static void stdlibDiagnosticCallback(
- char const* message,
- void* userData)
- {
- fputs(message, stderr);
- fflush(stderr);
+ fputs(message, stderr);
+ fflush(stderr);
#ifdef WIN32
- OutputDebugStringA(message);
+ OutputDebugStringA(message);
#endif
- }
+}
- class Session
- {
- public:
- bool useCache = false;
- CoreLib::String cacheDir;
+class Session
+{
+public:
+ bool useCache = false;
+ CoreLib::String cacheDir;
- RefPtr<ShaderCompiler> compiler;
+ RefPtr<Scope> slangLanguageScope;
+ RefPtr<Scope> hlslLanguageScope;
+ RefPtr<Scope> glslLanguageScope;
- RefPtr<Scope> slangLanguageScope;
- RefPtr<Scope> hlslLanguageScope;
- RefPtr<Scope> glslLanguageScope;
+ List<RefPtr<ProgramSyntaxNode>> loadedModuleCode;
- List<RefPtr<ProgramSyntaxNode>> loadedModuleCode;
+ Session(bool /*pUseCache*/, CoreLib::String /*pCacheDir*/)
+ {
+ // Initialize global state
+ // TODO: move this into the session instead
+ BasicExpressionType::Init();
- Session(bool /*pUseCache*/, CoreLib::String /*pCacheDir*/)
- {
- compiler = CreateShaderCompiler();
+ // Create scopes for various language builtins.
+ //
+ // TODO: load these on-demand to avoid parsing
+ // stdlib code for languages the user won't use.
- // Create scopes for various language builtins.
- //
- // TODO: load these on-demand to avoid parsing
- // stdlib code for languages the user won't use.
+ slangLanguageScope = new Scope();
- slangLanguageScope = new Scope();
+ hlslLanguageScope = new Scope();
+ hlslLanguageScope->parent = slangLanguageScope;
- hlslLanguageScope = new Scope();
- hlslLanguageScope->parent = slangLanguageScope;
+ glslLanguageScope = new Scope();
+ glslLanguageScope->parent = slangLanguageScope;
- glslLanguageScope = new Scope();
- glslLanguageScope->parent = slangLanguageScope;
+ addBuiltinSource(slangLanguageScope, "stdlib", SlangStdLib::GetCode());
+ addBuiltinSource(glslLanguageScope, "glsl", getGLSLLibraryCode());
+ }
- addBuiltinSource(slangLanguageScope, "stdlib", SlangStdLib::GetCode());
- addBuiltinSource(glslLanguageScope, "glsl", getGLSLLibraryCode());
- }
+ ~Session()
+ {
+ // We need to clean up the strings for the standard library
+ // code that we might have allocated and loaded into static
+ // variables (TODO: don't use `static` variables for this stuff)
- ~Session()
- {
- // We need to clean up the strings for the standard library
- // code that we might have allocated and loaded into static
- // variables (TODO: don't use `static` variables for this stuff)
+ SlangStdLib::Finalize();
- SlangStdLib::Finalize();
+ // Ditto for our type represnetation stuff
- // Ditto for our type represnetation stuff
+ ExpressionType::Finalize();
+ }
- ExpressionType::Finalize();
- }
+ CompileUnit createPredefUnit()
+ {
+ CompileUnit translationUnit;
- CompileUnit createPredefUnit()
- {
- CompileUnit translationUnit;
+ RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode();
- RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode();
+ TranslationUnitOptions translationUnitOptions;
+ translationUnit.options = translationUnitOptions;
+ translationUnit.SyntaxNode = translationUnitSyntax;
- TranslationUnitOptions translationUnitOptions;
- translationUnit.options = translationUnitOptions;
- translationUnit.SyntaxNode = translationUnitSyntax;
+ return translationUnit;
+ }
- return translationUnit;
- }
+ void addBuiltinSource(
+ RefPtr<Scope> const& scope,
+ String const& path,
+ String const& source);
+};
- void addBuiltinSource(
- RefPtr<Scope> const& scope,
- String const& path,
- String const& source);
- };
+struct CompileRequest
+{
+ // Pointer to parent session
+ Session* mSession;
- struct CompileRequest
- {
- // Pointer to parent session
- Session* mSession;
+ // Input options
+ CompileOptions Options;
+
+ // Output stuff
+ DiagnosticSink mSink;
+ String mDiagnosticOutput;
- // Input options
- CompileOptions Options;
+ RefPtr<CollectionOfTranslationUnits> mCollectionOfTranslationUnits;
- // Output stuff
- DiagnosticSink mSink;
- String mDiagnosticOutput;
+ RefPtr<ProgramLayout> mReflectionData;
- RefPtr<CollectionOfTranslationUnits> mCollectionOfTranslationUnits;
+ CompileResult mResult;
- RefPtr<ProgramLayout> mReflectionData;
+ List<String> mDependencyFilePaths;
- CompileResult mResult;
+ CompileRequest(Session* session)
+ : mSession(session)
+ {}
- List<String> mDependencyFilePaths;
+ ~CompileRequest()
+ {}
- CompileRequest(Session* session)
- : mSession(session)
- {}
+ struct IncludeHandlerImpl : IncludeHandler
+ {
+ CompileRequest* request;
- ~CompileRequest()
- {}
+ List<String> searchDirs;
- struct IncludeHandlerImpl : IncludeHandler
+ virtual bool TryToFindIncludeFile(
+ CoreLib::String const& pathToInclude,
+ CoreLib::String const& pathIncludedFrom,
+ CoreLib::String* outFoundPath,
+ CoreLib::String* outFoundSource) override
{
- CompileRequest* request;
+ String path = Path::Combine(Path::GetDirectoryName(pathIncludedFrom), pathToInclude);
+ if (File::Exists(path))
+ {
+ *outFoundPath = path;
+ *outFoundSource = File::ReadAllText(path);
+
+ request->mDependencyFilePaths.Add(path);
- List<String> searchDirs;
+ return true;
+ }
- virtual bool TryToFindIncludeFile(
- CoreLib::String const& pathToInclude,
- CoreLib::String const& pathIncludedFrom,
- CoreLib::String* outFoundPath,
- CoreLib::String* outFoundSource) override
+ for (auto & dir : searchDirs)
{
- String path = Path::Combine(Path::GetDirectoryName(pathIncludedFrom), pathToInclude);
+ path = Path::Combine(dir, pathToInclude);
if (File::Exists(path))
{
*outFoundPath = path;
@@ -150,303 +166,453 @@ namespace SlangLib
return true;
}
+ }
+ return false;
+ }
+ };
- for (auto & dir : searchDirs)
- {
- path = Path::Combine(dir, pathToInclude);
- if (File::Exists(path))
- {
- *outFoundPath = path;
- *outFoundSource = File::ReadAllText(path);
- request->mDependencyFilePaths.Add(path);
+ CompileUnit parseTranslationUnit(
+ TranslationUnitOptions const& translationUnitOptions,
+ CompileOptions& options)
+ {
+ IncludeHandlerImpl includeHandler;
+ includeHandler.request = this;
- return true;
- }
- }
- return false;
- }
- };
+ CompileUnit translationUnit;
+
+ RefPtr<Scope> languageScope;
+ switch (translationUnitOptions.sourceLanguage)
+ {
+ case SourceLanguage::HLSL:
+ languageScope = mSession->hlslLanguageScope;
+ break;
+
+ case SourceLanguage::GLSL:
+ languageScope = mSession->glslLanguageScope;
+ break;
+
+ case SourceLanguage::Slang:
+ default:
+ languageScope = mSession->slangLanguageScope;
+ break;
+ }
+ Dictionary<String, String> preprocessorDefinitions;
+ for(auto& def : options.preprocessorDefinitions)
+ preprocessorDefinitions.Add(def.Key, def.Value);
+ for(auto& def : translationUnitOptions.preprocessorDefinitions)
+ preprocessorDefinitions.Add(def.Key, def.Value);
- CompileUnit parseTranslationUnit(
- TranslationUnitOptions const& translationUnitOptions)
+ RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode();
+
+ for (auto sourceFile : translationUnitOptions.sourceFiles)
{
- auto& options = Options;
+ auto sourceFilePath = sourceFile->path;
+
+ auto searchDirs = options.SearchDirectories;
+ searchDirs.Reverse();
+ searchDirs.Add(Path::GetDirectoryName(sourceFilePath));
+ searchDirs.Reverse();
+ includeHandler.searchDirs = searchDirs;
+
+ String source = sourceFile->content;
+
+ auto tokens = preprocessSource(
+ source,
+ sourceFilePath,
+ mResult.GetErrorWriter(),
+ &includeHandler,
+ preprocessorDefinitions,
+ translationUnitSyntax.Ptr());
+
+ parseSourceFile(
+ translationUnitSyntax.Ptr(),
+ options,
+ tokens,
+ mResult.GetErrorWriter(),
+ sourceFilePath,
+ languageScope);
+ }
- IncludeHandlerImpl includeHandler;
- includeHandler.request = this;
+ translationUnit.options = translationUnitOptions;
+ translationUnit.SyntaxNode = translationUnitSyntax;
- CompileUnit translationUnit;
+ return translationUnit;
+ }
- RefPtr<Scope> languageScope;
- switch( translationUnitOptions.sourceLanguage )
- {
- case SourceLanguage::HLSL:
- languageScope = mSession->hlslLanguageScope;
- break;
-
- case SourceLanguage::GLSL:
- languageScope = mSession->glslLanguageScope;
- break;
-
- case SourceLanguage::Slang:
- default:
- languageScope = mSession->slangLanguageScope;
- break;
- }
+ CompileUnit parseTranslationUnit(
+ TranslationUnitOptions const& translationUnitOptions)
+ {
+ return parseTranslationUnit(translationUnitOptions, Options);
+ }
+ void checkTranslationUnit(
+ CompileUnit& translationUnit,
+ RefPtr<SyntaxVisitor> visitor)
+ {
+ visitor->setSourceLanguage(translationUnit.options.sourceLanguage);
+ translationUnit.SyntaxNode->Accept(visitor.Ptr());
+ }
- auto& preprocesorDefinitions = options.PreprocessorDefinitions;
+ void checkTranslationUnit(
+ CompileUnit& translationUnit,
+ CompileOptions& options)
+ {
+ RefPtr<SyntaxVisitor> visitor = CreateSemanticsVisitor(
+ mResult.GetErrorWriter(),
+ options,
+ this);
- RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode();
+ checkTranslationUnit(translationUnit, visitor);
+ }
- for( auto sourceFile : translationUnitOptions.sourceFiles )
- {
- auto sourceFilePath = sourceFile->path;
+ void checkCollectionOfTranslationUnits(
+ RefPtr<CollectionOfTranslationUnits> collectionOfTranslationUnits)
+ {
+ RefPtr<SyntaxVisitor> visitor = CreateSemanticsVisitor(
+ mResult.GetErrorWriter(),
+ Options,
+ this);
+
+ for( auto& translationUnit : collectionOfTranslationUnits->translationUnits )
+ {
+ checkTranslationUnit(translationUnit, visitor);
+ }
+ }
- auto searchDirs = options.SearchDirectories;
- searchDirs.Reverse();
- searchDirs.Add(Path::GetDirectoryName(sourceFilePath));
- searchDirs.Reverse();
- includeHandler.searchDirs = searchDirs;
+ void generateOutputForCollectionOfTranslationUnits(
+ RefPtr<CollectionOfTranslationUnits> collectionOfTranslationUnits)
+ {
+ // Do binding generation, and then reflection (globally)
+ // before we move on to any code-generation activites.
+ GenerateParameterBindings(collectionOfTranslationUnits.Ptr());
- String source = sourceFile->content;
- auto tokens = preprocessSource(
- source,
- sourceFilePath,
- mResult.GetErrorWriter(),
- &includeHandler,
- preprocesorDefinitions,
- translationUnitSyntax.Ptr());
-
- parseSourceFile(
- translationUnitSyntax.Ptr(),
- options,
- tokens,
- mResult.GetErrorWriter(),
- sourceFilePath,
- languageScope);
- }
+ // HACK(tfoley): for right now I just want to pretty-print an AST
+ // into another language, so the whole compiler back-end is just
+ // getting in the way.
+ //
+ // I'm going to bypass it for now and see what I can do:
- translationUnit.options = translationUnitOptions;
- translationUnit.SyntaxNode = translationUnitSyntax;
+ ExtraContext extra;
+ extra.options = &Options;
+ extra.programLayout = collectionOfTranslationUnits->layout.Ptr();
+ extra.compileResult = &mResult;
- return translationUnit;
- }
+ generateOutput(extra, collectionOfTranslationUnits.Ptr());
+ }
- int executeCompilerDriverActions()
+ int executeCompilerDriverActions()
+ {
+ // If we are being asked to do pass-through, then we need to do that here...
+ if (Options.passThrough != PassThroughMode::None)
{
- // If we are being asked to do pass-through, then we need to do that here...
- if (Options.passThrough != PassThroughMode::None)
+ for (auto& translationUnitOptions : Options.translationUnits)
{
- for( auto& translationUnitOptions : Options.translationUnits )
+ switch (translationUnitOptions.sourceLanguage)
{
- switch( translationUnitOptions.sourceLanguage )
- {
// We can pass-through code written in a native shading language
- case SourceLanguage::GLSL:
- case SourceLanguage::HLSL:
- break;
+ case SourceLanguage::GLSL:
+ case SourceLanguage::HLSL:
+ break;
// All other translation units need to be skipped
- default:
- continue;
- }
-
- auto sourceFile = translationUnitOptions.sourceFiles[0];
- auto sourceFilePath = sourceFile->path;
- String source = sourceFile->content;
-
- mSession->compiler->PassThrough(
- source,
- sourceFilePath,
- Options,
- translationUnitOptions);
+ default:
+ continue;
}
- return 0;
- }
- // TODO: load the stdlib
+ auto sourceFile = translationUnitOptions.sourceFiles[0];
+ auto sourceFilePath = sourceFile->path;
+ String source = sourceFile->content;
- mCollectionOfTranslationUnits = new CollectionOfTranslationUnits();
+ auto translationUnitResult = passThrough(
+ source,
+ sourceFilePath,
+ Options,
+ translationUnitOptions);
- // Parse everything from the input files requested
- //
- // TODO: this may trigger the loading and/or compilation of additional modules.
- for( auto& translationUnitOptions : Options.translationUnits )
- {
- auto translationUnit = parseTranslationUnit(translationUnitOptions);
- mCollectionOfTranslationUnits->translationUnits.Add(translationUnit);
+ mResult.translationUnits.Add(translationUnitResult);
}
- if( mResult.GetErrorCount() != 0 )
- return 1;
-
- // Now perform semantic checks, emit output, etc.
- mSession->compiler->Compile(
- mResult, mCollectionOfTranslationUnits.Ptr(), Options);
- if(mResult.GetErrorCount() != 0)
- return 1;
-
- mReflectionData = mCollectionOfTranslationUnits->layout;
-
return 0;
}
- // Act as expected of the API-based compiler
- int executeAPIActions()
- {
- mResult.mSink = &mSink;
-
- int err = executeCompilerDriverActions();
+ // TODO: load the stdlib
- mDiagnosticOutput = mSink.outputBuffer.ProduceString();
+ mCollectionOfTranslationUnits = new CollectionOfTranslationUnits();
- if(mSink.GetErrorCount() != 0)
- return mSink.GetErrorCount();
-
- return err;
+ // Parse everything from the input files requested
+ //
+ // TODO: this may trigger the loading and/or compilation of additional modules.
+ for (auto& translationUnitOptions : Options.translationUnits)
+ {
+ auto translationUnit = parseTranslationUnit(translationUnitOptions);
+ mCollectionOfTranslationUnits->translationUnits.Add(translationUnit);
}
+ if (mResult.GetErrorCount() != 0)
+ return 1;
- int addTranslationUnit(SourceLanguage language, String const& name)
- {
- int result = Options.translationUnits.Count();
+ // Perform semantic checking on the whole collection
+ checkCollectionOfTranslationUnits(mCollectionOfTranslationUnits);
+ if (mResult.GetErrorCount() != 0)
+ return 1;
- TranslationUnitOptions translationUnit;
- translationUnit.sourceLanguage = SourceLanguage(language);
+ // Generate output code, in whatever format was requested
+ generateOutputForCollectionOfTranslationUnits(mCollectionOfTranslationUnits);
+ if (mResult.GetErrorCount() != 0)
+ return 1;
- Options.translationUnits.Add(translationUnit);
+ // Extract the reflection layout information so that users
+ // can easily query it.
+ mReflectionData = mCollectionOfTranslationUnits->layout;
- return result;
- }
+ return 0;
+ }
- void addTranslationUnitSourceString(
- int translationUnitIndex,
- String const& path,
- String const& source)
- {
- RefPtr<SourceFile> sourceFile = new SourceFile();
- sourceFile->path = path;
- sourceFile->content = source;
+ // Act as expected of the API-based compiler
+ int executeAPIActions()
+ {
+ mResult.mSink = &mSink;
- Options.translationUnits[translationUnitIndex].sourceFiles.Add(sourceFile);
- }
+ int err = executeCompilerDriverActions();
- void addTranslationUnitSourceFile(
- int translationUnitIndex,
- String const& path)
- {
- String source;
- try
- {
- source = File::ReadAllText(path);
- }
- catch( ... )
- {
- // Emit a diagnostic!
- mSink.diagnose(
- CodePosition(0,0,0,path),
- Diagnostics::cannotOpenFile,
- path);
- return;
- }
+ mDiagnosticOutput = mSink.outputBuffer.ProduceString();
- addTranslationUnitSourceString(
- translationUnitIndex,
- path,
- source);
+ if (mSink.GetErrorCount() != 0)
+ return mSink.GetErrorCount();
- mDependencyFilePaths.Add(path);
- }
+ return err;
+ }
- int addTranslationUnitEntryPoint(
- int translationUnitIndex,
- String const& name,
- Profile profile)
- {
- EntryPointOption entryPoint;
- entryPoint.name = name;
- entryPoint.profile = profile;
+ int addTranslationUnit(SourceLanguage language, String const& name)
+ {
+ int result = Options.translationUnits.Count();
- // TODO: realistically want this to be global across all TUs...
- int result = Options.translationUnits[translationUnitIndex].entryPoints.Count();
+ TranslationUnitOptions translationUnit;
+ translationUnit.sourceLanguage = SourceLanguage(language);
- Options.translationUnits[translationUnitIndex].entryPoints.Add(entryPoint);
- return result;
- }
- };
+ Options.translationUnits.Add(translationUnit);
- void Session::addBuiltinSource(
- RefPtr<Scope> const& scope,
- String const& path,
- String const& source)
+ return result;
+ }
+
+ void addTranslationUnitSourceString(
+ int translationUnitIndex,
+ String const& path,
+ String const& source)
{
- CompileRequest compileRequest(this);
+ RefPtr<SourceFile> sourceFile = new SourceFile();
+ sourceFile->path = path;
+ sourceFile->content = source;
- auto translationUnitIndex = compileRequest.addTranslationUnit(SourceLanguage::Slang, path);
+ Options.translationUnits[translationUnitIndex].sourceFiles.Add(sourceFile);
+ }
- compileRequest.addTranslationUnitSourceString(
+ void addTranslationUnitSourceFile(
+ int translationUnitIndex,
+ String const& path)
+ {
+ String source;
+ try
+ {
+ source = File::ReadAllText(path);
+ }
+ catch (...)
+ {
+ // Emit a diagnostic!
+ mSink.diagnose(
+ CodePosition(0, 0, 0, path),
+ Diagnostics::cannotOpenFile,
+ path);
+ return;
+ }
+
+ addTranslationUnitSourceString(
translationUnitIndex,
path,
source);
- int err = compileRequest.executeAPIActions();
- if(err)
- {
- fprintf(stderr, "%s", compileRequest.mDiagnosticOutput.Buffer());
+ mDependencyFilePaths.Add(path);
+ }
-#ifdef _WIN32
- OutputDebugStringA(compileRequest.mDiagnosticOutput.Buffer());
-#endif
+ int addTranslationUnitEntryPoint(
+ int translationUnitIndex,
+ String const& name,
+ Profile profile)
+ {
+ EntryPointOption entryPoint;
+ entryPoint.name = name;
+ entryPoint.profile = profile;
- assert(!"error in stdlib");
- }
+ // TODO: realistically want this to be global across all TUs...
+ int result = Options.translationUnits[translationUnitIndex].entryPoints.Count();
+
+ Options.translationUnits[translationUnitIndex].entryPoints.Add(entryPoint);
+ return result;
+ }
- // Extract the AST for the code we just parsed
- auto syntax = compileRequest.mCollectionOfTranslationUnits->translationUnits[translationUnitIndex].SyntaxNode;
+ Dictionary<String, RefPtr<ProgramSyntaxNode>> loadedModules;
- // HACK(tfoley): mark all declarations in the "stdlib" so
- // that we can detect them later (e.g., so we don't emit them)
- for (auto m : syntax->Members)
+ RefPtr<ProgramSyntaxNode> findOrImportModule(
+ String const& name,
+ CodePosition const& loc)
+ {
+ // Have we already loaded a module matching this name?
+ // If so, return it.
+ RefPtr<ProgramSyntaxNode> moduleDecl;
+ if (loadedModules.TryGetValue(name, moduleDecl))
+ return moduleDecl;
+
+ // Derive a file name for the module, by taking the given
+ // identifier, replacing all occurences of `_` with `-`,
+ // and then appending `.slang`.
+ //
+ // For example, `foo_bar` becomes `foo-bar.slang`.
+
+ StringBuilder sb;
+ for (auto c : name)
{
- auto fromStdLibModifier = new FromStdLibModifier();
+ if (c == '_')
+ c = '-';
- fromStdLibModifier->next = m->modifiers.first;
- m->modifiers.first = fromStdLibModifier;
+ sb.Append(c);
}
+ sb.Append(".slang");
- // Add the resulting code to the appropriate scope
- if( !scope->containerDecl )
- {
- // We are the first chunk of code to be loaded for this scope
- scope->containerDecl = syntax.Ptr();
- }
- else
+ String fileName = sb.ProduceString();
+
+ // Next, try to find the file of the given name,
+ // using our ordinary include-handling logic.
+
+ IncludeHandlerImpl includeHandler;
+ includeHandler.request = this;
+
+ String pathIncludedFrom = loc.FileName;
+
+ String foundPath;
+ String foundSource;
+ bool found = includeHandler.TryToFindIncludeFile(fileName, pathIncludedFrom, &foundPath, &foundSource);
+ if (!found)
{
- // We need to create a new scope to link into the whole thing
- auto subScope = new Scope();
- subScope->containerDecl = syntax.Ptr();
- subScope->nextSibling = scope->nextSibling;
- scope->nextSibling = subScope;
+ this->mSink.diagnose(loc, Diagnostics::cannotFindFile, fileName);
+
+ loadedModules[name] = nullptr;
+ return nullptr;
}
- // We need to retain this AST so that we can use it in other code
- // (Note that the `Scope` type does not retain the AST it points to)
- loadedModuleCode.Add(syntax);
+ // We've found a file that we can load for the given module, so
+ // now we need to try compiling it, etc.
+
+ // We don't want to use the same options that the user specified
+ // for loading modules on-demand. In particular, we always want
+ // semantic checking to be enabled.
+ CompileOptions moduleOptions;
+ moduleOptions.SearchDirectories = Options.SearchDirectories;
+ moduleOptions.profile = Options.profile;
+
+ RefPtr<SourceFile> sourceFile = new SourceFile();
+ sourceFile->path = foundPath;
+ sourceFile->content = foundSource;
+
+ TranslationUnitOptions translationUnitOptions;
+ translationUnitOptions.sourceFiles.Add(sourceFile);
+
+ CompileUnit translationUnit = parseTranslationUnit(translationUnitOptions, moduleOptions);
+
+ // TODO: handle errors
+
+ checkTranslationUnit(translationUnit, moduleOptions);
+
+ // Skip code generation
+
+ //
+
+ moduleDecl = translationUnit.SyntaxNode;
+
+ loadedModules.Add(name, moduleDecl);
+
+ return moduleDecl;
}
+
+};
+
+RefPtr<ProgramSyntaxNode> findOrImportModule(
+ CompileRequest* request,
+ String const& name,
+ CodePosition const& loc)
+{
+ return request->findOrImportModule(name, loc);
}
-using namespace SlangLib;
+void Session::addBuiltinSource(
+ RefPtr<Scope> const& scope,
+ String const& path,
+ String const& source)
+{
+ CompileRequest compileRequest(this);
+
+ auto translationUnitIndex = compileRequest.addTranslationUnit(SourceLanguage::Slang, path);
+
+ compileRequest.addTranslationUnitSourceString(
+ translationUnitIndex,
+ path,
+ source);
+
+ int err = compileRequest.executeAPIActions();
+ if (err)
+ {
+ fprintf(stderr, "%s", compileRequest.mDiagnosticOutput.Buffer());
+
+#ifdef _WIN32
+ OutputDebugStringA(compileRequest.mDiagnosticOutput.Buffer());
+#endif
+
+ assert(!"error in stdlib");
+ }
+
+ // Extract the AST for the code we just parsed
+ auto syntax = compileRequest.mCollectionOfTranslationUnits->translationUnits[translationUnitIndex].SyntaxNode;
+
+ // HACK(tfoley): mark all declarations in the "stdlib" so
+ // that we can detect them later (e.g., so we don't emit them)
+ for (auto m : syntax->Members)
+ {
+ auto fromStdLibModifier = new FromStdLibModifier();
+
+ fromStdLibModifier->next = m->modifiers.first;
+ m->modifiers.first = fromStdLibModifier;
+ }
+
+ // Add the resulting code to the appropriate scope
+ if (!scope->containerDecl)
+ {
+ // We are the first chunk of code to be loaded for this scope
+ scope->containerDecl = syntax.Ptr();
+ }
+ else
+ {
+ // We need to create a new scope to link into the whole thing
+ auto subScope = new Scope();
+ subScope->containerDecl = syntax.Ptr();
+ subScope->nextSibling = scope->nextSibling;
+ scope->nextSibling = subScope;
+ }
+
+ // We need to retain this AST so that we can use it in other code
+ // (Note that the `Scope` type does not retain the AST it points to)
+ loadedModuleCode.Add(syntax);
+}
+
+}}
// implementation of C interface
-#define SESSION(x) reinterpret_cast<SlangLib::Session *>(x)
-#define REQ(x) reinterpret_cast<SlangLib::CompileRequest*>(x)
+#define SESSION(x) reinterpret_cast<Slang::Compiler::Session *>(x)
+#define REQ(x) reinterpret_cast<Slang::Compiler::CompileRequest*>(x)
SLANG_API SlangSession* spCreateSession(const char * cacheDir)
{
- return reinterpret_cast<SlangSession *>(new SlangLib::Session((cacheDir ? true : false), cacheDir));
+ return reinterpret_cast<SlangSession *>(new Slang::Compiler::Session((cacheDir ? true : false), cacheDir));
}
SLANG_API void spDestroySession(
@@ -476,7 +642,7 @@ SLANG_API SlangCompileRequest* spCreateCompileRequest(
SlangSession* session)
{
auto s = SESSION(session);
- auto req = new SlangLib::CompileRequest(s);
+ auto req = new Slang::Compiler::CompileRequest(s);
return reinterpret_cast<SlangCompileRequest*>(req);
}
@@ -536,7 +702,7 @@ SLANG_API void spAddPreprocessorDefine(
const char* key,
const char* value)
{
- REQ(request)->Options.PreprocessorDefinitions[key] = value;
+ REQ(request)->Options.preprocessorDefinitions[key] = value;
}
SLANG_API char const* spGetDiagnosticOutput(
@@ -561,6 +727,18 @@ SLANG_API int spAddTranslationUnit(
name ? name : "");
}
+SLANG_API void spTranslationUnit_addPreprocessorDefine(
+ SlangCompileRequest* request,
+ int translationUnitIndex,
+ const char* key,
+ const char* value)
+{
+ auto req = REQ(request);
+
+ req->Options.translationUnits[translationUnitIndex].preprocessorDefinitions[key] = value;
+
+}
+
SLANG_API void spAddTranslationUnitSourceFile(
SlangCompileRequest* request,
int translationUnitIndex,