summaryrefslogtreecommitdiffstats
path: root/tests/language-feature/inheritance
Commit message (Collapse)AuthorAge
* Diagnose on use of struct inheritance. (#7419)Yong He2025-06-12
| | | | | | | | | | | | | * Diagnose on use of struct inheritance. * fix test. * Fix tests. * fix. --------- Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
* Feature/initialize list side branch (#6058)kaizhangNV2025-02-05
| | | | | | | | | | | | | | | | | | | | | | * SP004: implement initialize list translation to ctor - We synthesize a member-wise constructor for each struct follow the rules described in SP004. - Add logic to translate the initialize list to constructor invoke - Add cuda-host decoration for the synthesized constructor - Remove the default constructor when we have a valid member init constructor - Disable -zero-initialize option, will re-implement it in followup (#6109). - Fix the overload lookup issue When creating invoke expression for ctor, we need to call ResolveInvoke() to find us the best candidates, however the existing lookup logic could find us the base constructor for child struct, we should eliminate this case by providing the LookupOptions::IgnoreInheritance to lookup, this requires us to create a subcontext on SemanticsVisitor to indicate that we only want to use this option on looking the constructor. - Do not implicit initialize a struct that doesn't have explicit default constructor. Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix WGSL parameter block binding. (#5500)Yong He2024-11-06
| | | | | | | | | | | | | * Fix WGSL parameter block binding. * Re-enable tests. * Update failure list. * Fix entrypoint parameters. * Update tests. * Enable stat-var test.
* Enable WebGPU tests in CI (#5239)Anders Leino2024-10-15
|
* enable more metal tests (#4326)skallweitNV2024-06-10
|
* Metal compute tests (#4292)skallweitNV2024-06-07
|
* Support visibility control and default to `internal`. (#3380)Yong He2023-12-06
| | | | | | | | | | | | | | | | | | | * Support visibility control and default to `internal`. * Fix wip. * Fixes. * Fix. * Fix test. * Add legacy language detection and compatibility for existing code. * Add doc. --------- Co-authored-by: Yong He <yhe@nvidia.com>
* Warning on lossy implicit casts. (#2367)Yong He2022-08-17
| | | | | | | | | | | | | | | * Warning on bool to float conversion. * Fix test cases. * Improve. * LanguageServer: don't show constant value for non constant variables. * Fix tests. * Fix warnings in tests. Co-authored-by: Yong He <yhe@nvidia.com>
* Fix initializer lists for derived structs (#1862)T. Foley2021-05-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the user has a derived `struct` type: ```hlsl struct Base { int b = 1; } struct Derived : Base { int d = 2; } ``` Then it is still reasonable for them to want to use initializer lists when declaring variables using the `Derived` type: ```hlsl Derived x = {}; Derived y = { 7, 8 }; ``` This change implements two missing pieces of functionality in the Slang compiler to allow this case: * First, when the front-end semantic checks are applied to an initializer list, if the type being initialized is a derived `struct` type it always expects to find initialization arguments for its base type before those for its fields. * Second, when lowering an initializer-list expression from the AST to the IR, the compiler expects the first argument in the list to be the initial value for the base field (if any). This also applies to default-initialization of fields/variables. This change slightly entangles front-end logic with the logic for how struct inheritance is lowered to the IR, but the behavior is unlikely to confuse users who expect C++-like layout. It is worth noting that with this change it should be possible to initialize the base type using either a nested initializer list or flat arguments: ```hlsl struct BigBase { int x; int y; int z; } struct BigDerived : BigBase { int w; } BigDerived a = { {1,2,3}, 4 }; BigDerived b = { 1, 2, 3, 4 }; ``` This behavior should Just Work because of the existing C-like rules for initializer lists where an aggregate can be initialized by either a `{}`-enclosed block or distinct values for its leaf fields.
* Fix a bug in struct inheritance (#1861)T. Foley2021-05-27
| | | | | | | | | | | | | | | | | | | During lowering from AST to IR, the Slang compiler translates code that uses `struct` inheritance: ```hlsl struct Base { int a; } struct Derived : Base {} ``` into code where the inheritance relationship is "witnessed" by a simple field: ```hlsl struct Base { int a; } struct Derived { Base __anonymous_field__; } ``` The underlying bug here is that the `__anonymous_field__` that the compiler generated during IR lowering was not being given any linkage decorations (no mangled name). As a result, if multiple separately-compiled modules all access that field they could disagree on its identity as an IR instruction. This could lead to output code being generated where the declaration of `__anonymous_field__` uses one IR instruction, but accesses use another. This change includes a fix for the issue, and a test that serves as a reproducer for the original problem.
* Convert more tests to use shader objects (#1659)Tim Foley2021-01-15
| | | | | | | | | | | | | | | | | | | | | | | This change converts a large number of our existing tests to use the `ShaderObject` support that was added to the `gfx` layer. In many cases, tests were just updated to pass `-shaderobj` and the result Just Worked. In other cases, a `name` attribute had to be added to one or more `TEST_INPUT` lines. For tests that did not work with shader objects "out of the box," I spent a little bit of time trying to get them work, but fell back to letting those tests run in the older mode. Future changes to the infrastructure will be needed to get those additional tests working in the new path. Along with the changes to test files, the following implementation changes were made to get additional tests working: * Because the shader object mode uses explicit register bindings (from reflection), the hacky logic that was offseting `u` registers for D3D12 based on the number of render targets gets disabled (by another hack). * The "flat" reflection information coming from Slang was not correctly reporting "binding ranges" for things that consumed only uniform data (which would be everything on CUDA/CPU), so it was refactored to properly include binding ranges for anything where the type of the field/variable implied a binding range should be created (even if the `LayoutResourceKind` was `::Uniform`). * A few fixes were made to the CUDA implementation of `Renderer`, in order to get additional tests up and running. Most of these changes had to do with texture bindings, which hadn't really been tested previously. In addition, a few changes were made that were attempts at getting more tests working, but didn't actually help. These could be dropped if requested: * As a quality-of-life feature (not being used) the `object` style of `TEST_INPUT` line is upgraded to support inferring the type to use from the type of the input being set. * Any `object` shader input lines get ignored in non-shader-object mode.
* fixup: actually make the test case test somethingTim Foley2020-06-19
|
* Work on struct inheritance and interfacesTim Foley2020-06-18
The main new feature that works here is that a derived `struct` type can satisfy one or more interface requirements using methods it inherited from a base `struct` type: ```hlsl interface ICounter { [mutating] void increment(); } struct CounterBase { int val; [mutating] void increment() { val++; } } struct ResetableCounter : CounterBase, ICounter { [mutating] void reset() { val = 0; } } ``` Here the derived `ResetableCounter` type is satisfying the `increment()` requirement from `ICounter` using the inherited `CounterBase` method instead of one defined on `ResetableCounter`. The crux of the problem here was that after lowering to HLSL/GLSL, the above code looks something like: ```hlsl struct CounterBase { int val; }; void CounterBase_increment(in out CounterBase this) { this.val++; } struct ResetableCounter { CounterBase base; } void ResetableCounter_reset(in out ResetableCounter this) { this.base.val = 0; } ``` The central problem is that `CounterBase_increment` here is not type-compatible what we expect to find in the witness table for `ResetableCounter : ICounter`: the `this` parameter has the wrong type! The basic solution strategy here is to intercept the search for a witness to sastify an interface requirement in `findWitnessForInterfaceRequirement` (those witnesses get collected into a witness table). The revised logic first looks for an exact match, which will only consider members introduced for the type itself, and not those introduced by base types. If an exact match for a method requirement is not found, the semantic checker then tries to *synthesize* a witness for the requirement, which more or less amounts to generating a function like: ```hlsl [mutating] void ResetableCounter::synthesized_increment() { this.increment(); } ``` The body of that synthesized method will type-check just fine in this case (because it desugars into `this.base.increment()`, more or less), and thus the synthesized method declaration can be used as the actual witness that drives downstream code generation. Details: * I added some options to lookup to allow us to explicitly skip member lookup through base interfaces; this should make sure that we don't accidentally satisfy an interface requirement using a member of the same or another interface (since such members are conceptually `abstract`). * As it originally stood, the semantic checker was allowing `CounterBase.increment()` to satisfy the `increment()` requirement of `ResetableCounter` directly, with the result that we got invalid HLSL/GLSL code as output. In order to avoid this and other bad cases, I made sure that the "exact match" case of requirement satisfaction ignores members that included any "breadcrumbs" in the lookup result item (since the breadcrumbs would all indicate transformations that needed to be applied to `this` to find the right member). * If we eventually have targets where `this` is passed by pointer/reference in all cases, then all of this work is not needed for the common case of single inheritance, and the base-type method should be usable as a witness directly. I don't see any easy way to handle that special case without producing target-dependent code in the front-end. It might be that we need an IR pass that can detect functions that are trivial "forwarding" functions and replace them with the function they forward to. * This change includes a test case that should have come along with the original PR that started adding struct inheritance Caveats: * The comments in this change talk about things like allowing a method with a default parameter to satisfy a requirement without that parameter. That scenario won't actually work at present because we still have an enormous hack in our logic for checking methods against requirements: we don't actually consider their signatures! I couldn't fold a fix for that issue into this change because there are subtle corner cases around associated types that we need to handle correctly (which were part of the reason why the checking is as hacked as it is) * This change does *not* try to test or address the case where we want to have a `Derived` type conform to `ISomething` because it inherits from `Base` and `Base : ISomething`. That case has its own details that need to be worked out, but ideally can follow a similar implementation strategy when it comes to re-using methods from `Base` to satisfy requirement on `Derived`.