diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 7cfb3ae309..ecd0c624b0 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -117,6 +117,7 @@ def _NonInclusiveFileFilter(file): "src/dawn/node/tools/src/cmd/run-cts/main.go", # Terminal type name "src/dawn/samples/ComputeBoids.cpp", # External URL "src/dawn/tests/end2end/DepthBiasTests.cpp", # External URL + "src/tint/transform/canonicalize_entry_point_io.cc", # External URL "test/tint/samples/compute_boids.wgsl", # External URL "third_party/khronos/KHR/khrplatform.h", # Third party file "tools/roll-all", # Branch name diff --git a/src/tint/ast/f16.h b/src/tint/ast/f16.h index c444a20f65..bae6291356 100644 --- a/src/tint/ast/f16.h +++ b/src/tint/ast/f16.h @@ -22,7 +22,7 @@ namespace tint::ast { /// A float 16 type -class F16 : public Castable { +class F16 final : public Castable { public: /// Constructor /// @param pid the identifier of the program that owns this node diff --git a/src/tint/ast/int_literal_expression.h b/src/tint/ast/int_literal_expression.h index b4e184a925..10cbbee5a0 100644 --- a/src/tint/ast/int_literal_expression.h +++ b/src/tint/ast/int_literal_expression.h @@ -20,7 +20,7 @@ namespace tint::ast { /// An integer literal. The literal may have an 'i', 'u' or no suffix. -class IntLiteralExpression : public Castable { +class IntLiteralExpression final : public Castable { public: /// Literal suffix enum class Suffix { diff --git a/src/tint/castable.h b/src/tint/castable.h index c7b8608084..806d0f0499 100644 --- a/src/tint/castable.h +++ b/src/tint/castable.h @@ -101,6 +101,36 @@ struct TypeInfo { /// The type hash code bitwise-or'd with all ancestor's hashcodes. const HashCode full_hashcode; + /// @returns true if `type` derives from the class `TO` + /// @param object the object type to test from, which must be, or derive from + /// type `FROM`. + /// @see CastFlags + template + static inline bool Is(const tint::TypeInfo* object) { + constexpr const bool downcast = std::is_base_of::value; + constexpr const bool upcast = std::is_base_of::value; + constexpr const bool nocast = std::is_same::value; + constexpr const bool assert_is_castable = (FLAGS & kDontErrorOnImpossibleCast) == 0; + + static_assert(upcast || downcast || nocast || !assert_is_castable, "impossible cast"); + + return upcast || nocast || object->Is(); + } + + /// @returns true if this type derives from the class `T` + template + inline bool Is() const { + auto* type = &Of>(); + + if constexpr (std::is_final_v) { + // T is final, so nothing can derive from T. + // We do not need to check ancestors, only whether this type is equal to the type T. + return type == this; + } else { + return Is(type); + } + } + /// @param type the test type info /// @returns true if the class with this TypeInfo is of, or derives from the /// class with the given TypeInfo. @@ -112,8 +142,8 @@ struct TypeInfo { return false; } - // Walk the base types, starting with this TypeInfo, to see if any of the - // pointers match `type`. + // Walk the base types, starting with this TypeInfo, to see if any of the pointers match + // `type`. for (auto* ti = this; ti != nullptr; ti = ti->base) { if (ti == type) { return true; @@ -122,26 +152,6 @@ struct TypeInfo { return false; } - /// @returns true if `type` derives from the class `TO` - /// @param type the object type to test from, which must be, or derive from - /// type `FROM`. - /// @see CastFlags - template - static inline bool Is(const tint::TypeInfo* type) { - constexpr const bool downcast = std::is_base_of::value; - constexpr const bool upcast = std::is_base_of::value; - constexpr const bool nocast = std::is_same::value; - constexpr const bool assert_is_castable = (FLAGS & kDontErrorOnImpossibleCast) == 0; - - static_assert(upcast || downcast || nocast || !assert_is_castable, "impossible cast"); - - if (upcast || nocast) { - return true; - } - - return type->Is(&Of>()); - } - /// @returns the static TypeInfo for the type T template static const TypeInfo& Of() { @@ -211,14 +221,12 @@ struct TypeInfo { if constexpr (kCount == 0) { return false; } else if constexpr (kCount == 1) { - return Is(&Of>()); + return Is>(); } else if constexpr (kCount == 2) { - return Is(&Of>()) || - Is(&Of>()); + return Is>() || Is>(); } else if constexpr (kCount == 3) { - return Is(&Of>()) || - Is(&Of>()) || - Is(&Of>()); + return Is>() || Is>() || + Is>(); } else { // Optimization: Compare the object's hashcode to the bitwise-or of all // the tested type's hashcodes. If there's no intersection of bits in @@ -587,7 +595,7 @@ inline bool NonDefaultCases(T* object, // Attempt to dynamically cast the object to the handler type. If that // succeeds, call the case handler with the cast object. using CaseType = SwitchCaseType; - if (type->Is(&TypeInfo::Of())) { + if (type->Is()) { auto* ptr = static_cast(object); if constexpr (kHasReturnType) { new (result) RETURN_TYPE(static_cast(std::get<0>(cases)(ptr))); diff --git a/src/tint/sem/f16.h b/src/tint/sem/f16.h index 72984c13e7..87543ed0e4 100644 --- a/src/tint/sem/f16.h +++ b/src/tint/sem/f16.h @@ -22,7 +22,7 @@ namespace tint::sem { /// A float 16 type -class F16 : public Castable { +class F16 final : public Castable { public: /// Constructor F16(); diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h index e026b11d08..5ee93e5491 100644 --- a/src/tint/sem/struct.h +++ b/src/tint/sem/struct.h @@ -170,7 +170,7 @@ class Struct final : public Castable { }; /// StructMember holds the semantic information for structure members. -class StructMember : public Castable { +class StructMember final : public Castable { public: /// Constructor /// @param declaration the AST declaration node diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc index c3d5c8e361..a714581e1f 100644 --- a/src/tint/transform/decompose_memory_access.cc +++ b/src/tint/transform/decompose_memory_access.cc @@ -73,7 +73,7 @@ struct OffsetExpr : Offset { /// OffsetLiteral is an implementation of Offset that constructs a u32 literal /// value. -struct OffsetLiteral : Castable { +struct OffsetLiteral final : Castable { uint32_t const literal = 0; explicit OffsetLiteral(uint32_t lit) : literal(lit) {} diff --git a/src/tint/transform/expand_compound_assignment.h b/src/tint/transform/expand_compound_assignment.h index d38d297d14..1081df7b32 100644 --- a/src/tint/transform/expand_compound_assignment.h +++ b/src/tint/transform/expand_compound_assignment.h @@ -38,7 +38,7 @@ namespace tint::transform { /// /// This transform also handles increment and decrement statements in the same /// manner, by replacing `i++` with `i = i + 1`. -class ExpandCompoundAssignment : public Castable { +class ExpandCompoundAssignment final : public Castable { public: /// Constructor ExpandCompoundAssignment(); diff --git a/src/tint/transform/localize_struct_array_assignment.h b/src/tint/transform/localize_struct_array_assignment.h index 129c8491bb..130f8cc107 100644 --- a/src/tint/transform/localize_struct_array_assignment.h +++ b/src/tint/transform/localize_struct_array_assignment.h @@ -27,7 +27,8 @@ namespace tint::transform { /// /// @note Depends on the following transforms to have been run first: /// * SimplifyPointers -class LocalizeStructArrayAssignment : public Castable { +class LocalizeStructArrayAssignment final + : public Castable { public: /// Constructor LocalizeStructArrayAssignment(); diff --git a/src/tint/transform/loop_to_for_loop.h b/src/tint/transform/loop_to_for_loop.h index 0623d79b85..0e948c80c1 100644 --- a/src/tint/transform/loop_to_for_loop.h +++ b/src/tint/transform/loop_to_for_loop.h @@ -21,7 +21,7 @@ namespace tint::transform { /// LoopToForLoop is a Transform that attempts to convert WGSL `loop {}` /// statements into a for-loop statement. -class LoopToForLoop : public Castable { +class LoopToForLoop final : public Castable { public: /// Constructor LoopToForLoop(); diff --git a/src/tint/transform/manager.h b/src/tint/transform/manager.h index 9f5c6bcf21..04bf9fe895 100644 --- a/src/tint/transform/manager.h +++ b/src/tint/transform/manager.h @@ -27,7 +27,7 @@ namespace tint::transform { /// The inner transforms will execute in the appended order. /// If any inner transform fails the manager will return immediately and /// the error can be retrieved with the Output's diagnostics. -class Manager : public Castable { +class Manager final : public Castable { public: /// Constructor Manager(); diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.h b/src/tint/transform/module_scope_var_to_entry_point_param.h index e3a50f4013..40e6b7da6e 100644 --- a/src/tint/transform/module_scope_var_to_entry_point_param.h +++ b/src/tint/transform/module_scope_var_to_entry_point_param.h @@ -61,7 +61,7 @@ namespace tint::transform { /// foo(&p, sptr); /// } /// ``` -class ModuleScopeVarToEntryPointParam +class ModuleScopeVarToEntryPointParam final : public Castable { public: /// Constructor diff --git a/src/tint/transform/multiplanar_external_texture.h b/src/tint/transform/multiplanar_external_texture.h index fcb5156fa7..afd15a1701 100644 --- a/src/tint/transform/multiplanar_external_texture.h +++ b/src/tint/transform/multiplanar_external_texture.h @@ -50,7 +50,7 @@ struct BindingPoints { /// decoding, gamut conversion, and gamma encoding steps. Specifically // for BT.709 to SRGB conversion, it takes the fast path only doing the yuv->rgb // step and skipping all other steps. -class MultiplanarExternalTexture : public Castable { +class MultiplanarExternalTexture final : public Castable { public: /// BindingsMap is a map where the key is the binding location of a /// texture_external and the value is a struct containing the desired @@ -60,7 +60,7 @@ class MultiplanarExternalTexture : public Castable { + struct NewBindingPoints final : public Castable { /// Constructor /// @param bm a map to the new binding slots to use. explicit NewBindingPoints(BindingsMap bm); diff --git a/src/tint/transform/num_workgroups_from_uniform.h b/src/tint/transform/num_workgroups_from_uniform.h index 0111cccb58..292c823bc4 100644 --- a/src/tint/transform/num_workgroups_from_uniform.h +++ b/src/tint/transform/num_workgroups_from_uniform.h @@ -44,7 +44,7 @@ namespace tint::transform { /// /// @note Depends on the following transforms to have been run first: /// * CanonicalizeEntryPointIO -class NumWorkgroupsFromUniform : public Castable { +class NumWorkgroupsFromUniform final : public Castable { public: /// Constructor NumWorkgroupsFromUniform(); @@ -52,7 +52,7 @@ class NumWorkgroupsFromUniform : public Castable { + struct Config final : public Castable { /// Constructor /// @param ubo_bp the binding point to use for the generated uniform buffer. If ubo_bp /// contains no value, a free binding point will be used to ensure the generated program is diff --git a/src/tint/transform/promote_initializers_to_let.h b/src/tint/transform/promote_initializers_to_let.h index 41f99d7b37..226c7d8382 100644 --- a/src/tint/transform/promote_initializers_to_let.h +++ b/src/tint/transform/promote_initializers_to_let.h @@ -25,7 +25,7 @@ namespace tint::transform { /// array or structure. For example, the following is not immediately expressable for HLSL: /// `array(1, 2)[0]` /// @see crbug.com/tint/406 -class PromoteInitializersToLet : public Castable { +class PromoteInitializersToLet final : public Castable { public: /// Constructor PromoteInitializersToLet(); diff --git a/src/tint/transform/promote_side_effects_to_decl.h b/src/tint/transform/promote_side_effects_to_decl.h index 1e629b344f..d5d1126133 100644 --- a/src/tint/transform/promote_side_effects_to_decl.h +++ b/src/tint/transform/promote_side_effects_to_decl.h @@ -23,7 +23,7 @@ namespace tint::transform { /// declarations before the statement of usage with the goal of ensuring /// left-to-right order of evaluation, while respecting short-circuit /// evaluation. -class PromoteSideEffectsToDecl : public Castable { +class PromoteSideEffectsToDecl final : public Castable { public: /// Constructor PromoteSideEffectsToDecl(); diff --git a/src/tint/transform/remove_continue_in_switch.h b/src/tint/transform/remove_continue_in_switch.h index e706225500..9e5a4d51ad 100644 --- a/src/tint/transform/remove_continue_in_switch.h +++ b/src/tint/transform/remove_continue_in_switch.h @@ -23,7 +23,7 @@ namespace tint::transform { /// bool variable, and checking if the variable is set after the switch to /// continue. It is necessary to work around FXC "error X3708: continue cannot /// be used in a switch". See crbug.com/tint/1080. -class RemoveContinueInSwitch : public Castable { +class RemoveContinueInSwitch final : public Castable { public: /// Constructor RemoveContinueInSwitch(); diff --git a/src/tint/transform/remove_phonies.h b/src/tint/transform/remove_phonies.h index 20128a0e4e..d04023bed4 100644 --- a/src/tint/transform/remove_phonies.h +++ b/src/tint/transform/remove_phonies.h @@ -25,7 +25,7 @@ namespace tint::transform { /// RemovePhonies is a Transform that removes all phony-assignment statements, /// while preserving function call expressions in the RHS of the assignment that /// may have side-effects. -class RemovePhonies : public Castable { +class RemovePhonies final : public Castable { public: /// Constructor RemovePhonies(); diff --git a/src/tint/transform/remove_unreachable_statements.h b/src/tint/transform/remove_unreachable_statements.h index c75da3d45f..7f8b9472ad 100644 --- a/src/tint/transform/remove_unreachable_statements.h +++ b/src/tint/transform/remove_unreachable_statements.h @@ -24,7 +24,7 @@ namespace tint::transform { /// RemoveUnreachableStatements is a Transform that removes all statements /// marked as unreachable. -class RemoveUnreachableStatements : public Castable { +class RemoveUnreachableStatements final : public Castable { public: /// Constructor RemoveUnreachableStatements(); diff --git a/src/tint/transform/renamer.h b/src/tint/transform/renamer.h index 354acdade1..000aee9ca2 100644 --- a/src/tint/transform/renamer.h +++ b/src/tint/transform/renamer.h @@ -23,11 +23,11 @@ namespace tint::transform { /// Renamer is a Transform that renames all the symbols in a program. -class Renamer : public Castable { +class Renamer final : public Castable { public: /// Data is outputted by the Renamer transform. /// Data holds information about shader usage and constant buffer offsets. - struct Data : public Castable { + struct Data final : public Castable { /// Remappings is a map of old symbol name to new symbol name using Remappings = std::unordered_map; @@ -59,7 +59,7 @@ class Renamer : public Castable { /// Optional configuration options for the transform. /// If omitted, then the renamer will use Target::kAll. - struct Config : public Castable { + struct Config final : public Castable { /// Constructor /// @param tgt the targets to rename /// @param keep_unicode if false, symbols with non-ascii code-points are diff --git a/src/tint/transform/robustness.h b/src/tint/transform/robustness.h index 138b48cec3..549b666bb7 100644 --- a/src/tint/transform/robustness.h +++ b/src/tint/transform/robustness.h @@ -31,7 +31,7 @@ namespace tint::transform { /// the bounds of the array. Any access before the start of the array will clamp /// to zero and any access past the end of the array will clamp to /// (array length - 1). -class Robustness : public Castable { +class Robustness final : public Castable { public: /// Storage class to be skipped in the transform enum class StorageClass { @@ -40,7 +40,7 @@ class Robustness : public Castable { }; /// Configuration options for the transform - struct Config : public Castable { + struct Config final : public Castable { /// Constructor Config(); diff --git a/src/tint/transform/simplify_pointers.h b/src/tint/transform/simplify_pointers.h index 267b7b2d32..787c7d815f 100644 --- a/src/tint/transform/simplify_pointers.h +++ b/src/tint/transform/simplify_pointers.h @@ -31,7 +31,7 @@ namespace tint::transform { /// /// @note Depends on the following transforms to have been run first: /// * Unshadow -class SimplifyPointers : public Castable { +class SimplifyPointers final : public Castable { public: /// Constructor SimplifyPointers(); diff --git a/src/tint/transform/single_entry_point.h b/src/tint/transform/single_entry_point.h index 0a922a78d0..59aa021466 100644 --- a/src/tint/transform/single_entry_point.h +++ b/src/tint/transform/single_entry_point.h @@ -25,10 +25,10 @@ namespace tint::transform { /// /// All module-scope variables, types, and functions that are not used by the /// target entry point will also be removed. -class SingleEntryPoint : public Castable { +class SingleEntryPoint final : public Castable { public: /// Configuration options for the transform - struct Config : public Castable { + struct Config final : public Castable { /// Constructor /// @param entry_point the name of the entry point to keep explicit Config(std::string entry_point = ""); diff --git a/src/tint/transform/unshadow.h b/src/tint/transform/unshadow.h index ce5e9758aa..5ffe8399b9 100644 --- a/src/tint/transform/unshadow.h +++ b/src/tint/transform/unshadow.h @@ -21,7 +21,7 @@ namespace tint::transform { /// Unshadow is a Transform that renames any variables that shadow another /// variable. -class Unshadow : public Castable { +class Unshadow final : public Castable { public: /// Constructor Unshadow(); diff --git a/src/tint/transform/unwind_discard_functions.h b/src/tint/transform/unwind_discard_functions.h index 3b1d838ceb..105a9d8d39 100644 --- a/src/tint/transform/unwind_discard_functions.h +++ b/src/tint/transform/unwind_discard_functions.h @@ -36,7 +36,7 @@ namespace tint::transform { /// /// @note Depends on the following transforms to have been run first: /// * PromoteSideEffectsToDecl -class UnwindDiscardFunctions : public Castable { +class UnwindDiscardFunctions final : public Castable { public: /// Constructor UnwindDiscardFunctions(); diff --git a/src/tint/transform/vectorize_scalar_matrix_constructors.h b/src/tint/transform/vectorize_scalar_matrix_constructors.h index 83c4ce1aa6..31c57f0a8c 100644 --- a/src/tint/transform/vectorize_scalar_matrix_constructors.h +++ b/src/tint/transform/vectorize_scalar_matrix_constructors.h @@ -20,7 +20,7 @@ namespace tint::transform { /// A transform that converts scalar matrix constructors to the vector form. -class VectorizeScalarMatrixConstructors +class VectorizeScalarMatrixConstructors final : public Castable { public: /// Constructor diff --git a/src/tint/transform/vertex_pulling.h b/src/tint/transform/vertex_pulling.h index 78756005de..92eb627524 100644 --- a/src/tint/transform/vertex_pulling.h +++ b/src/tint/transform/vertex_pulling.h @@ -128,10 +128,10 @@ using VertexStateDescriptor = std::vector; /// code, but these are types that the data may arrive as. We need to convert /// these smaller types into the base types such as `f32` and `u32` for the /// shader to use. -class VertexPulling : public Castable { +class VertexPulling final : public Castable { public: /// Configuration options for the transform - struct Config : public Castable { + struct Config final : public Castable { /// Constructor Config(); diff --git a/src/tint/transform/zero_init_workgroup_memory.h b/src/tint/transform/zero_init_workgroup_memory.h index c75772553d..07feaa895a 100644 --- a/src/tint/transform/zero_init_workgroup_memory.h +++ b/src/tint/transform/zero_init_workgroup_memory.h @@ -22,7 +22,7 @@ namespace tint::transform { /// ZeroInitWorkgroupMemory is a transform that injects code at the top of entry /// points to zero-initialize workgroup memory used by that entry point (and all /// transitive functions called by that entry point) -class ZeroInitWorkgroupMemory : public Castable { +class ZeroInitWorkgroupMemory final : public Castable { public: /// Constructor ZeroInitWorkgroupMemory();