diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index 81a2430731..5084d221e0 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -554,7 +554,7 @@ sem::GlobalVariable* Resolver::GlobalVariable(const ast::Variable* var) { // TODO(bclayton): Call this at the end of resolve on all uniform and storage // referenced structs - if (!ValidateStorageClassLayout(sem)) { + if (!ValidateStorageClassLayout(sem, valid_type_storage_layouts_)) { return nullptr; } diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h index bcd780e779..1e7711fc5b 100644 --- a/src/tint/resolver/resolver.h +++ b/src/tint/resolver/resolver.h @@ -106,8 +106,9 @@ class Resolver { /// Describes the context in which a variable is declared enum class VariableKind { kParameter, kLocal, kGlobal }; - std::set> - valid_type_storage_layouts_; + using ValidTypeStorageLayouts = + std::set>; + ValidTypeStorageLayouts valid_type_storage_layouts_; /// Structure holding semantic information about a block (i.e. scope), such as /// parent block and variables declared in the block. @@ -307,8 +308,10 @@ class Resolver { bool ValidateNoDuplicateAttributes(const ast::AttributeList& attributes); bool ValidateStorageClassLayout(const sem::Type* type, ast::StorageClass sc, - Source source); - bool ValidateStorageClassLayout(const sem::Variable* var); + Source source, + ValidTypeStorageLayouts& layout); + bool ValidateStorageClassLayout(const sem::Variable* var, + ValidTypeStorageLayouts& layout); /// @returns true if the attribute list contains a /// ast::DisableValidationAttribute with the validation mode equal to diff --git a/src/tint/resolver/resolver_validation.cc b/src/tint/resolver/resolver_validation.cc index 0ef4ef9db8..161204903c 100644 --- a/src/tint/resolver/resolver_validation.cc +++ b/src/tint/resolver/resolver_validation.cc @@ -230,7 +230,8 @@ bool Resolver::ValidateVariableConstructorOrCast( bool Resolver::ValidateStorageClassLayout(const sem::Type* store_ty, ast::StorageClass sc, - Source source) { + Source source, + ValidTypeStorageLayouts& layouts) { // https://gpuweb.github.io/gpuweb/wgsl/#storage-class-layout-constraints auto is_uniform_struct_or_array = [sc](const sem::Type* ty) { @@ -270,8 +271,8 @@ bool Resolver::ValidateStorageClassLayout(const sem::Type* store_ty, uint32_t required_align = required_alignment_of(m->Type()); // Recurse into the member type. - if (!ValidateStorageClassLayout(m->Type(), sc, - m->Declaration()->type->source)) { + if (!ValidateStorageClassLayout( + m->Type(), sc, m->Declaration()->type->source, layouts)) { AddNote("see layout of struct:\n" + str->Layout(builder_->Symbols()), str->Declaration()->source); return false; @@ -339,7 +340,7 @@ bool Resolver::ValidateStorageClassLayout(const sem::Type* store_ty, // TODO(crbug.com/tint/1388): Ideally we'd pass the source for nested // element type here, but we can't easily get that from the semantic node. // We should consider recursing through the AST type nodes instead. - if (!ValidateStorageClassLayout(arr->ElemType(), sc, source)) { + if (!ValidateStorageClassLayout(arr->ElemType(), sc, source, layouts)) { return false; } @@ -381,10 +382,11 @@ bool Resolver::ValidateStorageClassLayout(const sem::Type* store_ty, return true; } -bool Resolver::ValidateStorageClassLayout(const sem::Variable* var) { +bool Resolver::ValidateStorageClassLayout(const sem::Variable* var, + ValidTypeStorageLayouts& layouts) { if (auto* str = var->Type()->UnwrapRef()->As()) { if (!ValidateStorageClassLayout(str, var->StorageClass(), - str->Declaration()->source)) { + str->Declaration()->source, layouts)) { AddNote("see declaration of variable", var->Declaration()->source); return false; } @@ -394,7 +396,7 @@ bool Resolver::ValidateStorageClassLayout(const sem::Variable* var) { source = var->Declaration()->type->source; } if (!ValidateStorageClassLayout(var->Type()->UnwrapRef(), - var->StorageClass(), source)) { + var->StorageClass(), source, layouts)) { return false; } }