Rename TypeDeterminer to Resolver
Move out of the src root and into its own subdirectory Rename methods to remove the 'Determine' prefix. Fixed: tint:529 Change-Id: Idf89d647780f8a2e7495c1c9e6c402e00ad45b7c Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/44041 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
fd31bbd3f1
commit
5f0ea11365
6
BUILD.gn
6
BUILD.gn
|
@ -377,6 +377,8 @@ source_set("libtint_core_src") {
|
|||
"src/program_builder.h",
|
||||
"src/reader/reader.cc",
|
||||
"src/reader/reader.h",
|
||||
"src/resolver/resolver.cc",
|
||||
"src/resolver/resolver.h",
|
||||
"src/scope_stack.h",
|
||||
"src/semantic/call.h",
|
||||
"src/semantic/expression.h",
|
||||
|
@ -455,8 +457,6 @@ source_set("libtint_core_src") {
|
|||
"src/type/vector_type.h",
|
||||
"src/type/void_type.cc",
|
||||
"src/type/void_type.h",
|
||||
"src/type_determiner.cc",
|
||||
"src/type_determiner.h",
|
||||
"src/utils/unique_vector.h",
|
||||
"src/validator/validator.cc",
|
||||
"src/validator/validator.h",
|
||||
|
@ -842,6 +842,7 @@ source_set("tint_unittests_core_src") {
|
|||
"src/intrinsic_table_test.cc",
|
||||
"src/program_builder_test.cc",
|
||||
"src/program_test.cc",
|
||||
"src/resolver/resolver_test.cc",
|
||||
"src/semantic/sem_intrinsic_test.cc",
|
||||
"src/scope_stack_test.cc",
|
||||
"src/symbol_table_test.cc",
|
||||
|
@ -871,7 +872,6 @@ source_set("tint_unittests_core_src") {
|
|||
"src/type/type_manager_test.cc",
|
||||
"src/type/u32_type_test.cc",
|
||||
"src/type/vector_type_test.cc",
|
||||
"src/type_determiner_test.cc",
|
||||
"src/utils/command_test.cc",
|
||||
"src/utils/command.h",
|
||||
"src/utils/tmpfile_test.cc",
|
||||
|
|
26
docs/arch.md
26
docs/arch.md
|
@ -24,7 +24,7 @@
|
|||
┃ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┃┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
|
||||
▲ ┆ Build ▼ ┆
|
||||
┏━━━┻━━━┓ ┆ ┏━━━━━━━━┻━━━━━━━━┓ ┆
|
||||
┃ Clone ┃ ┆ ┃ Type Determiner ┃ ┆
|
||||
┃ Clone ┃ ┆ ┃ Resolver ┃ ┆
|
||||
┗━━━┳━━━┛ ┆ ┗━━━━━━━━━━━━━━━━━┛ ┆
|
||||
▲ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┃┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
|
||||
┃ ▼
|
||||
|
@ -69,8 +69,8 @@ simpler. A `ProgramBuilder` can only be used once, and must be discarded after
|
|||
the `Program` is constructed.
|
||||
|
||||
A `Program` is built from the `ProgramBuilder` by `std::move()`ing the
|
||||
`ProgramBuilder` to a new `Program` object. When built, type determination is
|
||||
run so the produced `Program` will contain all the needed semantic information.
|
||||
`ProgramBuilder` to a new `Program` object. When built, resolution is performed
|
||||
so the produced `Program` will contain all the needed semantic information.
|
||||
|
||||
At any time before building the `Program`, `ProgramBuilder::IsValid()` may be
|
||||
called to ensure the AST is **structurally** correct. This checks that things
|
||||
|
@ -101,7 +101,7 @@ can set, aside from storing it as an unsigned integer.
|
|||
|
||||
## Types
|
||||
|
||||
Types are constructed during the Reader and Type Determination phases, and are
|
||||
Types are constructed during the Reader and resolution phases, and are
|
||||
held by the `Program` or `ProgramBuilder`. AST and semantic nodes can both
|
||||
reference types.
|
||||
|
||||
|
@ -120,7 +120,7 @@ a higher / more abstract level than the AST. This includes information such as
|
|||
the resolved type of each expression, the resolved overload of an intrinsic
|
||||
function call, and the module scoped variables used by each function.
|
||||
|
||||
Semantic information is generated by the `TypeDeterminer` when the `Program`
|
||||
Semantic information is generated by the `Resolver` when the `Program`
|
||||
is built from a `ProgramBuilder`.
|
||||
|
||||
The `semantic::Info` class holds a map of `ast::Node`s to `semantic::Node`s.
|
||||
|
@ -142,15 +142,15 @@ During the Writer phase, symbols may be emitted as strings using a `Namer`.
|
|||
A `Namer` may output the symbol in any form that preserves the uniqueness of
|
||||
that symbol.
|
||||
|
||||
## Type Determiner
|
||||
## Resolver
|
||||
|
||||
The `TypeDeterminer` will automatically run when a `Program` is built.
|
||||
A `TypeDeterminer` creates the `Program`s semantic information by analyzing the
|
||||
The `Resolver` will automatically run when a `Program` is built.
|
||||
A `Resolver` creates the `Program`s semantic information by analyzing the
|
||||
`Program`s AST and type information.
|
||||
|
||||
The `TypeDeterminer` will do the minimal amount of validation required in order
|
||||
The `Resolver` will do the minimal amount of validation required in order
|
||||
to always be accessing valid nodes, reporting any errors found in the
|
||||
`Program`'s diagnostics. Even if the `TypeDeterminer` doesn't generate any
|
||||
`Program`'s diagnostics. Even if the `Resolver` doesn't generate any
|
||||
errors doesn't mean the generated `Program` is semantically valid. Use the
|
||||
`Validator` to check for a `Program`'s final validity.
|
||||
|
||||
|
@ -158,10 +158,10 @@ errors doesn't mean the generated `Program` is semantically valid. Use the
|
|||
|
||||
A `Program` holds an immutable version of the information from the
|
||||
`ProgramBuilder` along with semantic information generated by the
|
||||
`TypeDeterminer`.
|
||||
`Resolver`.
|
||||
|
||||
Like `ProgramBuilder`, `Program::IsValid()` may be called to ensure the AST is
|
||||
structurally correct and that the `TypeDeterminer` did not report any errors.
|
||||
structurally correct and that the `Resolver` did not report any errors.
|
||||
`Program::IsValid()` does not perform semantic validation, use the `Validator`
|
||||
to check for a `Program`'s final validity.
|
||||
|
||||
|
@ -192,7 +192,7 @@ This is for things like Vertex Pulling or Robust Buffer Access.
|
|||
|
||||
A transform operates by cloning the input `Program` into a new `ProgramBuilder`,
|
||||
applying the required changes, and then finally building and returning a new
|
||||
output `Program`. As type determination is always run when a `Program` is built,
|
||||
output `Program`. As the resolver is always run when a `Program` is built,
|
||||
Transforms will always emit a `Program` with semantic information.
|
||||
|
||||
The input `Program` to a transform must be valid (pass validation).
|
||||
|
|
|
@ -191,6 +191,8 @@ set(TINT_LIB_SRCS
|
|||
program.h
|
||||
reader/reader.cc
|
||||
reader/reader.h
|
||||
resolver/resolver.cc
|
||||
resolver/resolver.h
|
||||
scope_stack.h
|
||||
semantic/call.h
|
||||
semantic/expression.h
|
||||
|
@ -229,8 +231,6 @@ set(TINT_LIB_SRCS
|
|||
transform/transform.h
|
||||
transform/vertex_pulling.cc
|
||||
transform/vertex_pulling.h
|
||||
type_determiner.cc
|
||||
type_determiner.h
|
||||
type/access_control_type.cc
|
||||
type/access_control_type.h
|
||||
type/alias_type.cc
|
||||
|
@ -470,13 +470,13 @@ if(${TINT_BUILD_TESTS})
|
|||
inspector/inspector_test.cc
|
||||
intrinsic_table_test.cc
|
||||
program_test.cc
|
||||
resolver/resolver_test.cc
|
||||
semantic/sem_intrinsic_test.cc
|
||||
scope_stack_test.cc
|
||||
symbol_table_test.cc
|
||||
symbol_test.cc
|
||||
traits_test.cc
|
||||
test_main.cc
|
||||
type_determiner_test.cc
|
||||
type/access_control_type_test.cc
|
||||
type/alias_type_test.cc
|
||||
type/array_type_test.cc
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "tint/tint.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -704,7 +703,6 @@ class InspectorHelper : public ProgramBuilder {
|
|||
type::Sampler* comparison_sampler_type() { return &comparison_sampler_type_; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<TypeDeterminer> td_;
|
||||
std::unique_ptr<Program> program_;
|
||||
std::unique_ptr<Inspector> inspector_;
|
||||
type::Sampler sampler_type_;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include "src/clone_context.h"
|
||||
#include "src/demangler.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/resolver/resolver.h"
|
||||
#include "src/semantic/expression.h"
|
||||
#include "src/type_determiner.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
|
@ -44,9 +44,9 @@ Program::Program(Program&& program)
|
|||
Program::Program(ProgramBuilder&& builder) {
|
||||
is_valid_ = builder.IsValid();
|
||||
if (builder.ResolveOnBuild() && builder.IsValid()) {
|
||||
TypeDeterminer td(&builder);
|
||||
if (!td.Determine()) {
|
||||
diagnostics_.add_error(td.error());
|
||||
Resolver resolver(&builder);
|
||||
if (!resolver.Resolve()) {
|
||||
diagnostics_.add_error(resolver.error());
|
||||
is_valid_ = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ ast::VariableDeclStatement* ProgramBuilder::WrapInStatement(ast::Variable* v) {
|
|||
}
|
||||
|
||||
ast::Statement* ProgramBuilder::WrapInStatement(ast::Expression* expr) {
|
||||
// TODO(ben-clayton): This is valid enough for the TypeDeterminer, but the LHS
|
||||
// TODO(ben-clayton): This is valid enough for the Resolver, but the LHS
|
||||
// may not be assignable, and so may not validate.
|
||||
return create<ast::AssignmentStatement>(expr, expr);
|
||||
}
|
||||
|
|
|
@ -206,12 +206,11 @@ class ProgramBuilder {
|
|||
return diagnostics_;
|
||||
}
|
||||
|
||||
/// Controls whether the TypeDeterminer will be run on the program when it is
|
||||
/// built.
|
||||
/// Controls whether the Resolver will be run on the program when it is built.
|
||||
/// @param enable the new flag value (defaults to true)
|
||||
void SetResolveOnBuild(bool enable) { resolve_on_build_ = enable; }
|
||||
|
||||
/// @return true if the TypeDeterminer will be run on the program when it is
|
||||
/// @return true if the Resolver will be run on the program when it is
|
||||
/// built.
|
||||
bool ResolveOnBuild() const { return resolve_on_build_; }
|
||||
|
||||
|
@ -1128,22 +1127,21 @@ class ProgramBuilder {
|
|||
}
|
||||
|
||||
/// Helper for returning the resolved semantic type of the expression `expr`.
|
||||
/// @note As the TypeDeterminator is run when the Program is built, this will
|
||||
/// only be useful for the TypeDeterminer itself and tests that use their own
|
||||
/// TypeDeterminer.
|
||||
/// @note As the Resolver is run when the Program is built, this will only be
|
||||
/// useful for the Resolver itself and tests that use their own Resolver.
|
||||
/// @param expr the AST expression
|
||||
/// @return the resolved semantic type for the expression, or nullptr if the
|
||||
/// expression has no resolved type.
|
||||
type::Type* TypeOf(ast::Expression* expr) const;
|
||||
|
||||
/// Wraps the ast::Expression in a statement. This is used by tests that
|
||||
/// construct a partial AST and require the TypeDeterminer to reach these
|
||||
/// construct a partial AST and require the Resolver to reach these
|
||||
/// nodes.
|
||||
/// @param expr the ast::Expression to be wrapped by an ast::Statement
|
||||
/// @return the ast::Statement that wraps the ast::Expression
|
||||
ast::Statement* WrapInStatement(ast::Expression* expr);
|
||||
/// Wraps the ast::Variable in a ast::VariableDeclStatement. This is used by
|
||||
/// tests that construct a partial AST and require the TypeDeterminer to reach
|
||||
/// tests that construct a partial AST and require the Resolver to reach
|
||||
/// these nodes.
|
||||
/// @param v the ast::Variable to be wrapped by an ast::VariableDeclStatement
|
||||
/// @return the ast::VariableDeclStatement that wraps the ast::Variable
|
||||
|
@ -1154,7 +1152,7 @@ class ProgramBuilder {
|
|||
/// @return `stmt`
|
||||
ast::Statement* WrapInStatement(ast::Statement* stmt);
|
||||
/// Wraps the list of arguments in a simple function so that each is reachable
|
||||
/// by the TypeDeterminer.
|
||||
/// by the Resolver.
|
||||
/// @param args a mix of ast::Expression, ast::Statement, ast::Variables.
|
||||
template <typename... ARGS>
|
||||
void WrapInFunction(ARGS&&... args) {
|
||||
|
@ -1162,7 +1160,7 @@ class ProgramBuilder {
|
|||
WrapInFunction(stmts);
|
||||
}
|
||||
/// @param stmts a list of ast::Statement that will be wrapped by a function,
|
||||
/// so that each statement is reachable by the TypeDeterminer.
|
||||
/// so that each statement is reachable by the Resolver.
|
||||
void WrapInFunction(ast::StatementList stmts);
|
||||
|
||||
/// The builder types
|
||||
|
@ -1185,7 +1183,7 @@ class ProgramBuilder {
|
|||
/// the first argument.
|
||||
Source source_;
|
||||
|
||||
/// Set by SetResolveOnBuild(). If set, the TypeDeterminer will be run on the
|
||||
/// Set by SetResolveOnBuild(). If set, the Resolver will be run on the
|
||||
/// program when built.
|
||||
bool resolve_on_build_ = true;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ class SpvParserTestBase : public T {
|
|||
/// @returns a parser for the given binary
|
||||
std::unique_ptr<ParserImpl> parser(const std::vector<uint32_t>& input) {
|
||||
auto parser = std::make_unique<ParserImpl>(input);
|
||||
// Don't run the TypeDeterminer when building the program.
|
||||
// Don't run the Resolver when building the program.
|
||||
// We're not interested in type information with these tests.
|
||||
parser->builder().SetResolveOnBuild(false);
|
||||
return parser;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/resolver/resolver.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
@ -91,19 +91,19 @@ class ScopedAssignment {
|
|||
|
||||
} // namespace
|
||||
|
||||
TypeDeterminer::TypeDeterminer(ProgramBuilder* builder)
|
||||
Resolver::Resolver(ProgramBuilder* builder)
|
||||
: builder_(builder), intrinsic_table_(IntrinsicTable::Create()) {}
|
||||
|
||||
TypeDeterminer::~TypeDeterminer() = default;
|
||||
Resolver::~Resolver() = default;
|
||||
|
||||
TypeDeterminer::BlockInfo::BlockInfo(TypeDeterminer::BlockInfo::Type type,
|
||||
TypeDeterminer::BlockInfo* parent,
|
||||
const ast::BlockStatement* block)
|
||||
: type(type), parent(parent), block(block) {}
|
||||
Resolver::BlockInfo::BlockInfo(Resolver::BlockInfo::Type ty,
|
||||
Resolver::BlockInfo* p,
|
||||
const ast::BlockStatement* b)
|
||||
: type(ty), parent(p), block(b) {}
|
||||
|
||||
TypeDeterminer::BlockInfo::~BlockInfo() = default;
|
||||
Resolver::BlockInfo::~BlockInfo() = default;
|
||||
|
||||
void TypeDeterminer::set_referenced_from_function_if_needed(VariableInfo* var,
|
||||
void Resolver::set_referenced_from_function_if_needed(VariableInfo* var,
|
||||
bool local) {
|
||||
if (current_function_ == nullptr) {
|
||||
return;
|
||||
|
@ -119,8 +119,8 @@ void TypeDeterminer::set_referenced_from_function_if_needed(VariableInfo* var,
|
|||
}
|
||||
}
|
||||
|
||||
bool TypeDeterminer::Determine() {
|
||||
bool result = DetermineInternal();
|
||||
bool Resolver::Resolve() {
|
||||
bool result = ResolveInternal();
|
||||
|
||||
// Even if resolving failed, create all the semantic nodes for information we
|
||||
// did generate.
|
||||
|
@ -129,34 +129,34 @@ bool TypeDeterminer::Determine() {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineInternal() {
|
||||
bool Resolver::ResolveInternal() {
|
||||
for (auto* var : builder_->AST().GlobalVariables()) {
|
||||
variable_stack_.set_global(var->symbol(), CreateVariableInfo(var));
|
||||
|
||||
if (var->has_constructor()) {
|
||||
if (!DetermineResultType(var->constructor())) {
|
||||
if (!Expression(var->constructor())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DetermineFunctions(builder_->AST().Functions())) {
|
||||
if (!Functions(builder_->AST().Functions())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineFunctions(const ast::FunctionList& funcs) {
|
||||
bool Resolver::Functions(const ast::FunctionList& funcs) {
|
||||
for (auto* func : funcs) {
|
||||
if (!DetermineFunction(func)) {
|
||||
if (!Function(func)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineFunction(ast::Function* func) {
|
||||
bool Resolver::Function(ast::Function* func) {
|
||||
auto* func_info = function_infos_.Create<FunctionInfo>(func);
|
||||
|
||||
ScopedAssignment<FunctionInfo*> sa(current_function_, func_info);
|
||||
|
@ -166,7 +166,7 @@ bool TypeDeterminer::DetermineFunction(ast::Function* func) {
|
|||
variable_stack_.set(param->symbol(), CreateVariableInfo(param));
|
||||
}
|
||||
|
||||
if (!DetermineBlockStatement(func->body())) {
|
||||
if (!BlockStatement(func->body())) {
|
||||
return false;
|
||||
}
|
||||
variable_stack_.pop_scope();
|
||||
|
@ -180,35 +180,35 @@ bool TypeDeterminer::DetermineFunction(ast::Function* func) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineBlockStatement(const ast::BlockStatement* stmt) {
|
||||
bool Resolver::BlockStatement(const ast::BlockStatement* stmt) {
|
||||
auto* block =
|
||||
block_infos_.Create(BlockInfo::Type::Generic, current_block_, stmt);
|
||||
block_to_info_[stmt] = block;
|
||||
ScopedAssignment<BlockInfo*> scope_sa(current_block_, block);
|
||||
|
||||
return DetermineStatements(stmt->list());
|
||||
return Statements(stmt->list());
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineStatements(const ast::StatementList& stmts) {
|
||||
bool Resolver::Statements(const ast::StatementList& stmts) {
|
||||
for (auto* stmt : stmts) {
|
||||
if (auto* decl = stmt->As<ast::VariableDeclStatement>()) {
|
||||
if (!ValidateVariableDeclStatement(decl)) {
|
||||
if (!VariableDeclStatement(decl)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DetermineVariableStorageClass(stmt)) {
|
||||
if (!VariableStorageClass(stmt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DetermineResultType(stmt)) {
|
||||
if (!Statement(stmt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineVariableStorageClass(ast::Statement* stmt) {
|
||||
bool Resolver::VariableStorageClass(ast::Statement* stmt) {
|
||||
auto* var_decl = stmt->As<ast::VariableDeclStatement>();
|
||||
if (var_decl == nullptr) {
|
||||
return true;
|
||||
|
@ -238,25 +238,25 @@ bool TypeDeterminer::DetermineVariableStorageClass(ast::Statement* stmt) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
|
||||
bool Resolver::Statement(ast::Statement* stmt) {
|
||||
auto* sem_statement = builder_->create<semantic::Statement>(stmt);
|
||||
|
||||
ScopedAssignment<semantic::Statement*> sa(current_statement_, sem_statement);
|
||||
|
||||
if (auto* a = stmt->As<ast::AssignmentStatement>()) {
|
||||
return DetermineResultType(a->lhs()) && DetermineResultType(a->rhs());
|
||||
return Expression(a->lhs()) && Expression(a->rhs());
|
||||
}
|
||||
if (auto* b = stmt->As<ast::BlockStatement>()) {
|
||||
return DetermineBlockStatement(b);
|
||||
return BlockStatement(b);
|
||||
}
|
||||
if (stmt->Is<ast::BreakStatement>()) {
|
||||
return true;
|
||||
}
|
||||
if (auto* c = stmt->As<ast::CallStatement>()) {
|
||||
return DetermineResultType(c->expr());
|
||||
return Expression(c->expr());
|
||||
}
|
||||
if (auto* c = stmt->As<ast::CaseStatement>()) {
|
||||
return DetermineBlockStatement(c->body());
|
||||
return BlockStatement(c->body());
|
||||
}
|
||||
if (stmt->Is<ast::ContinueStatement>()) {
|
||||
// Set if we've hit the first continue statement in our parent loop
|
||||
|
@ -277,20 +277,18 @@ bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
|
|||
return true;
|
||||
}
|
||||
if (auto* e = stmt->As<ast::ElseStatement>()) {
|
||||
return DetermineResultType(e->condition()) &&
|
||||
DetermineBlockStatement(e->body());
|
||||
return Expression(e->condition()) && BlockStatement(e->body());
|
||||
}
|
||||
if (stmt->Is<ast::FallthroughStatement>()) {
|
||||
return true;
|
||||
}
|
||||
if (auto* i = stmt->As<ast::IfStatement>()) {
|
||||
if (!DetermineResultType(i->condition()) ||
|
||||
!DetermineBlockStatement(i->body())) {
|
||||
if (!Expression(i->condition()) || !BlockStatement(i->body())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto* else_stmt : i->else_statements()) {
|
||||
if (!DetermineResultType(else_stmt)) {
|
||||
if (!Statement(else_stmt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -306,31 +304,31 @@ bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
|
|||
block_to_info_[l->body()] = block;
|
||||
ScopedAssignment<BlockInfo*> scope_sa(current_block_, block);
|
||||
|
||||
if (!DetermineStatements(l->body()->list())) {
|
||||
if (!Statements(l->body()->list())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (l->has_continuing()) {
|
||||
auto* block = block_infos_.Create(BlockInfo::Type::LoopContinuing,
|
||||
auto* cont_block = block_infos_.Create(BlockInfo::Type::LoopContinuing,
|
||||
current_block_, l->continuing());
|
||||
block_to_info_[l->continuing()] = block;
|
||||
ScopedAssignment<BlockInfo*> scope_sa(current_block_, block);
|
||||
block_to_info_[l->continuing()] = cont_block;
|
||||
ScopedAssignment<BlockInfo*> scope_sa2(current_block_, cont_block);
|
||||
|
||||
if (!DetermineStatements(l->continuing()->list())) {
|
||||
if (!Statements(l->continuing()->list())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (auto* r = stmt->As<ast::ReturnStatement>()) {
|
||||
return DetermineResultType(r->value());
|
||||
return Expression(r->value());
|
||||
}
|
||||
if (auto* s = stmt->As<ast::SwitchStatement>()) {
|
||||
if (!DetermineResultType(s->condition())) {
|
||||
if (!Expression(s->condition())) {
|
||||
return false;
|
||||
}
|
||||
for (auto* case_stmt : s->body()) {
|
||||
if (!DetermineResultType(case_stmt)) {
|
||||
if (!Statement(case_stmt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +338,7 @@ bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
|
|||
variable_stack_.set(v->variable()->symbol(),
|
||||
variable_to_info_.at(v->variable()));
|
||||
current_block_->decls.push_back(v->variable());
|
||||
return DetermineResultType(v->variable()->constructor());
|
||||
return Expression(v->variable()->constructor());
|
||||
}
|
||||
|
||||
diagnostics_.add_error(
|
||||
|
@ -349,16 +347,16 @@ bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineResultType(const ast::ExpressionList& list) {
|
||||
bool Resolver::Expressions(const ast::ExpressionList& list) {
|
||||
for (auto* expr : list) {
|
||||
if (!DetermineResultType(expr)) {
|
||||
if (!Expression(expr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
|
||||
bool Resolver::Expression(ast::Expression* expr) {
|
||||
// This is blindly called above, so in some cases the expression won't exist.
|
||||
if (!expr) {
|
||||
return true;
|
||||
|
@ -369,28 +367,28 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
|
|||
}
|
||||
|
||||
if (auto* a = expr->As<ast::ArrayAccessorExpression>()) {
|
||||
return DetermineArrayAccessor(a);
|
||||
return ArrayAccessor(a);
|
||||
}
|
||||
if (auto* b = expr->As<ast::BinaryExpression>()) {
|
||||
return DetermineBinary(b);
|
||||
return Binary(b);
|
||||
}
|
||||
if (auto* b = expr->As<ast::BitcastExpression>()) {
|
||||
return DetermineBitcast(b);
|
||||
return Bitcast(b);
|
||||
}
|
||||
if (auto* c = expr->As<ast::CallExpression>()) {
|
||||
return DetermineCall(c);
|
||||
return Call(c);
|
||||
}
|
||||
if (auto* c = expr->As<ast::ConstructorExpression>()) {
|
||||
return DetermineConstructor(c);
|
||||
return Constructor(c);
|
||||
}
|
||||
if (auto* i = expr->As<ast::IdentifierExpression>()) {
|
||||
return DetermineIdentifier(i);
|
||||
return Identifier(i);
|
||||
}
|
||||
if (auto* m = expr->As<ast::MemberAccessorExpression>()) {
|
||||
return DetermineMemberAccessor(m);
|
||||
return MemberAccessor(m);
|
||||
}
|
||||
if (auto* u = expr->As<ast::UnaryOpExpression>()) {
|
||||
return DetermineUnaryOp(u);
|
||||
return UnaryOp(u);
|
||||
}
|
||||
|
||||
diagnostics_.add_error("unknown expression for type determination",
|
||||
|
@ -398,12 +396,11 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineArrayAccessor(
|
||||
ast::ArrayAccessorExpression* expr) {
|
||||
if (!DetermineResultType(expr->array())) {
|
||||
bool Resolver::ArrayAccessor(ast::ArrayAccessorExpression* expr) {
|
||||
if (!Expression(expr->array())) {
|
||||
return false;
|
||||
}
|
||||
if (!DetermineResultType(expr->idx_expr())) {
|
||||
if (!Expression(expr->idx_expr())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -439,16 +436,16 @@ bool TypeDeterminer::DetermineArrayAccessor(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineBitcast(ast::BitcastExpression* expr) {
|
||||
if (!DetermineResultType(expr->expr())) {
|
||||
bool Resolver::Bitcast(ast::BitcastExpression* expr) {
|
||||
if (!Expression(expr->expr())) {
|
||||
return false;
|
||||
}
|
||||
SetType(expr, expr->type());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineCall(ast::CallExpression* call) {
|
||||
if (!DetermineResultType(call->params())) {
|
||||
bool Resolver::Call(ast::CallExpression* call) {
|
||||
if (!Expressions(call->params())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -465,7 +462,7 @@ bool TypeDeterminer::DetermineCall(ast::CallExpression* call) {
|
|||
|
||||
auto intrinsic_type = semantic::ParseIntrinsicType(name);
|
||||
if (intrinsic_type != IntrinsicType::kNone) {
|
||||
if (!DetermineIntrinsicCall(call, intrinsic_type)) {
|
||||
if (!IntrinsicCall(call, intrinsic_type)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -515,8 +512,7 @@ bool TypeDeterminer::DetermineCall(ast::CallExpression* call) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineIntrinsicCall(
|
||||
ast::CallExpression* call,
|
||||
bool Resolver::IntrinsicCall(ast::CallExpression* call,
|
||||
semantic::IntrinsicType intrinsic_type) {
|
||||
std::vector<type::Type*> arg_tys;
|
||||
arg_tys.reserve(call->params().size());
|
||||
|
@ -571,10 +567,10 @@ bool TypeDeterminer::DetermineIntrinsicCall(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) {
|
||||
bool Resolver::Constructor(ast::ConstructorExpression* expr) {
|
||||
if (auto* ty = expr->As<ast::TypeConstructorExpression>()) {
|
||||
for (auto* value : ty->values()) {
|
||||
if (!DetermineResultType(value)) {
|
||||
if (!Expression(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -586,7 +582,7 @@ bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineIdentifier(ast::IdentifierExpression* expr) {
|
||||
bool Resolver::Identifier(ast::IdentifierExpression* expr) {
|
||||
auto symbol = expr->symbol();
|
||||
VariableInfo* var;
|
||||
if (variable_stack_.get(symbol, &var)) {
|
||||
|
@ -615,9 +611,9 @@ bool TypeDeterminer::DetermineIdentifier(ast::IdentifierExpression* expr) {
|
|||
auto& decls = loop_block->decls;
|
||||
// If our identifier is in loop_block->decls, make sure its index is
|
||||
// less than first_continue
|
||||
auto iter = std::find_if(
|
||||
decls.begin(), decls.end(),
|
||||
[&symbol](auto* var) { return var->symbol() == symbol; });
|
||||
auto iter =
|
||||
std::find_if(decls.begin(), decls.end(),
|
||||
[&symbol](auto* v) { return v->symbol() == symbol; });
|
||||
if (iter != decls.end()) {
|
||||
auto var_decl_index =
|
||||
static_cast<size_t>(std::distance(decls.begin(), iter));
|
||||
|
@ -656,9 +652,8 @@ bool TypeDeterminer::DetermineIdentifier(ast::IdentifierExpression* expr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineMemberAccessor(
|
||||
ast::MemberAccessorExpression* expr) {
|
||||
if (!DetermineResultType(expr->structure())) {
|
||||
bool Resolver::MemberAccessor(ast::MemberAccessorExpression* expr) {
|
||||
if (!Expression(expr->structure())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -772,8 +767,8 @@ bool TypeDeterminer::DetermineMemberAccessor(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineBinary(ast::BinaryExpression* expr) {
|
||||
if (!DetermineResultType(expr->lhs()) || !DetermineResultType(expr->rhs())) {
|
||||
bool Resolver::Binary(ast::BinaryExpression* expr) {
|
||||
if (!Expression(expr->lhs()) || !Expression(expr->rhs())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -844,9 +839,9 @@ bool TypeDeterminer::DetermineBinary(ast::BinaryExpression* expr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::DetermineUnaryOp(ast::UnaryOpExpression* expr) {
|
||||
bool Resolver::UnaryOp(ast::UnaryOpExpression* expr) {
|
||||
// Result type matches the parameter type.
|
||||
if (!DetermineResultType(expr->expr())) {
|
||||
if (!Expression(expr->expr())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -855,8 +850,7 @@ bool TypeDeterminer::DetermineUnaryOp(ast::UnaryOpExpression* expr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::ValidateVariableDeclStatement(
|
||||
const ast::VariableDeclStatement* stmt) {
|
||||
bool Resolver::VariableDeclStatement(const ast::VariableDeclStatement* stmt) {
|
||||
auto* ctor = stmt->variable()->constructor();
|
||||
if (!ctor) {
|
||||
return true;
|
||||
|
@ -877,14 +871,13 @@ bool TypeDeterminer::ValidateVariableDeclStatement(
|
|||
return true;
|
||||
}
|
||||
|
||||
TypeDeterminer::VariableInfo* TypeDeterminer::CreateVariableInfo(
|
||||
ast::Variable* var) {
|
||||
Resolver::VariableInfo* Resolver::CreateVariableInfo(ast::Variable* var) {
|
||||
auto* info = variable_infos_.Create(var);
|
||||
variable_to_info_.emplace(var, info);
|
||||
return info;
|
||||
}
|
||||
|
||||
type::Type* TypeDeterminer::TypeOf(ast::Expression* expr) {
|
||||
type::Type* Resolver::TypeOf(ast::Expression* expr) {
|
||||
auto it = expr_info_.find(expr);
|
||||
if (it != expr_info_.end()) {
|
||||
return it->second.type;
|
||||
|
@ -892,12 +885,12 @@ type::Type* TypeDeterminer::TypeOf(ast::Expression* expr) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void TypeDeterminer::SetType(ast::Expression* expr, type::Type* type) {
|
||||
void Resolver::SetType(ast::Expression* expr, type::Type* type) {
|
||||
assert(expr_info_.count(expr) == 0);
|
||||
expr_info_.emplace(expr, ExpressionInfo{type, current_statement_});
|
||||
}
|
||||
|
||||
void TypeDeterminer::CreateSemanticNodes() const {
|
||||
void Resolver::CreateSemanticNodes() const {
|
||||
auto& sem = builder_->Sem();
|
||||
|
||||
// Collate all the 'ancestor_entry_points' - this is a map of function symbol
|
||||
|
@ -906,7 +899,7 @@ void TypeDeterminer::CreateSemanticNodes() const {
|
|||
for (auto* func : builder_->AST().Functions()) {
|
||||
auto it = function_to_info_.find(func);
|
||||
if (it == function_to_info_.end()) {
|
||||
continue; // Type determination has likely errored. Process what we can.
|
||||
continue; // Resolver has likely errored. Process what we can.
|
||||
}
|
||||
|
||||
auto* info = it->second;
|
||||
|
@ -984,14 +977,13 @@ void TypeDeterminer::CreateSemanticNodes() const {
|
|||
}
|
||||
}
|
||||
|
||||
TypeDeterminer::VariableInfo::VariableInfo(ast::Variable* decl)
|
||||
Resolver::VariableInfo::VariableInfo(ast::Variable* decl)
|
||||
: declaration(decl), storage_class(decl->declared_storage_class()) {}
|
||||
|
||||
TypeDeterminer::VariableInfo::~VariableInfo() = default;
|
||||
Resolver::VariableInfo::~VariableInfo() = default;
|
||||
|
||||
TypeDeterminer::FunctionInfo::FunctionInfo(ast::Function* decl)
|
||||
: declaration(decl) {}
|
||||
Resolver::FunctionInfo::FunctionInfo(ast::Function* decl) : declaration(decl) {}
|
||||
|
||||
TypeDeterminer::FunctionInfo::~FunctionInfo() = default;
|
||||
Resolver::FunctionInfo::~FunctionInfo() = default;
|
||||
|
||||
} // namespace tint
|
|
@ -12,8 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TYPE_DETERMINER_H_
|
||||
#define SRC_TYPE_DETERMINER_H_
|
||||
#ifndef SRC_RESOLVER_RESOLVER_H_
|
||||
#define SRC_RESOLVER_RESOLVER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -49,21 +49,21 @@ namespace semantic {
|
|||
class Statement;
|
||||
} // namespace semantic
|
||||
|
||||
/// Determines types for all items in the given tint program
|
||||
class TypeDeterminer {
|
||||
/// Resolves types for all items in the given tint program
|
||||
class Resolver {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param builder the program builder
|
||||
explicit TypeDeterminer(ProgramBuilder* builder);
|
||||
explicit Resolver(ProgramBuilder* builder);
|
||||
|
||||
/// Destructor
|
||||
~TypeDeterminer();
|
||||
~Resolver();
|
||||
|
||||
/// @returns error messages from the type determiner
|
||||
/// @returns error messages from the resolver
|
||||
std::string error() const { return diagnostics_.str(); }
|
||||
|
||||
/// @returns true if the type determiner was successful
|
||||
bool Determine();
|
||||
/// @returns true if the resolver was successful
|
||||
bool Resolve();
|
||||
|
||||
private:
|
||||
/// Structure holding semantic information about a variable.
|
||||
|
@ -124,9 +124,9 @@ class TypeDeterminer {
|
|||
return curr;
|
||||
}
|
||||
|
||||
BlockInfo* FindFirstParent(BlockInfo::Type type) {
|
||||
BlockInfo* FindFirstParent(BlockInfo::Type ty) {
|
||||
return FindFirstParent(
|
||||
[type](auto* block_info) { return block_info->type == type; });
|
||||
[ty](auto* block_info) { return block_info->type == ty; });
|
||||
}
|
||||
|
||||
const Type type;
|
||||
|
@ -143,45 +143,44 @@ class TypeDeterminer {
|
|||
BlockAllocator<BlockInfo> block_infos_;
|
||||
BlockInfo* current_block_ = nullptr;
|
||||
|
||||
/// Determines type information for the program, without creating final the
|
||||
/// semantic nodes.
|
||||
/// @returns true if the determination was successful
|
||||
bool DetermineInternal();
|
||||
/// Resolves the program, without creating final the semantic nodes.
|
||||
/// @returns true on success, false on error
|
||||
bool ResolveInternal();
|
||||
|
||||
/// Determines type information for functions
|
||||
/// Resolves functions
|
||||
/// @param funcs the functions to check
|
||||
/// @returns true if the determination was successful
|
||||
bool DetermineFunctions(const ast::FunctionList& funcs);
|
||||
/// Determines type information for a function. Requires all dependency
|
||||
/// @returns true on success, false on error
|
||||
bool Functions(const ast::FunctionList& funcs);
|
||||
/// Resolves a function. Requires all dependency
|
||||
/// (callee) functions to have DetermineFunction() called on them first.
|
||||
/// @param func the function to check
|
||||
/// @returns true if the determination was successful
|
||||
bool DetermineFunction(ast::Function* func);
|
||||
/// Determines the type information for a block statement
|
||||
/// @returns true on success, false on error
|
||||
bool Function(ast::Function* func);
|
||||
/// Resolves a block statement
|
||||
/// @param stmt the block statement
|
||||
/// @returns true if determination was successful
|
||||
bool DetermineBlockStatement(const ast::BlockStatement* stmt);
|
||||
/// Determines type information for a set of statements
|
||||
/// @param stmts the statements to check
|
||||
/// @returns true if the determination was successful
|
||||
bool DetermineStatements(const ast::StatementList& stmts);
|
||||
/// Determines type information for a statement
|
||||
bool BlockStatement(const ast::BlockStatement* stmt);
|
||||
/// Resolves the list of statements
|
||||
/// @param stmts the statements to resolve
|
||||
/// @returns true on success, false on error
|
||||
bool Statements(const ast::StatementList& stmts);
|
||||
/// Resolves a statement
|
||||
/// @param stmt the statement to check
|
||||
/// @returns true if the determination was successful
|
||||
bool DetermineResultType(ast::Statement* stmt);
|
||||
/// Determines type information for an expression list
|
||||
/// @returns true on success, false on error
|
||||
bool Statement(ast::Statement* stmt);
|
||||
/// Resolves an expression list
|
||||
/// @param list the expression list to check
|
||||
/// @returns true if the determination was successful
|
||||
bool DetermineResultType(const ast::ExpressionList& list);
|
||||
/// Determines type information for an expression
|
||||
/// @returns true on success, false on error
|
||||
bool Expressions(const ast::ExpressionList& list);
|
||||
/// Resolves an expression
|
||||
/// @param expr the expression to check
|
||||
/// @returns true if the determination was successful
|
||||
bool DetermineResultType(ast::Expression* expr);
|
||||
/// Determines the storage class for variables. This assumes that it is only
|
||||
/// @returns true on success, false on error
|
||||
bool Expression(ast::Expression* expr);
|
||||
/// Resolves the storage class for variables. This assumes that it is only
|
||||
/// called for things in function scope, not module scope.
|
||||
/// @param stmt the statement to check
|
||||
/// @returns false on error
|
||||
bool DetermineVariableStorageClass(ast::Statement* stmt);
|
||||
bool VariableStorageClass(ast::Statement* stmt);
|
||||
|
||||
/// Creates the nodes and adds them to the semantic::Info mappings of the
|
||||
/// ProgramBuilder.
|
||||
|
@ -202,18 +201,18 @@ class TypeDeterminer {
|
|||
|
||||
void set_referenced_from_function_if_needed(VariableInfo* var, bool local);
|
||||
|
||||
bool DetermineArrayAccessor(ast::ArrayAccessorExpression* expr);
|
||||
bool DetermineBinary(ast::BinaryExpression* expr);
|
||||
bool DetermineBitcast(ast::BitcastExpression* expr);
|
||||
bool DetermineCall(ast::CallExpression* expr);
|
||||
bool DetermineConstructor(ast::ConstructorExpression* expr);
|
||||
bool DetermineIdentifier(ast::IdentifierExpression* expr);
|
||||
bool DetermineIntrinsicCall(ast::CallExpression* call,
|
||||
bool ArrayAccessor(ast::ArrayAccessorExpression* expr);
|
||||
bool Binary(ast::BinaryExpression* expr);
|
||||
bool Bitcast(ast::BitcastExpression* expr);
|
||||
bool Call(ast::CallExpression* expr);
|
||||
bool Constructor(ast::ConstructorExpression* expr);
|
||||
bool Identifier(ast::IdentifierExpression* expr);
|
||||
bool IntrinsicCall(ast::CallExpression* call,
|
||||
semantic::IntrinsicType intrinsic_type);
|
||||
bool DetermineMemberAccessor(ast::MemberAccessorExpression* expr);
|
||||
bool DetermineUnaryOp(ast::UnaryOpExpression* expr);
|
||||
bool MemberAccessor(ast::MemberAccessorExpression* expr);
|
||||
bool UnaryOp(ast::UnaryOpExpression* expr);
|
||||
|
||||
bool ValidateVariableDeclStatement(const ast::VariableDeclStatement* stmt);
|
||||
bool VariableDeclStatement(const ast::VariableDeclStatement* stmt);
|
||||
|
||||
VariableInfo* CreateVariableInfo(ast::Variable*);
|
||||
|
||||
|
@ -244,4 +243,4 @@ class TypeDeterminer {
|
|||
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_TYPE_DETERMINER_H_
|
||||
#endif // SRC_RESOLVER_RESOLVER_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -53,7 +53,6 @@
|
|||
#include "src/semantic/function.h"
|
||||
#include "src/type/struct_type.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::FirstIndexOffset::Data);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "src/transform/manager.h"
|
||||
|
||||
#include "src/program_builder.h"
|
||||
#include "src/type_determiner.h"
|
||||
|
||||
namespace tint {
|
||||
namespace transform {
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "src/program_builder.h"
|
||||
#include "src/reader/wgsl/parser.h"
|
||||
#include "src/transform/manager.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/wgsl/generator.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "src/type/test_helper.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
|
||||
namespace tint {
|
||||
namespace type {
|
||||
|
@ -108,9 +107,10 @@ TEST_F(StorageTextureTest, F32) {
|
|||
type::StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, Types());
|
||||
Type* s = create<StorageTexture>(TextureDimension::k2dArray,
|
||||
ImageFormat::kRgba32Float, subtype);
|
||||
TypeDeterminer td(this);
|
||||
|
||||
ASSERT_TRUE(td.Determine()) << td.error();
|
||||
auto program = Build();
|
||||
|
||||
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
|
||||
ASSERT_TRUE(s->Is<Texture>());
|
||||
ASSERT_TRUE(s->Is<StorageTexture>());
|
||||
EXPECT_TRUE(s->As<StorageTexture>()->type()->Is<F32>());
|
||||
|
@ -121,9 +121,10 @@ TEST_F(StorageTextureTest, U32) {
|
|||
type::StorageTexture::SubtypeFor(ImageFormat::kRg32Uint, Types());
|
||||
Type* s = create<StorageTexture>(TextureDimension::k2dArray,
|
||||
ImageFormat::kRg32Uint, subtype);
|
||||
TypeDeterminer td(this);
|
||||
|
||||
ASSERT_TRUE(td.Determine()) << td.error();
|
||||
auto program = Build();
|
||||
|
||||
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
|
||||
ASSERT_TRUE(s->Is<Texture>());
|
||||
ASSERT_TRUE(s->Is<StorageTexture>());
|
||||
EXPECT_TRUE(s->As<StorageTexture>()->type()->Is<U32>());
|
||||
|
@ -134,9 +135,10 @@ TEST_F(StorageTextureTest, I32) {
|
|||
type::StorageTexture::SubtypeFor(ImageFormat::kRgba32Sint, Types());
|
||||
Type* s = create<StorageTexture>(TextureDimension::k2dArray,
|
||||
ImageFormat::kRgba32Sint, subtype);
|
||||
TypeDeterminer td(this);
|
||||
|
||||
ASSERT_TRUE(td.Determine()) << td.error();
|
||||
auto program = Build();
|
||||
|
||||
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
|
||||
ASSERT_TRUE(s->Is<Texture>());
|
||||
ASSERT_TRUE(s->Is<StorageTexture>());
|
||||
EXPECT_TRUE(s->As<StorageTexture>()->type()->Is<I32>());
|
||||
|
|
|
@ -27,7 +27,19 @@ namespace type {
|
|||
|
||||
/// Helper class for testing
|
||||
template <typename BASE>
|
||||
class TestHelperBase : public BASE, public ProgramBuilder {};
|
||||
class TestHelperBase : public BASE, public ProgramBuilder {
|
||||
public:
|
||||
/// Builds and returns the program. Must only be called once per test
|
||||
/// @return the built program
|
||||
Program Build() {
|
||||
diag::Formatter formatter;
|
||||
[&]() {
|
||||
ASSERT_TRUE(IsValid()) << "Builder program is not valid\n"
|
||||
<< formatter.format(Diagnostics());
|
||||
}();
|
||||
return Program(std::move(*this));
|
||||
}
|
||||
};
|
||||
using TestHelper = TestHelperBase<testing::Test>;
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "src/type/f32_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/validator/validator_impl.h"
|
||||
#include "src/validator/validator_test_helper.h"
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "src/type/f32_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/validator/validator_impl.h"
|
||||
#include "src/validator/validator_test_helper.h"
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include "src/type/struct_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/validator/validator_impl.h"
|
||||
#include "src/validator/validator_test_helper.h"
|
||||
|
||||
|
@ -85,39 +84,6 @@ TEST_F(ValidatorTest, AssignToScalar_Fail) {
|
|||
"reference storage: __i32");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, UsingUndefinedVariable_Fail) {
|
||||
// b = 2;
|
||||
|
||||
SetSource(Source{Source::Location{12, 34}});
|
||||
auto* lhs = Expr("b");
|
||||
auto* rhs = Expr(2);
|
||||
auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
|
||||
WrapInFunction(assign);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
EXPECT_EQ(td()->error(),
|
||||
"12:34 error: v-0006: identifier must be declared before use: b");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, UsingUndefinedVariableInBlockStatement_Fail) {
|
||||
// {
|
||||
// b = 2;
|
||||
// }
|
||||
|
||||
SetSource(Source{Source::Location{12, 34}});
|
||||
auto* lhs = Expr("b");
|
||||
auto* rhs = Expr(2);
|
||||
|
||||
auto* body = create<ast::BlockStatement>(ast::StatementList{
|
||||
create<ast::AssignmentStatement>(lhs, rhs),
|
||||
});
|
||||
WrapInFunction(body);
|
||||
|
||||
EXPECT_FALSE(td()->Determine());
|
||||
EXPECT_EQ(td()->error(),
|
||||
"12:34 error: v-0006: identifier must be declared before use: b");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, AssignCompatibleTypes_Pass) {
|
||||
// var a :i32 = 2;
|
||||
// a = 2
|
||||
|
|
|
@ -18,9 +18,7 @@
|
|||
|
||||
namespace tint {
|
||||
|
||||
ValidatorTestHelper::ValidatorTestHelper() {
|
||||
td_ = std::make_unique<TypeDeterminer>(this);
|
||||
}
|
||||
ValidatorTestHelper::ValidatorTestHelper() = default;
|
||||
|
||||
ValidatorTestHelper::~ValidatorTestHelper() = default;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "src/program_builder.h"
|
||||
#include "src/semantic/expression.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/validator/validator_impl.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -56,10 +55,6 @@ class ValidatorTestHelper : public ProgramBuilder {
|
|||
return *val_;
|
||||
}
|
||||
|
||||
/// A handle to type_determiner
|
||||
/// @returns a pointer to the type_determiner object
|
||||
TypeDeterminer* td() const { return td_.get(); }
|
||||
|
||||
/// Inserts a variable into the current scope.
|
||||
/// @param var the variable to register.
|
||||
void RegisterVariable(ast::Variable* var) {
|
||||
|
@ -78,7 +73,6 @@ class ValidatorTestHelper : public ProgramBuilder {
|
|||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<TypeDeterminer> td_;
|
||||
std::unique_ptr<Program> program_;
|
||||
std::unique_ptr<ValidatorImpl> val_;
|
||||
std::vector<ast::Variable*> vars_for_testing_;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "src/ast/stage_decoration.h"
|
||||
#include "src/ast/variable.h"
|
||||
#include "src/program.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/hlsl/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "src/type/struct_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/hlsl/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "src/type/i32_type.h"
|
||||
#include "src/type/matrix_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/hlsl/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "src/semantic/call.h"
|
||||
#include "src/type/f32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/hlsl/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "src/type/depth_texture_type.h"
|
||||
#include "src/type/multisampled_texture_type.h"
|
||||
#include "src/type/sampled_texture_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/hlsl/generator_impl.h"
|
||||
#include "src/writer/hlsl/test_helper.h"
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "src/program.h"
|
||||
#include "src/type/struct_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/hlsl/test_helper.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "src/diagnostic/formatter.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/transform/hlsl.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/hlsl/generator_impl.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "src/type/i32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/msl/generator_impl.h"
|
||||
#include "src/writer/msl/test_helper.h"
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "src/type/struct_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/msl/generator_impl.h"
|
||||
#include "src/writer/msl/test_helper.h"
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "src/type/i32_type.h"
|
||||
#include "src/type/matrix_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/msl/generator_impl.h"
|
||||
#include "src/writer/msl/test_helper.h"
|
||||
|
||||
|
@ -53,7 +52,7 @@ TEST_P(MslImportData_SingleParamTest, FloatScalar) {
|
|||
auto param = GetParam();
|
||||
auto* call = Call(param.name, 1.f);
|
||||
|
||||
// The call type determination will set the intrinsic data for the ident
|
||||
// The resolver will set the intrinsic data for the ident
|
||||
WrapInFunction(call);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "src/semantic/call.h"
|
||||
#include "src/type/f32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/msl/generator_impl.h"
|
||||
#include "src/writer/msl/test_helper.h"
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "src/type/depth_texture_type.h"
|
||||
#include "src/type/multisampled_texture_type.h"
|
||||
#include "src/type/sampled_texture_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/msl/generator_impl.h"
|
||||
#include "src/writer/msl/test_helper.h"
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/msl/generator_impl.h"
|
||||
#include "src/writer/msl/test_helper.h"
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "src/ast/module.h"
|
||||
#include "src/diagnostic/formatter.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/msl/generator_impl.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "src/type/struct_type.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "src/type/i32_type.h"
|
||||
#include "src/type/struct_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "src/type/matrix_type.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "src/program.h"
|
||||
#include "src/type/f32_type.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "src/ast/scalar_constructor_expression.h"
|
||||
#include "src/ast/variable_decl_statement.h"
|
||||
#include "src/type/f32_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "src/type/f32_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "src/type/struct_type.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/discard_statement.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "src/ast/variable.h"
|
||||
#include "src/ast/workgroup_decoration.h"
|
||||
#include "src/semantic/function.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "src/type/i32_type.h"
|
||||
#include "src/type/struct_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "src/type/f32_type.h"
|
||||
#include "src/type/struct_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "src/type/struct_type.h"
|
||||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "src/type/f32_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "src/ast/sint_literal.h"
|
||||
#include "src/type/bool_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "src/type/multisampled_texture_type.h"
|
||||
#include "src/type/sampled_texture_type.h"
|
||||
#include "src/type/storage_texture_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "src/ast/scalar_constructor_expression.h"
|
||||
#include "src/ast/sint_literal.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "src/ast/type_constructor_expression.h"
|
||||
#include "src/type/f32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "src/ast/switch_statement.h"
|
||||
#include "src/type/bool_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "src/type/u32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "src/type/f32_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type/vector_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
#include "src/writer/spirv/spv_dump.h"
|
||||
#include "src/writer/spirv/test_helper.h"
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "src/diagnostic/formatter.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/transform/spirv.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/spirv/binary_writer.h"
|
||||
#include "src/writer/spirv/builder.h"
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "src/type/f32_type.h"
|
||||
#include "src/type/i32_type.h"
|
||||
#include "src/type/void_type.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/wgsl/generator_impl.h"
|
||||
#include "src/writer/wgsl/test_helper.h"
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/type_determiner.h"
|
||||
#include "src/writer/wgsl/generator_impl.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -31,7 +30,7 @@ namespace wgsl {
|
|||
template <typename BASE>
|
||||
class TestHelperBase : public BASE, public ProgramBuilder {
|
||||
public:
|
||||
TestHelperBase() : td(this) {}
|
||||
TestHelperBase() = default;
|
||||
|
||||
~TestHelperBase() override = default;
|
||||
|
||||
|
@ -48,8 +47,6 @@ class TestHelperBase : public BASE, public ProgramBuilder {
|
|||
return *gen_;
|
||||
}
|
||||
|
||||
/// The type determiner
|
||||
TypeDeterminer td;
|
||||
/// The program built with a call to Build()
|
||||
std::unique_ptr<Program> program;
|
||||
|
||||
|
|
Loading…
Reference in New Issue