summaryrefslogtreecommitdiffstats
path: root/source/slang/slang.cpp
Commit message (Collapse)AuthorAge
* Organize code better by splitting some big files (#7890)Theresa Foley2025-07-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * Organize code better by splitting some big files The basic change here is that the majority of the declarations in `slang-compiler.h` have been split out into a set of smaller and more focused files. As a result, the implement of those declarations have been moved from `slang-compiler.cpp` and `slang.cpp` over to those new files when the proper home for code is obvious. I have tried as much as possible to *not* make any edits to the code along the way, and just copy-paste declarations from one place to another as-is. The exceptions I am aware of are: * In some cases a function that used to be file-scope `static` was used by code that landed in two or more different `.cpp` files. In these cases, I changed the function to be non-`static` (removing the `_` prefix from its name, if it had one, per our naming conventions), and put a declaration for the function into the most appropriate header I could identify. * I added a few comments in places where I saw ugly or unfortunate things in the code I was moving, and wanted to tag them with `TODO`s so we can hopefully get to them in the fullness of time. * I added top-level comments to each of the new `.h` files that was introduced to try to explain the logic for what goes into that file. * In cases where one of the new header files mostly existed to declare a single type, I sometimes added more detail to the doc comment on that type, to better explain the type and its role in the compiler (this is text that otherwise might have gone into the comment at the top leve lof the file, but I figured that the doc comment would have higher discoverability). I expect that the most contentious choice here is that the `Session` class lands in `slang-global-session.h` while `slang-session.h` holds the `Linkage` class. The names used in this change are consistent with how the relevant concepts in the public Slang API are named, and are consistent with how we *intend* to rename the classes themselves in time. * format code * fixup --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix findFunctionByNameInType to preserve functions with different signatures ↵Copilot2025-07-22
| | | | | | | (#7827) findFunctionByNameInType was only returning one function when multiple functions existed with the same name but different signatures. This broke reflection functionality for extension methods. Fix the issue by changing findDeclFromStringInType by not calling maybeResolveOverloadedExpr if checkedTerm is overloaded functions. We still call maybeResolveOverloadedExpr when any candidates in the overloaded list is not DeclRefExpr referencing a function.
* Add utility to trace creation of problematic IRInsts to assist LLM in ↵Copilot2025-07-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | debugging (#7820) * Initial plan * Add SLANG_DEBUG_IR_BREAK environment variable support Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Apply code formatting to SLANG_DEBUG_IR_BREAK implementation Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Improve stack trace debugging with -rdynamic flag and backtrace_symbols Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Address PR feedback: use PlatformUtil::getEnvironmentVariable, remove -rdynamic flag, and delete fallback branch Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Address PR feedback: simplify env var parsing, move backtrace to PlatformUtil, use #if for SLANG_LINUX_FAMILY Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Address PR feedback: remove unneeded include, make backtrace() more generic by removing uid parameter Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Fix and clone source tracking. * Add python script to dump traces. * Update instructions. * Batch calls to addr2line * Cleanup claude instructions. * update claude action. * Remove duplicated build instructions from claude.yml workflow Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * fix build error. * Fix build errors --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com> Co-authored-by: Gangzheng Tong <tonggangzheng@gmail.com>
* Merge NamePool and RootNamePool into a single type (#7797)Copilot2025-07-17
| | | | | | | | | | | | | | | | | | | | | | | * Initial plan * Merge NamePool and RootNamePool into single NamePool class Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Remove unnecessary comment from slang-fiddle-scrape.cpp Co-authored-by: Theresa Foley <tangent-vector@users.noreply.github.com> * Address review feedback: initialize namePool to nullptr and remove unnecessary comments Co-authored-by: Theresa Foley <tangent-vector@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Theresa Foley <tangent-vector@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
* Stable names and backwards compat for serialized IR modules (#7644)Ellie Hermaszewska2025-07-09
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * stable names * tests, options and ci for stable names * Add back compat design document * fix warnings * formatting * comment * neaten * regenerate command line reference * consolidate ci scripts * faster ci * remove libreadline * Move new function to end of interface --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Use fossil for IR serialization (#7619)Ellie Hermaszewska2025-07-08
| | | | | | | | | | | | | | | | | | | | | | | * bottleneck ir module reading and writing * compute/simple working * more complex tests working * neaten * factor out SourceLoc serialization * document changes * Appease clang * Correct name serialization * remove unnecessary code * neaten * neaten
* Catch abort exception from leaking from loadModule (#7627)aidanfnv2025-07-07
|
* Language Server Enhancements (#7604)Yong He2025-07-03
| | | | | | | | | | | | | | | | | | | | | | | * Language Server: auto-select the best candidate in signature help. * Fix constructor call highlighting + goto definition. * Add test. * format code * Improve ctor signature help. * Add tests. * Fix decl path printing for extension children. * Allow goto definition to show core module source. * c++ compile fix. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Replace SLANG_ALIGN_OF with C++11 alignof (#7523)Julius Ikkala2025-07-03
| | | | | * Replace SLANG_ALIGN_OF with C++11 alignof * Fix formatting (again)
* Fix diagnostics not appearing when semantic tokens are disabled (#7477) (#7532)Harsh Aggarwal (NVIDIA)2025-07-02
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Fix diagnostics not appearing when semantic tokens are disabled (#7477) Previously, the language server only triggered module loading and compilation through semantic token requests. When semantic tokens were disabled, didOpenTextDocument and didChangeTextDocument would only update the workspace without compiling modules, meaning no diagnostics were generated. This change: - Adds module loading to didOpenTextDocument for .slang/.hlsl files - Adds module loading to didChangeTextDocument for .slang/.hlsl files - Triggers diagnostic updates via resetDiagnosticUpdateTime for Slang files - Ensures diagnostics appear immediately when opening/editing files - Maintains backward compatibility with existing LSP features Additionally fixes JSON serialization to properly handle NullResponse types by serializing them as JSON null instead of empty objects, improving LSP protocol compliance. Now diagnostics work correctly regardless of semantic token settings. * Revert: Remove unrelated change - will pick up in seprate PR * Fix module state corruption when checkAllTranslationUnits throws Add try/catch in Linkage::loadParsedModule to properly clean up module maps when checkAllTranslationUnits() fails with an exception. This prevents incorrect state in WorkspaceVersion::getOrLoadModule where failed modules remained in the loaded modules map, causing subsequent calls to return stale/invalid module references. * Update to address review comments * update: remove explicit checking for .slang and .hlsl
* Remove some cruft/complexity from IR serialization (#7483)Theresa Foley2025-07-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Remove some cruft/complexity from IR serialization This is a very simple cleanup to unnecessary code paths and remove some flexibility that isn't actually needed, to hopefully simplify the task of more completely overhauling the approach to IR serialization in a later change. The concrete feature that gets removed here is a debug-only feature (which thus shouldn't be affecting any users of Slang) that was added long ago in the life of the compiler as we were working to truly separate the front- and back-ends. At the time there was a lot of code in the compiler back-end that still made use of AST-level data structures, and thus got in the way of our goal to support separate compilation and linking (such that final code generation can only depend on the IR, and not the AST). The option was used to cause the Slang IR to be serialized out and then read back in as part of compilation, to try and enforce that only the wanted constructs could pass through that bottleneck. The idea was only ever half implemented, however, because it made use of a secondary implementation path in IR serialization that supported serializing the "raw" source locations (which are heavily dependent on AST-level information, even down to the number of bytes in source files). This change removes the feature entirely, since it is no longer useful for its intended purpose, and its presence causes there to be entire second code path for source locations in IR serialization that would need to have test coverage if we wanted to be sure it kept working. In addition, our pre-existing infrastructure for module serialization had various options that have either stopped being useful, or were not really useful at the time they were introduced. For example: there are no places in the code today where we attempt to serialize out a module without including both the serialized AST and IR. If that was a feature that we ever supported, the relevant code got removed at some preceding point without breaking any of our tests or (seemingly) upsetting users. Similarly, the options being passed into writing of a serialized module included both a flag to control whether source locations should be serialized *and* a pointer to the `SourceManager` to use in that case... but it was only ever meaningful to set both, or neither. The option has been changed to just be the `SourceManager` pointer, and the name has been updated to reflect its very narrow intended use case. * format code * fixup * regenerate command line reference --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
* Add support for on-demand AST deserialization (#7482)Theresa Foley2025-06-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Note that this change does not actually *enable* on-demand deserialization of ASTs, because doing so is incompatible with the current compiler architecture where we have both an `ASTBuilder` and a `SharedASTBuilder`, and there are important invariants about how all AST nodes related to the core module must be created before those of any module using the core module. Instead, this change simply adds the *infrastructure* for on-demand deserialization, and ensures that those code paths get used at runtime, but actually "demands" all of the nodes in a given serialized AST immediately as part of the deserialization process. Important notes about the implementation approach: * PR #7242 ensured that all of the code accessing the direct member declarations of a `ContainerDecl` went through a small(-ish) set of accessor methods. This change takes advantage of that work by further abstracting the storage of the direct member declarations out in a type, `ContainerDeclDirectMemberDecls`, which makes it easy to add custom serialization logic for just that type. * The `ContainerDeclDirectMemberDecls` type also stores two pointers (one a `RefPtr` and the other a plain pointer) that are only used in the case where the members of a given `ContainerDecl` are being accessed through on-demand deserialization. This can be queried using the `isUsingOnDemandDeserialization()` method but any code accessing a `ContainerDecl` through the intended public API should never need to care about that detail. * Many of the accessor methods that were added in PR #7242 now branch on whether `isUsingOnDemandDeserialization()` is set. The normal code path is unchanged, and the implementation logic for the on-demand-deserialization case is largely held in `slang-serialize-ast.cpp`, to keep it close to the definitions of the serialized data structures themselves. * A few types in the `slang-ast-*.h` headers have had `FIDDLE()` annotations added to them, so that they can be used to synthesize some of the serialization logic that was previously hand-written. * The `_registerBuiltinDeclsRec()` function (which is used to scan the built-in module ASTs for the various "magic" declarations that the `SharedASTBuilder` needs to know about) was factored a bit to support the way that registration needs to behave differently in the case of loading a serialized module (if we kept using the existing recursive search, then it would force every declaration in the core module to be loaded right away). The new `_collectBuiltinDeclsThatNeedRegistrationRec()` function mirrors the overall traversal pattern to produce a flat list that gets included in the serialized AST module. Note in particular that we no longer call `registerBuiltinDecls()` from within `_readBuiltinModule()`. * The interface of the `Module` type was slightly expanded so that there is a more complete API for accessing the declarations exported from the module. Previously they could only be queried by their mangled name, but the new API also allows the entire list to be iterated over. The `ensureLookupAcceleratorBuilt()` method factors out the logic for building those data structures for a module. Note that in the case where on-demand deserialization is being used for a module, the `findExportedDeclByMandledName()` query will use serialized data directly, rather than build the lookup accelerators as C++ data structures (this is required if we are to avoid immediately deserializing all of the (exported) declarations in the core module as soon as it is loaded). * A few methods related to loading serialized modules (e.g., `loadSerializedModule()`) have been updated so that along with a pointer to the serialized `ModuleChunk` (which, for those who aren't aware, is a pointer directly into the serialized bytes of the module file), they receive an `ISlangBlob` that refers to the entire blob holding the serialized data (which the `ModuleChunk` is part of). Passing this pointer down allows code running under these methods to retain a reference-counted pointer to the blob to stop the memory of the serialized module from being released until deserialization has been completed. * The data types defined in `slang-fossil.h` have been overhauled significantly: * The most important change that is relevant to this work is the introduction of the `Fossilized<T>` template, which is used to statically map a "live" C++ type `T` to its binary fossilized representation. The `slang-fossil.h` file provides infrastructure allowing `Fossilized<T>` to be specialized for user-defined types, and also provides the necessary mappings for the core types like strings, arrays, and dictionaries. * A key point is that in C++ code, one can take a value of some type `Foo`, serialize it using a `Fossil::SerialWriter`, get a pointer to that serialized data, and then directly cast it to a `Fossilized<Foo>*` and navigate the serialized data directly (without deserializing it back into a `Foo`). For that process to work, any specialization of `Fossilized<T>` must be sure to match the layout that will be produced by the `serialize()` implementation for `T`, when writing to a `Fossil::SerialWriter`. * Another key change in the public interface of `slang-fossil.h` is that dynamically-typed traversal of the data used to be handled just with `FossilizedValRef`, but now uses a few different types. The `Fossil::ValRef<T>` and `Fossil::AnyValRef` types are used to capture the use cases that want reference-like behavior (basically a `Fossil::ValRef<T>` can be thought of as sort of like a `T&`), while `Fossil::ValPtr<T>` and `Fossil::AnyValPtr` are used for cases that want pointer like behavior (akin to `T*`). * Then there are related changes in `slang-serialize-fossil.*`: * The implementation of `Fossil::SerialReader` has been changed to use `Fossil::AnyValPtr` in most places where it formerly used `FossilizedValRef`. Using pointers (that can be null) instead of a weird kind of pseudo-reference (that could still be null) to traverse things was making the code harder to follow than it ought to be, in terms of understanding the levels of indirection in various places. * Some of the state that was previously in `Fossil::SerialReader` has been split into `Fossil::ReadContext`. This type allows multiple `Fossil::SerialReader`s to be created to read from the same serialized blob(s), while maintaining a persistent mapping from fossilized data pointers to live object pointers. The `ReadContext` also maintains the work list of deferred deserialization actions waiting to be performed, and only flushes that list when the last currently-open `SerialReader` is about to go out of scope. * In order to support the split of `Fossil::SerialReader` described above (and also to clean up something that didn't quite feel right in the original serialization design) the base serialization framework in `slang-serialize.h` has been tweaked so that a `Serializer` now wraps *two* pointers instead of just one. The first pointer continues to be an implementation of `ISerializerImpl`, which handles the actual reading/writing of data, while the other pointer is an explicit "context" pointer for operations that need additional user-defined context. * Similar to the changes made to the accessors for direct member declarations in a `ContainerDecl`, the `Module::findExportedDeclByMangledName()` method was updated to conditionally execute a different code path in the case of a module that has been loaded from serialized data. * Some improvements have been made to the fiddle tool: * Most importantly, the error-handling logic around Lua script execution has been cleaned up to better match correct Lua idiom. Native functions exposed to the Lua scripts have been changed to just use `lua_call` instead of `lua_pcall`, so rather than attempt to intercept Lua errors they will just automatically propagate them. * All Lua-related errors are caught at the top level, and reported in a way that uses the source location of the fiddle template that was being evaluated when the error was raised. In most cases, a Lua error should be accompanied by a stack trace of the Lua evluation state. The file paths and line numbers given should be accurate, but aren't directly double-clickable in the Visual Studio output panel, because they use a different format (a good future change might be to process the Lua stack trace and rewrite it into a format that is better for our needs). * Fixed a subtle bug where having "raw" content (parts of the template that should neither be evaluated nor emitted into the output) that consisted of only whitespace could result in a template being translated to invalid Lua code. * The bulk of the change is, unsurprisingly, in `slang-serialize-ast.cpp`. * This file has been refactored enough to look like a complete rewrite. A lot of work has been put into comments that describe the overall approach being taken, so hopefully it can be understood even by somebody who wasn't familiar with the previous code. Some of these are just plain cleanups, rather than being directly related to on-demand serialization. * Where possible, the code for reading and writing types that needed custom serialization has been moved so that the read/write functions are next to one another, making it easier to visually confirm that the serialized representations match on the read and write sides. * Where possible, the serialization logic for all types (not just the AST nodes, as was the case before) is being generated via fiddle. * Rather than just defining `serialize()` overloads for each of the relevant types, the code now defines `Fossilized<...>` specializations for these types as well, to enable statically-typed in-memory traversal of the serialized data. Note, however, that for the most part the `Fossilized<...>` representation types are *not* being used by the code (really only the `ASTModuleInfo` and `ContainerDeclDirectMemberDeclsInfo` types are traversed directly). This can be considered more as work to prove out the design of the `Fossil<...>` template approach, and it may or may not end up being relevant in the future. * The trivial bit of work to enable on-demand deserialization is in `ASTSerialReadContext::handleContainerDeclDirectMemberDecls()` where, rather than recursively reading the contained declarations, the method effectively just grabs the current cursor of the `Fossil::SerialReader` (which is pointed into the fossilized data) and stashes it into the `ContainerDeclDirectMemberDecls`, along with a `RefPtr` to the `ASTSerialReadContext` itself. Those stashed pointers are what enables the accessors on `ContaienrDeclDirectMemberDecls` to look up information on-demand. * The more interesting bits of the approach mostly come at the end of the file, where the accessor operations for on-demand deserialization are implemented. Once all the relevant work has been done to write the data structures, and produce `Fossilized<...>` types with the right layout, the work itself may seem almost trivial: a little bit of array iteration, and a little bit of binary-search lookup. * As a reminder, all of this infrastructure for on-demand deserialization is now in place and able to be invoked by the rest of the compiler, but declarations are currently all being loaded eagerly. The `SLANG_DISABLE_ON_DEMAND_AST_DESERIALIZATION` macro is being used to enable a small bit of extra logic in `ASTSerialReadContext::_cleanUpASTNode` so that the "cleanup" on a just-deserialized `ContainerDecl` includes eagerly querying its list of direct member declarations, which will cause them to be recursively deserialized.
* Skip processing import declarations after errors (#7393)James Helferty (NVIDIA)2025-06-13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add test case for missing import attribution Add a test case that imports a non-existent file, followed by a valid file. Tests for absence of a bug where slang reports existent files as non-existent if they're imported after a non-existent file. * Skip processing imports after errors Skip processing additional imports after the first error. This behavior is already observed in Linkage::loadSourceModuleImpl, but since that happenes after import processing already started, a false diagnostic gets generated for a missing import. By hoisting this check out before the import is processed, the diagnostic message for a missing file is no longer erroneously generated. Fixes #6453 * Revert "Skip processing imports after errors" This reverts commit 6b2fef09782414de4c5e017c4ecb5f2affa0c199. * Remove early abort of import processing Partial revert of commit 04f1bad Reverts an early return in Linkage::loadSourceModuleImpl() whenever any error diagnostic message has already been generated. This was causing earlier errors to prevent subsequent imports from succeeding, and was misattributing them to a missing file. Fixes #6453 --------- Co-authored-by: Yong He <yonghe@outlook.com>
* Fix API changes from separate debugging support (#7397)jarcherNV2025-06-12
| | | | | | Recent separate debugging support added two new functions which broke backwards compatibility. This change restores the old API and moves the new functions to an IComponentType2 interface which can be used if separate debug files are needed.
* Mediate access to ContainerDecl members (#7242)Theresa Foley2025-06-09
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Most of what this change does is straightforward: take all the places in the code that used to operate directly on `ContainerDecl::members` and related fields, and instead have them call into a smaller set of accessor methods defined on `ContainerDecl`. The primary motivation for making this change is that in order to implement on-demand loading of members from serialized AST modules, we need a way to identify and intercept the "demand" for those members. On-demand loading benefits from having all accesses to the members of a `ContainerDecl` be as narrow as possible. If a part of the code only need a member at a specific index, it should say so. If it only needs access to members with a specific name, or a given subclass of `Decl`, then it should say so. A secondary motivation for this change is that there have recently been several changes that added complexity and special cases by introducing code that operated on (and *mutated*) the member list of a container decl in ways that the existing code had never done before. Any code that mutates the member list of a `ContainerDecl` needs to be sure to not disrupt the invariants that the lookup acceleration structures currently rely on. One of the recent changes added a declaration-to-index map to the set of acceleration structures (with different validation/invalidation behavior than the others...) while other recent changes would remove or insert declarations in ways that could change the indices of other declarations in the same container. It is not clear if any of these pieces of code were aware of the others, and the invariants that might be expected or broken along the way. This change bottlenecks the vast majority of accesses to the members of a `ContainerDecl` through the following operations: * Getting a `List` of all of the direct member declarations of a container * Get the number of direct member declarations, and accessing them by index. * Looking up the list of direct member declarations with a given name. * Adding a new direct member declaration to the end of the list. Some other operations are layered on top of those (e.g., getting a list of all the direct member declarations of a given C++ class). These layered operations are still centralized on the `ContainerDecl`, with the intention that we *can* change them to be non-layered implementations if we ever need to for performance (e.g., by building a lookup structure for finding member declarations by their type). The exceptional cases of access/mutation on the direct members of a `ContainerDecl` have also been encapsulated, but rather than expose what would risk appearing like general-purpose accessors (e.g., `removeDecl(d)`, `setDecl(index)`, etc.), these operations have been explicitly named after the specific use case that they serve in the codebase today, to discourage others from using them for more kinds of operations we'd rather not support. These operations have also been given parameter signatures that match their use cases, to make it so that even somebody determined to abuse them would have to invent suitable arguments out of thin air. In the case of the declaration-to-index mapping, this change eliminates that acceleration structure, in favor or slightly more complicated (and possibly inefficient, yes) code at the use site. Over time, it would be good to closely scrutinize each of the use cases that requires more complicated interaction with the members of a `ContainerDecl`, to see whether any of them can be reframed in terms of the more basic operations, or if there is some clean abstraction we can introduce to make operations that mutate the member list feel like... hacky.
* Add command line option for separate debug info (#7178)jarcherNV2025-06-06
| | | | | | | | | | | | | * Add command line option for separate debug info Add command line arg -separate-debug-info which, if provided, produces both a .spv and a .dbg.spv file. The .dbg.spv file contains full debug info and the .spv file has all debug info stripped out. Also add a DebugBuildIdentifier instruction to store a unique hash in both the output files, so they can be more easily matched together. A matching API is provided to allow using the Slang API to retrieve a base and debug SPIRV as well as the debug build identifier string.
* Fix crash when loading modules with syntax errors (#6993) (#7288)Harsh Aggarwal (NVIDIA)2025-06-05
| | | | | | | | | | | | | | * Fix#6993 - Emit Diagnostic Warning and Fix SIGSEGV * Update external/slang-rhi submodule * Add checks for valid stage names for paq in SemanticsVisitor check * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
* Fix missing debug info for the included slang file (#7281)Lujin Wang2025-06-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Fix missing debug info in the included slang file Issue: https://github.com/shader-slang/slang/issues/7271 Debug info including DebugFunction, DebugLocation, and DebugValue are missing in IR for "#included" Slang shader file. The included shader file was not added to TranslationUnit's source file list, therefore mapSourceFileToDebugSourceInst.add() was not called for the source in generateIRForTranslationUnit(), and later mapSourceFileToDebugSourceInst.tryGetValue() could not get value for the source to add DebugLocationDecoration, which led to missing DebugFunction, DebugLocation and other debug info for the included file in IR. Adding the include file in TranslationUnit's source file list fixes the issue. * Add source file using PreprocessorHandler Call _addSourceFile from FrontEndPreprocessorHandler::handleFileDependency. * Just use FrontEndPreprocessorHandler * Make _addSourceFile public * format code * Distingush the included source file * Add m_includedFileSet to avoid adding dup file HashSet<SourceFile*> m_includedFileSet; --------- Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Make interface types non c-style in Slang2026. (#7260)Yong He2025-06-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Make interface types non c-style. * Make Optional<T> work with autodiff and existential types. * Fix. * patch behind slang 2026. * Fix warnings. * cleanup. * Fix tests. * Fix. * Fix com interface lowering. * Add comment to test. * regenerate command line reference * Add test for passing `none` to autodiff function. * Fix recording of `getDynamicObjectRTTIBytes`. * Fix nested Optional types. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix the memory leak (#7290)Jay Kwak2025-06-03
| | | | | When we return a raw point to a module, we should decrement the reference count. The module is owned by its session so it should be valid as long as the session is valid.
* Language version + tuple syntax. (#7230)Yong He2025-05-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Language version + tuple syntax. * Fix compile error. * regenerate documentation Table of Contents * Fix. * regenerate command line reference * Fix. * Fix. * Fix more test failures. * revert empty line change, * Retrigger CI * #version->#lang * Update source/core/slang-type-text-util.cpp Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> * Remove comments. * Fix parsing logic. * Fix parser. * Fix parser. * update test comment * Update options. * regenerate documentation Table of Contents * regenerate command line reference --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
* Add checking for hlsl register semantic. (#7118)Yong He2025-05-15
| | | | | | | | | | | * Add checking for hlsl register semantic. * Fix. * Fix test. * Fix switch error. * Fix tests.
* Support the new CoopVec builtins (#7108)Jay Kwak2025-05-14
| | | | | | | | | **NOTE: This is a breaking change for users who were using POC variant of DXC. In order to keep the compatibility, the users will have to use -capability hlsl_coopvec_poc to their command line. This PR adds a new capability "hlsl_coopvec_poc". When it is used, the HLSL for CoopVec will be emitted for the POC variant of DXC. When it is not used, the HLSL for CoopVec will be emitted for the DXC that officially supports the cooperative vector.
* support specialization constant sized array (#6871)kaizhangNV2025-05-14
| | | | | | | | | | | | | | | | | | | | | Close #6859 Goal of this PR We want to support an array whose size can be specialization constant for shared/global variable e.g. layout (constant_id = 0) const uint BLOCK_SIZE = 64; shared float buf_a[(BLOCK_SIZE + 5) * 4]; Overview of the solution: During IndexExpr check, we will loose the restriction to allow SpecConst passing, but the size parameter will not be a constant value because it cannot be folded into a constant, so we will make it follow the same logic as generic parameter value, and the size will be represented by FuncCallIntVal/PolynomialIntVal/DeclRefIntVal. During IR lowering, we will detect whether there is spec constant in the IntVal, and wrap the IRInst with a SpecConstRateType, and propagate the type though the lowering logic, such that the IntVal representing the array size will have SpecConstRateType. During spirv emit stage, if we detect that a IRInst has SpecConstRateType, we will emit it as SpecConstantOp. We have to implement new logic to emit OpSpecConstantOp, the existing emit logic doesn't support emitting OpSpecConstantOp, especially this op can embed arithmetic operation at global scope, where we can only emit arithmetic instruct at local. But there are only few instructs we need to support. Overview of the solution: This PR doesn't support generic, and we will create a separate PR to extend that, tracked in #6840.
* Cleanups related to RIFF support (#7041)Theresa Foley2025-05-12
|
* Add Slang Byte Code generation and interpreter. (#6896)Yong He2025-04-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add Slang Byte Code generation and interpreter. * Fix compile issues. * format code * More compile fix. * Fix clang issue. * Fix more clang issues. * Another clang fix. * Fix clang issues. * Fix another clang issue. * Fix wasm build. * Update building.md * Fix test-server. * Fix compile error. * Fix bug. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Update spirv-tools to for SDK v2025.2 (#6893)Gangzheng Tong2025-04-25
| | | | | | | | | | | | | | | | | | | | * Update spirv-tools to for SDK v2025.2 Fixes: #6850 * bump spirv version to 1.4 for op linkage * skip-spirv-validation for coop mat * add skip-spirv-validation option to slang session desc * use SPV_ENV_UNIVERSAL_1_6 for spirv-tool env target Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* A new approach to AST serialization (#6854)Theresa Foley2025-04-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * A new approach to AST serialization This change completely overhauls the way that AST nodes are being serialized, and the offline source-code generation steps that enable that serialization. In practice, this ends up being a complete overhaul of the way that *modules* are being serialized (not just the AST part), although things like the serialization format for the Slang IR and for source locations are not affected. The rest of this commit message is broken down in to sections, in an attempt to help guide anybody looking at the code in how to make sense of all the changes. The Old C++ Extractor --------------------- AST serialization used to be driven by information scraped using the `slang-cpp-extractor` tool, which did an ad hoc parse of the C++ declarations of the AST node types and then generated a set of "X macros" that could be for macro-based code generation within the rest of the compiler. While the existing approach was functional, it wasn't easy to understand or maintain, and it has been getting in the way of forward progress on other features we'd like to work on in the language and compiler. This change removes the `slang-cpp-extractor` tool entirely. Marking Up the AST Declarations ------------------------------- The most notable change that contributors to the compiler may notice is the large number of invocations of a macro `FIDDLE()` on the declarations of the AST node types. The basic idea is that only declarations (namespaces, types, fields) that are preceded by `FIDDLE()` are visible to the code generator tool. So if somebody is working with the AST and wondering why a new node type isn't working, or why a field they added isn't being serialized correctly, it is probably because they need to add `FIDDLE()` in front of it. Generating the Boilerplate Code ------------------------------- The file `slang-ast-boilerplate.cpp` provides a good example of how the information extracted from the marked-up AST declarations gets used. In that file, the `FIDDLE TEMPLATE` construct is used to generate type information for each of the AST node types. Similar logic is used in `slang-ast-forward-declarations.h` to generate the declaration of the `ASTNodeType` enumeration, and forward-declare all the AST node classes. For many parts of the code, simply including that file replaces the need for the old `slang-generated-*.h` files. Replacing Visitors and Related Logic ------------------------------------ The old visitor types for the AST used the macros that were generated by `slang-cpp-extractor`, so something new was needed to replace them. The same goes for the `SLANG_AST_NODE_VIRTUAL_CALL` macros. The core of the solution implemented here is in `slang-ast-dispatch.h`. Given a "dispatchable" AST node type (say, `Expr`), a call like: ``` ASTNodeDispatcher<Expr,R>(expr, [&](auto e) { return doSomething(e); }) ``` is an expression of type `R`, which does the equivalent of something like: ``` switch(expr->getTag()) { case ASTNodeType::VarExpr: return doSomething(static_cast<VarExpr*>(expr)); // ... } ``` The `SLANG_AST_NODE_VIRTUAL_CALL` macro is now implemented in terms of `ASTNodeDispatcher`. The implementation of the visitor types is more involved. The code in this change retains some of the macro names from the original version, just to try and make the parallels more clear. The visitor types are all implemented on top of the `ASTNodeDispatcher` approach, and use `FIDDLE TEMPLATE` to generate all the boilerplate `visit*()` method declarations. Refactoring of `Linkage` Module Loading --------------------------------------- Needing to revisit all the places where modules get deserialized made it clear that there is a lot of complexity and apparent duplication in the core routines on the `Linkage` that get used for loading modules. This change tries to clean up some of that logic, but it is worth noting that there are two legacy features that get in the way of making things as clean as they should be: * The `LoadedModuleDictionary` type that gets passed around a lot exists entirely to handle the corner case where somebody uses the Slang API to perform a compilation with multiple `TranslationUnitRequest`s in the same `FrontEndCompileRequest`, and one of the translation units `import`s the module defined by another of the translation units. * There are a lot of special-case behaviors and routines entirely there to support the `ModuleLibrary` feature, although that feature should be considered deprecated (or at least subject to getting entirely re-designed down the line). The basic idea of the cleanup is that all of the (non-deprecated) ways load a module from a serialized binary, or compile one from source should now bottleneck through `loadModuleImpl`, which then bifurcates into `loadSourceModuleImpl` for the compilation case and `loadBinaryModuleImpl` for the deserialization case. High-Level Serialization Approach --------------------------------- The old serialization logic used the [RIFF](https://en.wikipedia.org/wiki/Resource_Interchange_File_Format) format to encode the high-level structure of things, and this change retains that usage (and actually doubles down on the RIFF usage). The old serialization system relied on the idea that for any given type `Foo` that wants to support serialization, there should be something like a `SerialFooData` type in C++, that can represent the state of a `Foo`, and then the actual serialization applied to that `SerialFooData`. This means that in most cases there are four pieces of code written: * During serialization: * Copying the data of a `Foo` in memory over to a `SerialFooData` in memory * Writing the state of a `SerialFooData` into the serialized data stream * During deserialization: * Reading the state of a `SerialFooData` from a serialized data stream * Copying the data of the `SerialFooData` in memory over to a `Foo` The new logic gets rid of the intermediate `SerialFooData`. In the serialization direction, we take a `Foo` and write it to the `RIFFContainer` directly, or using some other utilities layered on top of it. In the deserialization direction, we have additional flexibility. Given a `RIFFContainer::Chunk*` that represents a serialized `Foo`, we often navigate through the in-memory representation of the RIFF data to get to the parts of the serialized value that we actually want/need, without needing to deserialize the entire `Foo`. To support this kind of operation, this change introduces a few helper types like `ContainerChunkRef` an `ModuleChunkRef`, that are little more than typed wrappers around a `RIFFContainer::Chunk*`. The Module "Container" Part --------------------------- A serialized `Module` is encoded as a RIFF chunk, using logic in `slang-serialize-container.cpp` - both before and after this change. This change reorganizes a lot of the code in that file, to account for the way that eliminating the intermediate `SerialContainerData` type streamlines the overall task of writing out the parts of the module. In the deserialization logic... there isn't really much to do in `slang-serialize-container.cpp`. Most of the logic in `slang.cpp` and `slang-module-library.cpp` that pertains to deserializing modules uses the `ModuleChunkRef`-based approach, and simply extracts the pieces of the serialized module that it needs. The Actual Serialization of the AST ----------------------------------- The actual AST serialization logic is in `slang-serialize-ast.cpp`. The basic approach in both the writing and reading directions is: * Use the `FIDDLE TEMPLATE` system to generate a set of functions, one for each AST node type, that recursively invoke the read/write logic on each field of that node (after recursively invoking the case for its direct superclass) * Use the `ASTNodeDispatcher` system to dispatch out to those functions whene reading or writing anything derived from `NodeBase` * For now, handle all types *not* derived from `NodeBase` by hand. There's a lot of room for improvement around that last item: it should be just as easy to generate the serialization and deserialization logic for other types that don't inherit from `NodeBase`, but the current change tries to err on the side of making the logic as explicit and simplistic as possible, rather than trying to get too clever too soon. The actual serialization *format* used for the AST is almost comically simplistic: the code uses hierarchical RIFF chunks to emulate a JSON-like structure. This is a very wasteful representation (e.g., a `bool` or a null pointer each take up *8 bytes*), but the goal for now is to start with the simplest thing that could possibly work, and only add more cleverness once we are sure it won't get in the way of important future improvements (like lazy/on-demand deserialization or IR and AST, to improve compiler startup times). The files `slang-serialize.{h,cpp}` have been co-opted to define a new pair of types `Encoder` and `Decoder` that are used for a more-or-less stream-oriented way or reading or writing RIFF chunks for the JSON-like structure. Almost everything related to the actual AST serialization could do with a cleanup pass, and some time spent on picking good/better names for everything. Smaller Stuff ------------- * Cleaned up a lot of code that was using bare `ASTNodeType` or the extractor's `ReflectClassInfo` type to consistently use `SyntaxClass`. * Fixed an apparent bug in how the destination-driven code genarator was handling `TryExpr`s * Fixed an apparent bug in how the GLSL legalization pass was handling translation of certain `SV_*` semantics. * format code * fixup: template errors caught by non-VS compilers * format code * fixup: more template errors * fixup: more stuff VS didn't catch * fixup: it's amazing VS doesn't catch these... * fixup: yet more template stuff VS ignores * fixup: more VS template nonsense * fixup: unreachable return macro usage * fixup: more unreacable returns * fixup: unused parameter * fixup: strict aliasing * fixup: allow missing entry point list chunk * fixup: wasm build script * fixup: AST changes since this PR was created --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
* Remove support for ad hoc Slang IR compression (#6834)Theresa Foley2025-04-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Remove support for ad hoc Slang IR compression This change is part of a larger effort to clean up the approach to serialization in the Slang compiler. The overall goal is to simplify and streamline all of the serialization-related logic, so that we are left with code that is less "clever," and easier to understand for contributors to the codebase. Removing support for compression of serialized Slang IR has benefits that include: * Reduction in code complexity: consider things like the subtle way that the `FOURCC`s for compressed chunks were being computed from the uncompressed versions, and the mental overhead that goes into understanding that, for anybody who would dare to touch this code. * Reduction in testing burden: there have been, de facto, two very different code paths for serialization of the Slang IR, and it is not clear that the existing test corpus for Slang has sufficient coverage for both options. By having only a single code path, every test that performs any amount of IR serialization helps with test coverage of that one path. * Opportunity to explore alternatives. This is perhaps a reiteration of the first point, but once the code is stripped down to the simplest thing that could possibly work (I am not claiming it has reached that point yet), it becomes easier for contributors to understand, and it becomes more tractable for somebody to come along with an improved approach that performs better (in either compression ratio or performance) while still being maintainable. In my own local setup, I found that removing support for Slang IR compression led to the `slang-core-module-generated.h` file increasing in size from 46.1MB to 47.4MB. This increase in the `.h` file size for the core library binary only resulted in a release build of `slang.dll` increasing from 20.0MB to 20.2MB. Removing the ad hoc compression support has almost no impact on the size of actual binary Slang modules *so long* as the additional LZ4 compression step is being applied to them. * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Correct modifier isConst initialization (#6645)Gangzheng Tong2025-03-20
| | | | | | | | | | | | | | The previous implementation had two issues in the modifier processing loop: 1. isConst was incorrectly initialized to true, making the const check redundant 2. Premature loop break could skip processing important modifiers. e.g. isExtern Changes: - Initialize isConst to false by default - Remove early break condition to process all modifiers Fixes: #6606 Co-authored-by: Yong He <yonghe@outlook.com>
* Add referenced modules as libraries when creating a session (#6569)Anders Leino2025-03-12
| | | | | | | | | | | | | | | | | | | | | | | In the legacy compile request based API, the referenced modules are added to the request's linkage libraries as part of compiler option parsing. In the non-legacy compilation API, the argument parsing creates a temprary compile request and so those libraries only survive as options. This change will look for such options when creating an ISession object, and again add the referenced modules to the libraries of the new linkage that's contained in the ISession object. This is done in two steps: 1. Factor out a helper to create a referenced module artifact in the same way as it's done during legacy option parsing. 2. Use the helper function to create artifacts to add to the linkage libararies, when the session is created. This helps to address issue #4760, because it enables passing in downstream modules via options, as is required for the following tests: tests/library/library-test.slang.2 (dx12) tests/library/export-test.slang.2 (dx12)
* Set the HLSL supported compiler version to 2018 (#6502)Tony (Atanas) Zlatinski2025-03-11
| | | Co-authored-by: Jay Kwak <82421531+jkwak-work@users.noreply.github.com>
* IR: Add SPIR-V disassembly for embedded downstream IR dumps (#6529)Mukund Keshava2025-03-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * IR: Add SPIR-V disassembly for embedded downstream IR dumps When dumping IR that contains embedded downstream SPIR-V code (via EmbeddedDownstreamIR instructions), display the disassembled SPIR-V instead of just showing "<binary blob>". This CL also does: - Adds a new interface for disassembly and get result. - Modify export-library-generics.slang test test to check for the disassembled SPIR-V Fixes #6513 * Add module-dual-target-verify test Fixes #6517 Adds a new test to verify that dxil and spirv targets are stored separately in the precompiled blob. * Fix review comments from cheneym2 * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Get options also from the default target (#6530)Anders Leino2025-03-06
| | | | | | | | | | | | | This helps to address issue #4760. The particular issue motivating this fix is that IGlobalSession::parseCommandLineArguments uses a temporary compile request to parse options. The compile request only adds the OptionKind::ForceDXLayout (-fvk-use-dx-layout) to the "current target" which may be the default target, which IGlobalSession::parseCommandLineArguments didn't look for, meaning that options like ForceDXLayout were just ignored. This leads to test failures in tests that rely on this option, e.g. tests/spirv/cbuffer-dx-layout-1.slang.
* Add Slang-specific intrinsics for integer pack/unpack (#6459)Darren Wihandi2025-02-28
| | | | | | | | | | | | | | | | | | | | | * update hlsl meta * update test * use slang syntax in meta file * improve meta file * fix pack clamp u8 * remove builtin packed types, use typealias instead * fix wgsl pack clamp * fix formatting --------- Co-authored-by: Yong He <yonghe@outlook.com>
* Don't add multiple matrix layout options when creating a session (#6476)Anders Leino2025-02-27
| | | | | | | | The default matrix layout mode was applied in addition to any related options, and this caused the wrong matrix layout mode to be used. For example, tests/compute/column-major was failing when attempting to migrate to the new compilation API. This helps to address issue #4760
* Fix a bug where Session::parseCommandLineArguments returns invalid data (#6461)Anders Leino2025-02-27
| | | | | This helps to address issue #4760. Co-authored-by: Yong He <yonghe@outlook.com>
* Fix TypeCheckingCache concurrency and candidate lifetime. (#6444)Yong He2025-02-24
| | | | | * Fix TypeCheckingCache concurrency. * Fix.
* Improve performance when compiling small shaders. (#6396)Yong He2025-02-23
| | | | | | | Improve performance when compiling small shaders. Avoid copying witness table entries that are not getting used during linking. Avoid copying auto-diff related decorations and derivative functions during linking, if the user modules doesn't use autodiff. Cache operator overload resolution results on global session, so each new Session doesn't need to repetitively run through overload resolution from scratch.
* Reflection Fixes. (#6346)Yong He2025-02-13
| | | | | | | | | | | * Fix 6317. * Fixes #6316. * Fix cmake preset. --------- Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
* Respect per-target debug options (#6193)Anders Leino2025-01-31
| | | | | | | | | | | | | | | | | * Base compiler options for targets on target-specific compiler options Before this change, the target compiler options were based on the linkage-wide compiler options, which where later again inherited from (basically a no-op). With this change, the target-specific compiler options are added first, and then the linkage-wide comnpiler options are inherited from. * Remove debug instructions if target-specific setting is NONE This helps to address #6092. * Make sure the linkage debug info level is sufficient for each target This closes #6092.
* Add a unit test to cover type-conformance compilation API. (#6178)Yong He2025-01-28
| | | Co-authored-by: Anders Leino <aleino@nvidia.com>
* Cache and reuse glsl module. (#6152)Yong He2025-01-22
| | | | | | | | | | | * Cache and reuse glsl module. * Fix. * Implement record/replay for the new api. * Fix record replay. * Fix test.
* Catch all exceptions from loadModule* and link API calls. (#6143)Anders Leino2025-01-22
| | | This closes #5950.
* Fix issue with specialization using arithmetic expressions (#6084)Sai Praveen Bangaru2025-01-14
|
* Create DirectDeclRef when creating Decl to prevent invalid dedup. (#5945)Yong He2025-01-03
| | | | | | | | | * Create DirectDeclRef when creating Decl to prevent invalid dedup. * Fix test. * fix * update slang-rhi
* Fixed incorrect condition in Session::queryInterface. (#5978)Pétur Darri Pétursson2025-01-01
| | | An AND operator was used where an OR should have been used.
* Add packed 8bit builtin types (#5939)Darren Wihandi2024-12-26
| | | | | * Add packed bytes builtin type * fix test
* Fix entrypoint auto discovery logic. (#5885)Yong He2024-12-17
| | | | | | | | | * Fix entrypoint auto discovery logic. * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix a crash when search for files. (#5818)Yong He2024-12-10
| | | Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>