diff options
Diffstat (limited to 'source/slang/compiler.cpp')
| -rw-r--r-- | source/slang/compiler.cpp | 857 |
1 files changed, 376 insertions, 481 deletions
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index e78de9133..d02e5d10b 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -53,606 +53,501 @@ namespace Slang // - int compilerInstances = 0; - - class ShaderCompilerImpl : public ShaderCompiler + String EmitHLSL(ExtraContext& context) { - public: - - // Actual context for compilation... :( - struct ExtraContext + if (context.getOptions().passThrough != PassThroughMode::None) { - CompileOptions const* options = nullptr; - TranslationUnitOptions const* translationUnitOptions = nullptr; - - CompileResult* compileResult = nullptr; - - RefPtr<ProgramSyntaxNode> programSyntax; - ProgramLayout* programLayout; - - String sourceText; - String sourcePath; - - CompileOptions const& getOptions() { return *options; } - TranslationUnitOptions const& getTranslationUnitOptions() { return *translationUnitOptions; } - }; - - - String EmitHLSL(ExtraContext& context) + return context.sourceText; + } + else { - if (context.getOptions().passThrough != PassThroughMode::None) - { - return context.sourceText; - } - else - { - // TODO(tfoley): probably need a way to customize the emit logic... - return emitProgram( - context.programSyntax.Ptr(), - context.programLayout, - CodeGenTarget::HLSL); - } + // TODO(tfoley): probably need a way to customize the emit logic... + return emitProgram( + context.programSyntax.Ptr(), + context.programLayout, + CodeGenTarget::HLSL); } + } - String emitGLSLForEntryPoint(ExtraContext& context, EntryPointOption const& entryPoint) + String emitGLSLForEntryPoint(ExtraContext& context, EntryPointOption const& /*entryPoint*/) + { + if (context.getOptions().passThrough != PassThroughMode::None) { - if (context.getOptions().passThrough != PassThroughMode::None) - { - return context.sourceText; - } - else - { - // TODO(tfoley): probably need a way to customize the emit logic... - return emitProgram( - context.programSyntax.Ptr(), - context.programLayout, - CodeGenTarget::GLSL); - } + return context.sourceText; } + else + { + // TODO(tfoley): probably need a way to customize the emit logic... + return emitProgram( + context.programSyntax.Ptr(), + context.programLayout, + CodeGenTarget::GLSL); + } + } - char const* GetHLSLProfileName(Profile profile) + char const* GetHLSLProfileName(Profile profile) + { + switch(profile.raw) { - switch(profile.raw) - { - #define PROFILE(TAG, NAME, STAGE, VERSION) case Profile::TAG: return #NAME; - #include "profile-defs.h" + #define PROFILE(TAG, NAME, STAGE, VERSION) case Profile::TAG: return #NAME; + #include "profile-defs.h" - default: - // TODO: emit an error here! - return "unknown"; - } + default: + // TODO: emit an error here! + return "unknown"; } + } #ifdef _WIN32 - void* GetD3DCompilerDLL() - { - // TODO(tfoley): let user specify version of d3dcompiler DLL to use. - static HMODULE d3dCompiler = LoadLibraryA("d3dcompiler_47"); - // TODO(tfoley): handle case where we can't find it gracefully - assert(d3dCompiler); - return d3dCompiler; - } + void* GetD3DCompilerDLL() + { + // TODO(tfoley): let user specify version of d3dcompiler DLL to use. + static HMODULE d3dCompiler = LoadLibraryA("d3dcompiler_47"); + // TODO(tfoley): handle case where we can't find it gracefully + assert(d3dCompiler); + return d3dCompiler; + } - List<uint8_t> EmitDXBytecodeForEntryPoint( - ExtraContext& context, - EntryPointOption const& entryPoint) + List<uint8_t> EmitDXBytecodeForEntryPoint( + ExtraContext& context, + EntryPointOption const& entryPoint) + { + static pD3DCompile D3DCompile_ = nullptr; + if (!D3DCompile_) { - static pD3DCompile D3DCompile_ = nullptr; - if (!D3DCompile_) - { - HMODULE d3dCompiler = (HMODULE)GetD3DCompilerDLL(); - assert(d3dCompiler); + HMODULE d3dCompiler = (HMODULE)GetD3DCompilerDLL(); + assert(d3dCompiler); - D3DCompile_ = (pD3DCompile)GetProcAddress(d3dCompiler, "D3DCompile"); - assert(D3DCompile_); - } + D3DCompile_ = (pD3DCompile)GetProcAddress(d3dCompiler, "D3DCompile"); + assert(D3DCompile_); + } - // The HLSL compiler will try to "canonicalize" our input file path, - // and we don't want it to do that, because they it won't report - // the same locations on error messages that we would. - // - // To work around that, we prepend a custom `#line` directive. + // The HLSL compiler will try to "canonicalize" our input file path, + // and we don't want it to do that, because they it won't report + // the same locations on error messages that we would. + // + // To work around that, we prepend a custom `#line` directive. - String rawHlslCode = EmitHLSL(context); + String rawHlslCode = EmitHLSL(context); - StringBuilder hlslCodeBuilder; - hlslCodeBuilder << "#line 1 \""; - for(auto c : context.sourcePath) + StringBuilder hlslCodeBuilder; + hlslCodeBuilder << "#line 1 \""; + for(auto c : context.sourcePath) + { + char buffer[] = { c, 0 }; + switch(c) { - char buffer[] = { c, 0 }; - switch(c) - { - default: - hlslCodeBuilder << buffer; - break; + default: + hlslCodeBuilder << buffer; + break; - case '\\': - hlslCodeBuilder << "\\\\"; - } + case '\\': + hlslCodeBuilder << "\\\\"; } - hlslCodeBuilder << "\"\n"; - hlslCodeBuilder << rawHlslCode; - - auto hlslCode = hlslCodeBuilder.ProduceString(); - - ID3DBlob* codeBlob; - ID3DBlob* diagnosticsBlob; - HRESULT hr = D3DCompile_( - hlslCode.begin(), - hlslCode.Length(), - context.sourcePath.begin(), - nullptr, - nullptr, - entryPoint.name.begin(), - GetHLSLProfileName(entryPoint.profile), - 0, - 0, - &codeBlob, - &diagnosticsBlob); - List<uint8_t> data; - if (codeBlob) - { - data.AddRange((uint8_t const*)codeBlob->GetBufferPointer(), (int)codeBlob->GetBufferSize()); - codeBlob->Release(); - } - if (diagnosticsBlob) + } + hlslCodeBuilder << "\"\n"; + hlslCodeBuilder << rawHlslCode; + + auto hlslCode = hlslCodeBuilder.ProduceString(); + + ID3DBlob* codeBlob; + ID3DBlob* diagnosticsBlob; + HRESULT hr = D3DCompile_( + hlslCode.begin(), + hlslCode.Length(), + context.sourcePath.begin(), + nullptr, + nullptr, + entryPoint.name.begin(), + GetHLSLProfileName(entryPoint.profile), + 0, + 0, + &codeBlob, + &diagnosticsBlob); + List<uint8_t> data; + if (codeBlob) + { + data.AddRange((uint8_t const*)codeBlob->GetBufferPointer(), (int)codeBlob->GetBufferSize()); + codeBlob->Release(); + } + if (diagnosticsBlob) + { + // TODO(tfoley): need a better policy for how we translate diagnostics + // back into the Slang world (although we should always try to generate + // HLSL that doesn't produce any diagnostics...) + String diagnostics = (char const*) diagnosticsBlob->GetBufferPointer(); + fprintf(stderr, "%s", diagnostics.begin()); + OutputDebugStringA(diagnostics.begin()); + diagnosticsBlob->Release(); + } + if (FAILED(hr)) + { + // TODO(tfoley): What to do on failure? + } + return data; + } + + List<uint8_t> EmitDXBytecode( + ExtraContext& context) + { + if(context.getTranslationUnitOptions().entryPoints.Count() != 1) + { + if(context.getTranslationUnitOptions().entryPoints.Count() == 0) { - // TODO(tfoley): need a better policy for how we translate diagnostics - // back into the Slang world (although we should always try to generate - // HLSL that doesn't produce any diagnostics...) - String diagnostics = (char const*) diagnosticsBlob->GetBufferPointer(); - fprintf(stderr, "%s", diagnostics.begin()); - OutputDebugStringA(diagnostics.begin()); - diagnosticsBlob->Release(); + // TODO(tfoley): need to write diagnostics into this whole thing... + fprintf(stderr, "no entry point specified\n"); } - if (FAILED(hr)) + else { - // TODO(tfoley): What to do on failure? + fprintf(stderr, "multiple entry points specified\n"); } - return data; + return List<uint8_t>(); } - List<uint8_t> EmitDXBytecode( - ExtraContext& context) + return EmitDXBytecodeForEntryPoint(context, context.getTranslationUnitOptions().entryPoints[0]); + } + + String EmitDXBytecodeAssemblyForEntryPoint( + ExtraContext& context, + EntryPointOption const& entryPoint) + { + static pD3DDisassemble D3DDisassemble_ = nullptr; + if (!D3DDisassemble_) { - if(context.getTranslationUnitOptions().entryPoints.Count() != 1) - { - if(context.getTranslationUnitOptions().entryPoints.Count() == 0) - { - // TODO(tfoley): need to write diagnostics into this whole thing... - fprintf(stderr, "no entry point specified\n"); - } - else - { - fprintf(stderr, "multiple entry points specified\n"); - } - return List<uint8_t>(); - } + HMODULE d3dCompiler = (HMODULE)GetD3DCompilerDLL(); + assert(d3dCompiler); - return EmitDXBytecodeForEntryPoint(context, context.getTranslationUnitOptions().entryPoints[0]); + D3DDisassemble_ = (pD3DDisassemble)GetProcAddress(d3dCompiler, "D3DDisassemble"); + assert(D3DDisassemble_); } - String EmitDXBytecodeAssemblyForEntryPoint( - ExtraContext& context, - EntryPointOption const& entryPoint) + List<uint8_t> dxbc = EmitDXBytecodeForEntryPoint(context, entryPoint); + if (!dxbc.Count()) { - static pD3DDisassemble D3DDisassemble_ = nullptr; - if (!D3DDisassemble_) - { - HMODULE d3dCompiler = (HMODULE)GetD3DCompilerDLL(); - assert(d3dCompiler); - - D3DDisassemble_ = (pD3DDisassemble)GetProcAddress(d3dCompiler, "D3DDisassemble"); - assert(D3DDisassemble_); - } - - List<uint8_t> dxbc = EmitDXBytecodeForEntryPoint(context, entryPoint); - if (!dxbc.Count()) - { - return ""; - } + return ""; + } - ID3DBlob* codeBlob; - HRESULT hr = D3DDisassemble_( - &dxbc[0], - dxbc.Count(), - 0, - nullptr, - &codeBlob); + ID3DBlob* codeBlob; + HRESULT hr = D3DDisassemble_( + &dxbc[0], + dxbc.Count(), + 0, + nullptr, + &codeBlob); - String result; - if (codeBlob) - { - result = String((char const*) codeBlob->GetBufferPointer()); - codeBlob->Release(); - } - if (FAILED(hr)) - { - // TODO(tfoley): need to figure out what to diagnose here... - } - return result; + String result; + if (codeBlob) + { + result = String((char const*) codeBlob->GetBufferPointer()); + codeBlob->Release(); + } + if (FAILED(hr)) + { + // TODO(tfoley): need to figure out what to diagnose here... } + return result; + } - String EmitDXBytecodeAssembly( - ExtraContext& context) + String EmitDXBytecodeAssembly( + ExtraContext& context) + { + if(context.getTranslationUnitOptions().entryPoints.Count() == 0) { - if(context.getTranslationUnitOptions().entryPoints.Count() == 0) - { - // TODO(tfoley): need to write diagnostics into this whole thing... - fprintf(stderr, "no entry point specified\n"); - return ""; - } - - StringBuilder sb; - for (auto entryPoint : context.getTranslationUnitOptions().entryPoints) - { - sb << EmitDXBytecodeAssemblyForEntryPoint(context, entryPoint); - } - return sb.ProduceString(); + // TODO(tfoley): need to write diagnostics into this whole thing... + fprintf(stderr, "no entry point specified\n"); + return ""; } - - HMODULE getGLSLCompilerDLL() + StringBuilder sb; + for (auto entryPoint : context.getTranslationUnitOptions().entryPoints) { - // TODO(tfoley): let user specify version of glslang DLL to use. - static HMODULE glslCompiler = LoadLibraryA("glslang"); - // TODO(tfoley): handle case where we can't find it gracefully - assert(glslCompiler); - return glslCompiler; + sb << EmitDXBytecodeAssemblyForEntryPoint(context, entryPoint); } + return sb.ProduceString(); + } - String emitSPIRVAssemblyForEntryPoint( - ExtraContext& context, - EntryPointOption const& entryPoint) - { - String rawGLSL = emitGLSLForEntryPoint(context, entryPoint); + HMODULE getGLSLCompilerDLL() + { + // TODO(tfoley): let user specify version of glslang DLL to use. + static HMODULE glslCompiler = LoadLibraryA("glslang"); + // TODO(tfoley): handle case where we can't find it gracefully + assert(glslCompiler); + return glslCompiler; + } - static glslang_CompileFunc glslang_compile = nullptr; - if (!glslang_compile) - { - HMODULE glslCompiler = getGLSLCompilerDLL(); - assert(glslCompiler); - glslang_compile = (glslang_CompileFunc)GetProcAddress(glslCompiler, "glslang_compile"); - assert(glslang_compile); - } + String emitSPIRVAssemblyForEntryPoint( + ExtraContext& context, + EntryPointOption const& entryPoint) + { + String rawGLSL = emitGLSLForEntryPoint(context, entryPoint); - StringBuilder diagnosticBuilder; - StringBuilder outputBuilder; + static glslang_CompileFunc glslang_compile = nullptr; + if (!glslang_compile) + { + HMODULE glslCompiler = getGLSLCompilerDLL(); + assert(glslCompiler); - auto outputFunc = [](char const* text, void* userData) - { - *(StringBuilder*)userData << text; - }; + glslang_compile = (glslang_CompileFunc)GetProcAddress(glslCompiler, "glslang_compile"); + assert(glslang_compile); + } - glslang_CompileRequest request; - request.sourcePath = context.sourcePath.begin(); - request.sourceText = rawGLSL.begin(); - request.slangStage = (SlangStage) entryPoint.profile.GetStage(); + StringBuilder diagnosticBuilder; + StringBuilder outputBuilder; - request.diagnosticFunc = outputFunc; - request.diagnosticUserData = &diagnosticBuilder; + auto outputFunc = [](char const* text, void* userData) + { + *(StringBuilder*)userData << text; + }; - request.outputFunc = outputFunc; - request.outputUserData = &outputBuilder; + glslang_CompileRequest request; + request.sourcePath = context.sourcePath.begin(); + request.sourceText = rawGLSL.begin(); + request.slangStage = (SlangStage) entryPoint.profile.GetStage(); - int err = glslang_compile(&request); + request.diagnosticFunc = outputFunc; + request.diagnosticUserData = &diagnosticBuilder; - String diagnostics = diagnosticBuilder.ProduceString(); - String output = outputBuilder.ProduceString(); + request.outputFunc = outputFunc; + request.outputUserData = &outputBuilder; - if(err) - { - OutputDebugStringA(diagnostics.Buffer()); - fprintf(stderr, "%s", diagnostics.Buffer()); - exit(1); - } + int err = glslang_compile(&request); - return output; + String diagnostics = diagnosticBuilder.ProduceString(); + String output = outputBuilder.ProduceString(); + + if(err) + { + OutputDebugStringA(diagnostics.Buffer()); + fprintf(stderr, "%s", diagnostics.Buffer()); + exit(1); } + + return output; + } #endif - String emitSPIRVAssembly( - ExtraContext& context) + String emitSPIRVAssembly( + ExtraContext& context) + { + if(context.getTranslationUnitOptions().entryPoints.Count() == 0) { - if(context.getTranslationUnitOptions().entryPoints.Count() == 0) - { - // TODO(tfoley): need to write diagnostics into this whole thing... - fprintf(stderr, "no entry point specified\n"); - return ""; - } - - StringBuilder sb; - for (auto entryPoint : context.getTranslationUnitOptions().entryPoints) - { - sb << emitSPIRVAssemblyForEntryPoint(context, entryPoint); - } - return sb.ProduceString(); + // TODO(tfoley): need to write diagnostics into this whole thing... + fprintf(stderr, "no entry point specified\n"); + return ""; } - // Do emit logic for a single entry point - EntryPointResult emitEntryPoint(ExtraContext& context, EntryPointOption& entryPoint) + StringBuilder sb; + for (auto entryPoint : context.getTranslationUnitOptions().entryPoints) { - EntryPointResult result; + sb << emitSPIRVAssemblyForEntryPoint(context, entryPoint); + } + return sb.ProduceString(); + } - switch (context.getOptions().Target) + // Do emit logic for a single entry point + EntryPointResult emitEntryPoint(ExtraContext& context, EntryPointOption& entryPoint) + { + EntryPointResult result; + + switch (context.getOptions().Target) + { + case CodeGenTarget::GLSL: { - case CodeGenTarget::GLSL: - { - String code = emitGLSLForEntryPoint(context, entryPoint); - result.outputSource = code; - } - break; + String code = emitGLSLForEntryPoint(context, entryPoint); + result.outputSource = code; + } + break; - case CodeGenTarget::DXBytecode: - { - auto code = EmitDXBytecodeForEntryPoint(context, entryPoint); + case CodeGenTarget::DXBytecode: + { + auto code = EmitDXBytecodeForEntryPoint(context, entryPoint); - // TODO(tfoley): Need to figure out an appropriate interface - // for returning binary code, in addition to source. + // TODO(tfoley): Need to figure out an appropriate interface + // for returning binary code, in addition to source. #if 0 - if (context.compileResult) - { - StringBuilder sb; - sb.Append((char*) code.begin(), code.Count()); + if (context.compileResult) + { + StringBuilder sb; + sb.Append((char*) code.begin(), code.Count()); - String codeString = sb.ProduceString(); - result.outputSource = codeString; - } - else + String codeString = sb.ProduceString(); + result.outputSource = codeString; + } + else #endif + { + int col = 0; + for(auto ii : code) { - int col = 0; - for(auto ii : code) - { - if(col != 0) fputs(" ", stdout); - fprintf(stdout, "%02X", ii); - col++; - if(col == 8) - { - fputs("\n", stdout); - col = 0; - } - } - if(col != 0) + if(col != 0) fputs(" ", stdout); + fprintf(stdout, "%02X", ii); + col++; + if(col == 8) { fputs("\n", stdout); + col = 0; } } - return result; - } - break; - - case CodeGenTarget::DXBytecodeAssembly: - { - String code = EmitDXBytecodeAssemblyForEntryPoint(context, entryPoint); - result.outputSource = code; - } - break; - - case CodeGenTarget::SPIRVAssembly: - { - String code = emitSPIRVAssemblyForEntryPoint(context, entryPoint); - result.outputSource = code; + if(col != 0) + { + fputs("\n", stdout); + } } - break; - - // Note(tfoley): We currently hit this case when compiling the stdlib - case CodeGenTarget::Unknown: - break; - - default: - throw "unimplemented"; + return result; } + break; - return result; - - - } - - TranslationUnitResult emitTranslationUnitEntryPoints(ExtraContext& context) - { - TranslationUnitResult result; - - for (auto& entryPoint : context.getTranslationUnitOptions().entryPoints) + case CodeGenTarget::DXBytecodeAssembly: { - EntryPointResult entryPointResult = emitEntryPoint(context, entryPoint); - - result.entryPoints.Add(entryPointResult); + String code = EmitDXBytecodeAssemblyForEntryPoint(context, entryPoint); + result.outputSource = code; } + break; - // The result for the translation unit will just be the concatenation - // of the results for each entry point. This doesn't actually make - // much sense, but it is good enough for now. - StringBuilder sb; - for (auto& entryPointResult : result.entryPoints) + case CodeGenTarget::SPIRVAssembly: { - sb << entryPointResult.outputSource; + String code = emitSPIRVAssemblyForEntryPoint(context, entryPoint); + result.outputSource = code; } + break; - result.outputSource = sb.ProduceString(); + // Note(tfoley): We currently hit this case when compiling the stdlib + case CodeGenTarget::Unknown: + break; - return result; + default: + throw "unimplemented"; } - // Do emit logic for an entire translation unit, which might - // have zero or more entry points - TranslationUnitResult emitTranslationUnit(ExtraContext& context) - { - // Most of our code generation targets will require us - // to proceed through one entry point at a time, but - // in some cases we can emit an entire translation unit - // in one go. + return result; - switch (context.getOptions().Target) - { - default: - // The default behavior is going to loop over all the entry - // points, and then collect an aggregate result. - return emitTranslationUnitEntryPoints(context); - case CodeGenTarget::HLSL: - // When targetting HLSL, we can emit the entire translation unit - // as a single HLSL program, and include all the entry points. - { - - String hlsl = EmitHLSL(context); - - TranslationUnitResult result; - result.outputSource = hlsl; + } - // Because the user might ask for per-entry-point source, - // we will just attach the same string as the result for - // each entry point. - for( auto& entryPoint : context.getTranslationUnitOptions().entryPoints ) - { - (void)entryPoint; + TranslationUnitResult emitTranslationUnitEntryPoints(ExtraContext& context) + { + TranslationUnitResult result; - EntryPointResult entryPointResult; - entryPointResult.outputSource = hlsl; - result.entryPoints.Add(entryPointResult); - } + for (auto& entryPoint : context.getTranslationUnitOptions().entryPoints) + { + EntryPointResult entryPointResult = emitEntryPoint(context, entryPoint); - return result; - } - break; - } + result.entryPoints.Add(entryPointResult); } - TranslationUnitResult DoNewEmitLogic(ExtraContext& context) + // The result for the translation unit will just be the concatenation + // of the results for each entry point. This doesn't actually make + // much sense, but it is good enough for now. + StringBuilder sb; + for (auto& entryPointResult : result.entryPoints) { - TranslationUnitResult result = emitTranslationUnit(context); - - // As a bit of a hack, we include a mode where we just - // print things to standard output, so that we can see them - // - // TODO(tfoley): Is this path ever needed/used? - if( !context.compileResult ) - { - fprintf(stdout, "%s", result.outputSource.Buffer()); - } - - return result; + sb << entryPointResult.outputSource; } - void DoNewEmitLogic( - ExtraContext& context, - CollectionOfTranslationUnits* collectionOfTranslationUnits) - { - switch (context.getOptions().Target) - { - default: - // For most targets, we will do things per-translation-unit - for( auto translationUnit : collectionOfTranslationUnits->translationUnits ) - { - ExtraContext innerContext = context; - innerContext.translationUnitOptions = &translationUnit.options; - innerContext.programSyntax = translationUnit.SyntaxNode; - innerContext.sourcePath = "slang"; // don't have this any more! - innerContext.sourceText = ""; - - TranslationUnitResult translationUnitResult = DoNewEmitLogic(innerContext); - context.compileResult->translationUnits.Add(translationUnitResult); - } - break; + result.outputSource = sb.ProduceString(); - case CodeGenTarget::ReflectionJSON: - { - String reflectionJSON = emitReflectionJSON(context.programLayout); + return result; + } - // HACK(tfoley): just print it out since that is what people probably expect. - // TODO: need a way to control where output gets routed across all possible targets. - fprintf(stdout, "%s", reflectionJSON.begin()); - } - break; - } - } + // Do emit logic for an entire translation unit, which might + // have zero or more entry points + TranslationUnitResult emitTranslationUnit(ExtraContext& context) + { + // Most of our code generation targets will require us + // to proceed through one entry point at a time, but + // in some cases we can emit an entire translation unit + // in one go. - virtual void Compile( - CompileResult& result, - CollectionOfTranslationUnits* collectionOfTranslationUnits, - const CompileOptions& options) override + switch (context.getOptions().Target) { - RefPtr<SyntaxVisitor> visitor = CreateSemanticsVisitor(result.GetErrorWriter(), options); - try + default: + // The default behavior is going to loop over all the entry + // points, and then collect an aggregate result. + return emitTranslationUnitEntryPoints(context); + + case CodeGenTarget::HLSL: + // When targetting HLSL, we can emit the entire translation unit + // as a single HLSL program, and include all the entry points. { - for( auto& translationUnit : collectionOfTranslationUnits->translationUnits ) - { - visitor->setSourceLanguage(translationUnit.options.sourceLanguage); - translationUnit.SyntaxNode->Accept(visitor.Ptr()); - } - if (result.GetErrorCount() > 0) - return; + String hlsl = EmitHLSL(context); - // Do binding generation, and then reflection (globally) - // before we move on to any code-generation activites. - GenerateParameterBindings(collectionOfTranslationUnits); + TranslationUnitResult result; + result.outputSource = hlsl; + // Because the user might ask for per-entry-point source, + // we will just attach the same string as the result for + // each entry point. + for( auto& entryPoint : context.getTranslationUnitOptions().entryPoints ) + { + (void)entryPoint; - // 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: + EntryPointResult entryPointResult; + entryPointResult.outputSource = hlsl; + result.entryPoints.Add(entryPointResult); + } - ExtraContext extra; - extra.options = &options; - extra.programLayout = collectionOfTranslationUnits->layout.Ptr(); - extra.compileResult = &result; - DoNewEmitLogic(extra, collectionOfTranslationUnits); - } - catch (int) - { + return result; } - catch (...) - { - throw; - } - return; + break; } + } - ShaderCompilerImpl() - { - if (compilerInstances == 0) - { - BasicExpressionType::Init(); - } - compilerInstances++; - } + TranslationUnitResult generateOutput(ExtraContext& context) + { + TranslationUnitResult result = emitTranslationUnit(context); + return result; + } - ~ShaderCompilerImpl() + void generateOutput( + ExtraContext& context, + CollectionOfTranslationUnits* collectionOfTranslationUnits) + { + switch (context.getOptions().Target) { - compilerInstances--; - if (compilerInstances == 0) + default: + // For most targets, we will do things per-translation-unit + for( auto translationUnit : collectionOfTranslationUnits->translationUnits ) { - BasicExpressionType::Finalize(); - SlangStdLib::Finalize(); + ExtraContext innerContext = context; + innerContext.translationUnitOptions = &translationUnit.options; + innerContext.programSyntax = translationUnit.SyntaxNode; + innerContext.sourcePath = "slang"; // don't have this any more! + innerContext.sourceText = ""; + + TranslationUnitResult translationUnitResult = generateOutput(innerContext); + context.compileResult->translationUnits.Add(translationUnitResult); } - } + break; - virtual TranslationUnitResult PassThrough( - String const& sourceText, - String const& sourcePath, - const CompileOptions & options, - TranslationUnitOptions const& translationUnitOptions) override - { - ExtraContext extra; - extra.options = &options; - extra.translationUnitOptions = &translationUnitOptions; - extra.sourcePath = sourcePath; - extra.sourceText = sourceText; + case CodeGenTarget::ReflectionJSON: + { + String reflectionJSON = emitReflectionJSON(context.programLayout); - return DoNewEmitLogic(extra); + // HACK(tfoley): just print it out since that is what people probably expect. + // TODO: need a way to control where output gets routed across all possible targets. + fprintf(stdout, "%s", reflectionJSON.begin()); + } + break; } + } - }; - - ShaderCompiler * CreateShaderCompiler() + TranslationUnitResult passThrough( + String const& sourceText, + String const& sourcePath, + const CompileOptions & options, + TranslationUnitOptions const& translationUnitOptions) { - return new ShaderCompilerImpl(); + ExtraContext extra; + extra.options = &options; + extra.translationUnitOptions = &translationUnitOptions; + extra.sourcePath = sourcePath; + extra.sourceText = sourceText; + + return generateOutput(extra); } } |
