Replace all uses of assert() with TINT_ICE macros
Use TINT_ICE() where we have diagnostics, TINT_ASSERT() where we do not. Change-Id: Ic6e842a7afdd957654c3461e5d03ecec7332e6f9 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/46444 Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
dba65b7a34
commit
90f43cf87f
|
@ -55,7 +55,10 @@ Module* Module::Clone(CloneContext* ctx) const {
|
||||||
|
|
||||||
void Module::Copy(CloneContext* ctx, const Module* src) {
|
void Module::Copy(CloneContext* ctx, const Module* src) {
|
||||||
for (auto* decl : ctx->Clone(src->global_declarations_)) {
|
for (auto* decl : ctx->Clone(src->global_declarations_)) {
|
||||||
assert(decl);
|
if (!decl) {
|
||||||
|
TINT_ICE(ctx->dst->Diagnostics()) << "src global declaration was nullptr";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (auto* ty = decl->As<type::Type>()) {
|
if (auto* ty = decl->As<type::Type>()) {
|
||||||
AddConstructedType(ty);
|
AddConstructedType(ty);
|
||||||
} else if (auto* func = decl->As<Function>()) {
|
} else if (auto* func = decl->As<Function>()) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace {
|
||||||
|
|
||||||
void AppendResourceBindings(std::vector<ResourceBinding>* dest,
|
void AppendResourceBindings(std::vector<ResourceBinding>* dest,
|
||||||
const std::vector<ResourceBinding>& orig) {
|
const std::vector<ResourceBinding>& orig) {
|
||||||
assert(dest);
|
TINT_ASSERT(dest);
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1386,7 +1386,11 @@ semantic::Intrinsic* Impl::Overload::Match(ProgramBuilder& builder,
|
||||||
// This stage also populates the open_types and open_numbers.
|
// This stage also populates the open_types and open_numbers.
|
||||||
auto count = std::min(parameters.size(), args.size());
|
auto count = std::min(parameters.size(), args.size());
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
assert(args[i]);
|
if (!args[i]) {
|
||||||
|
TINT_ICE(diagnostics) << "args[" << i << "] is nullptr";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
auto* arg_ty = args[i];
|
auto* arg_ty = args[i];
|
||||||
if (auto* ptr = arg_ty->As<type::Pointer>()) {
|
if (auto* ptr = arg_ty->As<type::Pointer>()) {
|
||||||
if (!parameters[i].matcher->ExpectsPointer()) {
|
if (!parameters[i].matcher->ExpectsPointer()) {
|
||||||
|
@ -1447,7 +1451,10 @@ semantic::Intrinsic* Impl::Overload::Match(ProgramBuilder& builder,
|
||||||
Builder::BuildState builder_state{builder.Types(), matcher_state.open_types,
|
Builder::BuildState builder_state{builder.Types(), matcher_state.open_types,
|
||||||
matcher_state.open_numbers};
|
matcher_state.open_numbers};
|
||||||
auto* ret = return_type->Build(builder_state);
|
auto* ret = return_type->Build(builder_state);
|
||||||
assert(ret); // Build() must return a type
|
if (!ret) {
|
||||||
|
TINT_ICE(diagnostics) << "Build() did not return a type";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Build the semantic parameters
|
// Build the semantic parameters
|
||||||
semantic::ParameterList params;
|
semantic::ParameterList params;
|
||||||
|
|
|
@ -119,7 +119,7 @@ std::string Program::str(const ast::Node* node) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::AssertNotMoved() const {
|
void Program::AssertNotMoved() const {
|
||||||
assert(!moved_);
|
TINT_ASSERT(!moved_);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/call_statement.h"
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/variable_decl_statement.h"
|
#include "src/ast/variable_decl_statement.h"
|
||||||
|
#include "src/debug.h"
|
||||||
#include "src/demangler.h"
|
#include "src/demangler.h"
|
||||||
#include "src/semantic/expression.h"
|
#include "src/semantic/expression.h"
|
||||||
|
|
||||||
|
@ -74,7 +75,10 @@ void ProgramBuilder::MarkAsMoved() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramBuilder::AssertNotMoved() const {
|
void ProgramBuilder::AssertNotMoved() const {
|
||||||
assert(!moved_);
|
if (moved_) {
|
||||||
|
TINT_ICE(const_cast<ProgramBuilder*>(this)->Diagnostics())
|
||||||
|
<< "Attempting to use ProgramBuilder after it has been moved";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type::Type* ProgramBuilder::TypeOf(ast::Expression* expr) const {
|
type::Type* ProgramBuilder::TypeOf(ast::Expression* expr) const {
|
||||||
|
|
|
@ -734,7 +734,7 @@ FunctionEmitter::StatementBlock::StatementBlock(StatementBlock&& other) =
|
||||||
FunctionEmitter::StatementBlock::~StatementBlock() = default;
|
FunctionEmitter::StatementBlock::~StatementBlock() = default;
|
||||||
|
|
||||||
void FunctionEmitter::StatementBlock::Finalize(ProgramBuilder* pb) {
|
void FunctionEmitter::StatementBlock::Finalize(ProgramBuilder* pb) {
|
||||||
assert(!finalized_ /* Finalize() must only be called once */);
|
TINT_ASSERT(!finalized_ /* Finalize() must only be called once */);
|
||||||
|
|
||||||
for (size_t i = 0; i < statements_.size(); i++) {
|
for (size_t i = 0; i < statements_.size(); i++) {
|
||||||
if (auto* sb = statements_[i]->As<StatementBuilder>()) {
|
if (auto* sb = statements_[i]->As<StatementBuilder>()) {
|
||||||
|
@ -750,7 +750,7 @@ void FunctionEmitter::StatementBlock::Finalize(ProgramBuilder* pb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionEmitter::StatementBlock::Add(ast::Statement* statement) {
|
void FunctionEmitter::StatementBlock::Add(ast::Statement* statement) {
|
||||||
assert(!finalized_ /* Add() must not be called after Finalize() */);
|
TINT_ASSERT(!finalized_ /* Add() must not be called after Finalize() */);
|
||||||
statements_.emplace_back(statement);
|
statements_.emplace_back(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,8 +762,8 @@ void FunctionEmitter::PushNewStatementBlock(const Construct* construct,
|
||||||
|
|
||||||
void FunctionEmitter::PushGuard(const std::string& guard_name,
|
void FunctionEmitter::PushGuard(const std::string& guard_name,
|
||||||
uint32_t end_id) {
|
uint32_t end_id) {
|
||||||
assert(!statements_stack_.empty());
|
TINT_ASSERT(!statements_stack_.empty());
|
||||||
assert(!guard_name.empty());
|
TINT_ASSERT(!guard_name.empty());
|
||||||
// Guard control flow by the guard variable. Introduce a new
|
// Guard control flow by the guard variable. Introduce a new
|
||||||
// if-selection with a then-clause ending at the same block
|
// if-selection with a then-clause ending at the same block
|
||||||
// as the statement block at the top of the stack.
|
// as the statement block at the top of the stack.
|
||||||
|
@ -780,7 +780,7 @@ void FunctionEmitter::PushGuard(const std::string& guard_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
|
void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
|
||||||
assert(!statements_stack_.empty());
|
TINT_ASSERT(!statements_stack_.empty());
|
||||||
const auto& top = statements_stack_.back();
|
const auto& top = statements_stack_.back();
|
||||||
|
|
||||||
auto* cond = MakeTrue(Source{});
|
auto* cond = MakeTrue(Source{});
|
||||||
|
@ -793,14 +793,14 @@ void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::StatementList FunctionEmitter::ast_body() {
|
const ast::StatementList FunctionEmitter::ast_body() {
|
||||||
assert(!statements_stack_.empty());
|
TINT_ASSERT(!statements_stack_.empty());
|
||||||
auto& entry = statements_stack_[0];
|
auto& entry = statements_stack_[0];
|
||||||
entry.Finalize(&builder_);
|
entry.Finalize(&builder_);
|
||||||
return entry.GetStatements();
|
return entry.GetStatements();
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
|
ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
|
||||||
assert(!statements_stack_.empty());
|
TINT_ASSERT(!statements_stack_.empty());
|
||||||
if (statement != nullptr) {
|
if (statement != nullptr) {
|
||||||
statements_stack_.back().Add(statement);
|
statements_stack_.back().Add(statement);
|
||||||
}
|
}
|
||||||
|
@ -808,9 +808,9 @@ ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Statement* FunctionEmitter::LastStatement() {
|
ast::Statement* FunctionEmitter::LastStatement() {
|
||||||
assert(!statements_stack_.empty());
|
TINT_ASSERT(!statements_stack_.empty());
|
||||||
auto& statement_list = statements_stack_.back().GetStatements();
|
auto& statement_list = statements_stack_.back().GetStatements();
|
||||||
assert(!statement_list.empty());
|
TINT_ASSERT(!statement_list.empty());
|
||||||
return statement_list.back();
|
return statement_list.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,7 +1221,7 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
|
||||||
// block. Also mark the the most recent continue target for which we
|
// block. Also mark the the most recent continue target for which we
|
||||||
// haven't reached the backedge block.
|
// haven't reached the backedge block.
|
||||||
|
|
||||||
assert(block_order_.size() > 0);
|
TINT_ASSERT(block_order_.size() > 0);
|
||||||
constructs_.clear();
|
constructs_.clear();
|
||||||
const auto entry_id = block_order_[0];
|
const auto entry_id = block_order_[0];
|
||||||
|
|
||||||
|
@ -1242,8 +1242,8 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
|
||||||
// A loop construct is added right after its associated continue construct.
|
// A loop construct is added right after its associated continue construct.
|
||||||
// In that case, adjust the parent up.
|
// In that case, adjust the parent up.
|
||||||
if (k == Construct::kLoop) {
|
if (k == Construct::kLoop) {
|
||||||
assert(parent);
|
TINT_ASSERT(parent);
|
||||||
assert(parent->kind == Construct::kContinue);
|
TINT_ASSERT(parent->kind == Construct::kContinue);
|
||||||
scope_end_pos = parent->end_pos;
|
scope_end_pos = parent->end_pos;
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
}
|
}
|
||||||
|
@ -1262,9 +1262,9 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
|
||||||
|
|
||||||
for (uint32_t i = 0; i < block_order_.size(); ++i) {
|
for (uint32_t i = 0; i < block_order_.size(); ++i) {
|
||||||
const auto block_id = block_order_[i];
|
const auto block_id = block_order_[i];
|
||||||
assert(block_id > 0);
|
TINT_ASSERT(block_id > 0);
|
||||||
auto* block_info = GetBlockInfo(block_id);
|
auto* block_info = GetBlockInfo(block_id);
|
||||||
assert(block_info);
|
TINT_ASSERT(block_info);
|
||||||
|
|
||||||
if (enclosing.empty()) {
|
if (enclosing.empty()) {
|
||||||
return Fail() << "internal error: too many merge blocks before block "
|
return Fail() << "internal error: too many merge blocks before block "
|
||||||
|
@ -1321,7 +1321,7 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(top);
|
TINT_ASSERT(top);
|
||||||
block_info->construct = top;
|
block_info->construct = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1530,9 +1530,9 @@ bool FunctionEmitter::ClassifyCFGEdges() {
|
||||||
// NEC(S) is the parent of NEC(T).
|
// NEC(S) is the parent of NEC(T).
|
||||||
|
|
||||||
for (const auto src : block_order_) {
|
for (const auto src : block_order_) {
|
||||||
assert(src > 0);
|
TINT_ASSERT(src > 0);
|
||||||
auto* src_info = GetBlockInfo(src);
|
auto* src_info = GetBlockInfo(src);
|
||||||
assert(src_info);
|
TINT_ASSERT(src_info);
|
||||||
const auto src_pos = src_info->pos;
|
const auto src_pos = src_info->pos;
|
||||||
const auto& src_construct = *(src_info->construct);
|
const auto& src_construct = *(src_info->construct);
|
||||||
|
|
||||||
|
@ -1570,7 +1570,7 @@ bool FunctionEmitter::ClassifyCFGEdges() {
|
||||||
for (const auto dest : successors) {
|
for (const auto dest : successors) {
|
||||||
const auto* dest_info = GetBlockInfo(dest);
|
const auto* dest_info = GetBlockInfo(dest);
|
||||||
// We've already checked terminators are valid.
|
// We've already checked terminators are valid.
|
||||||
assert(dest_info);
|
TINT_ASSERT(dest_info);
|
||||||
const auto dest_pos = dest_info->pos;
|
const auto dest_pos = dest_info->pos;
|
||||||
|
|
||||||
// Insert the edge kind entry and keep a handle to update
|
// Insert the edge kind entry and keep a handle to update
|
||||||
|
@ -1595,7 +1595,7 @@ bool FunctionEmitter::ClassifyCFGEdges() {
|
||||||
<< " (violates post-dominance rule)";
|
<< " (violates post-dominance rule)";
|
||||||
}
|
}
|
||||||
const auto* ct_info = GetBlockInfo(continue_construct->begin_id);
|
const auto* ct_info = GetBlockInfo(continue_construct->begin_id);
|
||||||
assert(ct_info);
|
TINT_ASSERT(ct_info);
|
||||||
if (ct_info->header_for_continue != dest) {
|
if (ct_info->header_for_continue != dest) {
|
||||||
return Fail()
|
return Fail()
|
||||||
<< "Invalid backedge (" << src << "->" << dest
|
<< "Invalid backedge (" << src << "->" << dest
|
||||||
|
@ -1874,7 +1874,7 @@ bool FunctionEmitter::FindIfSelectionInternalHeaders() {
|
||||||
// The first clause might be a then-clause or an else-clause.
|
// The first clause might be a then-clause or an else-clause.
|
||||||
const auto second_head = std::max(true_head_pos, false_head_pos);
|
const auto second_head = std::max(true_head_pos, false_head_pos);
|
||||||
const auto end_first_clause_pos = second_head - 1;
|
const auto end_first_clause_pos = second_head - 1;
|
||||||
assert(end_first_clause_pos < block_order_.size());
|
TINT_ASSERT(end_first_clause_pos < block_order_.size());
|
||||||
const auto end_first_clause = block_order_[end_first_clause_pos];
|
const auto end_first_clause = block_order_[end_first_clause_pos];
|
||||||
uint32_t premerge_id = 0;
|
uint32_t premerge_id = 0;
|
||||||
uint32_t if_break_id = 0;
|
uint32_t if_break_id = 0;
|
||||||
|
@ -2072,15 +2072,15 @@ bool FunctionEmitter::EmitFunctionBodyStatements() {
|
||||||
|
|
||||||
// Upon entry, the statement stack has one entry representing the whole
|
// Upon entry, the statement stack has one entry representing the whole
|
||||||
// function.
|
// function.
|
||||||
assert(!constructs_.empty());
|
TINT_ASSERT(!constructs_.empty());
|
||||||
Construct* function_construct = constructs_[0].get();
|
Construct* function_construct = constructs_[0].get();
|
||||||
assert(function_construct != nullptr);
|
TINT_ASSERT(function_construct != nullptr);
|
||||||
assert(function_construct->kind == Construct::kFunction);
|
TINT_ASSERT(function_construct->kind == Construct::kFunction);
|
||||||
// Make the first entry valid by filling in the construct field, which
|
// Make the first entry valid by filling in the construct field, which
|
||||||
// had not been computed at the time the entry was first created.
|
// had not been computed at the time the entry was first created.
|
||||||
// TODO(dneto): refactor how the first construct is created vs.
|
// TODO(dneto): refactor how the first construct is created vs.
|
||||||
// this statements stack entry is populated.
|
// this statements stack entry is populated.
|
||||||
assert(statements_stack_.size() == 1);
|
TINT_ASSERT(statements_stack_.size() == 1);
|
||||||
statements_stack_[0].SetConstruct(function_construct);
|
statements_stack_[0].SetConstruct(function_construct);
|
||||||
|
|
||||||
for (auto block_id : block_order()) {
|
for (auto block_id : block_order()) {
|
||||||
|
@ -2270,8 +2270,8 @@ bool FunctionEmitter::EmitBasicBlock(const BlockInfo& block_info) {
|
||||||
bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
|
bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
|
||||||
// The block is the if-header block. So its construct is the if construct.
|
// The block is the if-header block. So its construct is the if construct.
|
||||||
auto* construct = block_info.construct;
|
auto* construct = block_info.construct;
|
||||||
assert(construct->kind == Construct::kIfSelection);
|
TINT_ASSERT(construct->kind == Construct::kIfSelection);
|
||||||
assert(construct->begin_id == block_info.id);
|
TINT_ASSERT(construct->begin_id == block_info.id);
|
||||||
|
|
||||||
const uint32_t true_head = block_info.true_head;
|
const uint32_t true_head = block_info.true_head;
|
||||||
const uint32_t false_head = block_info.false_head;
|
const uint32_t false_head = block_info.false_head;
|
||||||
|
@ -2396,8 +2396,8 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
|
||||||
bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
// The block is the if-header block. So its construct is the if construct.
|
// The block is the if-header block. So its construct is the if construct.
|
||||||
auto* construct = block_info.construct;
|
auto* construct = block_info.construct;
|
||||||
assert(construct->kind == Construct::kSwitchSelection);
|
TINT_ASSERT(construct->kind == Construct::kSwitchSelection);
|
||||||
assert(construct->begin_id == block_info.id);
|
TINT_ASSERT(construct->begin_id == block_info.id);
|
||||||
const auto* branch = block_info.basic_block->terminator();
|
const auto* branch = block_info.basic_block->terminator();
|
||||||
|
|
||||||
const auto selector_id = branch->GetSingleWordInOperand(0);
|
const auto selector_id = branch->GetSingleWordInOperand(0);
|
||||||
|
@ -2443,7 +2443,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
clause_heads[w] = clause_heads[r];
|
clause_heads[w] = clause_heads[r];
|
||||||
}
|
}
|
||||||
// We know it's not empty because it always has at least a default clause.
|
// We know it's not empty because it always has at least a default clause.
|
||||||
assert(!clause_heads.empty());
|
TINT_ASSERT(!clause_heads.empty());
|
||||||
clause_heads.resize(w + 1);
|
clause_heads.resize(w + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2652,9 +2652,9 @@ ast::Statement* FunctionEmitter::MakeBranchDetailed(
|
||||||
// Unless forced, don't bother with a break at the end of a case/default
|
// Unless forced, don't bother with a break at the end of a case/default
|
||||||
// clause.
|
// clause.
|
||||||
const auto header = dest_info.header_for_merge;
|
const auto header = dest_info.header_for_merge;
|
||||||
assert(header != 0);
|
TINT_ASSERT(header != 0);
|
||||||
const auto* exiting_construct = GetBlockInfo(header)->construct;
|
const auto* exiting_construct = GetBlockInfo(header)->construct;
|
||||||
assert(exiting_construct->kind == Construct::kSwitchSelection);
|
TINT_ASSERT(exiting_construct->kind == Construct::kSwitchSelection);
|
||||||
const auto candidate_next_case_pos = src_info.pos + 1;
|
const auto candidate_next_case_pos = src_info.pos + 1;
|
||||||
// Leaving the last block from the last case?
|
// Leaving the last block from the last case?
|
||||||
if (candidate_next_case_pos == dest_info.pos) {
|
if (candidate_next_case_pos == dest_info.pos) {
|
||||||
|
@ -2798,7 +2798,7 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
||||||
// Emit declarations of hoisted variables, in index order.
|
// Emit declarations of hoisted variables, in index order.
|
||||||
for (auto id : sorted_by_index(block_info.hoisted_ids)) {
|
for (auto id : sorted_by_index(block_info.hoisted_ids)) {
|
||||||
const auto* def_inst = def_use_mgr_->GetDef(id);
|
const auto* def_inst = def_use_mgr_->GetDef(id);
|
||||||
assert(def_inst);
|
TINT_ASSERT(def_inst);
|
||||||
auto* ast_type =
|
auto* ast_type =
|
||||||
RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
|
RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
|
||||||
AddStatement(create<ast::VariableDeclStatement>(
|
AddStatement(create<ast::VariableDeclStatement>(
|
||||||
|
@ -2811,9 +2811,9 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
||||||
// Emit declarations of phi state variables, in index order.
|
// Emit declarations of phi state variables, in index order.
|
||||||
for (auto id : sorted_by_index(block_info.phis_needing_state_vars)) {
|
for (auto id : sorted_by_index(block_info.phis_needing_state_vars)) {
|
||||||
const auto* def_inst = def_use_mgr_->GetDef(id);
|
const auto* def_inst = def_use_mgr_->GetDef(id);
|
||||||
assert(def_inst);
|
TINT_ASSERT(def_inst);
|
||||||
const auto phi_var_name = GetDefInfo(id)->phi_var;
|
const auto phi_var_name = GetDefInfo(id)->phi_var;
|
||||||
assert(!phi_var_name.empty());
|
TINT_ASSERT(!phi_var_name.empty());
|
||||||
auto* var = create<ast::Variable>(
|
auto* var = create<ast::Variable>(
|
||||||
Source{}, // source
|
Source{}, // source
|
||||||
builder_.Symbols().Register(phi_var_name), // symbol
|
builder_.Symbols().Register(phi_var_name), // symbol
|
||||||
|
@ -3066,7 +3066,7 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
}
|
}
|
||||||
auto expr = MakeExpression(ptr_id);
|
auto expr = MakeExpression(ptr_id);
|
||||||
// The load result type is the pointee type of its operand.
|
// The load result type is the pointee type of its operand.
|
||||||
assert(expr.type->Is<type::Pointer>());
|
TINT_ASSERT(expr.type->Is<type::Pointer>());
|
||||||
expr.type = expr.type->As<type::Pointer>()->type();
|
expr.type = expr.type->As<type::Pointer>()->type();
|
||||||
return EmitConstDefOrWriteToHoistedVar(inst, expr);
|
return EmitConstDefOrWriteToHoistedVar(inst, expr);
|
||||||
}
|
}
|
||||||
|
@ -3550,8 +3550,8 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||||
const auto pointer_type_id =
|
const auto pointer_type_id =
|
||||||
type_mgr_->FindPointerToType(pointee_type_id, storage_class);
|
type_mgr_->FindPointerToType(pointee_type_id, storage_class);
|
||||||
auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id);
|
auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id);
|
||||||
assert(ast_pointer_type);
|
TINT_ASSERT(ast_pointer_type);
|
||||||
assert(ast_pointer_type->Is<type::Pointer>());
|
TINT_ASSERT(ast_pointer_type->Is<type::Pointer>());
|
||||||
current_expr = TypedExpression{ast_pointer_type, next_expr};
|
current_expr = TypedExpression{ast_pointer_type, next_expr};
|
||||||
}
|
}
|
||||||
return current_expr;
|
return current_expr;
|
||||||
|
@ -3746,7 +3746,7 @@ TypedExpression FunctionEmitter::MakeVectorShuffle(
|
||||||
source, MakeExpression(vec0_id).expr, Swizzle(index)));
|
source, MakeExpression(vec0_id).expr, Swizzle(index)));
|
||||||
} else if (index < vec0_len + vec1_len) {
|
} else if (index < vec0_len + vec1_len) {
|
||||||
const auto sub_index = index - vec0_len;
|
const auto sub_index = index - vec0_len;
|
||||||
assert(sub_index < kMaxVectorLen);
|
TINT_ASSERT(sub_index < kMaxVectorLen);
|
||||||
values.emplace_back(create<ast::MemberAccessorExpression>(
|
values.emplace_back(create<ast::MemberAccessorExpression>(
|
||||||
source, MakeExpression(vec1_id).expr, Swizzle(sub_index)));
|
source, MakeExpression(vec1_id).expr, Swizzle(sub_index)));
|
||||||
} else if (index == 0xFFFFFFFF) {
|
} else if (index == 0xFFFFFFFF) {
|
||||||
|
@ -4045,7 +4045,7 @@ const Construct* FunctionEmitter::GetEnclosingScope(uint32_t first_pos,
|
||||||
uint32_t last_pos) const {
|
uint32_t last_pos) const {
|
||||||
const auto* enclosing_construct =
|
const auto* enclosing_construct =
|
||||||
GetBlockInfo(block_order_[first_pos])->construct;
|
GetBlockInfo(block_order_[first_pos])->construct;
|
||||||
assert(enclosing_construct != nullptr);
|
TINT_ASSERT(enclosing_construct != nullptr);
|
||||||
// Constructs are strictly nesting, so follow parent pointers
|
// Constructs are strictly nesting, so follow parent pointers
|
||||||
while (enclosing_construct &&
|
while (enclosing_construct &&
|
||||||
!enclosing_construct->ScopeContainsPos(last_pos)) {
|
!enclosing_construct->ScopeContainsPos(last_pos)) {
|
||||||
|
@ -4057,7 +4057,7 @@ const Construct* FunctionEmitter::GetEnclosingScope(uint32_t first_pos,
|
||||||
sibling_loop ? sibling_loop : enclosing_construct->parent;
|
sibling_loop ? sibling_loop : enclosing_construct->parent;
|
||||||
}
|
}
|
||||||
// At worst, we go all the way out to the function construct.
|
// At worst, we go all the way out to the function construct.
|
||||||
assert(enclosing_construct != nullptr);
|
TINT_ASSERT(enclosing_construct != nullptr);
|
||||||
return enclosing_construct;
|
return enclosing_construct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -998,7 +998,7 @@ class FunctionEmitter {
|
||||||
/// @return the built StatementBuilder
|
/// @return the built StatementBuilder
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
T* AddStatementBuilder(ARGS&&... args) {
|
T* AddStatementBuilder(ARGS&&... args) {
|
||||||
assert(!statements_stack_.empty());
|
TINT_ASSERT(!statements_stack_.empty());
|
||||||
return statements_stack_.back().AddStatementBuilder<T>(
|
return statements_stack_.back().AddStatementBuilder<T>(
|
||||||
std::forward<ARGS>(args)...);
|
std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,7 +233,6 @@ Token ParserImpl::peek() {
|
||||||
|
|
||||||
void ParserImpl::register_constructed(const std::string& name,
|
void ParserImpl::register_constructed(const std::string& name,
|
||||||
type::Type* type) {
|
type::Type* type) {
|
||||||
assert(type);
|
|
||||||
registered_constructs_[name] = type;
|
registered_constructs_[name] = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3156,7 +3155,9 @@ T ParserImpl::sync(Token::Type tok, F&& body) {
|
||||||
auto result = body();
|
auto result = body();
|
||||||
--sync_depth_;
|
--sync_depth_;
|
||||||
|
|
||||||
assert(sync_tokens_.back() == tok);
|
if (sync_tokens_.back() != tok) {
|
||||||
|
TINT_ICE(builder_.Diagnostics()) << "sync_tokens is out of sync";
|
||||||
|
}
|
||||||
sync_tokens_.pop_back();
|
sync_tokens_.pop_back();
|
||||||
|
|
||||||
if (result.errored) {
|
if (result.errored) {
|
||||||
|
|
|
@ -109,7 +109,7 @@ class ParserImpl {
|
||||||
/// return type will always be a pointer to a non-pointer type. #errored
|
/// return type will always be a pointer to a non-pointer type. #errored
|
||||||
/// must be false to call.
|
/// must be false to call.
|
||||||
inline typename detail::OperatorArrow<T>::type operator->() {
|
inline typename detail::OperatorArrow<T>::type operator->() {
|
||||||
assert(!errored);
|
TINT_ASSERT(!errored);
|
||||||
return detail::OperatorArrow<T>::ptr(value);
|
return detail::OperatorArrow<T>::ptr(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ class ParserImpl {
|
||||||
/// return type will always be a pointer to a non-pointer type. #errored
|
/// return type will always be a pointer to a non-pointer type. #errored
|
||||||
/// must be false to call.
|
/// must be false to call.
|
||||||
inline typename detail::OperatorArrow<T>::type operator->() {
|
inline typename detail::OperatorArrow<T>::type operator->() {
|
||||||
assert(!errored);
|
TINT_ASSERT(!errored);
|
||||||
return detail::OperatorArrow<T>::ptr(value);
|
return detail::OperatorArrow<T>::ptr(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1329,7 +1329,10 @@ type::Type* Resolver::TypeOf(ast::Expression* expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resolver::SetType(ast::Expression* expr, type::Type* type) {
|
void Resolver::SetType(ast::Expression* expr, type::Type* type) {
|
||||||
assert(expr_info_.count(expr) == 0);
|
if (expr_info_.count(expr)) {
|
||||||
|
TINT_ICE(builder_->Diagnostics())
|
||||||
|
<< "SetType() called twice for the same expression";
|
||||||
|
}
|
||||||
expr_info_.emplace(expr, ExpressionInfo{type, current_statement_});
|
expr_info_.emplace(expr, ExpressionInfo{type, current_statement_});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,9 @@
|
||||||
#ifndef SRC_SEMANTIC_INFO_H_
|
#ifndef SRC_SEMANTIC_INFO_H_
|
||||||
#define SRC_SEMANTIC_INFO_H_
|
#define SRC_SEMANTIC_INFO_H_
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "src/debug.h"
|
||||||
#include "src/semantic/node.h"
|
#include "src/semantic/node.h"
|
||||||
#include "src/semantic/type_mappings.h"
|
#include "src/semantic/type_mappings.h"
|
||||||
|
|
||||||
|
@ -63,7 +62,7 @@ class Info {
|
||||||
void Add(const AST_OR_TYPE* node,
|
void Add(const AST_OR_TYPE* node,
|
||||||
const SemanticNodeTypeFor<AST_OR_TYPE>* sem_node) {
|
const SemanticNodeTypeFor<AST_OR_TYPE>* sem_node) {
|
||||||
// Check there's no semantic info already existing for the node
|
// Check there's no semantic info already existing for the node
|
||||||
assert(Get(node) == nullptr);
|
TINT_ASSERT(Get(node) == nullptr);
|
||||||
map.emplace(node, sem_node);
|
map.emplace(node, sem_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ namespace type {
|
||||||
|
|
||||||
AccessControl::AccessControl(ast::AccessControl access, Type* subtype)
|
AccessControl::AccessControl(ast::AccessControl access, Type* subtype)
|
||||||
: access_(access), subtype_(subtype) {
|
: access_(access), subtype_(subtype) {
|
||||||
assert(subtype_);
|
TINT_ASSERT(subtype_);
|
||||||
assert(!subtype_->Is<AccessControl>());
|
TINT_ASSERT(!subtype_->Is<AccessControl>());
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessControl::AccessControl(AccessControl&&) = default;
|
AccessControl::AccessControl(AccessControl&&) = default;
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace type {
|
||||||
|
|
||||||
Alias::Alias(const Symbol& sym, Type* subtype)
|
Alias::Alias(const Symbol& sym, Type* subtype)
|
||||||
: symbol_(sym), subtype_(subtype) {
|
: symbol_(sym), subtype_(subtype) {
|
||||||
assert(subtype_);
|
TINT_ASSERT(subtype_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Alias::Alias(Alias&&) = default;
|
Alias::Alias(Alias&&) = default;
|
||||||
|
|
|
@ -31,7 +31,7 @@ Array::Array(Array&&) = default;
|
||||||
Array::~Array() = default;
|
Array::~Array() = default;
|
||||||
|
|
||||||
std::string Array::type_name() const {
|
std::string Array::type_name() const {
|
||||||
assert(subtype_);
|
TINT_ASSERT(subtype_);
|
||||||
|
|
||||||
std::string type_name = "__array" + subtype_->type_name();
|
std::string type_name = "__array" + subtype_->type_name();
|
||||||
if (!IsRuntimeArray()) {
|
if (!IsRuntimeArray()) {
|
||||||
|
|
|
@ -22,19 +22,15 @@ namespace tint {
|
||||||
namespace type {
|
namespace type {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
|
|
||||||
bool IsValidDepthDimension(TextureDimension dim) {
|
bool IsValidDepthDimension(TextureDimension dim) {
|
||||||
return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
|
return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
|
||||||
dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
|
dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NDEBUG
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
DepthTexture::DepthTexture(TextureDimension dim) : Base(dim) {
|
DepthTexture::DepthTexture(TextureDimension dim) : Base(dim) {
|
||||||
assert(IsValidDepthDimension(dim));
|
TINT_ASSERT(IsValidDepthDimension(dim));
|
||||||
}
|
}
|
||||||
|
|
||||||
DepthTexture::DepthTexture(DepthTexture&&) = default;
|
DepthTexture::DepthTexture(DepthTexture&&) = default;
|
||||||
|
|
|
@ -23,10 +23,10 @@ namespace type {
|
||||||
|
|
||||||
Matrix::Matrix(Type* subtype, uint32_t rows, uint32_t columns)
|
Matrix::Matrix(Type* subtype, uint32_t rows, uint32_t columns)
|
||||||
: subtype_(subtype), rows_(rows), columns_(columns) {
|
: subtype_(subtype), rows_(rows), columns_(columns) {
|
||||||
assert(rows > 1);
|
TINT_ASSERT(rows > 1);
|
||||||
assert(rows < 5);
|
TINT_ASSERT(rows < 5);
|
||||||
assert(columns > 1);
|
TINT_ASSERT(columns > 1);
|
||||||
assert(columns < 5);
|
TINT_ASSERT(columns < 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix::Matrix(Matrix&&) = default;
|
Matrix::Matrix(Matrix&&) = default;
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace type {
|
||||||
|
|
||||||
MultisampledTexture::MultisampledTexture(TextureDimension dim, Type* type)
|
MultisampledTexture::MultisampledTexture(TextureDimension dim, Type* type)
|
||||||
: Base(dim), type_(type) {
|
: Base(dim), type_(type) {
|
||||||
assert(type_);
|
TINT_ASSERT(type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default;
|
MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default;
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace type {
|
||||||
|
|
||||||
SampledTexture::SampledTexture(TextureDimension dim, Type* type)
|
SampledTexture::SampledTexture(TextureDimension dim, Type* type)
|
||||||
: Base(dim), type_(type) {
|
: Base(dim), type_(type) {
|
||||||
assert(type_);
|
TINT_ASSERT(type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
SampledTexture::SampledTexture(SampledTexture&&) = default;
|
SampledTexture::SampledTexture(SampledTexture&&) = default;
|
||||||
|
|
|
@ -22,8 +22,8 @@ namespace tint {
|
||||||
namespace type {
|
namespace type {
|
||||||
|
|
||||||
Vector::Vector(Type* subtype, uint32_t size) : subtype_(subtype), size_(size) {
|
Vector::Vector(Type* subtype, uint32_t size) : subtype_(subtype), size_(size) {
|
||||||
assert(size_ > 1);
|
TINT_ASSERT(size_ > 1);
|
||||||
assert(size_ < 5);
|
TINT_ASSERT(size_ < 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector::Vector(Vector&&) = default;
|
Vector::Vector(Vector&&) = default;
|
||||||
|
|
|
@ -776,7 +776,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto* texture = arg(Usage::kTexture);
|
auto* texture = arg(Usage::kTexture);
|
||||||
assert(texture);
|
if (!texture) {
|
||||||
|
TINT_ICE(diagnostics_) << "missing texture argument";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
|
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
|
||||||
|
|
||||||
|
@ -934,8 +937,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
|
||||||
pre << dims;
|
pre << dims;
|
||||||
} else {
|
} else {
|
||||||
static constexpr char xyzw[] = {'x', 'y', 'z', 'w'};
|
static constexpr char xyzw[] = {'x', 'y', 'z', 'w'};
|
||||||
assert(num_dimensions > 0);
|
if (num_dimensions < 0 || num_dimensions > 4) {
|
||||||
assert(num_dimensions <= 4);
|
TINT_ICE(diagnostics_) << "vector dimensions are " << num_dimensions;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (int i = 0; i < num_dimensions; i++) {
|
for (int i = 0; i < num_dimensions; i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
pre << ", ";
|
pre << ", ";
|
||||||
|
@ -999,7 +1004,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* param_coords = arg(Usage::kCoords);
|
auto* param_coords = arg(Usage::kCoords);
|
||||||
assert(param_coords);
|
if (!param_coords) {
|
||||||
|
TINT_ICE(diagnostics_) << "missing coords argument";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto emit_vector_appended_with_i32_zero = [&](tint::ast::Expression* vector) {
|
auto emit_vector_appended_with_i32_zero = [&](tint::ast::Expression* vector) {
|
||||||
auto* i32 = builder_.create<type::I32>();
|
auto* i32 = builder_.create<type::I32>();
|
||||||
|
|
|
@ -474,7 +474,10 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto* texture = arg(Usage::kTexture);
|
auto* texture = arg(Usage::kTexture);
|
||||||
assert(texture);
|
if (!texture) {
|
||||||
|
TINT_ICE(diagnostics_) << "missing texture arg";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
|
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
|
||||||
|
|
||||||
|
|
|
@ -1007,8 +1007,11 @@ bool Builder::GenerateMemberAccessor(ast::MemberAccessorExpression* expr,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Builder::GenerateAccessorExpression(ast::Expression* expr) {
|
uint32_t Builder::GenerateAccessorExpression(ast::Expression* expr) {
|
||||||
assert(expr->Is<ast::ArrayAccessorExpression>() ||
|
if (!expr->IsAnyOf<ast::ArrayAccessorExpression,
|
||||||
expr->Is<ast::MemberAccessorExpression>());
|
ast::MemberAccessorExpression>()) {
|
||||||
|
TINT_ICE(builder_.Diagnostics()) << "expression is not an accessor";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Gather a list of all the member and array accessors that are in this chain.
|
// Gather a list of all the member and array accessors that are in this chain.
|
||||||
// The list is built in reverse order as that's the order we need to access
|
// The list is built in reverse order as that's the order we need to access
|
||||||
|
@ -2113,12 +2116,17 @@ bool Builder::GenerateTextureIntrinsic(ast::CallExpression* call,
|
||||||
// Generates the argument with the given usage, returning the operand ID
|
// Generates the argument with the given usage, returning the operand ID
|
||||||
auto gen_arg = [&](Usage usage) {
|
auto gen_arg = [&](Usage usage) {
|
||||||
auto* argument = arg(usage);
|
auto* argument = arg(usage);
|
||||||
assert(argument);
|
if (!argument) {
|
||||||
|
TINT_ICE(builder_.Diagnostics())
|
||||||
|
<< "missing argument " << static_cast<int>(usage);
|
||||||
|
}
|
||||||
return gen(argument);
|
return gen(argument);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto* texture = arg(Usage::kTexture);
|
auto* texture = arg(Usage::kTexture);
|
||||||
assert(texture);
|
if (!texture) {
|
||||||
|
TINT_ICE(builder_.Diagnostics()) << "missing texture argument";
|
||||||
|
}
|
||||||
|
|
||||||
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
|
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
|
||||||
|
|
||||||
|
@ -3007,8 +3015,7 @@ bool Builder::GenerateTextureType(type::Texture* texture,
|
||||||
dim_literal = SpvDim1D;
|
dim_literal = SpvDim1D;
|
||||||
if (texture->Is<type::SampledTexture>()) {
|
if (texture->Is<type::SampledTexture>()) {
|
||||||
push_capability(SpvCapabilitySampled1D);
|
push_capability(SpvCapabilitySampled1D);
|
||||||
} else {
|
} else if (texture->Is<type::StorageTexture>()) {
|
||||||
assert(texture->Is<type::StorageTexture>());
|
|
||||||
push_capability(SpvCapabilityImage1D);
|
push_capability(SpvCapabilityImage1D);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,10 @@ class Builder {
|
||||||
/// Pushes a variable to the current function
|
/// Pushes a variable to the current function
|
||||||
/// @param operands the variable operands
|
/// @param operands the variable operands
|
||||||
void push_function_var(const OperandList& operands) {
|
void push_function_var(const OperandList& operands) {
|
||||||
assert(!functions_.empty());
|
if (functions_.empty()) {
|
||||||
|
TINT_ICE(builder_.Diagnostics())
|
||||||
|
<< "push_function_var() called without a function";
|
||||||
|
}
|
||||||
functions_.back().push_var(operands);
|
functions_.back().push_var(operands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue