#include "src/tint/lang/wgsl/resolver/validator.h"
#include <algorithm>
#include <bitset>
#include <limits>
#include <string_view>
#include <tuple>
#include <utility>
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/parameter_usage.h"
#include "src/tint/lang/core/type/abstract_numeric.h"
#include "src/tint/lang/core/type/atomic.h"
#include "src/tint/lang/core/type/depth_multisampled_texture.h"
#include "src/tint/lang/core/type/depth_texture.h"
#include "src/tint/lang/core/type/input_attachment.h"
#include "src/tint/lang/core/type/multisampled_texture.h"
#include "src/tint/lang/core/type/pointer.h"
#include "src/tint/lang/core/type/reference.h"
#include "src/tint/lang/core/type/sampled_texture.h"
#include "src/tint/lang/core/type/sampler.h"
#include "src/tint/lang/core/type/storage_texture.h"
#include "src/tint/lang/core/type/texture_dimension.h"
#include "src/tint/lang/wgsl/ast/alias.h"
#include "src/tint/lang/wgsl/ast/assignment_statement.h"
#include "src/tint/lang/wgsl/ast/blend_src_attribute.h"
#include "src/tint/lang/wgsl/ast/break_statement.h"
#include "src/tint/lang/wgsl/ast/call_statement.h"
#include "src/tint/lang/wgsl/ast/continue_statement.h"
#include "src/tint/lang/wgsl/ast/disable_validation_attribute.h"
#include "src/tint/lang/wgsl/ast/discard_statement.h"
#include "src/tint/lang/wgsl/ast/for_loop_statement.h"
#include "src/tint/lang/wgsl/ast/id_attribute.h"
#include "src/tint/lang/wgsl/ast/if_statement.h"
#include "src/tint/lang/wgsl/ast/internal_attribute.h"
#include "src/tint/lang/wgsl/ast/interpolate_attribute.h"
#include "src/tint/lang/wgsl/ast/loop_statement.h"
#include "src/tint/lang/wgsl/ast/return_statement.h"
#include "src/tint/lang/wgsl/ast/switch_statement.h"
#include "src/tint/lang/wgsl/ast/traverse_expressions.h"
#include "src/tint/lang/wgsl/ast/unary_op_expression.h"
#include "src/tint/lang/wgsl/ast/variable_decl_statement.h"
#include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
#include "src/tint/lang/wgsl/builtin_fn.h"
#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/lang/wgsl/sem/break_if_statement.h"
#include "src/tint/lang/wgsl/sem/call.h"
#include "src/tint/lang/wgsl/sem/for_loop_statement.h"
#include "src/tint/lang/wgsl/sem/function.h"
#include "src/tint/lang/wgsl/sem/if_statement.h"
#include "src/tint/lang/wgsl/sem/loop_statement.h"
#include "src/tint/lang/wgsl/sem/materialize.h"
#include "src/tint/lang/wgsl/sem/member_accessor_expression.h"
#include "src/tint/lang/wgsl/sem/statement.h"
#include "src/tint/lang/wgsl/sem/struct.h"
#include "src/tint/lang/wgsl/sem/switch_statement.h"
#include "src/tint/lang/wgsl/sem/value_constructor.h"
#include "src/tint/lang/wgsl/sem/value_conversion.h"
#include "src/tint/lang/wgsl/sem/variable.h"
#include "src/tint/lang/wgsl/sem/while_statement.h"
#include "src/tint/utils/containers/map.h"
#include "src/tint/utils/containers/reverse.h"
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/macros/scoped_assignment.h"
#include "src/tint/utils/math/math.h"
#include "src/tint/utils/text/string.h"
#include "src/tint/utils/text/string_stream.h"
#include "src/tint/utils/text/styled_text.h"
#include "src/tint/utils/text/text_style.h"
usingnamespacetint::core::fluent_types;
namespace tint::resolver {
namespace {
constexpr size_t kMaxFunctionParameters = …;
constexpr size_t kMaxSwitchCaseSelectors = …;
constexpr size_t kMaxClipDistancesSize = …;
bool IsValidStorageTextureDimension(core::type::TextureDimension dim) { … }
bool IsValidStorageTextureTexelFormat(core::TexelFormat format) { … }
bool IsInvalidStorageTextureTexelFormatInCompatibilityMode(core::TexelFormat format) { … }
template <typename CALLBACK>
void TraverseCallChain(const sem::Function* from, const sem::Function* to, CALLBACK&& callback) { … }
}
Validator::Validator(
ProgramBuilder* builder,
SemHelper& sem,
const wgsl::Extensions& enabled_extensions,
const wgsl::AllowedFeatures& allowed_features,
const wgsl::ValidationMode mode,
const Hashmap<const core::type::Type*, const Source*, 8>& atomic_composite_info,
Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts)
: … { … }
Validator::~Validator() = default;
diag::Diagnostic& Validator::AddError(const Source& source) const { … }
diag::Diagnostic& Validator::AddWarning(const Source& source) const { … }
diag::Diagnostic& Validator::AddNote(const Source& source) const { … }
diag::Diagnostic* Validator::MaybeAddDiagnostic(wgsl::DiagnosticRule rule,
const Source& source) const { … }
bool Validator::IsPlain(const core::type::Type* type) const { … }
bool Validator::IsFixedFootprint(const core::type::Type* type) const { … }
bool Validator::IsHostShareable(const core::type::Type* type) const { … }
bool Validator::IsStorable(const core::type::Type* type) const { … }
const ast::Statement* Validator::ClosestContinuing(bool stop_at_loop,
bool stop_at_switch,
sem::Statement* current_statement) const { … }
bool Validator::Enables(VectorRef<const ast::Enable*> enables) const { … }
bool Validator::Atomic(const ast::TemplatedIdentifier* a, const core::type::Atomic* s) const { … }
bool Validator::Pointer(const ast::TemplatedIdentifier* a, const core::type::Pointer* s) const { … }
bool Validator::StorageTexture(const core::type::StorageTexture* t, const Source& source) const { … }
bool Validator::SampledTexture(const core::type::SampledTexture* t, const Source& source) const { … }
bool Validator::MultisampledTexture(const core::type::MultisampledTexture* t,
const Source& source) const { … }
bool Validator::InputAttachment(const core::type::InputAttachment* t, const Source& source) const { … }
bool Validator::InputAttachmentIndexAttribute(const ast::InputAttachmentIndexAttribute* attr,
const core::type::Type* type,
const Source& source) const { … }
bool Validator::Materialize(const core::type::Type* to,
const core::type::Type* from,
const Source& source) const { … }
bool Validator::VariableInitializer(const ast::Variable* v,
const core::type::Type* storage_ty,
const sem::ValueExpression* initializer) const { … }
bool Validator::AddressSpaceLayout(const core::type::Type* store_ty,
core::AddressSpace address_space,
Source source) const { … }
bool Validator::LocalVariable(const sem::Variable* local) const { … }
bool Validator::GlobalVariable(
const sem::GlobalVariable* global,
const Hashmap<OverrideId, const sem::Variable*, 8>& override_ids) const { … }
bool Validator::Var(const sem::Variable* v) const { … }
bool Validator::Let(const sem::Variable* v) const { … }
bool Validator::Override(const sem::GlobalVariable* v,
const Hashmap<OverrideId, const sem::Variable*, 8>& override_ids) const { … }
bool Validator::Const(const sem::Variable*) const { … }
bool Validator::Parameter(const sem::Variable* var) const { … }
bool Validator::BuiltinAttribute(const ast::BuiltinAttribute* attr,
const core::type::Type* storage_ty,
ast::PipelineStage stage,
const bool is_input,
const bool ignore_clip_distances_type_validation) const { … }
bool Validator::InterpolateAttribute(const ast::InterpolateAttribute* attr,
const core::type::Type* storage_ty,
const ast::PipelineStage stage) const { … }
bool Validator::InvariantAttribute(const ast::InvariantAttribute* attr,
const ast::PipelineStage stage) const { … }
bool Validator::Function(const sem::Function* func, ast::PipelineStage stage) const { … }
bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage) const { … }
bool Validator::EvaluationStage(const sem::ValueExpression* expr,
core::EvaluationStage latest_stage,
std::string_view constraint) const { … }
bool Validator::Statements(VectorRef<const ast::Statement*> stmts) const { … }
bool Validator::BinaryExpression(const ast::Node* node,
const core::BinaryOp op,
const tint::sem::ValueExpression* lhs,
const tint::sem::ValueExpression* rhs) const { … }
bool Validator::BreakStatement(const sem::Statement* stmt,
sem::Statement* current_statement) const { … }
bool Validator::ContinueStatement(const sem::Statement* stmt,
sem::Statement* current_statement) const { … }
bool Validator::Call(const sem::Call* call, sem::Statement* current_statement) const { … }
bool Validator::LoopStatement(const sem::LoopStatement* stmt) const { … }
bool Validator::ForLoopStatement(const sem::ForLoopStatement* stmt) const { … }
bool Validator::WhileStatement(const sem::WhileStatement* stmt) const { … }
bool Validator::BreakIfStatement(const sem::BreakIfStatement* stmt,
sem::Statement* current_statement) const { … }
bool Validator::IfStatement(const sem::IfStatement* stmt) const { … }
bool Validator::BuiltinCall(const sem::Call* call) const { … }
bool Validator::TextureBuiltinFn(const sem::Call* call) const { … }
bool Validator::WorkgroupUniformLoad(const sem::Call* call) const { … }
bool Validator::SubgroupBroadcast(const sem::Call* call) const { … }
bool Validator::QuadBroadcast(const sem::Call* call) const { … }
bool Validator::RequiredFeaturesForBuiltinFn(const sem::Call* call) const { … }
bool Validator::CheckF16Enabled(const Source& source) const { … }
bool Validator::FunctionCall(const sem::Call* call, sem::Statement* current_statement) const { … }
bool Validator::StructureInitializer(const ast::CallExpression* ctor,
const core::type::Struct* struct_type) const { … }
bool Validator::ArrayConstructor(const ast::CallExpression* ctor,
const sem::Array* array_type) const { … }
bool Validator::Vector(const core::type::Type* el_ty, const Source& source) const { … }
bool Validator::Matrix(const core::type::Type* el_ty, const Source& source) const { … }
bool Validator::PipelineStages(VectorRef<sem::Function*> entry_points) const { … }
bool Validator::ModuleScopeVarUsages(VectorRef<sem::Function*> entry_points) const { … }
bool Validator::Array(const sem::Array* arr, const Source& el_source) const { … }
bool Validator::ArrayStrideAttribute(const ast::StrideAttribute* attr,
uint32_t el_size,
uint32_t el_align) const { … }
bool Validator::Alias(const ast::Alias*) const { … }
bool Validator::Structure(const sem::Struct* str, ast::PipelineStage stage) const { … }
bool Validator::LocationAttribute(const ast::LocationAttribute* attr,
const core::type::Type* type,
ast::PipelineStage stage,
const Source& source) const { … }
bool Validator::ColorAttribute(const ast::ColorAttribute* attr,
const core::type::Type* type,
ast::PipelineStage stage,
const Source& source,
const std::optional<bool> is_input) const { … }
bool Validator::BlendSrcAttribute(const ast::BlendSrcAttribute* attr,
ast::PipelineStage stage,
const std::optional<bool> is_input) const { … }
bool Validator::Return(const ast::ReturnStatement* ret,
const core::type::Type* func_type,
const core::type::Type* ret_type,
sem::Statement* current_statement) const { … }
bool Validator::SwitchStatement(const ast::SwitchStatement* s) { … }
bool Validator::Assignment(const ast::Statement* a, const core::type::Type* rhs_ty) const { … }
bool Validator::IncrementDecrementStatement(const ast::IncrementDecrementStatement* inc) const { … }
bool Validator::NoDuplicateAttributes(VectorRef<const ast::Attribute*> attributes) const { … }
bool Validator::DiagnosticControls(VectorRef<const ast::DiagnosticControl*> controls,
const char* use,
DiagnosticDuplicates allow_duplicates) const { … }
bool Validator::IsValidationDisabled(VectorRef<const ast::Attribute*> attributes,
ast::DisabledValidation validation) const { … }
bool Validator::IsValidationEnabled(VectorRef<const ast::Attribute*> attributes,
ast::DisabledValidation validation) const { … }
bool Validator::IsArrayWithOverrideCount(const core::type::Type* ty) const { … }
void Validator::RaiseArrayWithOverrideCountError(const Source& source) const { … }
std::string Validator::VectorPretty(uint32_t size, const core::type::Type* element_type) const { … }
bool Validator::CheckTypeAccessAddressSpace(const core::type::Type* store_ty,
core::Access access,
core::AddressSpace address_space,
VectorRef<const tint::ast::Attribute*> attributes,
const Source& source) const { … }
bool Validator::CheckNoMultipleModuleScopeVarsOfAddressSpace(sem::Function* entry_point,
core::AddressSpace space) const { … }
}