Skip to content

Commit 13a9c1b

Browse files
committed
[wgsl-out] avoid shadowing built-ins
1 parent 92e95ff commit 13a9c1b

25 files changed

+334
-43
lines changed

naga/src/back/glsl/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ impl<'a, W: Write> Writer<'a, W> {
663663
namer.reset(
664664
module,
665665
&keywords::RESERVED_KEYWORD_SET,
666+
proc::KeywordSet::empty(),
666667
proc::CaseInsensitiveKeywordSet::empty(),
667668
&[
668669
"gl_", // all GL built-in variables

naga/src/back/hlsl/writer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
155155
self.namer.reset(
156156
module,
157157
&super::keywords::RESERVED_SET,
158+
proc::KeywordSet::empty(),
158159
&super::keywords::RESERVED_CASE_INSENSITIVE_SET,
159160
super::keywords::RESERVED_PREFIXES,
160161
&mut self.names,

naga/src/back/msl/writer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4279,6 +4279,7 @@ impl<W: Write> Writer<W> {
42794279
self.namer.reset(
42804280
module,
42814281
&super::keywords::RESERVED_SET,
4282+
proc::KeywordSet::empty(),
42824283
proc::CaseInsensitiveKeywordSet::empty(),
42834284
&[CLAMPED_LOD_LOAD_PREFIX],
42844285
&mut self.names,

naga/src/back/wgsl/writer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl<W: Write> Writer<W> {
100100
self.namer.reset(
101101
module,
102102
&crate::keywords::wgsl::RESERVED_SET,
103+
&crate::keywords::wgsl::BUILTIN_IDENTIFIER_SET,
103104
// an identifier must not start with two underscore
104105
proc::CaseInsensitiveKeywordSet::empty(),
105106
&["__", "_naga"],

naga/src/keywords/wgsl.rs

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,266 @@ pub const RESERVED: &[&str] = &[
190190
///
191191
/// See <https://github.com/gfx-rs/wgpu/pull/7338> for benchmarks.
192192
pub static RESERVED_SET: RacyLock<KeywordSet> = RacyLock::new(|| KeywordSet::from_iter(RESERVED));
193+
194+
/// Shadowable words that the WGSL backend should avoid using for declarations.
195+
///
196+
/// Includes:
197+
/// - [6.9. Predeclared Types and Type-Generators]
198+
/// - [6.3.1. Predeclared enumerants]
199+
/// - [17. Built-in Functions]
200+
///
201+
/// This set must be separate from the [`RESERVED`] set above since the
202+
/// [`Namer`](crate::proc::Namer) must ignore these identifiers if they appear
203+
/// as struct member names. This is because this set contains `fract` and `exp`
204+
/// which are also names used by return types of the `frexp` and `modf` built-in functions.
205+
///
206+
/// [6.9. Predeclared Types and Type-Generators]: https://www.w3.org/TR/WGSL/#predeclared-types
207+
/// [6.3.1. Predeclared enumerants]: https://www.w3.org/TR/WGSL/#predeclared-enumerants
208+
/// [17. Built-in Functions]: https://www.w3.org/TR/WGSL/#builtin-functions
209+
pub const BUILTIN_IDENTIFIERS: &[&str] = &[
210+
// types
211+
"bool",
212+
"i32",
213+
"u32",
214+
"f32",
215+
"f16",
216+
"array",
217+
"atomic",
218+
"vec2",
219+
"vec3",
220+
"vec4",
221+
"mat2x2",
222+
"mat2x3",
223+
"mat2x4",
224+
"mat3x2",
225+
"mat3x3",
226+
"mat3x4",
227+
"mat4x2",
228+
"mat4x3",
229+
"mat4x4",
230+
"ptr",
231+
"sampler",
232+
"sampler_comparison",
233+
"texture_1d",
234+
"texture_2d",
235+
"texture_2d_array",
236+
"texture_3d",
237+
"texture_cube",
238+
"texture_cube_array",
239+
"texture_multisampled_2d",
240+
"texture_depth_multisampled_2d",
241+
"texture_external",
242+
"texture_storage_1d",
243+
"texture_storage_2d",
244+
"texture_storage_2d_array",
245+
"texture_storage_3d",
246+
"texture_depth_2d",
247+
"texture_depth_2d_array",
248+
"texture_depth_cube",
249+
"texture_depth_cube_array",
250+
// enumerants
251+
"read",
252+
"write",
253+
"read_write",
254+
"function",
255+
"private",
256+
"workgroup",
257+
"uniform",
258+
"storage",
259+
"rgba8unorm",
260+
"rgba8snorm",
261+
"rgba8uint",
262+
"rgba8sint",
263+
"rgba16unorm",
264+
"rgba16snorm",
265+
"rgba16uint",
266+
"rgba16sint",
267+
"rgba16float",
268+
"rg8unorm",
269+
"rg8snorm",
270+
"rg8uint",
271+
"rg8sint",
272+
"rg16unorm",
273+
"rg16snorm",
274+
"rg16uint",
275+
"rg16sint",
276+
"rg16float",
277+
"r32uint",
278+
"r32sint",
279+
"r32float",
280+
"rg32uint",
281+
"rg32sint",
282+
"rg32float",
283+
"rgba32uint",
284+
"rgba32sint",
285+
"rgba32float",
286+
"bgra8unorm",
287+
"r8unorm",
288+
"r8snorm",
289+
"r8uint",
290+
"r8sint",
291+
"r16unorm",
292+
"r16snorm",
293+
"r16uint",
294+
"r16sint",
295+
"r16float",
296+
"rgb10a2unorm",
297+
"rgb10a2uint",
298+
"rg11b10ufloat",
299+
// functions
300+
"bitcast",
301+
"all",
302+
"any",
303+
"select",
304+
"arrayLength",
305+
"abs",
306+
"acos",
307+
"acosh",
308+
"asin",
309+
"asinh",
310+
"atan",
311+
"atanh",
312+
"atan2",
313+
"ceil",
314+
"clamp",
315+
"cos",
316+
"cosh",
317+
"countLeadingZeros",
318+
"countOneBits",
319+
"countTrailingZeros",
320+
"cross",
321+
"degrees",
322+
"determinant",
323+
"distance",
324+
"dot",
325+
"dot4U8Packed",
326+
"dot4I8Packed",
327+
"exp",
328+
"exp2",
329+
"extractBits",
330+
"faceForward",
331+
"firstLeadingBit",
332+
"firstTrailingBit",
333+
"floor",
334+
"fma",
335+
"fract",
336+
"frexp",
337+
"insertBits",
338+
"inverseSqrt",
339+
"ldexp",
340+
"length",
341+
"log",
342+
"log2",
343+
"max",
344+
"min",
345+
"mix",
346+
"modf",
347+
"normalize",
348+
"pow",
349+
"quantizeToF16",
350+
"radians",
351+
"reflect",
352+
"refract",
353+
"reverseBits",
354+
"round",
355+
"saturate",
356+
"sign",
357+
"sin",
358+
"sinh",
359+
"smoothstep",
360+
"sqrt",
361+
"step",
362+
"tan",
363+
"tanh",
364+
"transpose",
365+
"trunc",
366+
"dpdx",
367+
"dpdxCoarse",
368+
"dpdxFine",
369+
"dpdy",
370+
"dpdyCoarse",
371+
"dpdyFine",
372+
"fwidth",
373+
"fwidthCoarse",
374+
"fwidthFine",
375+
"textureDimensions",
376+
"textureGather",
377+
"textureGatherCompare",
378+
"textureLoad",
379+
"textureNumLayers",
380+
"textureNumLevels",
381+
"textureNumSamples",
382+
"textureSample",
383+
"textureSampleBias",
384+
"textureSampleCompare",
385+
"textureSampleCompareLevel",
386+
"textureSampleGrad",
387+
"textureSampleLevel",
388+
"textureSampleBaseClampToEdge",
389+
"textureStore",
390+
"atomicLoad",
391+
"atomicStore",
392+
"atomicAdd",
393+
"atomicSub",
394+
"atomicMax",
395+
"atomicMin",
396+
"atomicAnd",
397+
"atomicOr",
398+
"atomicXor",
399+
"atomicExchange",
400+
"atomicCompareExchangeWeak",
401+
"pack4x8snorm",
402+
"pack4x8unorm",
403+
"pack4xI8",
404+
"pack4xU8",
405+
"pack4xI8Clamp",
406+
"pack4xU8Clamp",
407+
"pack2x16snorm",
408+
"pack2x16unorm",
409+
"pack2x16float",
410+
"unpack4x8snorm",
411+
"unpack4x8unorm",
412+
"unpack4xI8",
413+
"unpack4xU8",
414+
"unpack2x16snorm",
415+
"unpack2x16unorm",
416+
"unpack2x16float",
417+
"storageBarrier",
418+
"textureBarrier",
419+
"workgroupBarrier",
420+
"workgroupUniformLoad",
421+
"subgroupAdd",
422+
"subgroupExclusiveAdd",
423+
"subgroupInclusiveAdd",
424+
"subgroupAll",
425+
"subgroupAnd",
426+
"subgroupAny",
427+
"subgroupBallot",
428+
"subgroupBroadcast",
429+
"subgroupBroadcastFirst",
430+
"subgroupElect",
431+
"subgroupMax",
432+
"subgroupMin",
433+
"subgroupMul",
434+
"subgroupExclusiveMul",
435+
"subgroupInclusiveMul",
436+
"subgroupOr",
437+
"subgroupShuffle",
438+
"subgroupShuffleDown",
439+
"subgroupShuffleUp",
440+
"subgroupShuffleXor",
441+
"subgroupXor",
442+
"quadBroadcast",
443+
"quadSwapDiagonal",
444+
"quadSwapX",
445+
"quadSwapY",
446+
// not in the WGSL spec
447+
"i64",
448+
"u64",
449+
"f64",
450+
"push_constant",
451+
"r64uint",
452+
];
453+
454+
pub static BUILTIN_IDENTIFIER_SET: RacyLock<KeywordSet> =
455+
RacyLock::new(|| KeywordSet::from_iter(BUILTIN_IDENTIFIERS));

naga/src/proc/namer.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub struct Namer {
9090
/// The last numeric suffix used for each base name. Zero means "no suffix".
9191
unique: FastHashMap<String, u32>,
9292
keywords: &'static KeywordSet,
93+
builtin_identifiers: &'static KeywordSet,
9394
keywords_case_insensitive: &'static CaseInsensitiveKeywordSet,
9495
reserved_prefixes: Vec<&'static str>,
9596
}
@@ -173,6 +174,13 @@ impl Namer {
173174
/// Guarantee uniqueness by applying a numeric suffix when necessary. If `label_raw`
174175
/// itself ends with digits, separate them from the suffix with an underscore.
175176
pub fn call(&mut self, label_raw: &str) -> String {
177+
self.call_impl(label_raw, false)
178+
}
179+
180+
/// See documentation of [`Self::call`]. Additionally this function allows ignoring
181+
/// `Namer::builtin_identifiers` mainly for [`NameKey::StructMember`] since struct members
182+
/// can't shadow builtin identifiers.
183+
pub fn call_impl(&mut self, label_raw: &str, ignore_builtin_identifiers: bool) -> String {
176184
use core::fmt::Write as _; // for write!-ing to Strings
177185

178186
let base = self.sanitize(label_raw);
@@ -196,6 +204,8 @@ impl Namer {
196204
if base.ends_with(char::is_numeric)
197205
|| self.keywords.contains(base.as_ref())
198206
|| self.keywords_case_insensitive.contains(base.as_ref())
207+
|| (!ignore_builtin_identifiers
208+
&& self.builtin_identifiers.contains(base.as_ref()))
199209
{
200210
suffixed.push(SEPARATOR);
201211
}
@@ -209,10 +219,22 @@ impl Namer {
209219
}
210220

211221
pub fn call_or(&mut self, label: &Option<String>, fallback: &str) -> String {
212-
self.call(match *label {
213-
Some(ref name) => name,
214-
None => fallback,
215-
})
222+
self.call_or_impl(label, fallback, false)
223+
}
224+
225+
fn call_or_impl(
226+
&mut self,
227+
label: &Option<String>,
228+
fallback: &str,
229+
ignore_builtin_identifiers: bool,
230+
) -> String {
231+
self.call_impl(
232+
match *label {
233+
Some(ref name) => name,
234+
None => fallback,
235+
},
236+
ignore_builtin_identifiers,
237+
)
216238
}
217239

218240
/// Enter a local namespace for things like structs.
@@ -231,6 +253,7 @@ impl Namer {
231253
&mut self,
232254
module: &crate::Module,
233255
reserved_keywords: &'static KeywordSet,
256+
builtin_identifiers: &'static KeywordSet,
234257
reserved_keywords_case_insensitive: &'static CaseInsensitiveKeywordSet,
235258
reserved_prefixes: &[&'static str],
236259
output: &mut FastHashMap<NameKey, String>,
@@ -240,6 +263,7 @@ impl Namer {
240263

241264
self.unique.clear();
242265
self.keywords = reserved_keywords;
266+
self.builtin_identifiers = builtin_identifiers;
243267
self.keywords_case_insensitive = reserved_keywords_case_insensitive;
244268

245269
// Choose fallback names for anonymous entry point return types.
@@ -281,7 +305,7 @@ impl Namer {
281305
// struct members have their own namespace, because access is always prefixed
282306
self.namespace(members.len(), |namer| {
283307
for (index, member) in members.iter().enumerate() {
284-
let name = namer.call_or(&member.name, "member");
308+
let name = namer.call_or_impl(&member.name, "member", true);
285309
output.insert(NameKey::StructMember(ty_handle, index as u32), name);
286310
}
287311
})

naga/tests/out/wgsl/glsl-931-constant-emitting.frag.wgsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
const constant: i32 = 10i;
22

3-
fn function() -> f32 {
3+
fn function_() -> f32 {
44
return 0f;
55
}
66

77
fn main_1() {
8-
let _e0 = function();
8+
let _e0 = function_();
99
return;
1010
}
1111

0 commit comments

Comments
 (0)