From ccc26c2d22d471ae649bf16f37ed1cd6cfbddd1b Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 12 Jun 2024 09:45:50 -0700 Subject: Extend the COM-based API to support whole program compilation. (#4355) --- source/slang/slang-compiler.h | 31 +++++++++++++++++++++++++- source/slang/slang.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) (limited to 'source/slang') diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 789ac8816..881f511d0 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -309,6 +309,10 @@ namespace Slang SlangInt targetIndex, slang::IBlob** outCode, slang::IBlob** outDiagnostics) SLANG_OVERRIDE; + SLANG_NO_THROW SlangResult SLANG_MCALL getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics = nullptr) SLANG_OVERRIDE; SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( SlangInt entryPointIndex, @@ -602,11 +606,12 @@ namespace Slang Index argCount, DiagnosticSink* sink) SLANG_OVERRIDE; - private: + public: CompositeComponentType( Linkage* linkage, List> const& childComponents); + private: List> m_childComponents; // The following arrays hold the concatenated entry points, parameters, @@ -879,6 +884,14 @@ namespace Slang return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); } + SLANG_NO_THROW SlangResult SLANG_MCALL getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) SLANG_OVERRIDE + { + return Super::getTargetCode(targetIndex, outCode, outDiagnostics); + } + SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( SlangInt entryPointIndex, SlangInt targetIndex, @@ -1112,6 +1125,14 @@ namespace Slang return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); } + SLANG_NO_THROW SlangResult SLANG_MCALL getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) SLANG_OVERRIDE + { + return Super::getTargetCode(targetIndex, outCode, outDiagnostics); + } + SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( SlangInt entryPointIndex, SlangInt targetIndex, @@ -1286,6 +1307,14 @@ namespace Slang return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); } + SLANG_NO_THROW SlangResult SLANG_MCALL getTargetCode( + SlangInt targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) SLANG_OVERRIDE + { + return Super::getTargetCode(targetIndex, outCode, outDiagnostics); + } + SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( SlangInt entryPointIndex, SlangInt targetIndex, diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index f820bf8cd..ede22ec4f 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -4661,6 +4661,57 @@ void ComponentType::enumerateIRModules(EnumerateIRModulesCallback callback, void acceptVisitor(&visitor, nullptr); } +SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getTargetCode( + Int targetIndex, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) +{ + auto linkage = getLinkage(); + if (targetIndex < 0 || targetIndex >= linkage->targets.getCount()) + return SLANG_E_INVALID_ARG; + + // If the user hasn't specified any entry points, then we should + // discover all entrypoints that are defined in linked modules, and + // include all of them in the compile. + // + if (getEntryPointCount() == 0) + { + List modules; + this->enumerateModules([&](Module* module) + { + modules.add(module); + }); + List> components; + components.add(this); + for (auto module : modules) + { + for (auto entryPoint : module->getEntryPoints()) + { + components.add(entryPoint); + } + } + RefPtr composite = new CompositeComponentType(linkage, components); + ComPtr linkedComponentType; + SLANG_RETURN_ON_FAIL(composite->link(linkedComponentType.writeRef(), outDiagnostics)); + return linkedComponentType->getTargetCode(targetIndex, outCode, outDiagnostics); + } + + auto target = linkage->targets[targetIndex]; + auto targetProgram = getTargetProgram(target); + + DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer); + applySettingsToDiagnosticSink(&sink, &sink, linkage->m_optionSet); + applySettingsToDiagnosticSink(&sink, &sink, m_optionSet); + + IArtifact* artifact = targetProgram->getOrCreateWholeProgramResult(&sink); + sink.getBlobIfNeeded(outDiagnostics); + + if (artifact == nullptr) + return SLANG_FAIL; + + return artifact->loadBlob(ArtifactKeep::Yes, outCode); +} + // // CompositeComponentType // -- cgit v1.2.3