diff options
Diffstat (limited to 'source/slang/slang-options.cpp')
| -rw-r--r-- | source/slang/slang-options.cpp | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 977cf322c..ed7775e84 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -802,7 +802,8 @@ void initCommandOptions(CommandOptions& options) {OptionKind::VerifyDebugSerialIr, "-verify-debug-serial-ir", nullptr, - "Verify IR in the front-end."}}; + "Verify IR in the front-end."}, + {OptionKind::DumpModule, "-dump-module", nullptr, "Disassemble and print the module IR."}}; _addOptions(makeConstArrayView(debuggingOpts), options); /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Experimental !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ @@ -2949,6 +2950,88 @@ SlangResult OptionsParser::_parse(int argc, char const* const* argv) linkage->m_optionSet.add(OptionKind::BindlessSpaceIndex, (int)index); break; } + case OptionKind::DumpModule: + { + CommandLineArg fileName; + SLANG_RETURN_ON_FAIL(m_reader.expectArg(fileName)); + auto desc = slang::SessionDesc(); + ComPtr<slang::ISession> session; + m_session->createSession(desc, session.writeRef()); + ComPtr<slang::IBlob> diagnostics; + + // Coerce Slang to load from the given file, without letting it automatically + // choose .slang-module files over .slang files. + // First try to load as source string, and fall back to loading as an IR Blob. + // Avoid guessing based on filename or inspecting the file contents. + FileStream file; + if (SLANG_FAILED(file.init( + fileName.value, + FileMode::Open, + FileAccess::Read, + FileShare::None))) + { + m_sink->diagnose(arg.loc, Diagnostics::cannotOpenFile, fileName.value); + return SLANG_FAIL; + } + + List<uint8_t> buffer; + file.seek(SeekOrigin::End, 0); + const Int64 size = file.getPosition(); + buffer.setCount(size + 1); + file.seek(SeekOrigin::Start, 0); + SLANG_RETURN_ON_FAIL(file.readExactly(buffer.getBuffer(), (size_t)size)); + buffer[size] = 0; + file.close(); + + ComPtr<slang::IModule> module; + module = session->loadModuleFromSourceString( + "module", + "path", + (const char*)buffer.getBuffer(), + diagnostics.writeRef()); + if (!module) + { + // Load buffer as an IR blob + ComPtr<slang::IBlob> blob; + blob = RawBlob::create(buffer.getBuffer(), size); + + module = session->loadModuleFromIRBlob( + "module", + "path", + blob, + diagnostics.writeRef()); + } + + if (module) + { + ComPtr<slang::IBlob> disassemblyBlob; + if (SLANG_FAILED(module->disassemble(disassemblyBlob.writeRef()))) + { + m_sink->diagnose(arg.loc, Diagnostics::cannotDisassemble, fileName.value); + return SLANG_FAIL; + } + else + { + // success, print out the disassembly in a way that slang-test can read + m_sink->diagnoseRaw( + Severity::Note, + (const char*)disassemblyBlob->getBufferPointer()); + } + } + else + { + if (diagnostics) + { + m_sink->diagnoseRaw( + Severity::Error, + (const char*)diagnostics->getBufferPointer()); + } + return SLANG_FAIL; + } + + + break; + } default: { // Hmmm, we looked up and produced a valid enum, but it wasn't handled in the |
