reader/spirv: Replace std::make_unique<T> -> create<T>
create() is currently just a simple forwarder to std::make_unique<>, but will be later replaced with a function that returns a raw pointer, and owned by the context. Bug: tint:322 Change-Id: I72558482c4b6aff7a655087ee010b3e16b006192 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32860 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
eeac0c5f63
commit
307919dba9
|
@ -502,9 +502,8 @@ FunctionEmitter::StatementBlock::~StatementBlock() = default;
|
||||||
void FunctionEmitter::PushNewStatementBlock(const Construct* construct,
|
void FunctionEmitter::PushNewStatementBlock(const Construct* construct,
|
||||||
uint32_t end_id,
|
uint32_t end_id,
|
||||||
CompletionAction action) {
|
CompletionAction action) {
|
||||||
statements_stack_.emplace_back(
|
statements_stack_.emplace_back(StatementBlock{
|
||||||
StatementBlock{construct, end_id, action,
|
construct, end_id, action, create<ast::BlockStatement>(), nullptr});
|
||||||
std::make_unique<ast::BlockStatement>(), nullptr});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionEmitter::PushGuard(const std::string& guard_name,
|
void FunctionEmitter::PushGuard(const std::string& guard_name,
|
||||||
|
@ -515,10 +514,10 @@ void FunctionEmitter::PushGuard(const std::string& guard_name,
|
||||||
// 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.
|
||||||
const auto& top = statements_stack_.back();
|
const auto& top = statements_stack_.back();
|
||||||
auto cond = std::make_unique<ast::IdentifierExpression>(guard_name);
|
auto cond = create<ast::IdentifierExpression>(guard_name);
|
||||||
auto body = std::make_unique<ast::BlockStatement>();
|
auto body = create<ast::BlockStatement>();
|
||||||
auto* const guard_stmt = AddStatement(std::make_unique<ast::IfStatement>(
|
auto* const guard_stmt =
|
||||||
std::move(cond), std::move(body)))
|
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
|
||||||
->AsIf();
|
->AsIf();
|
||||||
PushNewStatementBlock(top.construct_, end_id,
|
PushNewStatementBlock(top.construct_, end_id,
|
||||||
[guard_stmt](StatementBlock* s) {
|
[guard_stmt](StatementBlock* s) {
|
||||||
|
@ -530,9 +529,9 @@ void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
|
||||||
assert(!statements_stack_.empty());
|
assert(!statements_stack_.empty());
|
||||||
const auto& top = statements_stack_.back();
|
const auto& top = statements_stack_.back();
|
||||||
auto cond = MakeTrue();
|
auto cond = MakeTrue();
|
||||||
auto body = std::make_unique<ast::BlockStatement>();
|
auto body = create<ast::BlockStatement>();
|
||||||
auto* const guard_stmt = AddStatement(std::make_unique<ast::IfStatement>(
|
auto* const guard_stmt =
|
||||||
std::move(cond), std::move(body)))
|
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
|
||||||
->AsIf();
|
->AsIf();
|
||||||
guard_stmt->set_condition(MakeTrue());
|
guard_stmt->set_condition(MakeTrue());
|
||||||
PushNewStatementBlock(top.construct_, end_id,
|
PushNewStatementBlock(top.construct_, end_id,
|
||||||
|
@ -649,13 +648,12 @@ bool FunctionEmitter::EmitFunctionDeclaration() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ast_fn =
|
auto ast_fn = create<ast::Function>(name, std::move(ast_params), ret_ty,
|
||||||
std::make_unique<ast::Function>(name, std::move(ast_params), ret_ty,
|
create<ast::BlockStatement>());
|
||||||
std::make_unique<ast::BlockStatement>());
|
|
||||||
|
|
||||||
if (ep_info_ != nullptr) {
|
if (ep_info_ != nullptr) {
|
||||||
ast_fn->add_decoration(
|
ast_fn->add_decoration(
|
||||||
std::make_unique<ast::StageDecoration>(ep_info_->stage, Source{}));
|
create<ast::StageDecoration>(ep_info_->stage, Source{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_module_.AddFunction(std::move(ast_fn));
|
ast_module_.AddFunction(std::move(ast_fn));
|
||||||
|
@ -1707,8 +1705,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
|
||||||
parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
|
parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
|
||||||
.expr);
|
.expr);
|
||||||
}
|
}
|
||||||
auto var_decl_stmt =
|
auto var_decl_stmt = create<ast::VariableDeclStatement>(std::move(var));
|
||||||
std::make_unique<ast::VariableDeclStatement>(std::move(var));
|
|
||||||
AddStatementForInstruction(std::move(var_decl_stmt), inst);
|
AddStatementForInstruction(std::move(var_decl_stmt), inst);
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
identifier_values_.insert(inst.result_id());
|
identifier_values_.insert(inst.result_id());
|
||||||
|
@ -1723,7 +1720,7 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
|
||||||
if (identifier_values_.count(id) || parser_impl_.IsScalarSpecConstant(id)) {
|
if (identifier_values_.count(id) || parser_impl_.IsScalarSpecConstant(id)) {
|
||||||
return TypedExpression(
|
return TypedExpression(
|
||||||
parser_impl_.ConvertType(def_use_mgr_->GetDef(id)->type_id()),
|
parser_impl_.ConvertType(def_use_mgr_->GetDef(id)->type_id()),
|
||||||
std::make_unique<ast::IdentifierExpression>(namer_.Name(id)));
|
create<ast::IdentifierExpression>(namer_.Name(id)));
|
||||||
}
|
}
|
||||||
if (singly_used_values_.count(id)) {
|
if (singly_used_values_.count(id)) {
|
||||||
auto expr = std::move(singly_used_values_[id]);
|
auto expr = std::move(singly_used_values_[id]);
|
||||||
|
@ -1742,9 +1739,9 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
|
||||||
switch (inst->opcode()) {
|
switch (inst->opcode()) {
|
||||||
case SpvOpVariable:
|
case SpvOpVariable:
|
||||||
// This occurs for module-scope variables.
|
// This occurs for module-scope variables.
|
||||||
return TypedExpression(parser_impl_.ConvertType(inst->type_id()),
|
return TypedExpression(
|
||||||
std::make_unique<ast::IdentifierExpression>(
|
parser_impl_.ConvertType(inst->type_id()),
|
||||||
namer_.Name(inst->result_id())));
|
create<ast::IdentifierExpression>(namer_.Name(inst->result_id())));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1973,20 +1970,19 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
|
||||||
const std::string guard_name = block_info.flow_guard_name;
|
const std::string guard_name = block_info.flow_guard_name;
|
||||||
if (!guard_name.empty()) {
|
if (!guard_name.empty()) {
|
||||||
// Declare the guard variable just before the "if", initialized to true.
|
// Declare the guard variable just before the "if", initialized to true.
|
||||||
auto guard_var = std::make_unique<ast::Variable>(
|
auto guard_var = create<ast::Variable>(
|
||||||
guard_name, ast::StorageClass::kFunction, parser_impl_.BoolType());
|
guard_name, ast::StorageClass::kFunction, parser_impl_.BoolType());
|
||||||
guard_var->set_constructor(MakeTrue());
|
guard_var->set_constructor(MakeTrue());
|
||||||
auto guard_decl =
|
auto guard_decl = create<ast::VariableDeclStatement>(std::move(guard_var));
|
||||||
std::make_unique<ast::VariableDeclStatement>(std::move(guard_var));
|
|
||||||
AddStatement(std::move(guard_decl));
|
AddStatement(std::move(guard_decl));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto condition_id =
|
const auto condition_id =
|
||||||
block_info.basic_block->terminator()->GetSingleWordInOperand(0);
|
block_info.basic_block->terminator()->GetSingleWordInOperand(0);
|
||||||
auto cond = MakeExpression(condition_id).expr;
|
auto cond = MakeExpression(condition_id).expr;
|
||||||
auto body = std::make_unique<ast::BlockStatement>();
|
auto body = create<ast::BlockStatement>();
|
||||||
auto* const if_stmt = AddStatement(std::make_unique<ast::IfStatement>(
|
auto* const if_stmt =
|
||||||
std::move(cond), std::move(body)))
|
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
|
||||||
->AsIf();
|
->AsIf();
|
||||||
|
|
||||||
// Generate the code for the condition.
|
// Generate the code for the condition.
|
||||||
|
@ -2040,14 +2036,15 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
|
||||||
|
|
||||||
auto push_else = [this, if_stmt, else_end, construct]() {
|
auto push_else = [this, if_stmt, else_end, construct]() {
|
||||||
// Push the else clause onto the stack first.
|
// Push the else clause onto the stack first.
|
||||||
PushNewStatementBlock(construct, else_end, [if_stmt](StatementBlock* s) {
|
PushNewStatementBlock(
|
||||||
|
construct, else_end, [this, if_stmt](StatementBlock* s) {
|
||||||
// Only set the else-clause if there are statements to fill it.
|
// Only set the else-clause if there are statements to fill it.
|
||||||
if (!s->statements_->empty()) {
|
if (!s->statements_->empty()) {
|
||||||
// The "else" consists of the statement list from the top of statments
|
// The "else" consists of the statement list from the top of
|
||||||
// stack, without an elseif condition.
|
// statments stack, without an elseif condition.
|
||||||
ast::ElseStatementList else_stmts;
|
ast::ElseStatementList else_stmts;
|
||||||
else_stmts.emplace_back(std::make_unique<ast::ElseStatement>(
|
else_stmts.emplace_back(
|
||||||
nullptr, std::move(s->statements_)));
|
create<ast::ElseStatement>(nullptr, std::move(s->statements_)));
|
||||||
if_stmt->set_else_statements(std::move(else_stmts));
|
if_stmt->set_else_statements(std::move(else_stmts));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2099,7 +2096,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
const auto* branch = block_info.basic_block->terminator();
|
const auto* branch = block_info.basic_block->terminator();
|
||||||
|
|
||||||
auto* const switch_stmt =
|
auto* const switch_stmt =
|
||||||
AddStatement(std::make_unique<ast::SwitchStatement>())->AsSwitch();
|
AddStatement(create<ast::SwitchStatement>())->AsSwitch();
|
||||||
const auto selector_id = branch->GetSingleWordInOperand(0);
|
const auto selector_id = branch->GetSingleWordInOperand(0);
|
||||||
// Generate the code for the selector.
|
// Generate the code for the selector.
|
||||||
auto selector = MakeExpression(selector_id);
|
auto selector = MakeExpression(selector_id);
|
||||||
|
@ -2111,7 +2108,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
construct, construct->end_id, [switch_stmt](StatementBlock* s) {
|
construct, construct->end_id, [switch_stmt](StatementBlock* s) {
|
||||||
switch_stmt->set_body(std::move(*std::move(s->cases_)));
|
switch_stmt->set_body(std::move(*std::move(s->cases_)));
|
||||||
});
|
});
|
||||||
statements_stack_.back().cases_ = std::make_unique<ast::CaseStatementList>();
|
statements_stack_.back().cases_ = create<ast::CaseStatementList>();
|
||||||
// Grab a pointer to the case list. It will get buried in the statement block
|
// Grab a pointer to the case list. It will get buried in the statement block
|
||||||
// stack.
|
// stack.
|
||||||
auto* cases = statements_stack_.back().cases_.get();
|
auto* cases = statements_stack_.back().cases_.get();
|
||||||
|
@ -2157,8 +2154,8 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
for (size_t i = last_clause_index;; --i) {
|
for (size_t i = last_clause_index;; --i) {
|
||||||
// Create the case clause. Temporarily put it in the wrong order
|
// Create the case clause. Temporarily put it in the wrong order
|
||||||
// on the case statement list.
|
// on the case statement list.
|
||||||
cases->emplace_back(std::make_unique<ast::CaseStatement>(
|
cases->emplace_back(
|
||||||
std::make_unique<ast::BlockStatement>()));
|
create<ast::CaseStatement>(create<ast::BlockStatement>()));
|
||||||
auto* clause = cases->back().get();
|
auto* clause = cases->back().get();
|
||||||
|
|
||||||
// Create a list of integer literals for the selector values leading to
|
// Create a list of integer literals for the selector values leading to
|
||||||
|
@ -2175,10 +2172,10 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
const uint32_t value32 = uint32_t(value & 0xFFFFFFFF);
|
const uint32_t value32 = uint32_t(value & 0xFFFFFFFF);
|
||||||
if (selector.type->is_unsigned_scalar_or_vector()) {
|
if (selector.type->is_unsigned_scalar_or_vector()) {
|
||||||
selectors.emplace_back(
|
selectors.emplace_back(
|
||||||
std::make_unique<ast::UintLiteral>(selector.type, value32));
|
create<ast::UintLiteral>(selector.type, value32));
|
||||||
} else {
|
} else {
|
||||||
selectors.emplace_back(
|
selectors.emplace_back(
|
||||||
std::make_unique<ast::SintLiteral>(selector.type, value32));
|
create<ast::SintLiteral>(selector.type, value32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clause->set_selectors(std::move(selectors));
|
clause->set_selectors(std::move(selectors));
|
||||||
|
@ -2195,9 +2192,9 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
if ((default_info == clause_heads[i]) && has_selectors &&
|
if ((default_info == clause_heads[i]) && has_selectors &&
|
||||||
construct->ContainsPos(default_info->pos)) {
|
construct->ContainsPos(default_info->pos)) {
|
||||||
// Generate a default clause with a just fallthrough.
|
// Generate a default clause with a just fallthrough.
|
||||||
auto stmts = std::make_unique<ast::BlockStatement>();
|
auto stmts = create<ast::BlockStatement>();
|
||||||
stmts->append(std::make_unique<ast::FallthroughStatement>());
|
stmts->append(create<ast::FallthroughStatement>());
|
||||||
auto case_stmt = std::make_unique<ast::CaseStatement>(std::move(stmts));
|
auto case_stmt = create<ast::CaseStatement>(std::move(stmts));
|
||||||
cases->emplace_back(std::move(case_stmt));
|
cases->emplace_back(std::move(case_stmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2214,9 +2211,9 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionEmitter::EmitLoopStart(const Construct* construct) {
|
bool FunctionEmitter::EmitLoopStart(const Construct* construct) {
|
||||||
auto* loop = AddStatement(std::make_unique<ast::LoopStatement>(
|
auto* loop =
|
||||||
std::make_unique<ast::BlockStatement>(),
|
AddStatement(create<ast::LoopStatement>(create<ast::BlockStatement>(),
|
||||||
std::make_unique<ast::BlockStatement>()))
|
create<ast::BlockStatement>()))
|
||||||
->AsLoop();
|
->AsLoop();
|
||||||
PushNewStatementBlock(
|
PushNewStatementBlock(
|
||||||
construct, construct->end_id,
|
construct, construct->end_id,
|
||||||
|
@ -2244,18 +2241,17 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
|
||||||
const auto& terminator = *(block_info.basic_block->terminator());
|
const auto& terminator = *(block_info.basic_block->terminator());
|
||||||
switch (terminator.opcode()) {
|
switch (terminator.opcode()) {
|
||||||
case SpvOpReturn:
|
case SpvOpReturn:
|
||||||
AddStatement(std::make_unique<ast::ReturnStatement>());
|
AddStatement(create<ast::ReturnStatement>());
|
||||||
return true;
|
return true;
|
||||||
case SpvOpReturnValue: {
|
case SpvOpReturnValue: {
|
||||||
auto value = MakeExpression(terminator.GetSingleWordInOperand(0));
|
auto value = MakeExpression(terminator.GetSingleWordInOperand(0));
|
||||||
AddStatement(
|
AddStatement(create<ast::ReturnStatement>(std::move(value.expr)));
|
||||||
std::make_unique<ast::ReturnStatement>(std::move(value.expr)));
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case SpvOpKill:
|
case SpvOpKill:
|
||||||
// For now, assume SPIR-V OpKill has same semantics as WGSL discard.
|
// For now, assume SPIR-V OpKill has same semantics as WGSL discard.
|
||||||
// TODO(dneto): https://github.com/gpuweb/gpuweb/issues/676
|
// TODO(dneto): https://github.com/gpuweb/gpuweb/issues/676
|
||||||
AddStatement(std::make_unique<ast::DiscardStatement>());
|
AddStatement(create<ast::DiscardStatement>());
|
||||||
return true;
|
return true;
|
||||||
case SpvOpUnreachable:
|
case SpvOpUnreachable:
|
||||||
// Translate as if it's a return. This avoids the problem where WGSL
|
// Translate as if it's a return. This avoids the problem where WGSL
|
||||||
|
@ -2263,10 +2259,10 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
|
||||||
{
|
{
|
||||||
const auto* result_type = type_mgr_->GetType(function_.type_id());
|
const auto* result_type = type_mgr_->GetType(function_.type_id());
|
||||||
if (result_type->AsVoid() != nullptr) {
|
if (result_type->AsVoid() != nullptr) {
|
||||||
AddStatement(std::make_unique<ast::ReturnStatement>());
|
AddStatement(create<ast::ReturnStatement>());
|
||||||
} else {
|
} else {
|
||||||
auto* ast_type = parser_impl_.ConvertType(function_.type_id());
|
auto* ast_type = parser_impl_.ConvertType(function_.type_id());
|
||||||
AddStatement(std::make_unique<ast::ReturnStatement>(
|
AddStatement(create<ast::ReturnStatement>(
|
||||||
parser_impl_.MakeNullValue(ast_type)));
|
parser_impl_.MakeNullValue(ast_type)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2350,7 +2346,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
|
||||||
break;
|
break;
|
||||||
case EdgeKind::kSwitchBreak: {
|
case EdgeKind::kSwitchBreak: {
|
||||||
if (forced) {
|
if (forced) {
|
||||||
return std::make_unique<ast::BreakStatement>();
|
return create<ast::BreakStatement>();
|
||||||
}
|
}
|
||||||
// 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.
|
||||||
|
@ -2375,10 +2371,10 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We need a break.
|
// We need a break.
|
||||||
return std::make_unique<ast::BreakStatement>();
|
return create<ast::BreakStatement>();
|
||||||
}
|
}
|
||||||
case EdgeKind::kLoopBreak:
|
case EdgeKind::kLoopBreak:
|
||||||
return std::make_unique<ast::BreakStatement>();
|
return create<ast::BreakStatement>();
|
||||||
case EdgeKind::kLoopContinue:
|
case EdgeKind::kLoopContinue:
|
||||||
// An unconditional continue to the next block is redundant and ugly.
|
// An unconditional continue to the next block is redundant and ugly.
|
||||||
// Skip it in that case.
|
// Skip it in that case.
|
||||||
|
@ -2386,7 +2382,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Otherwise, emit a regular continue statement.
|
// Otherwise, emit a regular continue statement.
|
||||||
return std::make_unique<ast::ContinueStatement>();
|
return create<ast::ContinueStatement>();
|
||||||
case EdgeKind::kIfBreak: {
|
case EdgeKind::kIfBreak: {
|
||||||
const auto& flow_guard =
|
const auto& flow_guard =
|
||||||
GetBlockInfo(dest_info.header_for_merge)->flow_guard_name;
|
GetBlockInfo(dest_info.header_for_merge)->flow_guard_name;
|
||||||
|
@ -2395,9 +2391,8 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
|
||||||
*flow_guard_name_ptr = flow_guard;
|
*flow_guard_name_ptr = flow_guard;
|
||||||
}
|
}
|
||||||
// Signal an exit from the branch.
|
// Signal an exit from the branch.
|
||||||
return std::make_unique<ast::AssignmentStatement>(
|
return create<ast::AssignmentStatement>(
|
||||||
std::make_unique<ast::IdentifierExpression>(flow_guard),
|
create<ast::IdentifierExpression>(flow_guard), MakeFalse());
|
||||||
MakeFalse());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For an unconditional branch, the break out to an if-selection
|
// For an unconditional branch, the break out to an if-selection
|
||||||
|
@ -2405,7 +2400,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EdgeKind::kCaseFallThrough:
|
case EdgeKind::kCaseFallThrough:
|
||||||
return std::make_unique<ast::FallthroughStatement>();
|
return create<ast::FallthroughStatement>();
|
||||||
case EdgeKind::kForward:
|
case EdgeKind::kForward:
|
||||||
// Unconditional forward branch is implicit.
|
// Unconditional forward branch is implicit.
|
||||||
break;
|
break;
|
||||||
|
@ -2420,19 +2415,19 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeSimpleIf(
|
||||||
if ((then_stmt == nullptr) && (else_stmt == nullptr)) {
|
if ((then_stmt == nullptr) && (else_stmt == nullptr)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto if_stmt = std::make_unique<ast::IfStatement>(
|
auto if_stmt = create<ast::IfStatement>(std::move(condition),
|
||||||
std::move(condition), std::make_unique<ast::BlockStatement>());
|
create<ast::BlockStatement>());
|
||||||
if (then_stmt != nullptr) {
|
if (then_stmt != nullptr) {
|
||||||
auto stmts = std::make_unique<ast::BlockStatement>();
|
auto stmts = create<ast::BlockStatement>();
|
||||||
stmts->append(std::move(then_stmt));
|
stmts->append(std::move(then_stmt));
|
||||||
if_stmt->set_body(std::move(stmts));
|
if_stmt->set_body(std::move(stmts));
|
||||||
}
|
}
|
||||||
if (else_stmt != nullptr) {
|
if (else_stmt != nullptr) {
|
||||||
auto stmts = std::make_unique<ast::BlockStatement>();
|
auto stmts = create<ast::BlockStatement>();
|
||||||
stmts->append(std::move(else_stmt));
|
stmts->append(std::move(else_stmt));
|
||||||
ast::ElseStatementList else_stmts;
|
ast::ElseStatementList else_stmts;
|
||||||
else_stmts.emplace_back(
|
else_stmts.emplace_back(
|
||||||
std::make_unique<ast::ElseStatement>(nullptr, std::move(stmts)));
|
create<ast::ElseStatement>(nullptr, std::move(stmts)));
|
||||||
if_stmt->set_else_statements(std::move(else_stmts));
|
if_stmt->set_else_statements(std::move(else_stmts));
|
||||||
}
|
}
|
||||||
return if_stmt;
|
return if_stmt;
|
||||||
|
@ -2479,7 +2474,7 @@ bool FunctionEmitter::EmitConditionalCaseFallThrough(
|
||||||
AddStatement(
|
AddStatement(
|
||||||
MakeSimpleIf(std::move(cond), std::move(other_branch), nullptr));
|
MakeSimpleIf(std::move(cond), std::move(other_branch), nullptr));
|
||||||
}
|
}
|
||||||
AddStatement(std::make_unique<ast::FallthroughStatement>());
|
AddStatement(create<ast::FallthroughStatement>());
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
@ -2506,7 +2501,7 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
||||||
assert(def_inst);
|
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(std::make_unique<ast::VariableDeclStatement>(
|
AddStatement(create<ast::VariableDeclStatement>(
|
||||||
parser_impl_.MakeVariable(id, ast::StorageClass::kFunction, ast_type)));
|
parser_impl_.MakeVariable(id, ast::StorageClass::kFunction, ast_type)));
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
identifier_values_.insert(id);
|
identifier_values_.insert(id);
|
||||||
|
@ -2517,10 +2512,10 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
||||||
assert(def_inst);
|
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());
|
assert(!phi_var_name.empty());
|
||||||
auto var = std::make_unique<ast::Variable>(
|
auto var =
|
||||||
phi_var_name, ast::StorageClass::kFunction,
|
create<ast::Variable>(phi_var_name, ast::StorageClass::kFunction,
|
||||||
parser_impl_.ConvertType(def_inst->type_id()));
|
parser_impl_.ConvertType(def_inst->type_id()));
|
||||||
AddStatement(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
|
AddStatement(create<ast::VariableDeclStatement>(std::move(var)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit regular statements.
|
// Emit regular statements.
|
||||||
|
@ -2550,9 +2545,8 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
|
||||||
for (auto assignment : block_info.phi_assignments) {
|
for (auto assignment : block_info.phi_assignments) {
|
||||||
const auto var_name = GetDefInfo(assignment.phi_id)->phi_var;
|
const auto var_name = GetDefInfo(assignment.phi_id)->phi_var;
|
||||||
auto expr = MakeExpression(assignment.value);
|
auto expr = MakeExpression(assignment.value);
|
||||||
AddStatement(std::make_unique<ast::AssignmentStatement>(
|
AddStatement(create<ast::AssignmentStatement>(
|
||||||
std::make_unique<ast::IdentifierExpression>(var_name),
|
create<ast::IdentifierExpression>(var_name), std::move(expr.expr)));
|
||||||
std::move(expr.expr)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2574,7 +2568,7 @@ bool FunctionEmitter::EmitConstDefinition(
|
||||||
ast_const->set_constructor(std::move(ast_expr.expr));
|
ast_const->set_constructor(std::move(ast_expr.expr));
|
||||||
ast_const->set_is_const(true);
|
ast_const->set_is_const(true);
|
||||||
AddStatementForInstruction(
|
AddStatementForInstruction(
|
||||||
std::make_unique<ast::VariableDeclStatement>(std::move(ast_const)), inst);
|
create<ast::VariableDeclStatement>(std::move(ast_const)), inst);
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
identifier_values_.insert(inst.result_id());
|
identifier_values_.insert(inst.result_id());
|
||||||
return success();
|
return success();
|
||||||
|
@ -2588,8 +2582,8 @@ bool FunctionEmitter::EmitConstDefOrWriteToHoistedVar(
|
||||||
if (def_info && def_info->requires_hoisted_def) {
|
if (def_info && def_info->requires_hoisted_def) {
|
||||||
// Emit an assignment of the expression to the hoisted variable.
|
// Emit an assignment of the expression to the hoisted variable.
|
||||||
AddStatementForInstruction(
|
AddStatementForInstruction(
|
||||||
std::make_unique<ast::AssignmentStatement>(
|
create<ast::AssignmentStatement>(
|
||||||
std::make_unique<ast::IdentifierExpression>(namer_.Name(result_id)),
|
create<ast::IdentifierExpression>(namer_.Name(result_id)),
|
||||||
std::move(ast_expr.expr)),
|
std::move(ast_expr.expr)),
|
||||||
inst);
|
inst);
|
||||||
return true;
|
return true;
|
||||||
|
@ -2654,7 +2648,7 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
// TODO(dneto): Order of evaluation?
|
// TODO(dneto): Order of evaluation?
|
||||||
auto lhs = MakeExpression(ptr_id);
|
auto lhs = MakeExpression(ptr_id);
|
||||||
auto rhs = MakeExpression(value_id);
|
auto rhs = MakeExpression(value_id);
|
||||||
AddStatementForInstruction(std::make_unique<ast::AssignmentStatement>(
|
AddStatementForInstruction(create<ast::AssignmentStatement>(
|
||||||
std::move(lhs.expr), std::move(rhs.expr)),
|
std::move(lhs.expr), std::move(rhs.expr)),
|
||||||
inst);
|
inst);
|
||||||
return success();
|
return success();
|
||||||
|
@ -2678,9 +2672,9 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
}
|
}
|
||||||
case SpvOpPhi: {
|
case SpvOpPhi: {
|
||||||
// Emit a read from the associated state variable.
|
// Emit a read from the associated state variable.
|
||||||
auto expr = TypedExpression(
|
auto expr =
|
||||||
parser_impl_.ConvertType(inst.type_id()),
|
TypedExpression(parser_impl_.ConvertType(inst.type_id()),
|
||||||
std::make_unique<ast::IdentifierExpression>(def_info->phi_var));
|
create<ast::IdentifierExpression>(def_info->phi_var));
|
||||||
return EmitConstDefOrWriteToHoistedVar(inst, std::move(expr));
|
return EmitConstDefOrWriteToHoistedVar(inst, std::move(expr));
|
||||||
}
|
}
|
||||||
case SpvOpFunctionCall:
|
case SpvOpFunctionCall:
|
||||||
|
@ -2714,7 +2708,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
if (binary_op != ast::BinaryOp::kNone) {
|
if (binary_op != ast::BinaryOp::kNone) {
|
||||||
auto arg0 = MakeOperand(inst, 0);
|
auto arg0 = MakeOperand(inst, 0);
|
||||||
auto arg1 = MakeOperand(inst, 1);
|
auto arg1 = MakeOperand(inst, 1);
|
||||||
auto binary_expr = std::make_unique<ast::BinaryExpression>(
|
auto binary_expr = create<ast::BinaryExpression>(
|
||||||
binary_op, std::move(arg0.expr), std::move(arg1.expr));
|
binary_op, std::move(arg0.expr), std::move(arg1.expr));
|
||||||
TypedExpression result(ast_type, std::move(binary_expr));
|
TypedExpression result(ast_type, std::move(binary_expr));
|
||||||
return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
|
return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
|
||||||
|
@ -2724,8 +2718,8 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
auto unary_op = ast::UnaryOp::kNegation;
|
auto unary_op = ast::UnaryOp::kNegation;
|
||||||
if (GetUnaryOp(opcode, &unary_op)) {
|
if (GetUnaryOp(opcode, &unary_op)) {
|
||||||
auto arg0 = MakeOperand(inst, 0);
|
auto arg0 = MakeOperand(inst, 0);
|
||||||
auto unary_expr = std::make_unique<ast::UnaryOpExpression>(
|
auto unary_expr =
|
||||||
unary_op, std::move(arg0.expr));
|
create<ast::UnaryOpExpression>(unary_op, std::move(arg0.expr));
|
||||||
TypedExpression result(ast_type, std::move(unary_expr));
|
TypedExpression result(ast_type, std::move(unary_expr));
|
||||||
return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
|
return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
|
||||||
arg0.type);
|
arg0.type);
|
||||||
|
@ -2735,9 +2729,8 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
if (unary_builtin_name != nullptr) {
|
if (unary_builtin_name != nullptr) {
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
params.emplace_back(MakeOperand(inst, 0).expr);
|
params.emplace_back(MakeOperand(inst, 0).expr);
|
||||||
return {ast_type,
|
return {ast_type, create<ast::CallExpression>(
|
||||||
std::make_unique<ast::CallExpression>(
|
create<ast::IdentifierExpression>(unary_builtin_name),
|
||||||
std::make_unique<ast::IdentifierExpression>(unary_builtin_name),
|
|
||||||
std::move(params))};
|
std::move(params))};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2751,7 +2744,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode == SpvOpBitcast) {
|
if (opcode == SpvOpBitcast) {
|
||||||
return {ast_type, std::make_unique<ast::BitcastExpression>(
|
return {ast_type, create<ast::BitcastExpression>(
|
||||||
ast_type, MakeOperand(inst, 0).expr)};
|
ast_type, MakeOperand(inst, 0).expr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2759,10 +2752,10 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
if (negated_op != ast::BinaryOp::kNone) {
|
if (negated_op != ast::BinaryOp::kNone) {
|
||||||
auto arg0 = MakeOperand(inst, 0);
|
auto arg0 = MakeOperand(inst, 0);
|
||||||
auto arg1 = MakeOperand(inst, 1);
|
auto arg1 = MakeOperand(inst, 1);
|
||||||
auto binary_expr = std::make_unique<ast::BinaryExpression>(
|
auto binary_expr = create<ast::BinaryExpression>(
|
||||||
negated_op, std::move(arg0.expr), std::move(arg1.expr));
|
negated_op, std::move(arg0.expr), std::move(arg1.expr));
|
||||||
auto negated_expr = std::make_unique<ast::UnaryOpExpression>(
|
auto negated_expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot,
|
||||||
ast::UnaryOp::kNot, std::move(binary_expr));
|
std::move(binary_expr));
|
||||||
return {ast_type, std::move(negated_expr)};
|
return {ast_type, std::move(negated_expr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2780,7 +2773,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||||
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
|
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
|
||||||
operands.emplace_back(MakeOperand(inst, iarg).expr);
|
operands.emplace_back(MakeOperand(inst, iarg).expr);
|
||||||
}
|
}
|
||||||
return {ast_type, std::make_unique<ast::TypeConstructorExpression>(
|
return {ast_type, create<ast::TypeConstructorExpression>(
|
||||||
ast_type, std::move(operands))};
|
ast_type, std::move(operands))};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2838,15 +2831,14 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto func = std::make_unique<ast::IdentifierExpression>(name);
|
auto func = create<ast::IdentifierExpression>(name);
|
||||||
ast::ExpressionList operands;
|
ast::ExpressionList operands;
|
||||||
// All parameters to GLSL.std.450 extended instructions are IDs.
|
// All parameters to GLSL.std.450 extended instructions are IDs.
|
||||||
for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) {
|
for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) {
|
||||||
operands.emplace_back(MakeOperand(inst, iarg).expr);
|
operands.emplace_back(MakeOperand(inst, iarg).expr);
|
||||||
}
|
}
|
||||||
auto* ast_type = parser_impl_.ConvertType(inst.type_id());
|
auto* ast_type = parser_impl_.ConvertType(inst.type_id());
|
||||||
auto call = std::make_unique<ast::CallExpression>(std::move(func),
|
auto call = create<ast::CallExpression>(std::move(func), std::move(operands));
|
||||||
std::move(operands));
|
|
||||||
return {ast_type, std::move(call)};
|
return {ast_type, std::move(call)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2913,7 +2905,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||||
// Replace the gl_PerVertex reference with the gl_Position reference
|
// Replace the gl_PerVertex reference with the gl_Position reference
|
||||||
ptr_ty_id = builtin_position_info.member_pointer_type_id;
|
ptr_ty_id = builtin_position_info.member_pointer_type_id;
|
||||||
current_expr.expr =
|
current_expr.expr =
|
||||||
std::make_unique<ast::IdentifierExpression>(namer_.Name(base_id));
|
create<ast::IdentifierExpression>(namer_.Name(base_id));
|
||||||
current_expr.type = parser_impl_.ConvertType(ptr_ty_id);
|
current_expr.type = parser_impl_.ConvertType(ptr_ty_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2963,13 +2955,13 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||||
<< " is too big. Max handled index is "
|
<< " is too big. Max handled index is "
|
||||||
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
||||||
}
|
}
|
||||||
auto letter_index = std::make_unique<ast::IdentifierExpression>(
|
auto letter_index =
|
||||||
swizzles[index_const_val]);
|
create<ast::IdentifierExpression>(swizzles[index_const_val]);
|
||||||
next_expr = std::make_unique<ast::MemberAccessorExpression>(
|
next_expr = create<ast::MemberAccessorExpression>(
|
||||||
std::move(current_expr.expr), std::move(letter_index));
|
std::move(current_expr.expr), std::move(letter_index));
|
||||||
} else {
|
} else {
|
||||||
// Non-constant index. Use array syntax
|
// Non-constant index. Use array syntax
|
||||||
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::ArrayAccessorExpression>(
|
||||||
std::move(current_expr.expr),
|
std::move(current_expr.expr),
|
||||||
std::move(MakeOperand(inst, index).expr));
|
std::move(MakeOperand(inst, index).expr));
|
||||||
}
|
}
|
||||||
|
@ -2978,20 +2970,20 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeMatrix:
|
case SpvOpTypeMatrix:
|
||||||
// Use array syntax.
|
// Use array syntax.
|
||||||
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::ArrayAccessorExpression>(
|
||||||
std::move(current_expr.expr),
|
std::move(current_expr.expr),
|
||||||
std::move(MakeOperand(inst, index).expr));
|
std::move(MakeOperand(inst, index).expr));
|
||||||
// All matrix components are the same type.
|
// All matrix components are the same type.
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeArray:
|
case SpvOpTypeArray:
|
||||||
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::ArrayAccessorExpression>(
|
||||||
std::move(current_expr.expr),
|
std::move(current_expr.expr),
|
||||||
std::move(MakeOperand(inst, index).expr));
|
std::move(MakeOperand(inst, index).expr));
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeRuntimeArray:
|
case SpvOpTypeRuntimeArray:
|
||||||
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::ArrayAccessorExpression>(
|
||||||
std::move(current_expr.expr),
|
std::move(current_expr.expr),
|
||||||
std::move(MakeOperand(inst, index).expr));
|
std::move(MakeOperand(inst, index).expr));
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
|
||||||
|
@ -3011,10 +3003,10 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||||
<< pointee_type_id << " having " << num_members << " members";
|
<< pointee_type_id << " having " << num_members << " members";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto member_access = std::make_unique<ast::IdentifierExpression>(
|
auto member_access = create<ast::IdentifierExpression>(
|
||||||
namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val)));
|
namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val)));
|
||||||
|
|
||||||
next_expr = std::make_unique<ast::MemberAccessorExpression>(
|
next_expr = create<ast::MemberAccessorExpression>(
|
||||||
std::move(current_expr.expr), std::move(member_access));
|
std::move(current_expr.expr), std::move(member_access));
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(
|
||||||
static_cast<uint32_t>(index_const_val));
|
static_cast<uint32_t>(index_const_val));
|
||||||
|
@ -3047,10 +3039,10 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||||
// expressions.
|
// expressions.
|
||||||
TypedExpression current_expr(MakeOperand(inst, 0));
|
TypedExpression current_expr(MakeOperand(inst, 0));
|
||||||
|
|
||||||
auto make_index = [](uint32_t literal) {
|
auto make_index = [this](uint32_t literal) {
|
||||||
ast::type::U32Type u32;
|
ast::type::U32Type u32;
|
||||||
return std::make_unique<ast::ScalarConstructorExpression>(
|
return create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::UintLiteral>(&u32, literal));
|
create<ast::UintLiteral>(&u32, literal));
|
||||||
};
|
};
|
||||||
static const char* swizzles[] = {"x", "y", "z", "w"};
|
static const char* swizzles[] = {"x", "y", "z", "w"};
|
||||||
|
|
||||||
|
@ -3088,8 +3080,8 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||||
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
||||||
}
|
}
|
||||||
auto letter_index =
|
auto letter_index =
|
||||||
std::make_unique<ast::IdentifierExpression>(swizzles[index_val]);
|
create<ast::IdentifierExpression>(swizzles[index_val]);
|
||||||
next_expr = std::make_unique<ast::MemberAccessorExpression>(
|
next_expr = create<ast::MemberAccessorExpression>(
|
||||||
std::move(current_expr.expr), std::move(letter_index));
|
std::move(current_expr.expr), std::move(letter_index));
|
||||||
// All vector components are the same type.
|
// All vector components are the same type.
|
||||||
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
||||||
|
@ -3110,7 +3102,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||||
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
||||||
}
|
}
|
||||||
// Use array syntax.
|
// Use array syntax.
|
||||||
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::ArrayAccessorExpression>(
|
||||||
std::move(current_expr.expr), make_index(index_val));
|
std::move(current_expr.expr), make_index(index_val));
|
||||||
// All matrix components are the same type.
|
// All matrix components are the same type.
|
||||||
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
||||||
|
@ -3120,7 +3112,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||||
// The array size could be a spec constant, and so it's not always
|
// The array size could be a spec constant, and so it's not always
|
||||||
// statically checkable. Instead, rely on a runtime index clamp
|
// statically checkable. Instead, rely on a runtime index clamp
|
||||||
// or runtime check to keep this safe.
|
// or runtime check to keep this safe.
|
||||||
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
|
next_expr = create<ast::ArrayAccessorExpression>(
|
||||||
std::move(current_expr.expr), make_index(index_val));
|
std::move(current_expr.expr), make_index(index_val));
|
||||||
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
current_type_id = current_type_inst->GetSingleWordInOperand(0);
|
||||||
break;
|
break;
|
||||||
|
@ -3135,10 +3127,10 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||||
<< current_type_id << " having " << num_members << " members";
|
<< current_type_id << " having " << num_members << " members";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto member_access = std::make_unique<ast::IdentifierExpression>(
|
auto member_access = create<ast::IdentifierExpression>(
|
||||||
namer_.GetMemberName(current_type_id, uint32_t(index_val)));
|
namer_.GetMemberName(current_type_id, uint32_t(index_val)));
|
||||||
|
|
||||||
next_expr = std::make_unique<ast::MemberAccessorExpression>(
|
next_expr = create<ast::MemberAccessorExpression>(
|
||||||
std::move(current_expr.expr), std::move(member_access));
|
std::move(current_expr.expr), std::move(member_access));
|
||||||
current_type_id = current_type_inst->GetSingleWordInOperand(index_val);
|
current_type_id = current_type_inst->GetSingleWordInOperand(index_val);
|
||||||
break;
|
break;
|
||||||
|
@ -3155,14 +3147,14 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ast::Expression> FunctionEmitter::MakeTrue() const {
|
std::unique_ptr<ast::Expression> FunctionEmitter::MakeTrue() const {
|
||||||
return std::make_unique<ast::ScalarConstructorExpression>(
|
return create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::BoolLiteral>(parser_impl_.BoolType(), true));
|
create<ast::BoolLiteral>(parser_impl_.BoolType(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ast::Expression> FunctionEmitter::MakeFalse() const {
|
std::unique_ptr<ast::Expression> FunctionEmitter::MakeFalse() const {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
return std::make_unique<ast::ScalarConstructorExpression>(
|
return create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::BoolLiteral>(parser_impl_.BoolType(), false));
|
create<ast::BoolLiteral>(parser_impl_.BoolType(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedExpression FunctionEmitter::MakeVectorShuffle(
|
TypedExpression FunctionEmitter::MakeVectorShuffle(
|
||||||
|
@ -3188,15 +3180,15 @@ TypedExpression FunctionEmitter::MakeVectorShuffle(
|
||||||
const auto index = inst.GetSingleWordInOperand(i);
|
const auto index = inst.GetSingleWordInOperand(i);
|
||||||
if (index < vec0_len) {
|
if (index < vec0_len) {
|
||||||
assert(index < sizeof(swizzles) / sizeof(swizzles[0]));
|
assert(index < sizeof(swizzles) / sizeof(swizzles[0]));
|
||||||
values.emplace_back(std::make_unique<ast::MemberAccessorExpression>(
|
values.emplace_back(create<ast::MemberAccessorExpression>(
|
||||||
MakeExpression(vec0_id).expr,
|
MakeExpression(vec0_id).expr,
|
||||||
std::make_unique<ast::IdentifierExpression>(swizzles[index])));
|
create<ast::IdentifierExpression>(swizzles[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 < sizeof(swizzles) / sizeof(swizzles[0]));
|
assert(sub_index < sizeof(swizzles) / sizeof(swizzles[0]));
|
||||||
values.emplace_back(std::make_unique<ast::MemberAccessorExpression>(
|
values.emplace_back(create<ast::MemberAccessorExpression>(
|
||||||
MakeExpression(vec1_id).expr,
|
MakeExpression(vec1_id).expr,
|
||||||
std::make_unique<ast::IdentifierExpression>(swizzles[sub_index])));
|
create<ast::IdentifierExpression>(swizzles[sub_index])));
|
||||||
} else if (index == 0xFFFFFFFF) {
|
} else if (index == 0xFFFFFFFF) {
|
||||||
// By rule, this maps to OpUndef. Instead, make it zero.
|
// By rule, this maps to OpUndef. Instead, make it zero.
|
||||||
values.emplace_back(parser_impl_.MakeNullValue(result_type->type()));
|
values.emplace_back(parser_impl_.MakeNullValue(result_type->type()));
|
||||||
|
@ -3206,7 +3198,7 @@ TypedExpression FunctionEmitter::MakeVectorShuffle(
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {result_type, std::make_unique<ast::TypeConstructorExpression>(
|
return {result_type, create<ast::TypeConstructorExpression>(
|
||||||
result_type, std::move(values))};
|
result_type, std::move(values))};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3497,28 +3489,27 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
params.push_back(std::move(arg_expr.expr));
|
params.push_back(std::move(arg_expr.expr));
|
||||||
TypedExpression result(expr_type,
|
TypedExpression result(expr_type, create<ast::TypeConstructorExpression>(
|
||||||
std::make_unique<ast::TypeConstructorExpression>(
|
|
||||||
expr_type, std::move(params)));
|
expr_type, std::move(params)));
|
||||||
|
|
||||||
if (requested_type == expr_type) {
|
if (requested_type == expr_type) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return {requested_type, std::make_unique<ast::BitcastExpression>(
|
return {requested_type, create<ast::BitcastExpression>(
|
||||||
requested_type, std::move(result.expr))};
|
requested_type, std::move(result.expr))};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
|
bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
|
||||||
// We ignore function attributes such as Inline, DontInline, Pure, Const.
|
// We ignore function attributes such as Inline, DontInline, Pure, Const.
|
||||||
auto function = std::make_unique<ast::IdentifierExpression>(
|
auto function = create<ast::IdentifierExpression>(
|
||||||
namer_.Name(inst.GetSingleWordInOperand(0)));
|
namer_.Name(inst.GetSingleWordInOperand(0)));
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
|
for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
|
||||||
params.emplace_back(MakeOperand(inst, iarg).expr);
|
params.emplace_back(MakeOperand(inst, iarg).expr);
|
||||||
}
|
}
|
||||||
auto call_expr = std::make_unique<ast::CallExpression>(std::move(function),
|
auto call_expr =
|
||||||
std::move(params));
|
create<ast::CallExpression>(std::move(function), std::move(params));
|
||||||
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||||
if (!result_type) {
|
if (!result_type) {
|
||||||
return Fail() << "internal error: no mapped type result of call: "
|
return Fail() << "internal error: no mapped type result of call: "
|
||||||
|
@ -3528,8 +3519,7 @@ bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
|
||||||
if (result_type->IsVoid()) {
|
if (result_type->IsVoid()) {
|
||||||
return nullptr !=
|
return nullptr !=
|
||||||
AddStatementForInstruction(
|
AddStatementForInstruction(
|
||||||
std::make_unique<ast::CallStatement>(std::move(call_expr)),
|
create<ast::CallStatement>(std::move(call_expr)), inst);
|
||||||
inst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EmitConstDefOrWriteToHoistedVar(inst,
|
return EmitConstDefOrWriteToHoistedVar(inst,
|
||||||
|
@ -3541,15 +3531,15 @@ TypedExpression FunctionEmitter::MakeIntrinsicCall(
|
||||||
const auto intrinsic = GetIntrinsic(inst.opcode());
|
const auto intrinsic = GetIntrinsic(inst.opcode());
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << intrinsic;
|
ss << intrinsic;
|
||||||
auto ident = std::make_unique<ast::IdentifierExpression>(ss.str());
|
auto ident = create<ast::IdentifierExpression>(ss.str());
|
||||||
ident->set_intrinsic(intrinsic);
|
ident->set_intrinsic(intrinsic);
|
||||||
|
|
||||||
ast::ExpressionList params;
|
ast::ExpressionList params;
|
||||||
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
|
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
|
||||||
params.emplace_back(MakeOperand(inst, iarg).expr);
|
params.emplace_back(MakeOperand(inst, iarg).expr);
|
||||||
}
|
}
|
||||||
auto call_expr = std::make_unique<ast::CallExpression>(std::move(ident),
|
auto call_expr =
|
||||||
std::move(params));
|
create<ast::CallExpression>(std::move(ident), std::move(params));
|
||||||
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||||
if (!result_type) {
|
if (!result_type) {
|
||||||
Fail() << "internal error: no mapped type result of call: "
|
Fail() << "internal error: no mapped type result of call: "
|
||||||
|
@ -3578,9 +3568,8 @@ TypedExpression FunctionEmitter::MakeSimpleSelect(
|
||||||
params.push_back(std::move(operand2.expr));
|
params.push_back(std::move(operand2.expr));
|
||||||
// The condition goes last.
|
// The condition goes last.
|
||||||
params.push_back(std::move(condition.expr));
|
params.push_back(std::move(condition.expr));
|
||||||
return {operand1.type,
|
return {operand1.type, create<ast::CallExpression>(
|
||||||
std::make_unique<ast::CallExpression>(
|
create<ast::IdentifierExpression>("select"),
|
||||||
std::make_unique<ast::IdentifierExpression>("select"),
|
|
||||||
std::move(params))};
|
std::move(params))};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "source/opt/basic_block.h"
|
#include "source/opt/basic_block.h"
|
||||||
|
@ -799,6 +800,13 @@ class FunctionEmitter {
|
||||||
/// @returns a boolean false expression.
|
/// @returns a boolean false expression.
|
||||||
std::unique_ptr<ast::Expression> MakeFalse() const;
|
std::unique_ptr<ast::Expression> MakeFalse() const;
|
||||||
|
|
||||||
|
/// @return a `std::unique_ptr` to a new `T` constructed with `args`
|
||||||
|
/// @param args the arguments to forward to the constructor for `T`
|
||||||
|
template <typename T, typename... ARGS>
|
||||||
|
std::unique_ptr<T> create(ARGS&&... args) const {
|
||||||
|
return std::make_unique<T>(std::forward<ARGS>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
ParserImpl& parser_impl_;
|
ParserImpl& parser_impl_;
|
||||||
ast::Module& ast_module_;
|
ast::Module& ast_module_;
|
||||||
spvtools::opt::IRContext& ir_context_;
|
spvtools::opt::IRContext& ir_context_;
|
||||||
|
|
|
@ -392,8 +392,7 @@ ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id,
|
||||||
<< ShowType(struct_type_id);
|
<< ShowType(struct_type_id);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return std::make_unique<ast::StructMemberOffsetDecoration>(decoration[1],
|
return create<ast::StructMemberOffsetDecoration>(decoration[1], Source{});
|
||||||
Source{});
|
|
||||||
case SpvDecorationNonReadable:
|
case SpvDecorationNonReadable:
|
||||||
// WGSL doesn't have a member decoration for this. Silently drop it.
|
// WGSL doesn't have a member decoration for this. Silently drop it.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -782,8 +781,7 @@ bool ParserImpl::ApplyArrayDecorations(
|
||||||
<< ": multiple ArrayStride decorations";
|
<< ": multiple ArrayStride decorations";
|
||||||
}
|
}
|
||||||
ast::ArrayDecorationList decos;
|
ast::ArrayDecorationList decos;
|
||||||
decos.push_back(
|
decos.push_back(create<ast::StrideDecoration>(stride, Source{}));
|
||||||
std::make_unique<ast::StrideDecoration>(stride, Source{}));
|
|
||||||
ast_type->set_decorations(std::move(decos));
|
ast_type->set_decorations(std::move(decos));
|
||||||
} else {
|
} else {
|
||||||
return Fail() << "invalid array type ID " << type_id
|
return Fail() << "invalid array type ID " << type_id
|
||||||
|
@ -806,10 +804,10 @@ ast::type::Type* ParserImpl::ConvertType(
|
||||||
const auto decoration = struct_decorations[0][0];
|
const auto decoration = struct_decorations[0][0];
|
||||||
if (decoration == SpvDecorationBlock) {
|
if (decoration == SpvDecorationBlock) {
|
||||||
ast_struct_decorations.push_back(
|
ast_struct_decorations.push_back(
|
||||||
std::make_unique<ast::StructBlockDecoration>(Source{}));
|
create<ast::StructBlockDecoration>(Source{}));
|
||||||
} else if (decoration == SpvDecorationBufferBlock) {
|
} else if (decoration == SpvDecorationBufferBlock) {
|
||||||
ast_struct_decorations.push_back(
|
ast_struct_decorations.push_back(
|
||||||
std::make_unique<ast::StructBlockDecoration>(Source{}));
|
create<ast::StructBlockDecoration>(Source{}));
|
||||||
remap_buffer_block_type_.insert(type_id);
|
remap_buffer_block_type_.insert(type_id);
|
||||||
} else {
|
} else {
|
||||||
Fail() << "struct with ID " << type_id
|
Fail() << "struct with ID " << type_id
|
||||||
|
@ -879,14 +877,14 @@ ast::type::Type* ParserImpl::ConvertType(
|
||||||
++num_non_writable_members;
|
++num_non_writable_members;
|
||||||
}
|
}
|
||||||
const auto member_name = namer_.GetMemberName(type_id, member_index);
|
const auto member_name = namer_.GetMemberName(type_id, member_index);
|
||||||
auto ast_struct_member = std::make_unique<ast::StructMember>(
|
auto ast_struct_member = create<ast::StructMember>(
|
||||||
member_name, ast_member_ty, std::move(ast_member_decorations));
|
member_name, ast_member_ty, std::move(ast_member_decorations));
|
||||||
ast_members.push_back(std::move(ast_struct_member));
|
ast_members.push_back(std::move(ast_struct_member));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now make the struct.
|
// Now make the struct.
|
||||||
auto ast_struct = std::make_unique<ast::Struct>(
|
auto ast_struct = create<ast::Struct>(std::move(ast_struct_decorations),
|
||||||
std::move(ast_struct_decorations), std::move(ast_members));
|
std::move(ast_members));
|
||||||
|
|
||||||
namer_.SuggestSanitizedName(type_id, "S");
|
namer_.SuggestSanitizedName(type_id, "S");
|
||||||
auto ast_struct_type = std::make_unique<ast::type::StructType>(
|
auto ast_struct_type = std::make_unique<ast::type::StructType>(
|
||||||
|
@ -971,8 +969,8 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||||
case SpvOpSpecConstantTrue:
|
case SpvOpSpecConstantTrue:
|
||||||
case SpvOpSpecConstantFalse: {
|
case SpvOpSpecConstantFalse: {
|
||||||
ast_type = ConvertType(inst.type_id());
|
ast_type = ConvertType(inst.type_id());
|
||||||
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
|
ast_expr =
|
||||||
std::make_unique<ast::BoolLiteral>(
|
create<ast::ScalarConstructorExpression>(create<ast::BoolLiteral>(
|
||||||
ast_type, inst.opcode() == SpvOpSpecConstantTrue));
|
ast_type, inst.opcode() == SpvOpSpecConstantTrue));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -980,19 +978,19 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||||
ast_type = ConvertType(inst.type_id());
|
ast_type = ConvertType(inst.type_id());
|
||||||
const uint32_t literal_value = inst.GetSingleWordInOperand(0);
|
const uint32_t literal_value = inst.GetSingleWordInOperand(0);
|
||||||
if (ast_type->IsI32()) {
|
if (ast_type->IsI32()) {
|
||||||
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
|
ast_expr =
|
||||||
std::make_unique<ast::SintLiteral>(
|
create<ast::ScalarConstructorExpression>(create<ast::SintLiteral>(
|
||||||
ast_type, static_cast<int32_t>(literal_value)));
|
ast_type, static_cast<int32_t>(literal_value)));
|
||||||
} else if (ast_type->IsU32()) {
|
} else if (ast_type->IsU32()) {
|
||||||
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
|
ast_expr =
|
||||||
std::make_unique<ast::UintLiteral>(
|
create<ast::ScalarConstructorExpression>(create<ast::UintLiteral>(
|
||||||
ast_type, static_cast<uint32_t>(literal_value)));
|
ast_type, static_cast<uint32_t>(literal_value)));
|
||||||
} else if (ast_type->IsF32()) {
|
} else if (ast_type->IsF32()) {
|
||||||
float float_value;
|
float float_value;
|
||||||
// Copy the bits so we can read them as a float.
|
// Copy the bits so we can read them as a float.
|
||||||
std::memcpy(&float_value, &literal_value, sizeof(float_value));
|
std::memcpy(&float_value, &literal_value, sizeof(float_value));
|
||||||
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
|
ast_expr = create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::FloatLiteral>(ast_type, float_value));
|
create<ast::FloatLiteral>(ast_type, float_value));
|
||||||
} else {
|
} else {
|
||||||
return Fail() << " invalid result type for OpSpecConstant "
|
return Fail() << " invalid result type for OpSpecConstant "
|
||||||
<< inst.PrettyPrint();
|
<< inst.PrettyPrint();
|
||||||
|
@ -1008,8 +1006,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||||
ast::VariableDecorationList spec_id_decos;
|
ast::VariableDecorationList spec_id_decos;
|
||||||
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
||||||
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
||||||
auto cid =
|
auto cid = create<ast::ConstantIdDecoration>(deco[1], Source{});
|
||||||
std::make_unique<ast::ConstantIdDecoration>(deco[1], Source{});
|
|
||||||
spec_id_decos.push_back(std::move(cid));
|
spec_id_decos.push_back(std::move(cid));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1020,8 +1017,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||||
ast_var->set_constructor(std::move(ast_expr));
|
ast_var->set_constructor(std::move(ast_expr));
|
||||||
ast_module_.AddGlobalVariable(std::move(ast_var));
|
ast_module_.AddGlobalVariable(std::move(ast_var));
|
||||||
} else {
|
} else {
|
||||||
auto ast_deco_var =
|
auto ast_deco_var = create<ast::DecoratedVariable>(std::move(ast_var));
|
||||||
std::make_unique<ast::DecoratedVariable>(std::move(ast_var));
|
|
||||||
ast_deco_var->set_is_const(true);
|
ast_deco_var->set_is_const(true);
|
||||||
ast_deco_var->set_constructor(std::move(ast_expr));
|
ast_deco_var->set_constructor(std::move(ast_expr));
|
||||||
ast_deco_var->set_decorations(std::move(spec_id_decos));
|
ast_deco_var->set_decorations(std::move(spec_id_decos));
|
||||||
|
@ -1140,13 +1136,13 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
||||||
// Make sure the variable has a name.
|
// Make sure the variable has a name.
|
||||||
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
|
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
|
||||||
"gl_Position");
|
"gl_Position");
|
||||||
auto var = std::make_unique<ast::DecoratedVariable>(MakeVariable(
|
auto var = create<ast::DecoratedVariable>(MakeVariable(
|
||||||
builtin_position_.per_vertex_var_id,
|
builtin_position_.per_vertex_var_id,
|
||||||
enum_converter_.ToStorageClass(builtin_position_.storage_class),
|
enum_converter_.ToStorageClass(builtin_position_.storage_class),
|
||||||
ConvertType(builtin_position_.member_type_id)));
|
ConvertType(builtin_position_.member_type_id)));
|
||||||
ast::VariableDecorationList decos;
|
ast::VariableDecorationList decos;
|
||||||
decos.push_back(std::make_unique<ast::BuiltinDecoration>(
|
decos.push_back(
|
||||||
ast::Builtin::kPosition, Source{}));
|
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
|
||||||
var->set_decorations(std::move(decos));
|
var->set_decorations(std::move(decos));
|
||||||
|
|
||||||
ast_module_.AddGlobalVariable(std::move(var));
|
ast_module_.AddGlobalVariable(std::move(var));
|
||||||
|
@ -1171,7 +1167,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||||
std::make_unique<ast::type::AccessControlType>(access, type));
|
std::make_unique<ast::type::AccessControlType>(access, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ast_var = std::make_unique<ast::Variable>(namer_.Name(id), sc, type);
|
auto ast_var = create<ast::Variable>(namer_.Name(id), sc, type);
|
||||||
|
|
||||||
ast::VariableDecorationList ast_decorations;
|
ast::VariableDecorationList ast_decorations;
|
||||||
for (auto& deco : GetDecorationsFor(id)) {
|
for (auto& deco : GetDecorationsFor(id)) {
|
||||||
|
@ -1191,7 +1187,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
ast_decorations.emplace_back(
|
||||||
std::make_unique<ast::BuiltinDecoration>(ast_builtin, Source{}));
|
create<ast::BuiltinDecoration>(ast_builtin, Source{}));
|
||||||
}
|
}
|
||||||
if (deco[0] == SpvDecorationLocation) {
|
if (deco[0] == SpvDecorationLocation) {
|
||||||
if (deco.size() != 2) {
|
if (deco.size() != 2) {
|
||||||
|
@ -1200,7 +1196,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
ast_decorations.emplace_back(
|
||||||
std::make_unique<ast::LocationDecoration>(deco[1], Source{}));
|
create<ast::LocationDecoration>(deco[1], Source{}));
|
||||||
}
|
}
|
||||||
if (deco[0] == SpvDecorationDescriptorSet) {
|
if (deco[0] == SpvDecorationDescriptorSet) {
|
||||||
if (deco.size() == 1) {
|
if (deco.size() == 1) {
|
||||||
|
@ -1209,7 +1205,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
ast_decorations.emplace_back(
|
||||||
std::make_unique<ast::SetDecoration>(deco[1], Source{}));
|
create<ast::SetDecoration>(deco[1], Source{}));
|
||||||
}
|
}
|
||||||
if (deco[0] == SpvDecorationBinding) {
|
if (deco[0] == SpvDecorationBinding) {
|
||||||
if (deco.size() == 1) {
|
if (deco.size() == 1) {
|
||||||
|
@ -1218,12 +1214,11 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ast_decorations.emplace_back(
|
ast_decorations.emplace_back(
|
||||||
std::make_unique<ast::BindingDecoration>(deco[1], Source{}));
|
create<ast::BindingDecoration>(deco[1], Source{}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ast_decorations.empty()) {
|
if (!ast_decorations.empty()) {
|
||||||
auto decorated_var =
|
auto decorated_var = create<ast::DecoratedVariable>(std::move(ast_var));
|
||||||
std::make_unique<ast::DecoratedVariable>(std::move(ast_var));
|
|
||||||
decorated_var->set_decorations(std::move(ast_decorations));
|
decorated_var->set_decorations(std::move(ast_decorations));
|
||||||
ast_var = std::move(decorated_var);
|
ast_var = std::move(decorated_var);
|
||||||
}
|
}
|
||||||
|
@ -1263,26 +1258,26 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
|
||||||
// Currently "null<type>" is missing from the WGSL parser.
|
// Currently "null<type>" is missing from the WGSL parser.
|
||||||
// See https://bugs.chromium.org/p/tint/issues/detail?id=34
|
// See https://bugs.chromium.org/p/tint/issues/detail?id=34
|
||||||
if (ast_type->IsU32()) {
|
if (ast_type->IsU32()) {
|
||||||
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
|
return {ast_type,
|
||||||
std::make_unique<ast::UintLiteral>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
ast_type, spirv_const->GetU32()))};
|
create<ast::UintLiteral>(ast_type, spirv_const->GetU32()))};
|
||||||
}
|
}
|
||||||
if (ast_type->IsI32()) {
|
if (ast_type->IsI32()) {
|
||||||
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
|
return {ast_type,
|
||||||
std::make_unique<ast::SintLiteral>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
ast_type, spirv_const->GetS32()))};
|
create<ast::SintLiteral>(ast_type, spirv_const->GetS32()))};
|
||||||
}
|
}
|
||||||
if (ast_type->IsF32()) {
|
if (ast_type->IsF32()) {
|
||||||
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
|
return {ast_type,
|
||||||
std::make_unique<ast::FloatLiteral>(
|
create<ast::ScalarConstructorExpression>(
|
||||||
ast_type, spirv_const->GetFloat()))};
|
create<ast::FloatLiteral>(ast_type, spirv_const->GetFloat()))};
|
||||||
}
|
}
|
||||||
if (ast_type->IsBool()) {
|
if (ast_type->IsBool()) {
|
||||||
const bool value = spirv_const->AsNullConstant()
|
const bool value = spirv_const->AsNullConstant()
|
||||||
? false
|
? false
|
||||||
: spirv_const->AsBoolConstant()->value();
|
: spirv_const->AsBoolConstant()->value();
|
||||||
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
|
return {ast_type, create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::BoolLiteral>(ast_type, value))};
|
create<ast::BoolLiteral>(ast_type, value))};
|
||||||
}
|
}
|
||||||
auto* spirv_composite_const = spirv_const->AsCompositeConstant();
|
auto* spirv_composite_const = spirv_const->AsCompositeConstant();
|
||||||
if (spirv_composite_const != nullptr) {
|
if (spirv_composite_const != nullptr) {
|
||||||
|
@ -1308,8 +1303,8 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
|
||||||
ast_components.emplace_back(std::move(ast_component.expr));
|
ast_components.emplace_back(std::move(ast_component.expr));
|
||||||
}
|
}
|
||||||
return {original_ast_type,
|
return {original_ast_type,
|
||||||
std::make_unique<ast::TypeConstructorExpression>(
|
create<ast::TypeConstructorExpression>(original_ast_type,
|
||||||
original_ast_type, std::move(ast_components))};
|
std::move(ast_components))};
|
||||||
}
|
}
|
||||||
auto* spirv_null_const = spirv_const->AsNullConstant();
|
auto* spirv_null_const = spirv_const->AsNullConstant();
|
||||||
if (spirv_null_const != nullptr) {
|
if (spirv_null_const != nullptr) {
|
||||||
|
@ -1336,20 +1331,20 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||||
type = type->UnwrapIfNeeded();
|
type = type->UnwrapIfNeeded();
|
||||||
|
|
||||||
if (type->IsBool()) {
|
if (type->IsBool()) {
|
||||||
return std::make_unique<ast::ScalarConstructorExpression>(
|
return create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::BoolLiteral>(type, false));
|
create<ast::BoolLiteral>(type, false));
|
||||||
}
|
}
|
||||||
if (type->IsU32()) {
|
if (type->IsU32()) {
|
||||||
return std::make_unique<ast::ScalarConstructorExpression>(
|
return create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::UintLiteral>(type, 0u));
|
create<ast::UintLiteral>(type, 0u));
|
||||||
}
|
}
|
||||||
if (type->IsI32()) {
|
if (type->IsI32()) {
|
||||||
return std::make_unique<ast::ScalarConstructorExpression>(
|
return create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::SintLiteral>(type, 0));
|
create<ast::SintLiteral>(type, 0));
|
||||||
}
|
}
|
||||||
if (type->IsF32()) {
|
if (type->IsF32()) {
|
||||||
return std::make_unique<ast::ScalarConstructorExpression>(
|
return create<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::FloatLiteral>(type, 0.0f));
|
create<ast::FloatLiteral>(type, 0.0f));
|
||||||
}
|
}
|
||||||
if (type->IsVector()) {
|
if (type->IsVector()) {
|
||||||
const auto* vec_ty = type->AsVector();
|
const auto* vec_ty = type->AsVector();
|
||||||
|
@ -1357,8 +1352,8 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||||
for (size_t i = 0; i < vec_ty->size(); ++i) {
|
for (size_t i = 0; i < vec_ty->size(); ++i) {
|
||||||
ast_components.emplace_back(MakeNullValue(vec_ty->type()));
|
ast_components.emplace_back(MakeNullValue(vec_ty->type()));
|
||||||
}
|
}
|
||||||
return std::make_unique<ast::TypeConstructorExpression>(
|
return create<ast::TypeConstructorExpression>(type,
|
||||||
type, std::move(ast_components));
|
std::move(ast_components));
|
||||||
}
|
}
|
||||||
if (type->IsMatrix()) {
|
if (type->IsMatrix()) {
|
||||||
const auto* mat_ty = type->AsMatrix();
|
const auto* mat_ty = type->AsMatrix();
|
||||||
|
@ -1370,8 +1365,8 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||||
for (size_t i = 0; i < mat_ty->columns(); ++i) {
|
for (size_t i = 0; i < mat_ty->columns(); ++i) {
|
||||||
ast_components.emplace_back(MakeNullValue(column_ty));
|
ast_components.emplace_back(MakeNullValue(column_ty));
|
||||||
}
|
}
|
||||||
return std::make_unique<ast::TypeConstructorExpression>(
|
return create<ast::TypeConstructorExpression>(type,
|
||||||
type, std::move(ast_components));
|
std::move(ast_components));
|
||||||
}
|
}
|
||||||
if (type->IsArray()) {
|
if (type->IsArray()) {
|
||||||
auto* arr_ty = type->AsArray();
|
auto* arr_ty = type->AsArray();
|
||||||
|
@ -1379,8 +1374,8 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||||
for (size_t i = 0; i < arr_ty->size(); ++i) {
|
for (size_t i = 0; i < arr_ty->size(); ++i) {
|
||||||
ast_components.emplace_back(MakeNullValue(arr_ty->type()));
|
ast_components.emplace_back(MakeNullValue(arr_ty->type()));
|
||||||
}
|
}
|
||||||
return std::make_unique<ast::TypeConstructorExpression>(
|
return create<ast::TypeConstructorExpression>(original_type,
|
||||||
original_type, std::move(ast_components));
|
std::move(ast_components));
|
||||||
}
|
}
|
||||||
if (type->IsStruct()) {
|
if (type->IsStruct()) {
|
||||||
auto* struct_ty = type->AsStruct();
|
auto* struct_ty = type->AsStruct();
|
||||||
|
@ -1388,8 +1383,8 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||||
for (auto& member : struct_ty->impl()->members()) {
|
for (auto& member : struct_ty->impl()->members()) {
|
||||||
ast_components.emplace_back(MakeNullValue(member->type()));
|
ast_components.emplace_back(MakeNullValue(member->type()));
|
||||||
}
|
}
|
||||||
return std::make_unique<ast::TypeConstructorExpression>(
|
return create<ast::TypeConstructorExpression>(original_type,
|
||||||
original_type, std::move(ast_components));
|
std::move(ast_components));
|
||||||
}
|
}
|
||||||
Fail() << "can't make null value for type: " << type->type_name();
|
Fail() << "can't make null value for type: " << type->type_name();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1416,15 +1411,15 @@ TypedExpression ParserImpl::RectifyOperandSignedness(SpvOp op,
|
||||||
auto* unsigned_ty = unsigned_type_for_[type];
|
auto* unsigned_ty = unsigned_type_for_[type];
|
||||||
if (unsigned_ty != nullptr) {
|
if (unsigned_ty != nullptr) {
|
||||||
// Conversion is required.
|
// Conversion is required.
|
||||||
return {unsigned_ty, std::make_unique<ast::BitcastExpression>(
|
return {unsigned_ty, create<ast::BitcastExpression>(
|
||||||
unsigned_ty, std::move(expr.expr))};
|
unsigned_ty, std::move(expr.expr))};
|
||||||
}
|
}
|
||||||
} else if (requires_signed) {
|
} else if (requires_signed) {
|
||||||
auto* signed_ty = signed_type_for_[type];
|
auto* signed_ty = signed_type_for_[type];
|
||||||
if (signed_ty != nullptr) {
|
if (signed_ty != nullptr) {
|
||||||
// Conversion is required.
|
// Conversion is required.
|
||||||
return {signed_ty, std::make_unique<ast::BitcastExpression>(
|
return {signed_ty,
|
||||||
signed_ty, std::move(expr.expr))};
|
create<ast::BitcastExpression>(signed_ty, std::move(expr.expr))};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We should not reach here.
|
// We should not reach here.
|
||||||
|
@ -1487,8 +1482,8 @@ TypedExpression ParserImpl::RectifyForcedResultType(
|
||||||
if ((forced_result_ty == nullptr) || (forced_result_ty == expr.type)) {
|
if ((forced_result_ty == nullptr) || (forced_result_ty == expr.type)) {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
return {expr.type, std::make_unique<ast::BitcastExpression>(
|
return {expr.type,
|
||||||
expr.type, std::move(expr.expr))};
|
create<ast::BitcastExpression>(expr.type, std::move(expr.expr))};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserImpl::EmitFunctions() {
|
bool ParserImpl::EmitFunctions() {
|
||||||
|
|
|
@ -432,6 +432,13 @@ class ParserImpl : Reader {
|
||||||
bool ApplyArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
|
bool ApplyArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
|
||||||
ast::type::ArrayType* ast_type);
|
ast::type::ArrayType* ast_type);
|
||||||
|
|
||||||
|
/// @return a `std::unique_ptr` to a new `T` constructed with `args`
|
||||||
|
/// @param args the arguments to forward to the constructor for `T`
|
||||||
|
template <typename T, typename... ARGS>
|
||||||
|
std::unique_ptr<T> create(ARGS&&... args) const {
|
||||||
|
return std::make_unique<T>(std::forward<ARGS>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
// The SPIR-V binary we're parsing
|
// The SPIR-V binary we're parsing
|
||||||
std::vector<uint32_t> spv_binary_;
|
std::vector<uint32_t> spv_binary_;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue