Skip to content

Commit 9ec6b91

Browse files
kaizhangNVslangbot
andauthored
Feature/initialize list side branch (#6058)
* 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>
1 parent 4b35064 commit 9ec6b91

File tree

85 files changed

+1719
-280
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1719
-280
lines changed

.github/workflows/falcor-test.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ jobs:
5959
run: |
6060
mkdir FalcorBin
6161
cd FalcorBin
62-
Copy-Item -Path 'C:\Falcor\build\windows-vs2022\bin' -Destination '.\build\windows-vs2022\bin' -Recurse -Exclude ("*.pdb")
63-
Copy-Item -Path 'C:\Falcor\tests' -Destination '.\' -Recurse
64-
Copy-Item -Path 'C:\Falcor\tools' -Destination '.\' -Recurse
65-
Copy-Item -Path 'C:\Falcor\media' -Destination '.\' -Recurse
66-
Copy-Item -Path 'C:\Falcor\media_internal' -Destination '.\' -Recurse
67-
Copy-Item -Path 'C:\Falcor\scripts' -Destination '.\' -Recurse
62+
Copy-Item -Path 'C:\Falcor-new\build\windows-vs2022\bin' -Destination '.\build\windows-vs2022\bin' -Recurse -Exclude ("*.pdb")
63+
Copy-Item -Path 'C:\Falcor-new\tests' -Destination '.\' -Recurse
64+
Copy-Item -Path 'C:\Falcor-new\tools' -Destination '.\' -Recurse
65+
Copy-Item -Path 'C:\Falcor-new\media' -Destination '.\' -Recurse
66+
Copy-Item -Path 'C:\Falcor-new\media_internal' -Destination '.\' -Recurse
67+
Copy-Item -Path 'C:\Falcor-new\scripts' -Destination '.\' -Recurse
6868
cd ..\
6969
- name: Build Slang
7070
run: |

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ cmake_policy(SET CMP0091 NEW)
3333
# tree relocatable
3434
set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
3535

36+
# Export the compile datebase as a json file, this can be used by VIM language server
37+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
38+
3639
# Enable placing targets into a hierarchy for IDE generators
3740
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
3841

docs/proposals/004-initialization.md

+36-2
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,39 @@ MyType x = MyType(y); // equivalent to `x = y`.
129129

130130
The compiler will attempt to resolve all type casts using type coercion rules, if that failed, will fall back to resolve it as a constructor call.
131131

132+
### Inheritance Initialization
133+
For derived structs, slang will synthesized the constructor by bringing the parameters from the base struct's constructor if the base struct also has a synthesized constructor. For example:
134+
```csharp
135+
struct Base
136+
{
137+
int x;
138+
// compiler synthesizes:
139+
// __init(int x) { ... }
140+
}
141+
struct Derived : Base
142+
{
143+
int y;
144+
// compiler synthesizes:
145+
// __init(int x, int y) { ... }
146+
}
147+
```
148+
149+
However, if the base struct has explicit ctors, the compiler will not synthesize a constructor for the derived struct.
150+
For example, given
151+
```csharp
152+
struct Base { int x; __init(int x) { this.x = x; } }
153+
struct Derived : Base { int y;}
154+
```
155+
The compiler will not synthesize a constructor for `Derived`, and the following code will fail to compile:
156+
```csharp
157+
158+
Derived d = {1}; // error, no matching ctor.
159+
Derived d = {1, 2}; // error, no matching ctor.
160+
Derived d = Derived(1); // error, no matching ctor.
161+
Derived d = Derived(1, 2); // error, no matching ctor.
162+
```
163+
164+
132165
### Initialization List
133166

134167
Slang allows initialization of a variable by assigning it with an initialization list.
@@ -167,7 +200,8 @@ If the above code passes type check, then it will be used as the way to initiali
167200

168201
If the above code does not pass type check, and if there is only one constructor for`MyType` that is synthesized as described in the previous section (and therefore marked as `[Synthesized]`, Slang continues to check if `S` meets the standard of a "legacy C-style struct` type.
169202
A type is a "legacy C-Style struct" if all of the following conditions are met:
170-
- It is a user-defined struct type or a basic scalar, vector or matrix type, e.g. `int`, `float4x4`.
203+
- It is a user-defined struct type or an enum, a basic scalar, vector or matrix type, e.g. `int`, `float4x4`.
204+
- It does not inherit from any other types.
171205
- It does not contain any explicit constructors defined by the user.
172206
- All its members have the same visibility as the type itself.
173207
- All its members are legacy C-Style structs or arrays of legacy C-style structs.
@@ -405,4 +439,4 @@ Alternatives Considered
405439

406440
One important decision point is whether or not Slang should allow variables to be left in uninitialized state after its declaration as it is allowed in C++. In contrast, C# forces everything to be default initialized at its declaration site, which come at the cost of incurring the burden to developers to come up with a way to define the default value for each type.
407441
Our opinion is we want to allow things as uninitialized, and to have the compiler validation checks to inform
408-
the developer something is wrong if they try to use a variable in uninitialized state. We believe it is desirable to tell the developer what's wrong instead of using a heavyweight mechanism to ensure everything is initialized at declaration sites, which can have non-trivial performance consequences for GPU programs, especially when the variable is declared in groupshared memory.
442+
the developer something is wrong if they try to use a variable in uninitialized state. We believe it is desirable to tell the developer what's wrong instead of using a heavyweight mechanism to ensure everything is initialized at declaration sites, which can have non-trivial performance consequences for GPU programs, especially when the variable is declared in groupshared memory.

source/slang/core.meta.slang

+2
Original file line numberDiff line numberDiff line change
@@ -1749,6 +1749,8 @@ struct NativeString
17491749
__implicit_conversion($(kConversionCost_None))
17501750
__intrinsic_op($(kIROp_getNativeStr))
17511751
__init(String value);
1752+
1753+
__init() { this = NativeString(""); }
17521754
};
17531755

17541756
extension Ptr<void>

source/slang/hlsl.meta.slang

+12-11
Original file line numberDiff line numberDiff line change
@@ -21107,11 +21107,12 @@ ${
2110721107

2110821108
case hlsl:
2110921109
uint isSingleLod = 0;
21110-
Footprint footprint = {__queryFootprint$(CoarseOrFine)NVAPI(
21110+
__queryFootprint$(CoarseOrFine)NVAPI(
2111121111
Shape.dimensions,
2111221112
__getRegisterSpace(this), __getRegisterIndex(this),
2111321113
__getRegisterSpace(sampler), __getRegisterIndex(sampler),
21114-
__vectorReshape<3>(coords), granularity, /* out */isSingleLod), false};
21114+
__vectorReshape<3>(coords), granularity, /* out */isSingleLod);
21115+
Footprint footprint = {false};
2111521116
footprint._isSingleLevel = (isSingleLod != 0);
2111621117
return footprint;
2111721118
}
@@ -21140,12 +21141,12 @@ ${
2114021141
return footprint;
2114121142
case hlsl:
2114221143
uint isSingleLod = 0;
21143-
Footprint footprint = {__queryFootprint$(CoarseOrFine)BiasNVAPI(
21144+
__queryFootprint$(CoarseOrFine)BiasNVAPI(
2114421145
Shape.dimensions,
2114521146
__getRegisterSpace(this), __getRegisterIndex(this),
2114621147
__getRegisterSpace(sampler), __getRegisterIndex(sampler),
21147-
__vectorReshape<3>(coords), granularity, lodBias, /* out */isSingleLod), false};
21148-
21148+
__vectorReshape<3>(coords), granularity, lodBias, /* out */isSingleLod);
21149+
Footprint footprint = {false};
2114921150
footprint._isSingleLevel = (isSingleLod != 0);
2115021151
return footprint;
2115121152
}
@@ -21223,12 +21224,12 @@ ${
2122321224
return footprint;
2122421225
case hlsl:
2122521226
uint isSingleLod = 0;
21226-
Footprint footprint = {__queryFootprint$(CoarseOrFine)LevelNVAPI(
21227+
__queryFootprint$(CoarseOrFine)LevelNVAPI(
2122721228
Shape.dimensions,
2122821229
__getRegisterSpace(this), __getRegisterIndex(this),
2122921230
__getRegisterSpace(sampler), __getRegisterIndex(sampler),
21230-
__vectorReshape<3>(coords), granularity, lod, /* out */isSingleLod), false};
21231-
21231+
__vectorReshape<3>(coords), granularity, lod, /* out */isSingleLod);
21232+
Footprint footprint = {false};
2123221233
footprint._isSingleLevel = (isSingleLod != 0);
2123321234
return footprint;
2123421235
}
@@ -21262,12 +21263,12 @@ ${{{
2126221263
return footprint;
2126321264
case hlsl:
2126421265
uint isSingleLod = 0;
21265-
Footprint footprint = {__queryFootprint$(CoarseOrFine)GradNVAPI(
21266+
__queryFootprint$(CoarseOrFine)GradNVAPI(
2126621267
Shape.dimensions,
2126721268
__getRegisterSpace(this), __getRegisterIndex(this),
2126821269
__getRegisterSpace(sampler), __getRegisterIndex(sampler),
21269-
__vectorReshape<3>(coords), granularity, __vectorReshape<3>(dx), __vectorReshape<3>(dy), /* out */isSingleLod), false};
21270-
21270+
__vectorReshape<3>(coords), granularity, __vectorReshape<3>(dx), __vectorReshape<3>(dy), /* out */isSingleLod);
21271+
Footprint footprint = {false};
2127121272
footprint._isSingleLevel = (isSingleLod != 0);
2127221273
return footprint;
2127321274
}

source/slang/slang-ast-decl.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ class AggTypeDecl : public AggTypeDeclBase
165165
class StructDecl : public AggTypeDecl
166166
{
167167
SLANG_AST_CLASS(StructDecl);
168+
169+
SLANG_UNREFLECTED
170+
// We will use these auxiliary to help in synthesizing the member initialize constructor.
171+
Slang::HashSet<VarDeclBase*> m_membersVisibleInCtor;
168172
};
169173

170174
class ClassDecl : public AggTypeDecl
@@ -374,9 +378,20 @@ class ConstructorDecl : public FunctionDeclBase
374378
{
375379
SLANG_AST_CLASS(ConstructorDecl)
376380

377-
// Indicates whether the declaration was synthesized by
378-
// slang and not actually provided by the user
379-
bool isSynthesized = false;
381+
enum class ConstructorFlavor : int
382+
{
383+
UserDefined = 0x00,
384+
// Indicates whether the declaration was synthesized by
385+
// Slang and not explicitly provided by the user
386+
SynthesizedDefault = 0x01,
387+
// Member initialize constructor is a synthesized ctor,
388+
// but it takes parameters.
389+
SynthesizedMemberInit = 0x02
390+
};
391+
392+
int m_flavor = (int)ConstructorFlavor::UserDefined;
393+
void addFlavor(ConstructorFlavor flavor) { m_flavor |= (int)flavor; }
394+
bool containsFlavor(ConstructorFlavor flavor) { return m_flavor & (int)flavor; }
380395
};
381396

382397
// A subscript operation used to index instances of a type

source/slang/slang-ast-expr.h

+7
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ class InitializerListExpr : public Expr
135135
{
136136
SLANG_AST_CLASS(InitializerListExpr)
137137
List<Expr*> args;
138+
139+
bool useCStyleInitialization = true;
138140
};
139141

140142
class GetArrayLengthExpr : public Expr
@@ -193,6 +195,11 @@ class InvokeExpr : public AppExprBase
193195
SLANG_AST_CLASS(InvokeExpr)
194196
};
195197

198+
class ExplicitCtorInvokeExpr : public InvokeExpr
199+
{
200+
SLANG_AST_CLASS(ExplicitCtorInvokeExpr)
201+
};
202+
196203
enum class TryClauseType
197204
{
198205
None,

0 commit comments

Comments
 (0)