| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix for a linked list usage bug; avoids dropping any modifiers when
moving type modifiers from a linked list of modifiers into their own
linked list. Since this change results in no_diff modifiers to
traditional functions ending up on the return type instead of the
function (due to the order they're parsed in), we duplicate the no_diff
modifier onto the function declaration after the fact.
Includes a test for the original issue. The no_diff redistribution case
is covered by a slangpy device test case.
Fixes #8332
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#8603)
This change achieves link-time type resolution with a different
mechanism.
For `extern struct Foo : IFoo = FooImpl;`,
instead of synthesizing a wrapper type `Foo` that has a `FooImpl inner`
field and dispatches all interface method calls to `inner.method()`,
this PR completely removes this synthesis step, and instead just lower
such `extern`/`export` types as `IRSymbolAlias` instructions that is
just a reference to the type being wrapped.
Then we extend the linker logic to clone the referenced symbol instead
of the SymbolAlias insts itself during linking.
By doing so, we greatly simply the logic need to support link-time
types, and achieves higher robustness by not having to deal with many
AST synthesis scenarios.
Closes #8554.
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Note that while this change touched a large numer of files, there are no
changes to functionality being made here. The only things being done are
renaming various symbols and, in a few cases, updating or adding
comments for consistency with the new names.
The core of the naming changes are:
* Most things named to refer to `OutType` (e.g., `IROutType`,
`IRBuilder::getOutType()`, etc.) have been consistently renamed to refer
to `OutParamType`, to emphasize that the relevant AST/IR node types are
only intended for use to represent `out` parameters.
* The same change as described above for `OutType` is also made for
`RefType`, which becomes `RefParamType` in most cases. One mess that
this exposes is the way that the `ExplicitRef<T>` type in the core
module currently lowers to `IRRefParamType`. This change sticks to the
rule of not making functional changes, so that mess is left as-is for
now.
* Names referring to `InOutType` have been changed to instead refer to
`BorrowInOutType`. The intention with this naming change is to emphasize
that the Slang rules for `inout` are semantically those of a borrow (or
at least our interpretation of what a borrow means).
* Names referring to `ConstRefType` have been changed to instead refer
to `BorrowInType`. This change starts work on clarifying that the
existing `__constref` modifier was never intended to be a read-only
analogue of `__ref`, and instead is the input-only analogue of `inout`.
* The `ParameterDirection` enum type has been changed to
`ParamPassingMode`, to reflect the fact that the concept of "direction"
fails to capture what is actually being encoded, particularly once we
have modes beyond simple `in`/`out`/`inout`.
While this change does not alter behavior in any case (the user-exposed
Slang language is unchanged), it is intended to set up subsequence
changes that will work to make the handling of these types in the
compiler more nuanced and correct. Breaking this part of the change out
separately is primarily motivated by a desire to minimize the effort for
reviewers.
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
|
| |
|
|
|
|
|
| |
- Fix bug parsing multiple link-time structs on the same line. Closes
#8553.
- Fix bug parsing anonymous struct type as function return type in
modern syntax. Closes #8558
- Support semantics on modern style param/var declarations.
|
| |
|
|
|
|
|
|
|
|
| |
Fixes #8439
When checked, generic type equality constraints types are now in a
canonical order, allowing for a commutative type equality operator.
---------
Co-authored-by: Mukund Keshava <mkeshava@nvidia.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixes #8406 (and #8410).
`AddressSpace`, `MemoryScope` and `AccessQualifier` are no longer
`BaseType`.
I added a new `__magic_enum` (very similar to `__magic_type`) syntax to
be able to easily create values or these enums from the compiler. (I
don't know if it was the right way to do it, but it works and the
changes are small enough?).
I had a weird bug: `tests/language-feature/capability/address-of.slang`
was failing in `IRBuilder::_findOrEmitConstant(IRConstant& keyInst)`.
When needing a new `u64(0)`, it did not find it in the `ConstantMap`
first, but then failed to add it right after because it already existed
in the map! But this was triggered by `IRPtrType*
IRBuilder::getPtrType(IROp op, IRType* valueType, AccessQualifier
accessQualifier, AddressSpace addressSpace)`, which is a strange
coincidence... but I could not find the issue in what I did. I ended up
bumping unordered_dense, and it solved the issue (so there was a bug in
there).
|
| |
|
|
|
| |
The code int x4 = 0xFFFFFFFFFFFFFFFF previously did not produce a
warning due to the value being too large for the type. This patch now
checks for this and similar issues during parsing.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Resolves #7628
Resolves: #8197
Primary Goals:
1. Add `Access` to pointer
2. AddressSpace::GroupShared support for pointers (SPIR-V)
3. Add `__getAddress()` to replace `&`
* `&` is not updated to `require(cpu)` since slangpy uses `&`. This
means we must: (1) merge PR; (2) replace `&` with `__getAddress()`; (3)
add `require(cpu)` to `&`
Changes:
* Added to `Ptr` the `Access` generic argument & logic (for
`Access::Read`).
* Moved the generic argument `AddressSpace` from `Ptr` to the end of the
type.
* Added pointer casting support between any `Ptr` as long as the
`AddressSpace` is the same
* Disallow globallycoherent T* and coherent T*
* Disallow const T*, T const*, and const T*
* Fixed .natvis display of `ConstantValue` `ValOperandNode`
* Support generic resolution of type-casted integers
* Added `VariablePointer` emitting for spirv + other minor logic needed
for groupshared pointers
Breaking Changes:
* Anyone using the `AddressSpace` of `Ptr` will now have to account for
the `Access` argument
* we disallow various syntax paired with `Ptr` and `T*`
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixes: #7410
Changes:
1. super-type capabilities must be a super-set of sub-type capabilities
(and support the same shader stages/targets)
* InheritanceDecl visits super-type to inherit it's capabilities;
validate InheritanceDecl capabilities against sub-type
* visit all container decl's with a default case
* clean up functionDeclBase visitor
* Simplify `diagnoseUndeclaredCapability` by moving logic into
capability checking (more correct*)
3. added changed behavior to documentation
4. fixed some incorrect capabilities
5. **we do not** diagnose capability errors on interface
requirement-to-implementation if both lack explicit capability
requirements. This change is to work around a slangpy regression (test
case for the failing situation is in
`tests\language-feature\capability\capability-interface-extension-1.slang`),
Note: maybe for slang-2026 we don't do this?
6. requirement & implementation must support the same shader
stage/target. This was changed because otherwise we can have cases where
`X` inherits from `Y`, but `Y` is only expected to be used in `glsl`
whilst `X` is expected to be used in `hlsl | glsl`
7. removed
`tests/language-feature/capability/capabilitySimplification3.slang`
because it tests nothing special (redundant)
Note: not using rebase due to separate branches depending on this PR
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
* Show signature help on generic parameters.
* Fix.
* Update tests.
* slang-test: make vvl error go through stderr.
* update slang-rhi
* Update slang-rhi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Initial plan
* Fix public unscoped enum constants visibility across module boundaries
Add visibility modifier copying in CompleteDecl for unscoped enum cases.
When synthesizing static const declarations for unscoped enum cases,
copy the visibility modifiers from the original enum declaration to
ensure they have the same visibility scope across module boundaries.
Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com>
* Create new visibility modifier instances instead of sharing existing ones
Address reviewer feedback to avoid sharing modifier instances between
declarations since modifiers form a linked list. Now creates new
instances of the appropriate visibility modifier type (Public, Private,
or Internal) instead of reusing the existing instance.
Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com>
* Move unscoped enum visibility tests into subdirectory structure
Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com>
* Use createByNodeType for visibility modifier creation as suggested
Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com>
* format code (#7867)
Co-authored-by: slangbot <186143334+slangbot@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: slangbot <ellieh+slangbot@nvidia.com>
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
|
| |
|
|
|
|
|
| |
* Improve lookup performance.
* Cleanup.
* Improve autocompletion latency.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#7740)
* Fix GLSL memory layout qualifiers not applied to uniform buffers or cbuffers
The `layout(scalar)` qualifier was being ignored for GLSL `uniform` blocks and
HLSL `cbuffer` declarations, causing them to use std140 layout instead of the
requested scalar layout.
**Root Cause**:
The parsing logic in `slang-parser.cpp` handled layout qualifiers inconsistently:
- GLSL `buffer` blocks correctly used `getLayoutArg()` to map layout modifiers
- GLSL `uniform` blocks and HLSL `cbuffer` skipped layout arguments entirely
**Solution**:
- Enhanced `parseHLSLCBufferDecl()` to check for GLSL layout qualifiers
- Added same `getLayoutArg()` logic used by buffer blocks
- Modified uniform block parsing to pass layout arguments through
**Testing**:
- Added comprehensive test case: `tests/glsl/layout-scalar-qualifier.slang`
- Verified fix works for both `uniform` blocks and `cbuffer` declarations
- Confirmed no regressions in existing test suite
**Before**: `layout(scalar) uniform {...}` → std140 layout (32 bytes, offset 0,16)
**After**: `layout(scalar) uniform {...}` → scalar layout (16 bytes, offset 0,4)
Fixes #7735
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: pdeayton-nv <pdeayton-nv@users.noreply.github.com>
* Apply code formatting to slang-parser.cpp
Fixed line wrapping, trailing whitespace, and parameter formatting
according to repository style guidelines.
Co-authored-by: Harsh Aggarwal (NVIDIA) <szihs@users.noreply.github.com>
* format code (#7742)
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: pdeayton-nv <pdeayton-nv@users.noreply.github.com>
Co-authored-by: Harsh Aggarwal (NVIDIA) <szihs@users.noreply.github.com>
Co-authored-by: slangbot <ellieh+slangbot@nvidia.com>
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
|
|
|
|
|
|
| |
* Fix language server crash.
* Fix tests.
* Fix.
* Revert changes.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
* Ensure generic constraints are checked before inner extension.
* Add warning for non-standard generic extension.
* Fix tests.
* Fix test.
* Ban interface types from equality constraints.
* Fix.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Parse optional witness syntax
* Allow failing optional constraint
* Make `is` work with optional constraint
* Allow using optional constraint in checked if statements
* Fix tests
* Make it work with structs
* Fix MSVC build error
* Disallow using `as` with optional constraints
* Update test to match split is/as errors
* Add tests
* Fix uninitialized variables in tests
* Add tests of incorrect uses & fix related bugs
* Mention optional constraints in docs
* format code
* Fix type unification with NoneWitness
* Fix formatting
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Co-authored-by: Nathan V. Morrical <natemorrical@gmail.com>
|
| |
|
|
|
| |
* Add additional completion keywords.
* LanguageServer: Enhance auto completion for `override`.
|
| |
|
|
|
|
|
| |
* Require `override` keyword for overriding default interface methods.
* Update doc.
* Fix test.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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>
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add check for the variable requirement
This change adds the capability check for the variables requirement.
With this check, the shader
```
[require(cpp_cuda_glsl_hlsl_metal_spirv)]
Buffer<float> InputTyped;
[require(cpp_cuda_glsl_hlsl_metal_spirv)]
RWBuffer<float> OutputTyped;
```
will issue error if targeting to WSGL
e.g. `.\build\Debug\bin\slangc .\tests\wgsl_no_buffer.slang -o
wgsl_no_buffer.txt -target wgsl -entry Main -stage compute`
.\tests\wgsl_no_buffer.slang(2): error 36108: 'InputTyped' has dependencies that are not compatible on the required target 'wgsl'.
Buffer<float> InputTyped;
^~~~~~~~~~
.\tests\wgsl_no_buffer.slang(4): error 36108: 'OutputTyped' has dependencies that are not compatible on the required target 'wgsl'.
RWBuffer<float> OutputTyped;
^~~~~~~~~~~
Fixes #6304
* Add var capability tests
* Do capability checks for global var only
* Add inferredCapabilityRequirements to var capability check
* Add requirement to the intrinsic types Buffer/RWBuffer
* format code
* Update capabliity test
* use DefaultDataLayout as default data layout
* Use visitMemberExpr to check the capabilities
* Update the cap tests to match the error messages
* update test to use the ScalarDataLayout for hlsl target
* Update tests check condition to use error number only
* Add default push_constant data layout type
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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>
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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 & 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 & 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<T, E>
* Use anyValue storage for Result<T,E>
* 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 <yonghe@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
fixes: [#7143](https://github.com/shader-slang/slang/issues/7143)
fixes: [#7146](https://github.com/shader-slang/slang/issues/7146)
Goal of PR:
* This PR is part of the larger #7115 refactor to how dynamic dispatch works.
* The first step is to add the `-std <std-revision>` flag.
* The second step is to provide basic `dyn` keyword support in AST. This does not include `varDecl` support since most of these interactions require `some` keyword support.
Future PR(s) goal:
* Support `some` keyword in AST. With this we will also implement all varDecl interactions between `dyn` and `some`.
* Add IR support for `some` and `dyn`.
Breakdown of PR:
* most of the logic is in `validateDyn.*`. This was done so that in the future when we implement more features we will have an easy time removing/adding restrictions to `dyn` interfaces.
Breaking changes:
* As per spec (https://github.com/shader-slang/spec/pull/14/files), any type conforming to a `dyn` interface errors if member list contains one of the following: opaque type, non copyable type, or unsized type.
* Due to the breaking change, the test `tests\compute\dynamic-dispatch-bindless-texture.slang` is incorrect. This has been fixed.
|
| |
|
|
|
|
|
|
|
|
|
| |
* Parse char literals as integers
* Fix formatting
* Parse escaped chars correctly
---------
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
* Initial support for immutable lambda expressions.
* More diagnostics, and langauge server fix.
* Language server fix.
* Fix bug identified in review.
* Add expected result.
* Update expected result.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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>
|
| |
|
| |
* Fix compiler warning with clang 18.1.8 on windows
|
| |
|
|
|
|
|
| |
* Consume `;` after parsing typedef decl.
* Fix.
* Fix regressions.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Fix mul operator followed by global scope
This should fix expr like `2.0f * ::a::b::c`.
But it will no longer parse something like
```
extension<T> Ptr<T> { static void foo(); }
int*::foo() // won't work, but this is a less common case
```
Fixes #6684
* Update simpe-namespace.slang to test global scope
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
* Fix reinterpret and bitcast.
* Fix warning.
* Fix.
* Fix.
---------
Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
* Simplify implicit cast ctors for vector & matrix.
* Fix formatting.
* Fix tests.
* Fix Falcor test.
* Mark __builtin_cast as internal.
|
| |
|
|
|
|
|
|
|
| |
* Fix modifier parsing.
* Fix.
* Fix.
* Fix.
|
| |
|
|
|
|
|
|
|
| |
* Support stage_switch.
* Update proposal status.
* Fix gl_InstanceID.
* Fix.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#6292)
When a module consists of multiple source files, the module scope gets over-written for
each source file that's parsed into the module.
The result is that if you do something like the following, where source1.slang contains
an import statement, then the imported module will get imported into the module scope
corresponding to source2.slang, but won't be found from the scope of source1.slang.
slangc source1.slang source2.slang # 1 module from 2 source files
This patch fixes this problem by not over-writing existing container decl scope
when parsing new source files into the container.
This closes $6221.
|
| |
|
|
|
|
|
| |
* Use two-stage parsing to disambiguate generic app and comparison.
* Typo fix.
* Update doc.
|
| |
|
|
|
|
|
| |
entrypoint. (#6260)
* Auto enable `-fvk-use-entrypoint-name` when there is more than one entrypoint.
* Fix.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* initial work
* more work
* more work on glsl intrinsics
* add subgroup broadcast for glsl
* wip add wgsl extension tracking
* enable tests, enable extensions and added some todos
* format and warning fixes
* fix wgsl extension tracker
---------
Co-authored-by: Yong He <yonghe@outlook.com>
|
| | |
|
| |
|
|
|
| |
* Allow __subscript<T> syntax.
* Fix.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Allow using specialization constants in numthreads attribute
* Add support for GLSL local_size_x_id syntax
* Fix overeager specialization constant parsing
* Add diagnostics for specialization constant numthreads
* Remove unused variable
* Fix local_size_x_id not finding existing specialization constant
* Allow materializeGetWorkGroupSize to reference specialization constants
* Use SpvOpExecutionModeId for modes that require it
* Cleanup specialization constant numthreads code
* Add tests for specialization constant work group sizes
* Fix implicit Slang::Int -> int32_t cast
* Fix querying thread group size in reflection API
---------
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
|
|
| |
* Add executable test on matrix-typed vertex input.
* Fix emit logic of matrix layout qualifier.
* Pass fragment shader varying input by constref to allow EvaluateAttributeAtCentroid etc. to be implemented correctly.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Fix parsing GLSL SSBO arrays / bindless descriptors
* Clean up SSBO array parsing
* Fix mutable SSBO arrays not being detected as such
* Allow sized SSBO arrays
* format code
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Close #5911.
In this issue, if we define the generic in source file 1,
and import it into source file 2, then when parsing the
reference of that generic in source file 2, we will not parse
the generic directly, instead we have a logic to speculate it
as generics first with a fake diagnostic sink, and if there is
no error report, we will consider it as a actual generic and will
parse it again.
In this logic, we will also disambiguate the expression based on
the following token, but we didn't consider the token '[', so we
will finally not treat the expression as generic.
The fix is just simply add '[' here.
Co-authored-by: Yong He <yonghe@outlook.com>
|