diff --git a/cmake/CompilerFlags.cmake b/cmake/CompilerFlags.cmake index f9b4c86c7d7..ecd4a4e7f16 100644 --- a/cmake/CompilerFlags.cmake +++ b/cmake/CompilerFlags.cmake @@ -214,19 +214,27 @@ function(set_default_compile_options target) ) if(SLANG_ENABLE_ASAN) - add_supported_cxx_flags( - ${target} - PRIVATE - /fsanitize=address - -fsanitize=address - ) - add_supported_cxx_linker_flags( - ${target} - BEFORE - PUBLIC - /INCREMENTAL:NO - -fsanitize=address - ) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # Clang defaults to statically linking the sanitizer runtime (except on macOS/Darwin), + # which is not compatible with `-Wl,--no-undefined`, so we need to use dynamic linking + # instead (`-shared-libsan`). + target_compile_options( + ${target} + PRIVATE -fsanitize=address -shared-libsan + ) + target_link_options( + ${target} + PUBLIC -fsanitize=address -shared-libsan + ) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + target_compile_options(${target} PRIVATE -fsanitize=address) + target_link_options(${target} PUBLIC -fsanitize=address) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + target_compile_options(${target} PRIVATE /fsanitize=address) + target_link_options(${target} PRIVATE /INCREMENTAL:NO) + else() + message(FATAL_ERROR "SLANG_ENABLE_ASAN: unsupported C++ compiler") + endif() endif() if(SLANG_ENABLE_COVERAGE) diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp index 190400f55ad..d0d50e53d50 100644 --- a/source/compiler-core/slang-downstream-compiler.cpp +++ b/source/compiler-core/slang-downstream-compiler.cpp @@ -69,16 +69,39 @@ SlangResult CommandLineDownstreamCompiler::compile( if (!isVersionCompatible(inOptions)) { // Not possible to compile with this version of the interface. + // TODO: Fix other `IDownstreamCompiler::compile` implementations not always writing to + // `outArtifact` when returning early. + const auto targetDesc = ArtifactDescUtil::makeDescForCompileTarget(SLANG_TARGET_UNKNOWN); + auto artifact = ArtifactUtil::createArtifact(targetDesc); + *outArtifact = artifact.detach(); return SLANG_E_NOT_IMPLEMENTED; } CompileOptions options = getCompatibleVersion(&inOptions); + const auto targetDesc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType); - // Copy the command line options - CommandLine cmdLine(m_cmdLine); + // Create the result artifact + auto resultArtifact = ArtifactUtil::createArtifact(targetDesc); - // Work out the ArtifactDesc - const auto targetDesc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType); + // Create the diagnostics + auto diagnostics = ArtifactDiagnostics::create(); + ArtifactUtil::addAssociated(resultArtifact, diagnostics); + + // If Slang was built using Clang or GCC and with sanitizers, the same `-fsanitize=...` flag + // must be used when linking an executable or shared library with a Slang library, or it will + // fail to link. We can't instrument Slang-generated C++ with sanitizers as they might report + // errors that can't be fixed, so we separate compilation and linking into two commands to + // enable sanitizers only during linking. + bool shouldSeparateCompileAndLink = false; + switch (options.targetType) + { + case SLANG_HOST_EXECUTABLE: + case SLANG_SHADER_SHARED_LIBRARY: + case SLANG_SHADER_HOST_CALLABLE: + case SLANG_HOST_SHARED_LIBRARY: + shouldSeparateCompileAndLink = true; + break; + } auto helper = DefaultArtifactHelper::getSingleton(); @@ -95,8 +118,13 @@ SlangResult CommandLineDownstreamCompiler::compile( { // We could use the path to the source, or use the source name/paths as defined on the // artifact For now we just go with a lock file based on "slang-generated". - SLANG_RETURN_ON_FAIL( - helper->createLockFile(asCharSlice(toSlice("slang-generated")), lockFile.writeRef())); + if (SLANG_FAILED(helper->createLockFile( + asCharSlice(toSlice("slang-generated")), + lockFile.writeRef()))) + { + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } auto lockArtifact = Artifact::create( ArtifactDesc::make(ArtifactKind::Base, ArtifactPayload::Lock, ArtifactStyle::None)); @@ -110,17 +138,83 @@ SlangResult CommandLineDownstreamCompiler::compile( options.modulePath = SliceUtil::asTerminatedCharSlice(modulePath); } + // Compile stage if executable or library target: compile source to object code + + ComPtr objectArtifact; + + if (shouldSeparateCompileAndLink) + { + CompileOptions compileOptions = options; + compileOptions.targetType = SLANG_OBJECT_CODE; + + CommandLine compileCmdLine(m_cmdLine); + if (SLANG_FAILED(calcArgs(compileOptions, compileCmdLine))) + { + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } + + List> compileArtifacts; + if (SLANG_FAILED(calcCompileProducts( + compileOptions, + DownstreamProductFlag::All, + lockFile, + compileArtifacts))) + { + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } + + // There should only be one object file (.o/.obj) as artifact + SLANG_ASSERT(compileArtifacts.getCount() == 1); + SLANG_ASSERT(compileArtifacts[0]->getDesc().kind == ArtifactKind::ObjectCode); + objectArtifact = compileArtifacts[0]; + + ExecuteResult compileResult; + if (SLANG_FAILED(ProcessUtil::execute(compileCmdLine, compileResult)) || + SLANG_FAILED(parseOutput(compileResult, diagnostics))) + { + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } + + // If compilation failed, return the diagnostics + if (compileResult.resultCode != 0 || !objectArtifact->exists()) + { + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } + } + + // Link stage if executable or library target, or single-stage compile if object code target + + CommandLine cmdLine(m_cmdLine); + + if (shouldSeparateCompileAndLink) + { + // Pass compiled object to linker + options.sourceArtifacts = makeSlice(objectArtifact.readRef(), 1); + } + // Append command line args to the end of cmdLine using the target specific function for the // specified options - SLANG_RETURN_ON_FAIL(calcArgs(options, cmdLine)); + if (SLANG_FAILED(calcArgs(options, cmdLine))) + { + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } // The 'productArtifact' is the main product produced from the compilation - the // executable/sharedlibrary/object etc ComPtr productArtifact; { List> artifacts; - SLANG_RETURN_ON_FAIL( - calcCompileProducts(options, DownstreamProductFlag::All, lockFile, artifacts)); + if (SLANG_FAILED( + calcCompileProducts(options, DownstreamProductFlag::All, lockFile, artifacts))) + { + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } for (IArtifact* artifact : artifacts) { @@ -139,6 +233,7 @@ SlangResult CommandLineDownstreamCompiler::compile( // Somethings gone wrong if we don't find the main artifact if (!productArtifact) { + *outArtifact = resultArtifact.detach(); return SLANG_FAIL; } @@ -152,7 +247,13 @@ SlangResult CommandLineDownstreamCompiler::compile( } #endif - SLANG_RETURN_ON_FAIL(ProcessUtil::execute(cmdLine, exeRes)); + if (SLANG_FAILED(ProcessUtil::execute(cmdLine, exeRes)) || + SLANG_FAILED(parseOutput(exeRes, diagnostics))) + { + // If the process failed or the output parsing failed, return the diagnostics + *outArtifact = resultArtifact.detach(); + return SLANG_FAIL; + } #if 0 { @@ -209,23 +310,13 @@ SlangResult CommandLineDownstreamCompiler::compile( } } - // Create the result artifact - auto artifact = ArtifactUtil::createArtifact(targetDesc); - - // Createa the diagnostics - auto diagnostics = ArtifactDiagnostics::create(); - - SLANG_RETURN_ON_FAIL(parseOutput(exeRes, diagnostics)); - - ArtifactUtil::addAssociated(artifact, diagnostics); - // Find the rep from the 'main' artifact, we'll just use the same representation on the output // artifact. Sharing is desirable, because the rep owns the file. if (auto fileRep = productArtifact ? findRepresentation(productArtifact) : nullptr) { - artifact->addRepresentation(fileRep); + resultArtifact->addRepresentation(fileRep); } // Add the artifact list if there is anything in it @@ -242,10 +333,10 @@ SlangResult CommandLineDownstreamCompiler::compile( artifactContainer->setChildren(slice.data, slice.count); - artifact->addAssociated(artifactContainer); + resultArtifact->addAssociated(artifactContainer); } - *outArtifact = artifact.detach(); + *outArtifact = resultArtifact.detach(); return SLANG_OK; } diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp index cabb7799650..e41fc144725 100644 --- a/source/compiler-core/slang-gcc-compiler-util.cpp +++ b/source/compiler-core/slang-gcc-compiler-util.cpp @@ -101,6 +101,14 @@ SlangResult GCCDownstreamCompilerUtil::calcVersion( { CommandLine cmdLine; cmdLine.setExecutableLocation(exe); + + return calcVersion(cmdLine, outDesc); +} + +SlangResult GCCDownstreamCompilerUtil::calcVersion( + CommandLine cmdLine, + DownstreamCompilerDesc& outDesc) +{ cmdLine.addArg("-v"); ExecuteResult exeRes; @@ -375,8 +383,7 @@ static SlangResult _parseGCCFamilyLine( SliceAllocator allocator; - diagnostics->reset(); - diagnostics->setRaw(SliceUtil::asCharSlice(exeRes.standardError)); + diagnostics->appendRaw(SliceUtil::asCharSlice(exeRes.standardError)); // We hold in workDiagnostics so as it is more convenient to append to the last with a // continuation also means we don't hold the allocations of building up continuations, just the @@ -603,12 +610,6 @@ static SlangResult _parseGCCFamilyLine( { // Shared library cmdLine.addArg("-shared"); - - if (PlatformUtil::isFamily(PlatformFamily::Unix, platformKind)) - { - // Position independent - cmdLine.addArg("-fPIC"); - } break; } case SLANG_HOST_EXECUTABLE: @@ -620,12 +621,42 @@ static SlangResult _parseGCCFamilyLine( { // Don't link, just produce object file cmdLine.addArg("-c"); + break; } default: break; } + switch (options.targetType) + { + case SLANG_HOST_EXECUTABLE: + case SLANG_SHADER_SHARED_LIBRARY: + case SLANG_SHADER_HOST_CALLABLE: + case SLANG_HOST_SHARED_LIBRARY: + // If Slang was built using Clang or GCC and with sanitizers, the same `-fsanitize=...` flag + // used for Slang must also be used when linking executables and shared libraries that we + // might be trying to link with Slang libraries. +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#if SLANG_CLANG || SLANG_GCC + cmdLine.addArg("-fsanitize=address"); +#endif // SLANG_CLANG || SLANG_GCC +#if SLANG_CLANG + cmdLine.addArg("-shared-libsan"); +#endif // SLANG_CLANG +#endif // __has_feature(address_sanitizer) +#endif // defined(__has_feature) + [[fallthrough]]; + + case SLANG_OBJECT_CODE: + if (PlatformUtil::isFamily(PlatformFamily::Unix, platformKind)) + { + // Position independent + cmdLine.addArg("-fPIC"); + } + } + // Add defines for (const auto& define : options.defines) { @@ -711,13 +742,17 @@ static SlangResult _parseGCCFamilyLine( const UnownedStringSlice path(fileRep->getPath()); libPathPool.add(Path::getParentDirectory(path)); - cmdLine.addPrefixPathArg( - "-l", - ArtifactDescUtil::getBaseNameFromPath(artifact->getDesc(), path)); + if (options.targetType != SLANG_OBJECT_CODE) + { + cmdLine.addPrefixPathArg( + "-l", + ArtifactDescUtil::getBaseNameFromPath(artifact->getDesc(), path)); + } } } if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP && + options.targetType != SLANG_OBJECT_CODE && !PlatformUtil::isFamily(PlatformFamily::Windows, platformKind)) { // Make STD libs available @@ -728,9 +763,12 @@ static SlangResult _parseGCCFamilyLine( for (const auto& libPath : libPathPool.getAdded()) { - // Note that any escaping of the path is handled in the ProcessUtil:: - cmdLine.addArg("-L"); - cmdLine.addArg(libPath); + if (options.targetType != SLANG_OBJECT_CODE) + { + // Note that any escaping of the path is handled in the ProcessUtil:: + cmdLine.addArg("-L"); + cmdLine.addArg(libPath); + } cmdLine.addArg("-F"); cmdLine.addArg(libPath); } @@ -748,13 +786,23 @@ static SlangResult _parseGCCFamilyLine( /* static */ SlangResult GCCDownstreamCompilerUtil::createCompiler( const ExecutableLocation& exe, ComPtr& outCompiler) +{ + CommandLine cmdLine; + cmdLine.setExecutableLocation(exe); + + return createCompiler(cmdLine, outCompiler); +} + +/* static */ SlangResult GCCDownstreamCompilerUtil::createCompiler( + const CommandLine& cmdLine, + ComPtr& outCompiler) { DownstreamCompilerDesc desc; - SLANG_RETURN_ON_FAIL(GCCDownstreamCompilerUtil::calcVersion(exe, desc)); + SLANG_RETURN_ON_FAIL(GCCDownstreamCompilerUtil::calcVersion(cmdLine, desc)); auto compiler = new GCCDownstreamCompiler(desc); ComPtr compilerIntf(compiler); - compiler->m_cmdLine.setExecutableLocation(exe); + compiler->m_cmdLine = cmdLine; outCompiler.swap(compilerIntf); return SLANG_OK; diff --git a/source/compiler-core/slang-gcc-compiler-util.h b/source/compiler-core/slang-gcc-compiler-util.h index e15701f94a9..99ced53f36f 100644 --- a/source/compiler-core/slang-gcc-compiler-util.h +++ b/source/compiler-core/slang-gcc-compiler-util.h @@ -18,6 +18,7 @@ struct GCCDownstreamCompilerUtil : public DownstreamCompilerUtilBase /// Runs the exe, and extracts the version info into outDesc static SlangResult calcVersion(const ExecutableLocation& exe, DownstreamCompilerDesc& outDesc); + static SlangResult calcVersion(CommandLine exe, DownstreamCompilerDesc& outDesc); /// Calculate gcc family compilers (including clang) cmdLine arguments from options static SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine); @@ -37,6 +38,9 @@ struct GCCDownstreamCompilerUtil : public DownstreamCompilerUtilBase static SlangResult createCompiler( const ExecutableLocation& exe, ComPtr& outCompiler); + static SlangResult createCompiler( + const CommandLine& cmdLine, + ComPtr& outCompiler); /// Finds GCC compiler/s and adds them to the set static SlangResult locateGCCCompilers( diff --git a/source/compiler-core/slang-metal-compiler.cpp b/source/compiler-core/slang-metal-compiler.cpp index af455a0f7f8..5e901d5f40b 100644 --- a/source/compiler-core/slang-metal-compiler.cpp +++ b/source/compiler-core/slang-metal-compiler.cpp @@ -16,12 +16,9 @@ class MetalDownstreamCompiler : public DownstreamCompilerBase // to create the inner compiler and wrap it here. // ComPtr cppCompiler; - String executablePath; - MetalDownstreamCompiler(ComPtr& innerCompiler, String path) - : DownstreamCompilerBase(innerCompiler->getDesc()) - , cppCompiler(innerCompiler) - , executablePath(path) + MetalDownstreamCompiler(ComPtr& innerCompiler) + : DownstreamCompilerBase(innerCompiler->getDesc()), cppCompiler(innerCompiler) { } @@ -47,9 +44,10 @@ class MetalDownstreamCompiler : public DownstreamCompilerBase { // Use metal-objdump to disassemble the Metal IR. - ExecutableLocation exeLocation(executablePath, "metal-objdump"); + ExecutableLocation exeLocation("xcrun"); CommandLine cmdLine; cmdLine.setExecutableLocation(exeLocation); + cmdLine.addArg("metal-objdump"); cmdLine.addArg("--disassemble"); ComPtr srcFile; SLANG_RETURN_ON_FAIL(from->requireFile(IArtifact::Keep::No, srcFile.writeRef())); @@ -64,37 +62,19 @@ class MetalDownstreamCompiler : public DownstreamCompilerBase } }; -static SlangResult locateMetalCompiler(const String& path, DownstreamCompilerSet* set) +static SlangResult locateMetalCompiler(DownstreamCompilerSet* set) { ComPtr innerCppCompiler; - ExecutableLocation metalcLocation = ExecutableLocation(path, "metal"); - - String metalSDKPath = path; - -#if defined(SLANG_APPLE_FAMILY) - // Use xcrun command to find the metal compiler. CommandLine xcrunCmdLine; ExecutableLocation xcrunLocation("xcrun"); xcrunCmdLine.setExecutableLocation(xcrunLocation); - xcrunCmdLine.addArg("--sdk"); - xcrunCmdLine.addArg("macosx"); - xcrunCmdLine.addArg("--find"); xcrunCmdLine.addArg("metal"); - ExecuteResult exeRes; - if (SLANG_SUCCEEDED(ProcessUtil::execute(xcrunCmdLine, exeRes))) - { - String metalPath = exeRes.standardOutput.trim(); - metalcLocation = ExecutableLocation(ExecutableLocation::Type::Path, metalPath); - metalSDKPath = Path::getParentDirectory(metalcLocation.m_pathOrName); - } -#endif - SLANG_RETURN_ON_FAIL( - GCCDownstreamCompilerUtil::createCompiler(metalcLocation, innerCppCompiler)); + SLANG_RETURN_ON_FAIL(GCCDownstreamCompilerUtil::createCompiler(xcrunCmdLine, innerCppCompiler)); ComPtr compiler = - ComPtr(new MetalDownstreamCompiler(innerCppCompiler, metalSDKPath)); + ComPtr(new MetalDownstreamCompiler(innerCppCompiler)); set->addCompiler(compiler); return SLANG_OK; } @@ -104,8 +84,9 @@ SlangResult MetalDownstreamCompilerUtil::locateCompilers( ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) { + SLANG_UNUSED(path); SLANG_UNUSED(loader); - return locateMetalCompiler(path, set); + return locateMetalCompiler(set); } } // namespace Slang diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp index a7da11333e5..1361f364c84 100644 --- a/source/compiler-core/slang-visual-studio-compiler-util.cpp +++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp @@ -502,9 +502,7 @@ static SlangResult _parseVisualStudioLine( const ExecuteResult& exeRes, IArtifactDiagnostics* diagnostics) { - diagnostics->reset(); - - diagnostics->setRaw(SliceUtil::asTerminatedCharSlice(exeRes.standardOutput)); + diagnostics->appendRaw(SliceUtil::asTerminatedCharSlice(exeRes.standardOutput)); SliceAllocator allocator; diff --git a/source/core/slang-string.h b/source/core/slang-string.h index 1a45f747bc9..aebecf74f5a 100644 --- a/source/core/slang-string.h +++ b/source/core/slang-string.h @@ -467,7 +467,11 @@ class SLANG_RT_API String friend class StringBuilder; private: - char* getData() const { return m_buffer ? m_buffer->getData() : (char*)""; } + char* getData() const + { + static char empty[] = ""; + return m_buffer ? m_buffer->getData() : empty; + } void ensureUniqueStorageWithCapacity(Index capacity); @@ -658,7 +662,11 @@ class SLANG_RT_API String #endif } } - bool operator==(const char* strbuffer) const { return (strcmp(begin(), strbuffer) == 0); } + bool operator==(const char* strbuffer) const + { + const char* volatile b = begin(); + return (strcmp(b, strbuffer) == 0); + } bool operator==(const String& str) const { return (strcmp(begin(), str.begin()) == 0); } bool operator!=(const char* strbuffer) const { return (strcmp(begin(), strbuffer) != 0); } diff --git a/source/core/slang-zip-file-system.cpp b/source/core/slang-zip-file-system.cpp index 0d3503222d1..6d312cae9d0 100644 --- a/source/core/slang-zip-file-system.cpp +++ b/source/core/slang-zip-file-system.cpp @@ -99,8 +99,8 @@ class ZipFileSystemImpl : public ComBaseObject, void _rebuildMap(); - /// Returns true if the named item is at the index - UnownedStringSlice _getPathAtIndex(Index index); + /// Returns the path of the named item at the index, or an empty string on error + String _getPathAtIndex(Index index); void* getInterface(const Guid& guid); void* getObject(const Guid& guid); @@ -225,7 +225,7 @@ void ZipFileSystemImpl::_rebuildMap() } } -UnownedStringSlice ZipFileSystemImpl::_getPathAtIndex(Index index) +String ZipFileSystemImpl::_getPathAtIndex(Index index) { SLANG_ASSERT(m_mode != Mode::None); @@ -233,10 +233,10 @@ UnownedStringSlice ZipFileSystemImpl::_getPathAtIndex(Index index) // Check it's added at the end if (!mz_zip_reader_file_stat(&m_archive, mz_uint(index), &fileStat)) { - return UnownedStringSlice(); + return String(); } - return UnownedStringSlice(fileStat.m_filename).trim('/'); + return String(UnownedStringSlice(fileStat.m_filename).trim('/')); } void ZipFileSystemImpl::_initReadWrite(mz_zip_archive& outWriter) diff --git a/source/slang-core-module/slang-embedded-core-module-source.cpp b/source/slang-core-module/slang-embedded-core-module-source.cpp index 0e03716cad6..de79be46f30 100644 --- a/source/slang-core-module/slang-embedded-core-module-source.cpp +++ b/source/slang-core-module/slang-embedded-core-module-source.cpp @@ -326,6 +326,15 @@ struct IntrinsicOpInfo #define EMIT_LINE_DIRECTIVE() sb << "#line " << (__LINE__ + 1) << " \"" << path << "\"\n" +#if SLANG_CLANG +// Clang takes around 10 minutes to compile this file with optimizations, with EarlyCSEPass taking +// ~95% of the execution time. Disabling optimizations here reduces the compilation time to seconds +// and has no noticeable impact on run-time performance. These functions are only called once, +// either at build time by slang-bootstrap, or on the first run of the slang-compiler library, +// depending on the value of the SLANG_EMBED_CORE_MODULE CMake option. +#pragma clang optimize off +#endif + ComPtr Session::getCoreLibraryCode() { #if SLANG_EMBED_CORE_MODULE_SOURCE @@ -382,3 +391,7 @@ ComPtr Session::getGLSLLibraryCode() return glslLibraryCode; } } // namespace Slang + +#if SLANG_CLANG +#pragma clang optimize on +#endif diff --git a/source/slang/slang-serialize-ast.cpp b/source/slang/slang-serialize-ast.cpp index 66b701ced83..2ebafb812ad 100644 --- a/source/slang/slang-serialize-ast.cpp +++ b/source/slang/slang-serialize-ast.cpp @@ -1899,8 +1899,8 @@ void writeSerializedModuleAST( // (which is more or less just a pair of pointers, to the two // values described above). // - Fossil::SerialWriter writer(blobBuilder); ASTSerialWriteContext context(moduleDecl, sourceLocWriter); + Fossil::SerialWriter writer(blobBuilder); ASTSerialWriteContext::ASTSerializer serializer(&writer, &context); // Once we have our `serializer`, we can finally invoke diff --git a/source/slang/slang-serialize-ir.cpp b/source/slang/slang-serialize-ir.cpp index 83955cc06cf..cd39057c2ea 100644 --- a/source/slang/slang-serialize-ir.cpp +++ b/source/slang/slang-serialize-ir.cpp @@ -735,8 +735,8 @@ void writeSerializedModuleIR( #else BlobBuilder blobBuilder; { - Fossil::SerialWriter writer(blobBuilder); IRSerialWriteContext context{sourceLocWriter}; + Fossil::SerialWriter writer(blobBuilder); IRWriteSerializer serializer(&writer, &context); serialize(serializer, moduleInfo); } diff --git a/tools/slang-fiddle/slang-fiddle-main.cpp b/tools/slang-fiddle/slang-fiddle-main.cpp index fea16dafe35..9caf44b34b2 100644 --- a/tools/slang-fiddle/slang-fiddle-main.cpp +++ b/tools/slang-fiddle/slang-fiddle-main.cpp @@ -407,7 +407,8 @@ int main(int argc, char const* const* argv) using namespace fiddle; using namespace Slang; - ComPtr writer(new FileWriter(stderr, WriterFlag::AutoFlush)); + ComPtr writer( + new FileWriter(stderr, WriterFlag::IsUnowned | WriterFlag::AutoFlush)); NamePool namePool; diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index 2625119ac00..939a8dba4ed 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -3009,10 +3009,8 @@ static TestResult runCPPCompilerSharedLibrary(TestContext* context, TestInput& i options.modulePath = SliceUtil::asTerminatedCharSlice(modulePath); ComPtr artifact; - if (SLANG_FAILED(compiler->compile(options, artifact.writeRef()))) - { - return TestResult::Fail; - } + // Not checking the result as some tests are supposed to make compilation or linking fail. + compiler->compile(options, artifact.writeRef()); auto diagnostics = findAssociatedRepresentation(artifact); @@ -3139,10 +3137,8 @@ static TestResult runCPPCompilerExecute(TestContext* context, TestInput& input) options.modulePath = SliceUtil::asTerminatedCharSlice(modulePath); ComPtr artifact; - if (SLANG_FAILED(compiler->compile(options, artifact.writeRef()))) - { - return TestResult::Fail; - } + // Not checking the result as some tests are supposed to make compilation or linking fail. + compiler->compile(options, artifact.writeRef()); String actualOutput; diff --git a/tools/slang-unit-test/unit-test-com-host-callable.cpp b/tools/slang-unit-test/unit-test-com-host-callable.cpp index 3d37247b7f8..c057cfc9e9f 100644 --- a/tools/slang-unit-test/unit-test-com-host-callable.cpp +++ b/tools/slang-unit-test/unit-test-com-host-callable.cpp @@ -132,8 +132,11 @@ struct ComTestContext { const SlangPassThrough cppCompilers[] = { SLANG_PASS_THROUGH_VISUAL_STUDIO, - SLANG_PASS_THROUGH_GCC, +#if SLANG_CLANG SLANG_PASS_THROUGH_CLANG, +#else + SLANG_PASS_THROUGH_GCC, +#endif }; // Do we have a C++ compiler for (const auto compiler : cppCompilers) diff --git a/tools/slang-unit-test/unit-test-get-target-code.cpp b/tools/slang-unit-test/unit-test-get-target-code.cpp index 6a9f6ca279b..d66b4385386 100644 --- a/tools/slang-unit-test/unit-test-get-target-code.cpp +++ b/tools/slang-unit-test/unit-test-get-target-code.cpp @@ -33,7 +33,8 @@ SLANG_UNIT_TEST(getTargetCode) String userSource = userSourceBody; ComPtr globalSession; - SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK); + SLANG_CHECK_ABORT( + slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK); slang::TargetDesc targetDesc = {}; // Request SPIR-V disassembly so we can check the content. targetDesc.format = SLANG_SPIRV_ASM; @@ -43,7 +44,7 @@ SLANG_UNIT_TEST(getTargetCode) sessionDesc.targets = &targetDesc; ComPtr session; - SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK); + SLANG_CHECK_ABORT(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK); ComPtr diagnosticBlob; auto module = session->loadModuleFromSourceString( @@ -51,17 +52,17 @@ SLANG_UNIT_TEST(getTargetCode) "m.slang", userSourceBody, diagnosticBlob.writeRef()); - SLANG_CHECK(module != nullptr); + SLANG_CHECK_ABORT(module != nullptr); ComPtr linkedProgram; module->link(linkedProgram.writeRef(), diagnosticBlob.writeRef()); - SLANG_CHECK(linkedProgram != nullptr); + SLANG_CHECK_ABORT(linkedProgram != nullptr); ComPtr code; linkedProgram->getTargetCode(0, code.writeRef(), diagnosticBlob.writeRef()); - SLANG_CHECK(code != nullptr); + SLANG_CHECK_ABORT(code != nullptr); - SLANG_CHECK(code->getBufferSize() != 0); + SLANG_CHECK_ABORT(code->getBufferSize() != 0); UnownedStringSlice resultStr = UnownedStringSlice((char*)code->getBufferPointer()); diff --git a/tools/slang-unit-test/unit-test-separate-debug.cpp b/tools/slang-unit-test/unit-test-separate-debug.cpp index 6ce849b0d0a..49999867bcf 100644 --- a/tools/slang-unit-test/unit-test-separate-debug.cpp +++ b/tools/slang-unit-test/unit-test-separate-debug.cpp @@ -41,7 +41,8 @@ SLANG_UNIT_TEST(separateDebug) )"; String userSource = userSourceBody; ComPtr globalSession; - SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK); + SLANG_CHECK_ABORT( + slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK); // Setup the target descriptor. slang::TargetDesc targetDesc = {}; @@ -67,7 +68,7 @@ SLANG_UNIT_TEST(separateDebug) sessionDesc.compilerOptionEntryCount = 2; ComPtr session; - SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK); + SLANG_CHECK_ABORT(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK); // Compile the module. ComPtr diagnosticBlob; @@ -76,7 +77,7 @@ SLANG_UNIT_TEST(separateDebug) "m.slang", userSourceBody, diagnosticBlob.writeRef()); - SLANG_CHECK(module != nullptr); + SLANG_CHECK_ABORT(module != nullptr); ComPtr entryPoint; module->findAndCheckEntryPoint( @@ -84,7 +85,7 @@ SLANG_UNIT_TEST(separateDebug) SLANG_STAGE_COMPUTE, entryPoint.writeRef(), diagnosticBlob.writeRef()); - SLANG_CHECK(entryPoint != nullptr); + SLANG_CHECK_ABORT(entryPoint != nullptr); ComPtr compositeProgram; slang::IComponentType* components[] = {module, entryPoint.get()}; @@ -93,11 +94,11 @@ SLANG_UNIT_TEST(separateDebug) 2, compositeProgram.writeRef(), diagnosticBlob.writeRef()); - SLANG_CHECK(compositeProgram != nullptr); + SLANG_CHECK_ABORT(compositeProgram != nullptr); ComPtr linkedProgram; compositeProgram->link(linkedProgram.writeRef(), diagnosticBlob.writeRef()); - SLANG_CHECK(linkedProgram != nullptr); + SLANG_CHECK_ABORT(linkedProgram != nullptr); // Use getEntryPointCompileResult to get the base and debug spirv, and metadata // containing the debug build identifier. @@ -110,22 +111,22 @@ SLANG_UNIT_TEST(separateDebug) // to query for it, and then use it to get the results. ComPtr compileResult; ComPtr linkedProgram2; - SLANG_CHECK( + SLANG_CHECK_ABORT( linkedProgram->queryInterface(SLANG_IID_PPV_ARGS(linkedProgram2.writeRef())) == SLANG_OK); auto result = linkedProgram2->getEntryPointCompileResult( 0, 0, compileResult.writeRef(), diagnosticBlob.writeRef()); - SLANG_CHECK(result == SLANG_OK); - SLANG_CHECK(compileResult != nullptr); - SLANG_CHECK(compileResult->getItemCount() == 2); - SLANG_CHECK(compileResult->getItemData(0, code.writeRef()) == SLANG_OK); - SLANG_CHECK(compileResult->getItemData(1, debugCode.writeRef()) == SLANG_OK); - SLANG_CHECK(compileResult->getMetadata(metadata.writeRef()) == SLANG_OK); + SLANG_CHECK_ABORT(result == SLANG_OK); + SLANG_CHECK_ABORT(compileResult != nullptr); + SLANG_CHECK_ABORT(compileResult->getItemCount() == 2); + SLANG_CHECK_ABORT(compileResult->getItemData(0, code.writeRef()) == SLANG_OK); + SLANG_CHECK_ABORT(compileResult->getItemData(1, debugCode.writeRef()) == SLANG_OK); + SLANG_CHECK_ABORT(compileResult->getMetadata(metadata.writeRef()) == SLANG_OK); debugBuildIdentifier = metadata->getDebugBuildIdentifier(); - SLANG_CHECK(debugBuildIdentifier != nullptr); + SLANG_CHECK_ABORT(debugBuildIdentifier != nullptr); // Get the data for the stripped SPIRV. // This is already verified by the separate-debug.slang test but we