diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc index fcb91642f5..53a69f9d23 100644 --- a/src/resolver/resolver.cc +++ b/src/resolver/resolver.cc @@ -1242,6 +1242,15 @@ void Resolver::CreateSemanticNodes() const { sem.Add(expr, builder_->create(expr, info.type, info.statement)); } + + // Create semantic nodes for all structs + for (auto it : struct_info_) { + auto* str = it.first; + auto* info = it.second; + builder_->Sem().Add(str, builder_->create( + str, std::move(info->members), info->align, + info->size, info->size_no_padding)); + } } bool Resolver::DefaultAlignAndSize(type::Type* ty, @@ -1288,9 +1297,9 @@ bool Resolver::DefaultAlignAndSize(type::Type* ty, size = vector_align[mat->rows()] * mat->columns(); return true; } else if (auto* s = ty->As()) { - if (auto* sem = Structure(s)) { - align = sem->Align(); - size = sem->Size(); + if (auto* si = Structure(s)) { + align = si->align; + size = si->size; return true; } return false; @@ -1354,10 +1363,11 @@ const semantic::Array* Resolver::Array(type::Array* arr) { return create_semantic(utils::RoundUp(el_align, el_size)); } -const semantic::Struct* Resolver::Structure(type::Struct* str) { - if (auto* sem = builder_->Sem().Get(str)) { - // Semantic info already constructed for this structure type - return sem; +Resolver::StructInfo* Resolver::Structure(type::Struct* str) { + auto info_it = struct_info_.find(str); + if (info_it != struct_info_.end()) { + // StructInfo already resolved for this structure type + return info_it->second; } semantic::StructMemberList sem_members; @@ -1451,10 +1461,13 @@ const semantic::Struct* Resolver::Structure(type::Struct* str) { auto size_no_padding = struct_size; struct_size = utils::RoundUp(struct_align, struct_size); - auto* sem = builder_->create( - str, std::move(sem_members), struct_align, struct_size, size_no_padding); - builder_->Sem().Add(str, sem); - return sem; + auto* info = struct_infos_.Create(); + info->members = std::move(sem_members); + info->align = struct_align; + info->size = struct_size; + info->size_no_padding = size_no_padding; + struct_info_.emplace(str, info); + return info; } template @@ -1470,8 +1483,10 @@ Resolver::VariableInfo::VariableInfo(ast::Variable* decl) Resolver::VariableInfo::~VariableInfo() = default; Resolver::FunctionInfo::FunctionInfo(ast::Function* decl) : declaration(decl) {} - Resolver::FunctionInfo::~FunctionInfo() = default; +Resolver::StructInfo::StructInfo() = default; +Resolver::StructInfo::~StructInfo() = default; + } // namespace resolver } // namespace tint diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h index 8fd690026b..4bbe5049b2 100644 --- a/src/resolver/resolver.h +++ b/src/resolver/resolver.h @@ -114,6 +114,18 @@ class Resolver { semantic::Statement* statement; }; + /// Structure holding semantic information about a struct. + /// Used to build the semantic::Struct nodes at the end of resolving. + struct StructInfo { + StructInfo(); + ~StructInfo(); + + std::vector members; + uint32_t align = 0; + uint32_t size = 0; + uint32_t size_no_padding = 0; + }; + /// Structure holding semantic information about a block (i.e. scope), such as /// parent block and variables declared in the block. /// Used to validate variable scoping rules. @@ -201,10 +213,9 @@ class Resolver { /// returned. const semantic::Array* Array(type::Array*); - /// @returns the semantic information for the structure `str`, building it if - /// it hasn't been constructed already. If an error is raised, nullptr is - /// returned. - const semantic::Struct* Structure(type::Struct* str); + /// @returns the StructInfo for the structure `str`, building it if it hasn't + /// been constructed already. If an error is raised, nullptr is returned. + StructInfo* Structure(type::Struct* str); /// @param align the output default alignment in bytes for the type `ty` /// @param size the output default size in bytes for the type `ty` @@ -239,10 +250,12 @@ class Resolver { std::unordered_map variable_to_info_; std::unordered_map function_calls_; std::unordered_map expr_info_; + std::unordered_map struct_info_; FunctionInfo* current_function_ = nullptr; semantic::Statement* current_statement_ = nullptr; BlockAllocator variable_infos_; BlockAllocator function_infos_; + BlockAllocator struct_infos_; }; } // namespace resolver