<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/slang-ast-stmt.h, branch master</title>
<subtitle>Making it easier to work with shaders</subtitle>
<id>https://git.yummers.dev/slang.git/atom?h=master</id>
<link rel='self' href='https://git.yummers.dev/slang.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/'/>
<updated>2025-08-18T15:10:27+00:00</updated>
<entry>
<title>Don't let clang-format reorder Fiddle `#include`s (#7887)</title>
<updated>2025-08-18T15:10:27+00:00</updated>
<author>
<name>Sam Estep</name>
<email>sam@samestep.com</email>
</author>
<published>2025-08-18T15:10:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=09054bff3d0874a92958b514ae2a9ff2b32483e5'/>
<id>urn:sha1:09054bff3d0874a92958b514ae2a9ff2b32483e5</id>
<content type='text'>
The documentation added by #6844 included instructions to make sure that
the Fiddle `#include` in a file comes after all the other `#include`s,
but it's easy to accidentally violate this via `clang-format`, as
happened for `source/slang/slang-ast-modifier.h` in #7559. This PR
guards against this sort of violation by separating all Fiddle
`#include`s from other `#include`s via a blank line followed by a `//`
line (as we already do in most cases), and also adds a sentence about
this in `tools/slang-fiddle/README.md`.

As a bonus, I also enabled Markdown syntax highlighting for all the code
blocks in that doc file.

Co-authored-by: Ellie Hermaszewska &lt;ellieh@nvidia.com&gt;</content>
</entry>
<entry>
<title>Support `expand` on concrete tuple values. (#8106)</title>
<updated>2025-08-07T15:10:02+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-08-07T15:10:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=7cd8130e1a3dbcca8746e0577fb8df3bf2975bf8'/>
<id>urn:sha1:7cd8130e1a3dbcca8746e0577fb8df3bf2975bf8</id>
<content type='text'>
Closes #8061.

Along with the fix, also enhanced coercion/overload resolution to filter
candidates based on the target type, allowing
`tests\language-feature\higher-order-functions\overloaded.slang` to
pass.</content>
</entry>
<entry>
<title>Remove SLANG_UNREFLECTED (#7241)</title>
<updated>2025-05-27T00:42:05+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-05-27T00:42:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=914f8c4b283bd81f2ea3ef00b184ff63245c9278'/>
<id>urn:sha1:914f8c4b283bd81f2ea3ef00b184ff63245c9278</id>
<content type='text'>
The `SLANG_UNREFLECTED` macro has been completely meaningless since we switched away from the old AST serialization/reflection approach, so the lingering uses of it in the code as pointless at best and misleading/confusing at worst.</content>
</entry>
<entry>
<title>Implement throw &amp; catch statements (#6916)</title>
<updated>2025-05-23T19:27:37+00:00</updated>
<author>
<name>Julius Ikkala</name>
<email>julius.ikkala@gmail.com</email>
</author>
<published>2025-05-23T19:27:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=57c3f938221c427b78da7087f8a832ba4a271a7c'/>
<id>urn:sha1:57c3f938221c427b78da7087f8a832ba4a271a7c</id>
<content type='text'>
* Implement throw statement

It already existed in the IR, so only parsing, checking and lowering was
missing.

* Initial catch implementation

Likely very broken.

* Error out when catch() isn't last in scope

* Prevent accessing variables from scope preceding catch

As those may actually not be available at that point.

* Add IError and use it in Result type lowering

* Add diagnostic tests

* Allow caught throws in non-throw functions

* Fix catch propagating between functions &amp; SPIR-V merge issue

* Add test for non-trivial error types

* Fix MSVC build

* Fix invalid value type from Result lowering

* Also lower error handling in templates

* Lower result types only after specialization

* Attempt to disambiguate error enums by witness table

* Revert matching by witness, types should be distinct too

* Don't assert valueField when getting Result's error value

It may not exist if the function returns void, but getting the error
value is still legitimate.

* Update tests for new error numbers &amp; get rid of expected.txt

* Change catch lowering to resemble breaking a loop

... To make SPIR-V happy.

* Fix dead catch blocks and invalid cached dominator tree

* More SPIR-V adjustment

* Lower catch as two nested loops

* Add defer interaction test and revert broken defer changes

* Fix enum type when throwing literals

* Cleanup and bikeshedding

* Document error handling mechanism

* Fix table of contents

* Use boolean tag in Result&lt;T, E&gt;

* Use anyValue storage for Result&lt;T,E&gt;

* Remove IError

* Fix formatting

* Eradicate success values from docs and tests

* Use parseModernParamDecl for catch parameter

* Implement do-catch syntax

* Implement catch-all

* Fix formatting

* Fix marshalling native calls that throw

---------

Co-authored-by: Yong He &lt;yonghe@outlook.com&gt;</content>
</entry>
<entry>
<title>A new approach to AST serialization (#6854)</title>
<updated>2025-04-22T20:26:57+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-04-22T20:26:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=1cf3f18a9ca1905a5bc51790ca723815dd5b1400'/>
<id>urn:sha1:1cf3f18a9ca1905a5bc51790ca723815dd5b1400</id>
<content type='text'>
* 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&lt;Expr,R&gt;(expr, [&amp;](auto e) { return doSomething(e); })
```

is an expression of type `R`, which does the equivalent of something like:

```
switch(expr-&gt;getTag())
{
case ASTNodeType::VarExpr: return doSomething(static_cast&lt;VarExpr*&gt;(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 &lt;186143334+slangbot@users.noreply.github.com&gt;
Co-authored-by: Yong He &lt;yonghe@outlook.com&gt;</content>
</entry>
<entry>
<title>Eliminate back-reference in ChildStmt (#6835)</title>
<updated>2025-04-17T16:53:37+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-04-17T16:53:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=8d1dca337e4b74c4b88a434eb2df5889410aff7c'/>
<id>urn:sha1:8d1dca337e4b74c4b88a434eb2df5889410aff7c</id>
<content type='text'>
* Eliminate back-reference in ChildStmt

This change is part of a larger effort to improve the code for AST
serialization in the Slang compiler.

Tree structures are understandably easier to serialize than DAGs,
and DAGs are easier than fully generaal graphs.

The Slang AST nodes form a tree structure... except when they don't.
Among the exceptions to nice tree-structured ASTs are:

1. References to `Decl`s are encoded as pointers to the AST `Decl`
  nodes themselves. This can result in cycles in the graph, and
  requires care in serialization.

2. Nodes that inherit from `Val` represent, well, *values* instead
  of actual pieces of syntax, and as such they are deduplicated so
  that identical values will (hopefully) be identical pointers.
  This results in a DAG structure for `Val`s, but at least it's not
  a general graph (except for cycles that go through a `Decl`).

3. There are some minor cases of DAG-structured sharing that the
  parser can introduce to deal with cases when a traditional-style
  declaration includes multiple declarators. E.g., given:

  ```
  static int a, b;
  ```

  The resulting `DeclGroup` will include distinct `Decl`s for `a`
  and `b`, which will share the `static` modifier through a
  `SharedModifiers` node, and the `int` type specifier through a
  `SharedTypeExpr` node.

  This duplication can be ignored, for the purposes of serialization,
  since duplicating those parts of the AST has no major down-sides.

4. There is the case of `ChildStmt`, used for things like `break`
  and `continue`, which stores a direct `Stmt*` to the enclosing
  parent statement being targetted. Storing the target is useful so
  that IR lowering doesn't need to repeat the work that the semantic
  checking logic did to associate each child statement with its parent.

  The parent link inside of `ChildStmt` creates a cycle in the AST
  `Stmt` hierarchy, since the outer statement contains the inner,
  and the inner statement stores a pointer to the outer.

This change eliminates the last of these sources of complication for
AST serialization, by changing the `ChildStmt` type to stored an
integer ID for the enclosing statement that it matches to, and having
each `BreakableStmt` (used to represent the outer `switch`, or loop,
or whatever) generate its own unique ID as part of semantic checking.

Note: if necessary, it is reasonable for the outer statement to have
its unique ID generated as part of parsing, rather than semantic
checking.

* format code

* Change unique ID to be a proper Decl

The fix here is to make the "unique ID" representation be a full
`Decl`-derived AST node, so that it is both allowed to break the
tree-structuring rules cleanly, and it is also trivially guaranteed
to be unique across all loaded ASTs.

* format code

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Add defer statement (#6619)</title>
<updated>2025-04-07T03:08:29+00:00</updated>
<author>
<name>Julius Ikkala</name>
<email>julius.ikkala@gmail.com</email>
</author>
<published>2025-04-07T03:08:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=1b82501dd0c74347cda4a2c7fe5a84fd610bb485'/>
<id>urn:sha1:1b82501dd0c74347cda4a2c7fe5a84fd610bb485</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Support stage_switch. (#6311)</title>
<updated>2025-02-07T06:02:43+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-02-07T06:02:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=bae87afb20f95f9f27c64c4955bbc4464c576509'/>
<id>urn:sha1:bae87afb20f95f9f27c64c4955bbc4464c576509</id>
<content type='text'>
* Support stage_switch.

* Update proposal status.

* Fix gl_InstanceID.

* Fix.</content>
</entry>
<entry>
<title>Use two-stage parsing to disambiguate generic app and comparison. (#6281)</title>
<updated>2025-02-05T20:32:56+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-02-05T20:32:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=7911c9437333692db275d2dff41264f4c8023be8'/>
<id>urn:sha1:7911c9437333692db275d2dff41264f4c8023be8</id>
<content type='text'>
* Use two-stage parsing to disambiguate generic app and comparison.

* Typo fix.

* Update doc.</content>
</entry>
<entry>
<title>format</title>
<updated>2024-10-29T06:49:26+00:00</updated>
<author>
<name>Ellie Hermaszewska</name>
<email>ellieh@nvidia.com</email>
</author>
<published>2024-10-29T06:49:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21'/>
<id>urn:sha1:f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21</id>
<content type='text'>
* format

* Minor test fixes

* enable checking cpp format in ci</content>
</entry>
</feed>
