[tint] Move builtin structs to the type namespace
This code is not tied to the WGSL resolver, and we want to be able to
use it from IR code.
Change-Id: Ief220bb4cf3e7952f9588bccdfb74c6a97334a6f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/141680
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 5c8d48d..89d5f1b 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -848,8 +848,6 @@
libtint_source_set("libtint_type_src") {
sources = [
- "resolver/builtin_structs.cc",
- "resolver/builtin_structs.h",
"type/abstract_float.cc",
"type/abstract_float.h",
"type/abstract_int.cc",
@@ -864,6 +862,8 @@
"type/atomic.h",
"type/bool.cc",
"type/bool.h",
+ "type/builtin_structs.cc",
+ "type/builtin_structs.h",
"type/clone_context.h",
"type/depth_multisampled_texture.cc",
"type/depth_multisampled_texture.h",
@@ -1798,6 +1798,7 @@
sources = [
"type/atomic_test.cc",
"type/bool_test.cc",
+ "type/builtin_structs_test.cc",
"type/depth_multisampled_texture_test.cc",
"type/depth_texture_test.cc",
"type/external_texture_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 8c6ea8a..a529f04 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -269,8 +269,6 @@
reflection.h
reader/reader.cc
reader/reader.h
- resolver/builtin_structs.cc
- resolver/builtin_structs.h
resolver/const_eval.cc
resolver/const_eval.h
resolver/dependency_graph.cc
@@ -477,6 +475,8 @@
type/atomic.h
type/bool.cc
type/bool.h
+ type/builtin_structs.cc
+ type/builtin_structs.h
type/clone_context.h
type/depth_multisampled_texture.cc
type/depth_multisampled_texture.h
@@ -1102,6 +1102,7 @@
type/array_test.cc
type/atomic_test.cc
type/bool_test.cc
+ type/builtin_structs_test.cc
type/depth_multisampled_texture_test.cc
type/depth_texture_test.cc
type/external_texture_test.cc
diff --git a/src/tint/diagnostic/diagnostic.h b/src/tint/diagnostic/diagnostic.h
index b56bd8d..bec9ab0 100644
--- a/src/tint/diagnostic/diagnostic.h
+++ b/src/tint/diagnostic/diagnostic.h
@@ -37,6 +37,7 @@
/// diagnostic message.
enum class System {
AST,
+ Builtin,
Clone,
Constant,
Inspector,
diff --git a/src/tint/ir/transform/demote_to_helper_test.cc b/src/tint/ir/transform/demote_to_helper_test.cc
index 9e41b6b..fe75df1 100644
--- a/src/tint/ir/transform/demote_to_helper_test.cc
+++ b/src/tint/ir/transform/demote_to_helper_test.cc
@@ -17,7 +17,7 @@
#include <utility>
#include "src/tint/ir/transform/test_helper.h"
-#include "src/tint/resolver/builtin_structs.h"
+#include "src/tint/type/builtin_structs.h"
#include "src/tint/type/f32.h"
#include "src/tint/type/storage_texture.h"
@@ -769,9 +769,8 @@
b.Discard();
b.ExitIf(ifelse);
});
- auto* result =
- b.Call(resolver::CreateAtomicCompareExchangeResult(ty, mod.symbols, ty.i32()),
- builtin::Function::kAtomicCompareExchangeWeak, buffer, 0_i, 42_i);
+ auto* result = b.Call(type::CreateAtomicCompareExchangeResult(ty, mod.symbols, ty.i32()),
+ builtin::Function::kAtomicCompareExchangeWeak, buffer, 0_i, 42_i);
b.Add(ty.i32(), b.Access(ty.i32(), result, 0_i), 1_i);
b.Return(ep, 0.5_f);
});
diff --git a/src/tint/resolver/builtin_structs.h b/src/tint/resolver/builtin_structs.h
deleted file mode 100644
index fd6d98f..0000000
--- a/src/tint/resolver/builtin_structs.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2023 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
-#define SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
-
-// Forward declarations
-namespace tint {
-class SymbolTable;
-} // namespace tint
-namespace tint::type {
-class Manager;
-class Struct;
-class Type;
-} // namespace tint::type
-
-namespace tint::resolver {
-
-/**
- * @param types the type manager
- * @param symbols the symbol table
- * @param ty the type of the `fract` and `whole` struct members.
- * @return the builtin struct type for a modf() builtin call.
- */
-type::Struct* CreateModfResult(type::Manager& types, SymbolTable& symbols, const type::Type* ty);
-
-/**
- * @param types the type manager
- * @param symbols the symbol table
- * @param fract the type of the `fract` struct member.
- * @return the builtin struct type for a frexp() builtin call.
- */
-type::Struct* CreateFrexpResult(type::Manager& types,
- SymbolTable& symbols,
- const type::Type* fract);
-
-/**
- * @param types the type manager
- * @param symbols the symbol table
- * @param ty the type of the `old_value` struct member.
- * @return the builtin struct type for a atomic_compare_exchange() builtin call.
- */
-type::Struct* CreateAtomicCompareExchangeResult(type::Manager& types,
- SymbolTable& symbols,
- const type::Type* ty);
-
-} // namespace tint::resolver
-
-#endif // SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index 755351f..f6bf22e 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -20,7 +20,6 @@
#include "src/tint/ast/binary_expression.h"
#include "src/tint/program_builder.h"
-#include "src/tint/resolver/builtin_structs.h"
#include "src/tint/sem/evaluation_stage.h"
#include "src/tint/sem/pipeline_stage_set.h"
#include "src/tint/sem/value_constructor.h"
@@ -30,6 +29,7 @@
#include "src/tint/type/abstract_int.h"
#include "src/tint/type/abstract_numeric.h"
#include "src/tint/type/atomic.h"
+#include "src/tint/type/builtin_structs.h"
#include "src/tint/type/depth_multisampled_texture.h"
#include "src/tint/type/depth_texture.h"
#include "src/tint/type/external_texture.h"
@@ -821,25 +821,26 @@
}
const type::Struct* build_modf_result(MatchState& state, const type::Type* el) {
- return CreateModfResult(state.builder.Types(), state.builder.Symbols(), el);
+ return type::CreateModfResult(state.builder.Types(), state.builder.Symbols(), el);
}
const type::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
auto* vec = state.builder.create<type::Vector>(el, n.Value());
- return CreateModfResult(state.builder.Types(), state.builder.Symbols(), vec);
+ return type::CreateModfResult(state.builder.Types(), state.builder.Symbols(), vec);
}
const type::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
- return CreateFrexpResult(state.builder.Types(), state.builder.Symbols(), el);
+ return type::CreateFrexpResult(state.builder.Types(), state.builder.Symbols(), el);
}
const type::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
auto* vec = state.builder.create<type::Vector>(el, n.Value());
- return CreateFrexpResult(state.builder.Types(), state.builder.Symbols(), vec);
+ return type::CreateFrexpResult(state.builder.Types(), state.builder.Symbols(), vec);
}
const type::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
- return CreateAtomicCompareExchangeResult(state.builder.Types(), state.builder.Symbols(), ty);
+ return type::CreateAtomicCompareExchangeResult(state.builder.Types(), state.builder.Symbols(),
+ ty);
}
/// ParameterInfo describes a parameter
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 4cc93c7..3a47118 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -43,7 +43,6 @@
#include "src/tint/ast/while_statement.h"
#include "src/tint/ast/workgroup_attribute.h"
#include "src/tint/builtin/builtin.h"
-#include "src/tint/resolver/builtin_structs.h"
#include "src/tint/resolver/uniformity.h"
#include "src/tint/sem/break_if_statement.h"
#include "src/tint/sem/builtin_enum_expression.h"
@@ -70,6 +69,7 @@
#include "src/tint/type/abstract_int.h"
#include "src/tint/type/array.h"
#include "src/tint/type/atomic.h"
+#include "src/tint/type/builtin_structs.h"
#include "src/tint/type/depth_multisampled_texture.h"
#include "src/tint/type/depth_texture.h"
#include "src/tint/type/external_texture.h"
@@ -2824,57 +2824,59 @@
case builtin::Builtin::kPackedVec3:
return packed_vec3_t();
case builtin::Builtin::kAtomicCompareExchangeResultI32:
- return CreateAtomicCompareExchangeResult(builder_->Types(), builder_->Symbols(), i32());
+ return type::CreateAtomicCompareExchangeResult(builder_->Types(), builder_->Symbols(),
+ i32());
case builtin::Builtin::kAtomicCompareExchangeResultU32:
- return CreateAtomicCompareExchangeResult(builder_->Types(), builder_->Symbols(), u32());
+ return type::CreateAtomicCompareExchangeResult(builder_->Types(), builder_->Symbols(),
+ u32());
case builtin::Builtin::kFrexpResultAbstract:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), af());
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), af());
case builtin::Builtin::kFrexpResultF16:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), f16());
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), f16());
case builtin::Builtin::kFrexpResultF32:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), f32());
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), f32());
case builtin::Builtin::kFrexpResultVec2Abstract:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(af(), 2));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(af(), 2));
case builtin::Builtin::kFrexpResultVec2F16:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f16(), 2));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f16(), 2));
case builtin::Builtin::kFrexpResultVec2F32:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f32(), 2));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f32(), 2));
case builtin::Builtin::kFrexpResultVec3Abstract:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(af(), 3));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(af(), 3));
case builtin::Builtin::kFrexpResultVec3F16:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f16(), 3));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f16(), 3));
case builtin::Builtin::kFrexpResultVec3F32:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f32(), 3));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f32(), 3));
case builtin::Builtin::kFrexpResultVec4Abstract:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(af(), 4));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(af(), 4));
case builtin::Builtin::kFrexpResultVec4F16:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f16(), 4));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f16(), 4));
case builtin::Builtin::kFrexpResultVec4F32:
- return CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f32(), 4));
+ return type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), vec(f32(), 4));
case builtin::Builtin::kModfResultAbstract:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), af());
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), af());
case builtin::Builtin::kModfResultF16:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), f16());
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), f16());
case builtin::Builtin::kModfResultF32:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), f32());
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), f32());
case builtin::Builtin::kModfResultVec2Abstract:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(af(), 2));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(af(), 2));
case builtin::Builtin::kModfResultVec2F16:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f16(), 2));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f16(), 2));
case builtin::Builtin::kModfResultVec2F32:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f32(), 2));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f32(), 2));
case builtin::Builtin::kModfResultVec3Abstract:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(af(), 3));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(af(), 3));
case builtin::Builtin::kModfResultVec3F16:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f16(), 3));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f16(), 3));
case builtin::Builtin::kModfResultVec3F32:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f32(), 3));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f32(), 3));
case builtin::Builtin::kModfResultVec4Abstract:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(af(), 4));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(af(), 4));
case builtin::Builtin::kModfResultVec4F16:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f16(), 4));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f16(), 4));
case builtin::Builtin::kModfResultVec4F32:
- return CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f32(), 4));
+ return type::CreateModfResult(builder_->Types(), builder_->Symbols(), vec(f32(), 4));
case builtin::Builtin::kUndefined:
break;
}
diff --git a/src/tint/resolver/builtin_structs.cc b/src/tint/type/builtin_structs.cc
similarity index 71%
rename from src/tint/resolver/builtin_structs.cc
rename to src/tint/type/builtin_structs.cc
index 0e7c659..8e54e85 100644
--- a/src/tint/resolver/builtin_structs.cc
+++ b/src/tint/type/builtin_structs.cc
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/tint/resolver/builtin_structs.h"
+#include "src/tint/type/builtin_structs.h"
#include <algorithm>
#include <string>
@@ -32,7 +32,7 @@
#include "src/tint/type/vector.h"
#include "src/tint/utils/string.h"
-namespace tint::resolver {
+namespace tint::type {
constexpr std::array kModfVecF32Names{
builtin::Builtin::kModfResultVec2F32,
@@ -49,16 +49,16 @@
builtin::Builtin::kModfResultVec3Abstract,
builtin::Builtin::kModfResultVec4Abstract,
};
-type::Struct* CreateModfResult(type::Manager& types, SymbolTable& symbols, const type::Type* ty) {
- auto build = [&](builtin::Builtin name, const type::Type* t) {
+Struct* CreateModfResult(Manager& types, SymbolTable& symbols, const Type* ty) {
+ auto build = [&](builtin::Builtin name, const Type* t) {
return types.Struct(symbols.Register(utils::ToString(name)),
{{symbols.Register("fract"), t}, {symbols.Register("whole"), t}});
};
return Switch(
ty, //
- [&](const type::F32*) { return build(builtin::Builtin::kModfResultF32, ty); },
- [&](const type::F16*) { return build(builtin::Builtin::kModfResultF16, ty); },
- [&](const type::AbstractFloat*) {
+ [&](const F32*) { return build(builtin::Builtin::kModfResultF32, ty); },
+ [&](const F16*) { return build(builtin::Builtin::kModfResultF16, ty); },
+ [&](const AbstractFloat*) {
auto* abstract = build(builtin::Builtin::kModfResultAbstract, ty);
abstract->SetConcreteTypes(utils::Vector{
build(builtin::Builtin::kModfResultF32, types.f32()),
@@ -66,13 +66,13 @@
});
return abstract;
},
- [&](const type::Vector* vec) {
+ [&](const Vector* vec) {
auto width = vec->Width();
return Switch(
vec->type(), //
- [&](const type::F32*) { return build(kModfVecF32Names[width - 2], vec); },
- [&](const type::F16*) { return build(kModfVecF16Names[width - 2], vec); },
- [&](const type::AbstractFloat*) {
+ [&](const F32*) { return build(kModfVecF32Names[width - 2], vec); },
+ [&](const F16*) { return build(kModfVecF16Names[width - 2], vec); },
+ [&](const AbstractFloat*) {
auto* abstract = build(kModfVecAbstractNames[width - 2], vec);
abstract->SetConcreteTypes(utils::Vector{
build(kModfVecF32Names[width - 2], types.vec(types.f32(), width)),
@@ -81,12 +81,12 @@
return abstract;
},
[&](Default) {
- TINT_ASSERT(Resolver, false && "unhandled modf type");
+ TINT_ASSERT(Builtin, false && "unhandled modf type");
return nullptr;
});
},
[&](Default) {
- TINT_ASSERT(Resolver, false && "unhandled modf type");
+ TINT_ASSERT(Builtin, false && "unhandled modf type");
return nullptr;
});
}
@@ -106,17 +106,17 @@
builtin::Builtin::kFrexpResultVec3Abstract,
builtin::Builtin::kFrexpResultVec4Abstract,
};
-type::Struct* CreateFrexpResult(type::Manager& types, SymbolTable& symbols, const type::Type* ty) {
- auto build = [&](builtin::Builtin name, const type::Type* fract_ty, const type::Type* exp_ty) {
+Struct* CreateFrexpResult(Manager& types, SymbolTable& symbols, const Type* ty) {
+ auto build = [&](builtin::Builtin name, const Type* fract_ty, const Type* exp_ty) {
return types.Struct(
symbols.Register(utils::ToString(name)),
{{symbols.Register("fract"), fract_ty}, {symbols.Register("exp"), exp_ty}});
};
return Switch(
ty, //
- [&](const type::F32*) { return build(builtin::Builtin::kFrexpResultF32, ty, types.i32()); },
- [&](const type::F16*) { return build(builtin::Builtin::kFrexpResultF16, ty, types.i32()); },
- [&](const type::AbstractFloat*) {
+ [&](const F32*) { return build(builtin::Builtin::kFrexpResultF32, ty, types.i32()); },
+ [&](const F16*) { return build(builtin::Builtin::kFrexpResultF16, ty, types.i32()); },
+ [&](const AbstractFloat*) {
auto* abstract = build(builtin::Builtin::kFrexpResultAbstract, ty, types.AInt());
abstract->SetConcreteTypes(utils::Vector{
build(builtin::Builtin::kFrexpResultF32, types.f32(), types.i32()),
@@ -124,17 +124,17 @@
});
return abstract;
},
- [&](const type::Vector* vec) {
+ [&](const Vector* vec) {
auto width = vec->Width();
return Switch(
vec->type(), //
- [&](const type::F32*) {
+ [&](const F32*) {
return build(kFrexpVecF32Names[width - 2], ty, types.vec(types.i32(), width));
},
- [&](const type::F16*) {
+ [&](const F16*) {
return build(kFrexpVecF16Names[width - 2], ty, types.vec(types.i32(), width));
},
- [&](const type::AbstractFloat*) {
+ [&](const AbstractFloat*) {
auto* vec_f32 = types.vec(types.f32(), width);
auto* vec_f16 = types.vec(types.f16(), width);
auto* vec_i32 = types.vec(types.i32(), width);
@@ -147,19 +147,17 @@
return abstract;
},
[&](Default) {
- TINT_ASSERT(Resolver, false && "unhandled frexp type");
+ TINT_ASSERT(Builtin, false && "unhandled frexp type");
return nullptr;
});
},
[&](Default) {
- TINT_ASSERT(Resolver, false && "unhandled frexp type");
+ TINT_ASSERT(Builtin, false && "unhandled frexp type");
return nullptr;
});
}
-type::Struct* CreateAtomicCompareExchangeResult(type::Manager& types,
- SymbolTable& symbols,
- const type::Type* ty) {
+Struct* CreateAtomicCompareExchangeResult(Manager& types, SymbolTable& symbols, const Type* ty) {
auto build = [&](builtin::Builtin name) {
return types.Struct(symbols.Register(utils::ToString(name)),
{
@@ -169,12 +167,12 @@
};
return Switch(
ty, //
- [&](const type::I32*) { return build(builtin::Builtin::kAtomicCompareExchangeResultI32); },
- [&](const type::U32*) { return build(builtin::Builtin::kAtomicCompareExchangeResultU32); },
+ [&](const I32*) { return build(builtin::Builtin::kAtomicCompareExchangeResultI32); },
+ [&](const U32*) { return build(builtin::Builtin::kAtomicCompareExchangeResultU32); },
[&](Default) {
- TINT_ASSERT(Resolver, false && "unhandled atomic_compare_exchange type");
+ TINT_ASSERT(Builtin, false && "unhandled atomic_compare_exchange type");
return nullptr;
});
}
-} // namespace tint::resolver
+} // namespace tint::type
diff --git a/src/tint/type/builtin_structs.h b/src/tint/type/builtin_structs.h
new file mode 100644
index 0000000..3e376b4
--- /dev/null
+++ b/src/tint/type/builtin_structs.h
@@ -0,0 +1,50 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_TYPE_BUILTIN_STRUCTS_H_
+#define SRC_TINT_TYPE_BUILTIN_STRUCTS_H_
+
+// Forward declarations
+namespace tint {
+class SymbolTable;
+} // namespace tint
+namespace tint::type {
+class Manager;
+class Struct;
+class Type;
+} // namespace tint::type
+
+namespace tint::type {
+
+/// @param types the type manager
+/// @param symbols the symbol table
+/// @param ty the type of the `fract` and `whole` struct members.
+/// @returns the builtin struct type for a modf() builtin call.
+Struct* CreateModfResult(Manager& types, SymbolTable& symbols, const Type* ty);
+
+/// @param types the type manager
+/// @param symbols the symbol table
+/// @param fract the type of the `fract` struct member.
+/// @returns the builtin struct type for a frexp() builtin call.
+Struct* CreateFrexpResult(Manager& types, SymbolTable& symbols, const Type* fract);
+
+/// @param types the type manager
+/// @param symbols the symbol table
+/// @param ty the type of the `old_value` struct member.
+/// @returns the builtin struct type for a atomic_compare_exchange() builtin call.
+Struct* CreateAtomicCompareExchangeResult(Manager& types, SymbolTable& symbols, const Type* ty);
+
+} // namespace tint::type
+
+#endif // SRC_TINT_TYPE_BUILTIN_STRUCTS_H_
diff --git a/src/tint/type/builtin_structs_test.cc b/src/tint/type/builtin_structs_test.cc
new file mode 100644
index 0000000..84eaa4b
--- /dev/null
+++ b/src/tint/type/builtin_structs_test.cc
@@ -0,0 +1,164 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/type/builtin_structs.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/program_id.h"
+#include "src/tint/symbol_table.h"
+#include "src/tint/type/abstract_float.h"
+#include "src/tint/type/abstract_int.h"
+#include "src/tint/type/bool.h"
+#include "src/tint/type/f16.h"
+#include "src/tint/type/f32.h"
+#include "src/tint/type/i32.h"
+#include "src/tint/type/manager.h"
+#include "src/tint/type/u32.h"
+#include "src/tint/type/vector.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::type {
+namespace {
+
+enum ElementType {
+ kAFloat,
+ kAInt,
+ kF32,
+ kF16,
+ kI32,
+ kU32,
+};
+
+template <typename T>
+class BuiltinStructsTest : public testing::TestWithParam<T> {
+ protected:
+ BuiltinStructsTest() : symbols(ProgramID::New()) {}
+
+ const Type* Make(ElementType t) {
+ switch (t) {
+ case kAFloat:
+ return ty.AFloat();
+ case kAInt:
+ return ty.AInt();
+ case kF32:
+ return ty.f32();
+ case kF16:
+ return ty.f16();
+ case kI32:
+ return ty.i32();
+ case kU32:
+ return ty.u32();
+ }
+ return nullptr;
+ }
+
+ Manager ty;
+ SymbolTable symbols;
+};
+
+struct FrexpCase {
+ ElementType in;
+ ElementType fract;
+ ElementType exp;
+};
+class BuiltinFrexpResultStructTest : public BuiltinStructsTest<FrexpCase> {
+ protected:
+ void Run(const Type* in_type, const Type* fract_type, const Type* exp_type) {
+ auto* result = CreateFrexpResult(ty, symbols, in_type);
+
+ auto* str = As<Struct>(result);
+ ASSERT_NE(str, nullptr);
+ ASSERT_EQ(str->Members().Length(), 2u);
+ EXPECT_EQ(str->Members()[0]->Name().Name(), "fract");
+ EXPECT_EQ(str->Members()[0]->Type(), fract_type);
+ EXPECT_EQ(str->Members()[1]->Name().Name(), "exp");
+ EXPECT_EQ(str->Members()[1]->Type(), exp_type);
+ }
+};
+TEST_P(BuiltinFrexpResultStructTest, Scalar) {
+ auto params = GetParam();
+ Run(Make(params.in), Make(params.fract), Make(params.exp));
+}
+TEST_P(BuiltinFrexpResultStructTest, Vec2) {
+ auto params = GetParam();
+ Run(ty.vec2(Make(params.in)), ty.vec2(Make(params.fract)), ty.vec2(Make(params.exp)));
+}
+TEST_P(BuiltinFrexpResultStructTest, Vec3) {
+ auto params = GetParam();
+ Run(ty.vec3(Make(params.in)), ty.vec3(Make(params.fract)), ty.vec3(Make(params.exp)));
+}
+TEST_P(BuiltinFrexpResultStructTest, Vec4) {
+ auto params = GetParam();
+ Run(ty.vec4(Make(params.in)), ty.vec4(Make(params.fract)), ty.vec4(Make(params.exp)));
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinFrexpResultStructTest,
+ BuiltinFrexpResultStructTest,
+ testing::Values(FrexpCase{kAFloat, kAFloat, kAInt},
+ FrexpCase{kF32, kF32, kI32},
+ FrexpCase{kF16, kF16, kI32}));
+
+class BuiltinModfResultStructTest : public BuiltinStructsTest<ElementType> {
+ protected:
+ void Run(const Type* type) {
+ auto* result = CreateModfResult(ty, symbols, type);
+
+ auto* str = As<Struct>(result);
+ ASSERT_NE(str, nullptr);
+ ASSERT_EQ(str->Members().Length(), 2u);
+ EXPECT_EQ(str->Members()[0]->Name().Name(), "fract");
+ EXPECT_EQ(str->Members()[0]->Type(), type);
+ EXPECT_EQ(str->Members()[1]->Name().Name(), "whole");
+ EXPECT_EQ(str->Members()[1]->Type(), type);
+ }
+};
+TEST_P(BuiltinModfResultStructTest, Scalar) {
+ Run(Make(GetParam()));
+}
+TEST_P(BuiltinModfResultStructTest, Vec2) {
+ Run(ty.vec2(Make(GetParam())));
+}
+TEST_P(BuiltinModfResultStructTest, Vec3) {
+ Run(ty.vec3(Make(GetParam())));
+}
+TEST_P(BuiltinModfResultStructTest, Vec4) {
+ Run(ty.vec4(Make(GetParam())));
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinModfResultStructTest,
+ BuiltinModfResultStructTest,
+ testing::Values(kAFloat, kF32, kF16));
+
+class BuiltinAtomicCompareExchangeResultStructTest : public BuiltinStructsTest<ElementType> {
+ protected:
+ void Run(const Type* type) {
+ auto* result = CreateAtomicCompareExchangeResult(ty, symbols, type);
+
+ auto* str = As<Struct>(result);
+ ASSERT_NE(str, nullptr);
+ ASSERT_EQ(str->Members().Length(), 2u);
+ EXPECT_EQ(str->Members()[0]->Name().Name(), "old_value");
+ EXPECT_EQ(str->Members()[0]->Type(), type);
+ EXPECT_EQ(str->Members()[1]->Name().Name(), "exchanged");
+ EXPECT_EQ(str->Members()[1]->Type(), ty.bool_());
+ }
+};
+TEST_P(BuiltinAtomicCompareExchangeResultStructTest, Scalar) {
+ Run(Make(GetParam()));
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinAtomicCompareExchangeResultStructTest,
+ BuiltinAtomicCompareExchangeResultStructTest,
+ testing::Values(kI32, kU32));
+
+} // namespace
+} // namespace tint::type
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
index 759ac00..acff41f 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
@@ -15,7 +15,7 @@
#include "src/tint/writer/spirv/ir/test_helper_ir.h"
#include "src/tint/builtin/function.h"
-#include "src/tint/resolver/builtin_structs.h"
+#include "src/tint/type/builtin_structs.h"
using namespace tint::number_suffixes; // NOLINT
@@ -209,7 +209,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Frexp_F32) {
- auto* str = resolver::CreateFrexpResult(ty, mod.symbols, ty.f32());
+ auto* str = type::CreateFrexpResult(ty, mod.symbols, ty.f32());
auto* arg = b.FunctionParam("arg", ty.f32());
auto* func = b.Function("foo", str);
func->SetParams({arg});
@@ -224,7 +224,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Frexp_F16) {
- auto* str = resolver::CreateFrexpResult(ty, mod.symbols, ty.f16());
+ auto* str = type::CreateFrexpResult(ty, mod.symbols, ty.f16());
auto* arg = b.FunctionParam("arg", ty.f16());
auto* func = b.Function("foo", str);
func->SetParams({arg});
@@ -239,7 +239,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Frexp_Vec2f) {
- auto* str = resolver::CreateFrexpResult(ty, mod.symbols, ty.vec2<f32>());
+ auto* str = type::CreateFrexpResult(ty, mod.symbols, ty.vec2<f32>());
auto* arg = b.FunctionParam("arg", ty.vec2<f32>());
auto* func = b.Function("foo", str);
func->SetParams({arg});
@@ -254,7 +254,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Frexp_Vec3h) {
- auto* str = resolver::CreateFrexpResult(ty, mod.symbols, ty.vec3<f16>());
+ auto* str = type::CreateFrexpResult(ty, mod.symbols, ty.vec3<f16>());
auto* arg = b.FunctionParam("arg", ty.vec3<f16>());
auto* func = b.Function("foo", str);
func->SetParams({arg});
@@ -283,7 +283,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Modf_F32) {
- auto* str = resolver::CreateModfResult(ty, mod.symbols, ty.f32());
+ auto* str = type::CreateModfResult(ty, mod.symbols, ty.f32());
auto* arg = b.FunctionParam("arg", ty.f32());
auto* func = b.Function("foo", str);
func->SetParams({arg});
@@ -298,7 +298,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Modf_F16) {
- auto* str = resolver::CreateModfResult(ty, mod.symbols, ty.f16());
+ auto* str = type::CreateModfResult(ty, mod.symbols, ty.f16());
auto* arg = b.FunctionParam("arg", ty.f16());
auto* func = b.Function("foo", str);
func->SetParams({arg});
@@ -313,7 +313,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Modf_Vec2f) {
- auto* str = resolver::CreateModfResult(ty, mod.symbols, ty.vec2<f32>());
+ auto* str = type::CreateModfResult(ty, mod.symbols, ty.vec2<f32>());
auto* arg = b.FunctionParam("arg", ty.vec2<f32>());
auto* func = b.Function("foo", str);
func->SetParams({arg});
@@ -328,7 +328,7 @@
}
TEST_F(SpvGeneratorImplTest, Builtin_Modf_Vec3h) {
- auto* str = resolver::CreateModfResult(ty, mod.symbols, ty.vec3<f16>());
+ auto* str = type::CreateModfResult(ty, mod.symbols, ty.vec3<f16>());
auto* arg = b.FunctionParam("arg", ty.vec3<f16>());
auto* func = b.Function("foo", str);
func->SetParams({arg});