Import Tint changes from Dawn Changes: - 51cf5838e2f9654c3073e79fed3c84c23377af80 [tint][sem] Add more Declaration() methods by Ben Clayton <bclayton@google.com> - 5a6b701b2dbf73868275fb13bdc6073b7b8642d5 Add ClampFragDepth transform to GLSL writer. by Stephen White <senorblanco@chromium.org> - 1b00745fc9e02ba00ff169c73d8b4bd2340ae6e5 [tint][ir] Don't emit instructions with abstract types. by Ben Clayton <bclayton@google.com> GitOrigin-RevId: 51cf5838e2f9654c3073e79fed3c84c23377af80 Change-Id: Ib38a806a1c2db501d4016f1870ce972953c9cba5 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/174641 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc index 4d18bb9..1601a76 100644 --- a/src/tint/cmd/tint/main.cc +++ b/src/tint/cmd/tint/main.cc
@@ -1080,11 +1080,18 @@ gen_options.texture_builtins_from_uniform = std::move(textureBuiltinsFromUniform); auto entry_point = inspector.GetEntryPoint(entry_point_name); + uint32_t offset = entry_point.push_constant_size; if (entry_point.instance_index_used) { // Place the first_instance push constant member after user-defined push constants (if // any). - gen_options.first_instance_offset = entry_point.push_constant_size; + gen_options.first_instance_offset = offset; + offset += 4; + } + if (entry_point.frag_depth_used) { + gen_options.min_depth_offset = offset + 0; + gen_options.max_depth_offset = offset + 4; + offset += 8; } auto result = tint::glsl::writer::Generate(prg, gen_options, entry_point_name);
diff --git a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc index 326c1a2..764b779 100644 --- a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc +++ b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
@@ -61,6 +61,7 @@ #include "src/tint/lang/wgsl/ast/transform/binding_remapper.h" #include "src/tint/lang/wgsl/ast/transform/builtin_polyfill.h" #include "src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.h" +#include "src/tint/lang/wgsl/ast/transform/clamp_frag_depth.h" #include "src/tint/lang/wgsl/ast/transform/demote_to_helper.h" #include "src/tint/lang/wgsl/ast/transform/direct_variable_access.h" #include "src/tint/lang/wgsl/ast/transform/disable_uniformity_analysis.h" @@ -206,6 +207,10 @@ manager.Add<ast::transform::OffsetFirstIndex>(); + // ClampFragDepth must come before CanonicalizeEntryPointIO, or the assignments to FragDepth are + // lost + manager.Add<ast::transform::ClampFragDepth>(); + // CanonicalizeEntryPointIO must come after Robustness manager.Add<ast::transform::CanonicalizeEntryPointIO>(); @@ -249,6 +254,8 @@ data.Add<ast::transform::OffsetFirstIndex::Config>(std::nullopt, options.first_instance_offset); + data.Add<ast::transform::ClampFragDepth::Config>(options.min_depth_offset, + options.max_depth_offset); SanitizedResult result; ast::transform::DataMap outputs; result.program = manager.Run(in, data, outputs);
diff --git a/src/tint/lang/glsl/writer/common/options.h b/src/tint/lang/glsl/writer/common/options.h index 7545366..62cd80c 100644 --- a/src/tint/lang/glsl/writer/common/options.h +++ b/src/tint/lang/glsl/writer/common/options.h
@@ -82,6 +82,12 @@ /// Offset of the firstInstance push constant. std::optional<int32_t> first_instance_offset; + /// Offset of the minDepth push constant. + std::optional<uint32_t> min_depth_offset; + + /// Offset of the maxDepth push constant. + std::optional<uint32_t> max_depth_offset; + /// Options used to map WGSL textureNumLevels/textureNumSamples builtins to internal uniform /// buffer values. If not specified, emits corresponding GLSL builtins /// textureQueryLevels/textureSamples directly. @@ -98,6 +104,8 @@ binding_remapper_options, external_texture_options, first_instance_offset, + min_depth_offset, + max_depth_offset, texture_builtins_from_uniform); };
diff --git a/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc b/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc index 4272172..c782db5 100644 --- a/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc +++ b/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc
@@ -66,6 +66,7 @@ if (options.clamp_frag_depth) { manager.Add<ast::transform::ClampFragDepth>(); + data.Add<ast::transform::ClampFragDepth::Config>(0, 4); } manager.Add<ast::transform::DisableUniformityAnalysis>();
diff --git a/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.cc b/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.cc index 59e6dd6..2b5e6a2 100644 --- a/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.cc +++ b/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.cc
@@ -35,6 +35,7 @@ #include "src/tint/lang/wgsl/ast/function.h" #include "src/tint/lang/wgsl/ast/module.h" #include "src/tint/lang/wgsl/ast/struct.h" +#include "src/tint/lang/wgsl/ast/transform/push_constant_helper.h" #include "src/tint/lang/wgsl/program/clone_context.h" #include "src/tint/lang/wgsl/program/program_builder.h" #include "src/tint/lang/wgsl/resolver/resolve.h" @@ -45,6 +46,7 @@ #include "src/tint/utils/macros/scoped_assignment.h" TINT_INSTANTIATE_TYPEINFO(tint::ast::transform::ClampFragDepth); +TINT_INSTANTIATE_TYPEINFO(tint::ast::transform::ClampFragDepth::Config); namespace tint::ast::transform { @@ -63,49 +65,37 @@ /// Runs the transform /// @returns the new program or SkipTransform if the transform is not required - Transform::ApplyResult Run() { - // Abort on any use of push constants in the module. - for (auto* global : src.AST().GlobalVariables()) { - if (auto* var = global->As<ast::Var>()) { - auto* v = src.Sem().Get(var); - if (TINT_UNLIKELY(v->AddressSpace() == core::AddressSpace::kPushConstant)) { - TINT_ICE() - << "ClampFragDepth doesn't know how to handle module that already use push " - "constants"; - return resolver::Resolve(b); - } - } - } - - if (!ShouldRun()) { + Transform::ApplyResult Run(const DataMap& inputs) { + const Config* cfg = inputs.Get<Config>(); + if (!cfg || !cfg->min_depth_offset.has_value() || !cfg->max_depth_offset.has_value()) { return SkipTransform; } + PushConstantHelper push_constant_helper(ctx); + // At least one entry-point needs clamping. Add the following to the module: // // enable chromium_experimental_push_constant; // - // struct FragDepthClampArgs { - // min : f32, - // max : f32, + // struct PushConstants { + // min_depth : f32, + // max_depth : f32, // } - // var<push_constant> frag_depth_clamp_args : FragDepthClampArgs; + // var<push_constant> push_constants : PushConstants; // // fn clamp_frag_depth(v : f32) -> f32 { - // return clamp(v, frag_depth_clamp_args.min, frag_depth_clamp_args.max); + // return clamp(v, push_constants.min, push_constants.max_depth); // } - b.Enable(wgsl::Extension::kChromiumExperimentalPushConstant); - b.Structure(b.Symbols().New("FragDepthClampArgs"), - Vector{b.Member("min", b.ty.f32()), b.Member("max", b.ty.f32())}); + push_constant_helper.InsertMember("min_depth", b.ty.f32(), *cfg->min_depth_offset); + push_constant_helper.InsertMember("max_depth", b.ty.f32(), *cfg->max_depth_offset); - auto args_sym = b.Symbols().New("frag_depth_clamp_args"); - b.GlobalVar(args_sym, b.ty("FragDepthClampArgs"), core::AddressSpace::kPushConstant); + Symbol buffer_name = push_constant_helper.Run(); auto base_fn_sym = b.Symbols().New("clamp_frag_depth"); b.Func(base_fn_sym, Vector{b.Param("v", b.ty.f32())}, b.ty.f32(), - Vector{b.Return(b.Call("clamp", "v", b.MemberAccessor(args_sym, "min"), - b.MemberAccessor(args_sym, "max")))}); + Vector{b.Return(b.Call("clamp", "v", b.MemberAccessor(buffer_name, "min_depth"), + b.MemberAccessor(buffer_name, "max_depth")))}); // If true, the currently cloned function returns frag depth directly as a scalar bool returns_frag_depth_as_value = false; @@ -185,17 +175,6 @@ } private: - /// @returns true if the transform should run - bool ShouldRun() { - for (auto* fn : src.AST().Functions()) { - if (fn->PipelineStage() == ast::PipelineStage::kFragment && - (ReturnsFragDepthAsValue(fn) || ReturnsFragDepthInStruct(fn))) { - return true; - } - } - - return false; - } /// @param attrs the attributes to examine /// @returns true if @p attrs contains a `@builtin(frag_depth)` attribute bool ContainsFragDepth(VectorRef<const ast::Attribute*> attrs) { @@ -237,9 +216,15 @@ ClampFragDepth::~ClampFragDepth() = default; ast::transform::Transform::ApplyResult ClampFragDepth::Apply(const Program& src, - const ast::transform::DataMap&, + const ast::transform::DataMap& inputs, ast::transform::DataMap&) const { - return State{src}.Run(); + return State{src}.Run(inputs); } +ClampFragDepth::Config::Config(std::optional<uint32_t> min_depth_off, + std::optional<uint32_t> max_depth_off) + : min_depth_offset(min_depth_off), max_depth_offset(max_depth_off) {} + +ClampFragDepth::Config::~Config() = default; + } // namespace tint::ast::transform
diff --git a/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.h b/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.h index 5bcd3ea..599b91c 100644 --- a/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.h +++ b/src/tint/lang/wgsl/ast/transform/clamp_frag_depth.h
@@ -69,6 +69,23 @@ /// Destructor ~ClampFragDepth() override; + /// Transform configuration options + struct Config final : public Castable<Config, ast::transform::Data> { + /// Constructor + /// @param min_depth_off Offset of the minDepth push constant + /// @param max_depth_off Offset of the maxDepth push constant + Config(std::optional<uint32_t> min_depth_off, std::optional<uint32_t> max_depth_off); + + /// Destructor + ~Config() override; + + /// Offset of the min_depth push constant + std::optional<uint32_t> min_depth_offset; + + /// Offset of the min_depth push constant + std::optional<uint32_t> max_depth_offset; + }; + /// @copydoc ast::transform::Transform::Apply ApplyResult Apply(const Program& program, const ast::transform::DataMap& inputs,
diff --git a/src/tint/lang/wgsl/ast/transform/clamp_frag_depth_test.cc b/src/tint/lang/wgsl/ast/transform/clamp_frag_depth_test.cc index cc09c6f..97f1f31 100644 --- a/src/tint/lang/wgsl/ast/transform/clamp_frag_depth_test.cc +++ b/src/tint/lang/wgsl/ast/transform/clamp_frag_depth_test.cc
@@ -40,48 +40,102 @@ EXPECT_FALSE(ShouldRun<ClampFragDepth>(src)); } -TEST_F(ClampFragDepthTest, ShouldRunNoFragmentShader) { +TEST_F(ClampFragDepthTest, ShouldRunNoConfig) { auto* src = R"( - fn f() -> f32 { + @fragment fn main() -> @builtin(frag_depth) f32 { return 0.0; } - - @compute @workgroup_size(1) fn cs() { - } - - @vertex fn vs() -> @builtin(position) vec4<f32> { - return vec4<f32>(); - } )"; EXPECT_FALSE(ShouldRun<ClampFragDepth>(src)); } -TEST_F(ClampFragDepthTest, ShouldRunFragmentShaderNoReturnType) { +TEST_F(ClampFragDepthTest, ShouldRunNoMin) { auto* src = R"( - @fragment fn main() { - } - )"; - - EXPECT_FALSE(ShouldRun<ClampFragDepth>(src)); -} - -TEST_F(ClampFragDepthTest, ShouldRunFragmentShaderNoFragDepth) { - auto* src = R"( - @fragment fn main() -> @location(0) f32 { + @fragment fn main() -> @builtin(frag_depth) f32 { return 0.0; } + )"; - struct S { - @location(0) a : f32, - @builtin(sample_mask) b : u32, - } - @fragment fn main2() -> S { - return S(); + DataMap config; + config.Add<ClampFragDepth::Config>(std::nullopt, 4); + + EXPECT_FALSE(ShouldRun<ClampFragDepth>(src, config)); +} + +TEST_F(ClampFragDepthTest, ShouldRunNoMinNoMax) { + auto* src = R"( + @fragment fn main() -> @builtin(frag_depth) f32 { + return 0.0; } )"; - EXPECT_FALSE(ShouldRun<ClampFragDepth>(src)); + DataMap config; + config.Add<ClampFragDepth::Config>(0, std::nullopt); + + EXPECT_FALSE(ShouldRun<ClampFragDepth>(src, config)); +} + +TEST_F(ClampFragDepthTest, ShouldRun) { + auto* src = R"( + @fragment fn main() -> @builtin(frag_depth) f32 { + return 0.0; + } + )"; + + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + + EXPECT_TRUE(ShouldRun<ClampFragDepth>(src, config)); +} + +TEST_F(ClampFragDepthTest, ExistingPushConstant) { + auto* src = R"( + enable chromium_experimental_push_constant; + + struct PushConstants { + a : f32, + } + + var<push_constant> push_constants : PushConstants; + @fragment fn main() -> @builtin(frag_depth) f32 { + return push_constants.a; + } + + )"; + + auto* expect = R"( +enable chromium_experimental_push_constant; + +struct PushConstants_1 { + a : f32, + /* @offset(4) */ + min_depth : f32, + /* @offset(8) */ + max_depth : f32, +} + +fn clamp_frag_depth(v : f32) -> f32 { + return clamp(v, push_constants.min_depth, push_constants.max_depth); +} + +struct PushConstants { + a : f32, +} + +var<push_constant> push_constants : PushConstants_1; + +@fragment +fn main() -> @builtin(frag_depth) f32 { + return clamp_frag_depth(push_constants.a); +} +)"; + + DataMap config; + config.Add<ClampFragDepth::Config>(4, 8); + + auto got = Run<ClampFragDepth>(src, config); + EXPECT_EQ(expect, str(got)); } TEST_F(ClampFragDepthTest, ShouldRunFragDepthAsDirectReturn) { @@ -91,7 +145,10 @@ } )"; - EXPECT_TRUE(ShouldRun<ClampFragDepth>(src)); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + + EXPECT_TRUE(ShouldRun<ClampFragDepth>(src, config)); } TEST_F(ClampFragDepthTest, ShouldRunFragDepthInStruct) { @@ -106,7 +163,10 @@ } )"; - EXPECT_TRUE(ShouldRun<ClampFragDepth>(src)); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + + EXPECT_TRUE(ShouldRun<ClampFragDepth>(src, config)); } TEST_F(ClampFragDepthTest, SingleReturnOfFragDepth) { @@ -119,15 +179,17 @@ auto* expect = R"( enable chromium_experimental_push_constant; -struct FragDepthClampArgs { - min : f32, - max : f32, +struct PushConstants { + /* @offset(0) */ + min_depth : f32, + /* @offset(4) */ + max_depth : f32, } -var<push_constant> frag_depth_clamp_args : FragDepthClampArgs; +var<push_constant> push_constants : PushConstants; fn clamp_frag_depth(v : f32) -> f32 { - return clamp(v, frag_depth_clamp_args.min, frag_depth_clamp_args.max); + return clamp(v, push_constants.min_depth, push_constants.max_depth); } @fragment @@ -136,7 +198,9 @@ } )"; - auto got = Run<ClampFragDepth>(src); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + auto got = Run<ClampFragDepth>(src, config); EXPECT_EQ(expect, str(got)); } @@ -153,15 +217,17 @@ auto* expect = R"( enable chromium_experimental_push_constant; -struct FragDepthClampArgs { - min : f32, - max : f32, +struct PushConstants { + /* @offset(0) */ + min_depth : f32, + /* @offset(4) */ + max_depth : f32, } -var<push_constant> frag_depth_clamp_args : FragDepthClampArgs; +var<push_constant> push_constants : PushConstants; fn clamp_frag_depth(v : f32) -> f32 { - return clamp(v, frag_depth_clamp_args.min, frag_depth_clamp_args.max); + return clamp(v, push_constants.min_depth, push_constants.max_depth); } @fragment @@ -173,7 +239,9 @@ } )"; - auto got = Run<ClampFragDepth>(src); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + auto got = Run<ClampFragDepth>(src, config); EXPECT_EQ(expect, str(got)); } @@ -190,15 +258,17 @@ auto* expect = R"( enable chromium_experimental_push_constant; -struct FragDepthClampArgs { - min : f32, - max : f32, +struct PushConstants { + /* @offset(0) */ + min_depth : f32, + /* @offset(4) */ + max_depth : f32, } -var<push_constant> frag_depth_clamp_args : FragDepthClampArgs; +var<push_constant> push_constants : PushConstants; fn clamp_frag_depth(v : f32) -> f32 { - return clamp(v, frag_depth_clamp_args.min, frag_depth_clamp_args.max); + return clamp(v, push_constants.min_depth, push_constants.max_depth); } @fragment @@ -212,7 +282,9 @@ } )"; - auto got = Run<ClampFragDepth>(src); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + auto got = Run<ClampFragDepth>(src, config); EXPECT_EQ(expect, str(got)); } @@ -230,15 +302,17 @@ auto* expect = R"( enable chromium_experimental_push_constant; -struct FragDepthClampArgs { - min : f32, - max : f32, +struct PushConstants { + /* @offset(0) */ + min_depth : f32, + /* @offset(4) */ + max_depth : f32, } -var<push_constant> frag_depth_clamp_args : FragDepthClampArgs; +var<push_constant> push_constants : PushConstants; fn clamp_frag_depth(v : f32) -> f32 { - return clamp(v, frag_depth_clamp_args.min, frag_depth_clamp_args.max); + return clamp(v, push_constants.min_depth, push_constants.max_depth); } struct S { @@ -256,7 +330,9 @@ } )"; - auto got = Run<ClampFragDepth>(src); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + auto got = Run<ClampFragDepth>(src, config); EXPECT_EQ(expect, str(got)); } @@ -285,15 +361,17 @@ auto* expect = R"( enable chromium_experimental_push_constant; -struct FragDepthClampArgs { - min : f32, - max : f32, +struct PushConstants { + /* @offset(0) */ + min_depth : f32, + /* @offset(4) */ + max_depth : f32, } -var<push_constant> frag_depth_clamp_args : FragDepthClampArgs; +var<push_constant> push_constants : PushConstants; fn clamp_frag_depth(v : f32) -> f32 { - return clamp(v, frag_depth_clamp_args.min, frag_depth_clamp_args.max); + return clamp(v, push_constants.min_depth, push_constants.max_depth); } struct S { @@ -330,7 +408,9 @@ } )"; - auto got = Run<ClampFragDepth>(src); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + auto got = Run<ClampFragDepth>(src, config); EXPECT_EQ(expect, str(got)); } @@ -352,15 +432,17 @@ auto* expect = R"( enable chromium_experimental_push_constant; -struct FragDepthClampArgs { - min : f32, - max : f32, +struct PushConstants { + /* @offset(0) */ + min_depth : f32, + /* @offset(4) */ + max_depth : f32, } -var<push_constant> frag_depth_clamp_args : FragDepthClampArgs; +var<push_constant> push_constants : PushConstants; fn clamp_frag_depth(v : f32) -> f32 { - return clamp(v, frag_depth_clamp_args.min, frag_depth_clamp_args.max); + return clamp(v, push_constants.min_depth, push_constants.max_depth); } struct S { @@ -386,7 +468,9 @@ } )"; - auto got = Run<ClampFragDepth>(src); + DataMap config; + config.Add<ClampFragDepth::Config>(0, 4); + auto got = Run<ClampFragDepth>(src, config); EXPECT_EQ(expect, str(got)); }
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc index 05505d1..6d4621a 100644 --- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc +++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -450,13 +450,24 @@ } void EmitAssignment(const ast::AssignmentStatement* stmt) { - // If assigning to a phony, just generate the RHS and we're done. Note that, because - // this isn't used, a subsequent transform could remove it due to it being dead code. - // This could then change the interface for the program (i.e. a global var no longer - // used). If that happens we have to either fix this to store to a phony value, or make - // sure we pull the interface before doing the dead code elimination. + // If assigning to a phony, and the expression evaluation stage is runtime or override, just + // generate the RHS and we're done. Note that, because this isn't used, a subsequent + // transform could remove it due to it being dead code. This could then change the interface + // for the program (i.e. a global var no longer used). If that happens we have to either fix + // this to store to a phony value, or make sure we pull the interface before doing the dead + // code elimination. if (stmt->lhs->Is<ast::PhonyExpression>()) { - (void)EmitValueExpression(stmt->rhs); + const auto* sem = program_.Sem().GetVal(stmt->rhs); + switch (sem->Stage()) { + case core::EvaluationStage::kRuntime: + case core::EvaluationStage::kOverride: + EmitValueExpression(stmt->rhs); + break; + case core::EvaluationStage::kNotEvaluated: + case core::EvaluationStage::kConstant: + // Don't emit. + break; + } return; }
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc index b47ee3a..9867cb4 100644 --- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc +++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc
@@ -26,6 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "gmock/gmock.h" +#include "src/tint/lang/core/builtin_fn.h" #include "src/tint/lang/core/constant/scalar.h" #include "src/tint/lang/core/fluent_types.h" #include "src/tint/lang/core/ir/block.h" @@ -1164,5 +1165,27 @@ )"); } +//////////////////////////////////////////////////////////////////////////////// +// Bugs +//////////////////////////////////////////////////////////////////////////////// +TEST_F(IR_FromProgramTest, BugChromium324466107) { + Func("f", Empty, ty.void_(), + Vector{ + // Abstract type on the RHS - cannot be emitted. + Assign(Phony(), Call(core::BuiltinFn::kFrexp, Call(ty.vec2<Infer>(), 2.0_a))), + }); + + auto m = Build(); + ASSERT_EQ(m, Success); + + EXPECT_EQ(Disassemble(m.Get()), + R"(%f = func():void -> %b1 { + %b1 = block { + ret + } +} +)"); +} + } // namespace } // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/sem/function_expression.cc b/src/tint/lang/wgsl/sem/function_expression.cc index d20ab00..d033140 100644 --- a/src/tint/lang/wgsl/sem/function_expression.cc +++ b/src/tint/lang/wgsl/sem/function_expression.cc
@@ -26,16 +26,21 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "src/tint/lang/wgsl/sem/function_expression.h" +#include "src/tint/lang/wgsl/ast/identifier_expression.h" TINT_INSTANTIATE_TYPEINFO(tint::sem::FunctionExpression); namespace tint::sem { -FunctionExpression::FunctionExpression(const ast::Expression* declaration, +FunctionExpression::FunctionExpression(const ast::IdentifierExpression* declaration, const Statement* statement, const sem::Function* function) : Base(declaration, statement), function_(function) {} FunctionExpression::~FunctionExpression() = default; +const ast::IdentifierExpression* FunctionExpression::Declaration() const { + return static_cast<const ast::IdentifierExpression*>(Base::Declaration()); +} + } // namespace tint::sem
diff --git a/src/tint/lang/wgsl/sem/function_expression.h b/src/tint/lang/wgsl/sem/function_expression.h index 5b0625f..8e2c4de 100644 --- a/src/tint/lang/wgsl/sem/function_expression.h +++ b/src/tint/lang/wgsl/sem/function_expression.h
@@ -31,6 +31,9 @@ #include "src/tint/lang/wgsl/sem/expression.h" // Forward declarations +namespace tint::ast { +class IdentifierExpression; +} // namespace tint::ast namespace tint::sem { class Function; } // namespace tint::sem @@ -45,13 +48,16 @@ /// @param declaration the AST node /// @param statement the statement that owns this expression /// @param function the function that the expression resolved to - FunctionExpression(const ast::Expression* declaration, + FunctionExpression(const ast::IdentifierExpression* declaration, const Statement* statement, const sem::Function* function); /// Destructor ~FunctionExpression() override; + /// @returns the AST node + const ast::IdentifierExpression* Declaration() const; + /// @return the function that the expression resolved to const sem::Function* Function() const { return function_; }
diff --git a/src/tint/lang/wgsl/sem/member_accessor_expression.cc b/src/tint/lang/wgsl/sem/member_accessor_expression.cc index 68bcd7a..8a10ac1 100644 --- a/src/tint/lang/wgsl/sem/member_accessor_expression.cc +++ b/src/tint/lang/wgsl/sem/member_accessor_expression.cc
@@ -48,6 +48,10 @@ MemberAccessorExpression::~MemberAccessorExpression() = default; +const ast::MemberAccessorExpression* MemberAccessorExpression::Declaration() const { + return static_cast<const ast::MemberAccessorExpression*>(declaration_); +} + StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* declaration, const core::type::Type* type, const Statement* statement,
diff --git a/src/tint/lang/wgsl/sem/member_accessor_expression.h b/src/tint/lang/wgsl/sem/member_accessor_expression.h index 67dcf08..bb6f388 100644 --- a/src/tint/lang/wgsl/sem/member_accessor_expression.h +++ b/src/tint/lang/wgsl/sem/member_accessor_expression.h
@@ -48,6 +48,9 @@ /// Destructor ~MemberAccessorExpression() override; + /// @returns the AST node + const ast::MemberAccessorExpression* Declaration() const; + protected: /// Constructor /// @param declaration the AST node
diff --git a/src/tint/lang/wgsl/sem/variable.cc b/src/tint/lang/wgsl/sem/variable.cc index 9d5e1b2..e056c77 100644 --- a/src/tint/lang/wgsl/sem/variable.cc +++ b/src/tint/lang/wgsl/sem/variable.cc
@@ -94,4 +94,8 @@ VariableUser::~VariableUser() = default; +const ast::IdentifierExpression* VariableUser::Declaration() const { + return static_cast<const ast::IdentifierExpression*>(Base::Declaration()); +} + } // namespace tint::sem
diff --git a/src/tint/lang/wgsl/sem/variable.h b/src/tint/lang/wgsl/sem/variable.h index 9809fcb..15ca981 100644 --- a/src/tint/lang/wgsl/sem/variable.h +++ b/src/tint/lang/wgsl/sem/variable.h
@@ -292,6 +292,9 @@ sem::Variable* variable); ~VariableUser() override; + /// @returns the AST node + const ast::IdentifierExpression* Declaration() const; + /// @returns the variable that this expression refers to const sem::Variable* Variable() const { return variable_; }