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:
Ben Clayton 2020-11-16 15:21:07 +00:00 committed by Commit Bot service account
parent eeac0c5f63
commit 307919dba9
4 changed files with 211 additions and 212 deletions

View File

@ -502,9 +502,8 @@ FunctionEmitter::StatementBlock::~StatementBlock() = default;
void FunctionEmitter::PushNewStatementBlock(const Construct* construct,
uint32_t end_id,
CompletionAction action) {
statements_stack_.emplace_back(
StatementBlock{construct, end_id, action,
std::make_unique<ast::BlockStatement>(), nullptr});
statements_stack_.emplace_back(StatementBlock{
construct, end_id, action, create<ast::BlockStatement>(), nullptr});
}
void FunctionEmitter::PushGuard(const std::string& guard_name,
@ -515,11 +514,11 @@ void FunctionEmitter::PushGuard(const std::string& guard_name,
// if-selection with a then-clause ending at the same block
// as the statement block at the top of the stack.
const auto& top = statements_stack_.back();
auto cond = std::make_unique<ast::IdentifierExpression>(guard_name);
auto body = std::make_unique<ast::BlockStatement>();
auto* const guard_stmt = AddStatement(std::make_unique<ast::IfStatement>(
std::move(cond), std::move(body)))
->AsIf();
auto cond = create<ast::IdentifierExpression>(guard_name);
auto body = create<ast::BlockStatement>();
auto* const guard_stmt =
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
->AsIf();
PushNewStatementBlock(top.construct_, end_id,
[guard_stmt](StatementBlock* s) {
guard_stmt->set_body(std::move(s->statements_));
@ -530,10 +529,10 @@ void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
assert(!statements_stack_.empty());
const auto& top = statements_stack_.back();
auto cond = MakeTrue();
auto body = std::make_unique<ast::BlockStatement>();
auto* const guard_stmt = AddStatement(std::make_unique<ast::IfStatement>(
std::move(cond), std::move(body)))
->AsIf();
auto body = create<ast::BlockStatement>();
auto* const guard_stmt =
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
->AsIf();
guard_stmt->set_condition(MakeTrue());
PushNewStatementBlock(top.construct_, end_id,
[guard_stmt](StatementBlock* s) {
@ -649,13 +648,12 @@ bool FunctionEmitter::EmitFunctionDeclaration() {
return false;
}
auto ast_fn =
std::make_unique<ast::Function>(name, std::move(ast_params), ret_ty,
std::make_unique<ast::BlockStatement>());
auto ast_fn = create<ast::Function>(name, std::move(ast_params), ret_ty,
create<ast::BlockStatement>());
if (ep_info_ != nullptr) {
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));
@ -1707,8 +1705,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
.expr);
}
auto var_decl_stmt =
std::make_unique<ast::VariableDeclStatement>(std::move(var));
auto var_decl_stmt = create<ast::VariableDeclStatement>(std::move(var));
AddStatementForInstruction(std::move(var_decl_stmt), inst);
// Save this as an already-named value.
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)) {
return TypedExpression(
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)) {
auto expr = std::move(singly_used_values_[id]);
@ -1742,9 +1739,9 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
switch (inst->opcode()) {
case SpvOpVariable:
// This occurs for module-scope variables.
return TypedExpression(parser_impl_.ConvertType(inst->type_id()),
std::make_unique<ast::IdentifierExpression>(
namer_.Name(inst->result_id())));
return TypedExpression(
parser_impl_.ConvertType(inst->type_id()),
create<ast::IdentifierExpression>(namer_.Name(inst->result_id())));
default:
break;
}
@ -1973,21 +1970,20 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
const std::string guard_name = block_info.flow_guard_name;
if (!guard_name.empty()) {
// 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_var->set_constructor(MakeTrue());
auto guard_decl =
std::make_unique<ast::VariableDeclStatement>(std::move(guard_var));
auto guard_decl = create<ast::VariableDeclStatement>(std::move(guard_var));
AddStatement(std::move(guard_decl));
}
const auto condition_id =
block_info.basic_block->terminator()->GetSingleWordInOperand(0);
auto cond = MakeExpression(condition_id).expr;
auto body = std::make_unique<ast::BlockStatement>();
auto* const if_stmt = AddStatement(std::make_unique<ast::IfStatement>(
std::move(cond), std::move(body)))
->AsIf();
auto body = create<ast::BlockStatement>();
auto* const if_stmt =
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
->AsIf();
// Generate the code for the condition.
@ -2040,17 +2036,18 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
auto push_else = [this, if_stmt, else_end, construct]() {
// Push the else clause onto the stack first.
PushNewStatementBlock(construct, else_end, [if_stmt](StatementBlock* s) {
// Only set the else-clause if there are statements to fill it.
if (!s->statements_->empty()) {
// The "else" consists of the statement list from the top of statments
// stack, without an elseif condition.
ast::ElseStatementList else_stmts;
else_stmts.emplace_back(std::make_unique<ast::ElseStatement>(
nullptr, std::move(s->statements_)));
if_stmt->set_else_statements(std::move(else_stmts));
}
});
PushNewStatementBlock(
construct, else_end, [this, if_stmt](StatementBlock* s) {
// Only set the else-clause if there are statements to fill it.
if (!s->statements_->empty()) {
// The "else" consists of the statement list from the top of
// statments stack, without an elseif condition.
ast::ElseStatementList else_stmts;
else_stmts.emplace_back(
create<ast::ElseStatement>(nullptr, std::move(s->statements_)));
if_stmt->set_else_statements(std::move(else_stmts));
}
});
};
if (GetBlockInfo(else_end)->pos < GetBlockInfo(then_end)->pos) {
@ -2099,7 +2096,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
const auto* branch = block_info.basic_block->terminator();
auto* const switch_stmt =
AddStatement(std::make_unique<ast::SwitchStatement>())->AsSwitch();
AddStatement(create<ast::SwitchStatement>())->AsSwitch();
const auto selector_id = branch->GetSingleWordInOperand(0);
// Generate the code for the selector.
auto selector = MakeExpression(selector_id);
@ -2111,7 +2108,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
construct, construct->end_id, [switch_stmt](StatementBlock* s) {
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
// stack.
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) {
// Create the case clause. Temporarily put it in the wrong order
// on the case statement list.
cases->emplace_back(std::make_unique<ast::CaseStatement>(
std::make_unique<ast::BlockStatement>()));
cases->emplace_back(
create<ast::CaseStatement>(create<ast::BlockStatement>()));
auto* clause = cases->back().get();
// 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);
if (selector.type->is_unsigned_scalar_or_vector()) {
selectors.emplace_back(
std::make_unique<ast::UintLiteral>(selector.type, value32));
create<ast::UintLiteral>(selector.type, value32));
} else {
selectors.emplace_back(
std::make_unique<ast::SintLiteral>(selector.type, value32));
create<ast::SintLiteral>(selector.type, value32));
}
}
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 &&
construct->ContainsPos(default_info->pos)) {
// Generate a default clause with a just fallthrough.
auto stmts = std::make_unique<ast::BlockStatement>();
stmts->append(std::make_unique<ast::FallthroughStatement>());
auto case_stmt = std::make_unique<ast::CaseStatement>(std::move(stmts));
auto stmts = create<ast::BlockStatement>();
stmts->append(create<ast::FallthroughStatement>());
auto case_stmt = create<ast::CaseStatement>(std::move(stmts));
cases->emplace_back(std::move(case_stmt));
}
@ -2214,10 +2211,10 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
}
bool FunctionEmitter::EmitLoopStart(const Construct* construct) {
auto* loop = AddStatement(std::make_unique<ast::LoopStatement>(
std::make_unique<ast::BlockStatement>(),
std::make_unique<ast::BlockStatement>()))
->AsLoop();
auto* loop =
AddStatement(create<ast::LoopStatement>(create<ast::BlockStatement>(),
create<ast::BlockStatement>()))
->AsLoop();
PushNewStatementBlock(
construct, construct->end_id,
[loop](StatementBlock* s) { loop->set_body(std::move(s->statements_)); });
@ -2244,18 +2241,17 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
const auto& terminator = *(block_info.basic_block->terminator());
switch (terminator.opcode()) {
case SpvOpReturn:
AddStatement(std::make_unique<ast::ReturnStatement>());
AddStatement(create<ast::ReturnStatement>());
return true;
case SpvOpReturnValue: {
auto value = MakeExpression(terminator.GetSingleWordInOperand(0));
AddStatement(
std::make_unique<ast::ReturnStatement>(std::move(value.expr)));
AddStatement(create<ast::ReturnStatement>(std::move(value.expr)));
}
return true;
case SpvOpKill:
// For now, assume SPIR-V OpKill has same semantics as WGSL discard.
// TODO(dneto): https://github.com/gpuweb/gpuweb/issues/676
AddStatement(std::make_unique<ast::DiscardStatement>());
AddStatement(create<ast::DiscardStatement>());
return true;
case SpvOpUnreachable:
// 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());
if (result_type->AsVoid() != nullptr) {
AddStatement(std::make_unique<ast::ReturnStatement>());
AddStatement(create<ast::ReturnStatement>());
} else {
auto* ast_type = parser_impl_.ConvertType(function_.type_id());
AddStatement(std::make_unique<ast::ReturnStatement>(
AddStatement(create<ast::ReturnStatement>(
parser_impl_.MakeNullValue(ast_type)));
}
}
@ -2350,7 +2346,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
break;
case EdgeKind::kSwitchBreak: {
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
// clause.
@ -2375,10 +2371,10 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
}
}
// We need a break.
return std::make_unique<ast::BreakStatement>();
return create<ast::BreakStatement>();
}
case EdgeKind::kLoopBreak:
return std::make_unique<ast::BreakStatement>();
return create<ast::BreakStatement>();
case EdgeKind::kLoopContinue:
// An unconditional continue to the next block is redundant and ugly.
// Skip it in that case.
@ -2386,7 +2382,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
break;
}
// Otherwise, emit a regular continue statement.
return std::make_unique<ast::ContinueStatement>();
return create<ast::ContinueStatement>();
case EdgeKind::kIfBreak: {
const auto& flow_guard =
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;
}
// Signal an exit from the branch.
return std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>(flow_guard),
MakeFalse());
return create<ast::AssignmentStatement>(
create<ast::IdentifierExpression>(flow_guard), MakeFalse());
}
// For an unconditional branch, the break out to an if-selection
@ -2405,7 +2400,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
break;
}
case EdgeKind::kCaseFallThrough:
return std::make_unique<ast::FallthroughStatement>();
return create<ast::FallthroughStatement>();
case EdgeKind::kForward:
// Unconditional forward branch is implicit.
break;
@ -2420,19 +2415,19 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeSimpleIf(
if ((then_stmt == nullptr) && (else_stmt == nullptr)) {
return nullptr;
}
auto if_stmt = std::make_unique<ast::IfStatement>(
std::move(condition), std::make_unique<ast::BlockStatement>());
auto if_stmt = create<ast::IfStatement>(std::move(condition),
create<ast::BlockStatement>());
if (then_stmt != nullptr) {
auto stmts = std::make_unique<ast::BlockStatement>();
auto stmts = create<ast::BlockStatement>();
stmts->append(std::move(then_stmt));
if_stmt->set_body(std::move(stmts));
}
if (else_stmt != nullptr) {
auto stmts = std::make_unique<ast::BlockStatement>();
auto stmts = create<ast::BlockStatement>();
stmts->append(std::move(else_stmt));
ast::ElseStatementList else_stmts;
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));
}
return if_stmt;
@ -2479,7 +2474,7 @@ bool FunctionEmitter::EmitConditionalCaseFallThrough(
AddStatement(
MakeSimpleIf(std::move(cond), std::move(other_branch), nullptr));
}
AddStatement(std::make_unique<ast::FallthroughStatement>());
AddStatement(create<ast::FallthroughStatement>());
return success();
}
@ -2506,7 +2501,7 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
assert(def_inst);
auto* ast_type =
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)));
// Save this as an already-named value.
identifier_values_.insert(id);
@ -2517,10 +2512,10 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
assert(def_inst);
const auto phi_var_name = GetDefInfo(id)->phi_var;
assert(!phi_var_name.empty());
auto var = std::make_unique<ast::Variable>(
phi_var_name, ast::StorageClass::kFunction,
parser_impl_.ConvertType(def_inst->type_id()));
AddStatement(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
auto var =
create<ast::Variable>(phi_var_name, ast::StorageClass::kFunction,
parser_impl_.ConvertType(def_inst->type_id()));
AddStatement(create<ast::VariableDeclStatement>(std::move(var)));
}
// Emit regular statements.
@ -2550,9 +2545,8 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
for (auto assignment : block_info.phi_assignments) {
const auto var_name = GetDefInfo(assignment.phi_id)->phi_var;
auto expr = MakeExpression(assignment.value);
AddStatement(std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>(var_name),
std::move(expr.expr)));
AddStatement(create<ast::AssignmentStatement>(
create<ast::IdentifierExpression>(var_name), std::move(expr.expr)));
}
}
@ -2574,7 +2568,7 @@ bool FunctionEmitter::EmitConstDefinition(
ast_const->set_constructor(std::move(ast_expr.expr));
ast_const->set_is_const(true);
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.
identifier_values_.insert(inst.result_id());
return success();
@ -2588,8 +2582,8 @@ bool FunctionEmitter::EmitConstDefOrWriteToHoistedVar(
if (def_info && def_info->requires_hoisted_def) {
// Emit an assignment of the expression to the hoisted variable.
AddStatementForInstruction(
std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>(namer_.Name(result_id)),
create<ast::AssignmentStatement>(
create<ast::IdentifierExpression>(namer_.Name(result_id)),
std::move(ast_expr.expr)),
inst);
return true;
@ -2654,7 +2648,7 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
// TODO(dneto): Order of evaluation?
auto lhs = MakeExpression(ptr_id);
auto rhs = MakeExpression(value_id);
AddStatementForInstruction(std::make_unique<ast::AssignmentStatement>(
AddStatementForInstruction(create<ast::AssignmentStatement>(
std::move(lhs.expr), std::move(rhs.expr)),
inst);
return success();
@ -2678,9 +2672,9 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
}
case SpvOpPhi: {
// Emit a read from the associated state variable.
auto expr = TypedExpression(
parser_impl_.ConvertType(inst.type_id()),
std::make_unique<ast::IdentifierExpression>(def_info->phi_var));
auto expr =
TypedExpression(parser_impl_.ConvertType(inst.type_id()),
create<ast::IdentifierExpression>(def_info->phi_var));
return EmitConstDefOrWriteToHoistedVar(inst, std::move(expr));
}
case SpvOpFunctionCall:
@ -2714,7 +2708,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
if (binary_op != ast::BinaryOp::kNone) {
auto arg0 = MakeOperand(inst, 0);
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));
TypedExpression result(ast_type, std::move(binary_expr));
return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
@ -2724,8 +2718,8 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
auto unary_op = ast::UnaryOp::kNegation;
if (GetUnaryOp(opcode, &unary_op)) {
auto arg0 = MakeOperand(inst, 0);
auto unary_expr = std::make_unique<ast::UnaryOpExpression>(
unary_op, std::move(arg0.expr));
auto unary_expr =
create<ast::UnaryOpExpression>(unary_op, std::move(arg0.expr));
TypedExpression result(ast_type, std::move(unary_expr));
return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
arg0.type);
@ -2735,10 +2729,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
if (unary_builtin_name != nullptr) {
ast::ExpressionList params;
params.emplace_back(MakeOperand(inst, 0).expr);
return {ast_type,
std::make_unique<ast::CallExpression>(
std::make_unique<ast::IdentifierExpression>(unary_builtin_name),
std::move(params))};
return {ast_type, create<ast::CallExpression>(
create<ast::IdentifierExpression>(unary_builtin_name),
std::move(params))};
}
const auto intrinsic = GetIntrinsic(opcode);
@ -2751,7 +2744,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
}
if (opcode == SpvOpBitcast) {
return {ast_type, std::make_unique<ast::BitcastExpression>(
return {ast_type, create<ast::BitcastExpression>(
ast_type, MakeOperand(inst, 0).expr)};
}
@ -2759,10 +2752,10 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
if (negated_op != ast::BinaryOp::kNone) {
auto arg0 = MakeOperand(inst, 0);
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));
auto negated_expr = std::make_unique<ast::UnaryOpExpression>(
ast::UnaryOp::kNot, std::move(binary_expr));
auto negated_expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot,
std::move(binary_expr));
return {ast_type, std::move(negated_expr)};
}
@ -2780,7 +2773,7 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
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))};
}
@ -2838,15 +2831,14 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
return {};
}
auto func = std::make_unique<ast::IdentifierExpression>(name);
auto func = create<ast::IdentifierExpression>(name);
ast::ExpressionList operands;
// All parameters to GLSL.std.450 extended instructions are IDs.
for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) {
operands.emplace_back(MakeOperand(inst, iarg).expr);
}
auto* ast_type = parser_impl_.ConvertType(inst.type_id());
auto call = std::make_unique<ast::CallExpression>(std::move(func),
std::move(operands));
auto call = create<ast::CallExpression>(std::move(func), std::move(operands));
return {ast_type, std::move(call)};
}
@ -2913,7 +2905,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
// Replace the gl_PerVertex reference with the gl_Position reference
ptr_ty_id = builtin_position_info.member_pointer_type_id;
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);
}
}
@ -2963,13 +2955,13 @@ TypedExpression FunctionEmitter::MakeAccessChain(
<< " is too big. Max handled index is "
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
}
auto letter_index = std::make_unique<ast::IdentifierExpression>(
swizzles[index_const_val]);
next_expr = std::make_unique<ast::MemberAccessorExpression>(
auto letter_index =
create<ast::IdentifierExpression>(swizzles[index_const_val]);
next_expr = create<ast::MemberAccessorExpression>(
std::move(current_expr.expr), std::move(letter_index));
} else {
// 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(MakeOperand(inst, index).expr));
}
@ -2978,20 +2970,20 @@ TypedExpression FunctionEmitter::MakeAccessChain(
break;
case SpvOpTypeMatrix:
// Use array syntax.
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
next_expr = create<ast::ArrayAccessorExpression>(
std::move(current_expr.expr),
std::move(MakeOperand(inst, index).expr));
// All matrix components are the same type.
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
break;
case SpvOpTypeArray:
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
next_expr = create<ast::ArrayAccessorExpression>(
std::move(current_expr.expr),
std::move(MakeOperand(inst, index).expr));
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
break;
case SpvOpTypeRuntimeArray:
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
next_expr = create<ast::ArrayAccessorExpression>(
std::move(current_expr.expr),
std::move(MakeOperand(inst, index).expr));
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(0);
@ -3011,10 +3003,10 @@ TypedExpression FunctionEmitter::MakeAccessChain(
<< pointee_type_id << " having " << num_members << " members";
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)));
next_expr = std::make_unique<ast::MemberAccessorExpression>(
next_expr = create<ast::MemberAccessorExpression>(
std::move(current_expr.expr), std::move(member_access));
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(
static_cast<uint32_t>(index_const_val));
@ -3047,10 +3039,10 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
// expressions.
TypedExpression current_expr(MakeOperand(inst, 0));
auto make_index = [](uint32_t literal) {
auto make_index = [this](uint32_t literal) {
ast::type::U32Type u32;
return std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::UintLiteral>(&u32, literal));
return create<ast::ScalarConstructorExpression>(
create<ast::UintLiteral>(&u32, literal));
};
static const char* swizzles[] = {"x", "y", "z", "w"};
@ -3088,8 +3080,8 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
}
auto letter_index =
std::make_unique<ast::IdentifierExpression>(swizzles[index_val]);
next_expr = std::make_unique<ast::MemberAccessorExpression>(
create<ast::IdentifierExpression>(swizzles[index_val]);
next_expr = create<ast::MemberAccessorExpression>(
std::move(current_expr.expr), std::move(letter_index));
// All vector components are the same type.
current_type_id = current_type_inst->GetSingleWordInOperand(0);
@ -3110,7 +3102,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
}
// Use array syntax.
next_expr = std::make_unique<ast::ArrayAccessorExpression>(
next_expr = create<ast::ArrayAccessorExpression>(
std::move(current_expr.expr), make_index(index_val));
// All matrix components are the same type.
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
// statically checkable. Instead, rely on a runtime index clamp
// 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));
current_type_id = current_type_inst->GetSingleWordInOperand(0);
break;
@ -3135,10 +3127,10 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
<< current_type_id << " having " << num_members << " members";
return {};
}
auto member_access = std::make_unique<ast::IdentifierExpression>(
auto member_access = create<ast::IdentifierExpression>(
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));
current_type_id = current_type_inst->GetSingleWordInOperand(index_val);
break;
@ -3155,14 +3147,14 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
}
std::unique_ptr<ast::Expression> FunctionEmitter::MakeTrue() const {
return std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::BoolLiteral>(parser_impl_.BoolType(), true));
return create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(parser_impl_.BoolType(), true));
}
std::unique_ptr<ast::Expression> FunctionEmitter::MakeFalse() const {
ast::type::BoolType bool_type;
return std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::BoolLiteral>(parser_impl_.BoolType(), false));
return create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(parser_impl_.BoolType(), false));
}
TypedExpression FunctionEmitter::MakeVectorShuffle(
@ -3188,15 +3180,15 @@ TypedExpression FunctionEmitter::MakeVectorShuffle(
const auto index = inst.GetSingleWordInOperand(i);
if (index < vec0_len) {
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,
std::make_unique<ast::IdentifierExpression>(swizzles[index])));
create<ast::IdentifierExpression>(swizzles[index])));
} else if (index < vec0_len + vec1_len) {
const auto sub_index = index - vec0_len;
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,
std::make_unique<ast::IdentifierExpression>(swizzles[sub_index])));
create<ast::IdentifierExpression>(swizzles[sub_index])));
} else if (index == 0xFFFFFFFF) {
// By rule, this maps to OpUndef. Instead, make it zero.
values.emplace_back(parser_impl_.MakeNullValue(result_type->type()));
@ -3206,7 +3198,7 @@ TypedExpression FunctionEmitter::MakeVectorShuffle(
return {};
}
}
return {result_type, std::make_unique<ast::TypeConstructorExpression>(
return {result_type, create<ast::TypeConstructorExpression>(
result_type, std::move(values))};
}
@ -3497,28 +3489,27 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
ast::ExpressionList params;
params.push_back(std::move(arg_expr.expr));
TypedExpression result(expr_type,
std::make_unique<ast::TypeConstructorExpression>(
expr_type, std::move(params)));
TypedExpression result(expr_type, create<ast::TypeConstructorExpression>(
expr_type, std::move(params)));
if (requested_type == expr_type) {
return result;
}
return {requested_type, std::make_unique<ast::BitcastExpression>(
return {requested_type, create<ast::BitcastExpression>(
requested_type, std::move(result.expr))};
}
bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
// 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)));
ast::ExpressionList params;
for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
params.emplace_back(MakeOperand(inst, iarg).expr);
}
auto call_expr = std::make_unique<ast::CallExpression>(std::move(function),
std::move(params));
auto call_expr =
create<ast::CallExpression>(std::move(function), std::move(params));
auto* result_type = parser_impl_.ConvertType(inst.type_id());
if (!result_type) {
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()) {
return nullptr !=
AddStatementForInstruction(
std::make_unique<ast::CallStatement>(std::move(call_expr)),
inst);
create<ast::CallStatement>(std::move(call_expr)), inst);
}
return EmitConstDefOrWriteToHoistedVar(inst,
@ -3541,15 +3531,15 @@ TypedExpression FunctionEmitter::MakeIntrinsicCall(
const auto intrinsic = GetIntrinsic(inst.opcode());
std::ostringstream ss;
ss << intrinsic;
auto ident = std::make_unique<ast::IdentifierExpression>(ss.str());
auto ident = create<ast::IdentifierExpression>(ss.str());
ident->set_intrinsic(intrinsic);
ast::ExpressionList params;
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
params.emplace_back(MakeOperand(inst, iarg).expr);
}
auto call_expr = std::make_unique<ast::CallExpression>(std::move(ident),
std::move(params));
auto call_expr =
create<ast::CallExpression>(std::move(ident), std::move(params));
auto* result_type = parser_impl_.ConvertType(inst.type_id());
if (!result_type) {
Fail() << "internal error: no mapped type result of call: "
@ -3578,10 +3568,9 @@ TypedExpression FunctionEmitter::MakeSimpleSelect(
params.push_back(std::move(operand2.expr));
// The condition goes last.
params.push_back(std::move(condition.expr));
return {operand1.type,
std::make_unique<ast::CallExpression>(
std::make_unique<ast::IdentifierExpression>("select"),
std::move(params))};
return {operand1.type, create<ast::CallExpression>(
create<ast::IdentifierExpression>("select"),
std::move(params))};
}
return {};
}

View File

@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "source/opt/basic_block.h"
@ -799,6 +800,13 @@ class FunctionEmitter {
/// @returns a boolean false expression.
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_;
ast::Module& ast_module_;
spvtools::opt::IRContext& ir_context_;

View File

@ -392,8 +392,7 @@ ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id,
<< ShowType(struct_type_id);
return nullptr;
}
return std::make_unique<ast::StructMemberOffsetDecoration>(decoration[1],
Source{});
return create<ast::StructMemberOffsetDecoration>(decoration[1], Source{});
case SpvDecorationNonReadable:
// WGSL doesn't have a member decoration for this. Silently drop it.
return nullptr;
@ -782,8 +781,7 @@ bool ParserImpl::ApplyArrayDecorations(
<< ": multiple ArrayStride decorations";
}
ast::ArrayDecorationList decos;
decos.push_back(
std::make_unique<ast::StrideDecoration>(stride, Source{}));
decos.push_back(create<ast::StrideDecoration>(stride, Source{}));
ast_type->set_decorations(std::move(decos));
} else {
return Fail() << "invalid array type ID " << type_id
@ -806,10 +804,10 @@ ast::type::Type* ParserImpl::ConvertType(
const auto decoration = struct_decorations[0][0];
if (decoration == SpvDecorationBlock) {
ast_struct_decorations.push_back(
std::make_unique<ast::StructBlockDecoration>(Source{}));
create<ast::StructBlockDecoration>(Source{}));
} else if (decoration == SpvDecorationBufferBlock) {
ast_struct_decorations.push_back(
std::make_unique<ast::StructBlockDecoration>(Source{}));
create<ast::StructBlockDecoration>(Source{}));
remap_buffer_block_type_.insert(type_id);
} else {
Fail() << "struct with ID " << type_id
@ -879,14 +877,14 @@ ast::type::Type* ParserImpl::ConvertType(
++num_non_writable_members;
}
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));
ast_members.push_back(std::move(ast_struct_member));
}
// Now make the struct.
auto ast_struct = std::make_unique<ast::Struct>(
std::move(ast_struct_decorations), std::move(ast_members));
auto ast_struct = create<ast::Struct>(std::move(ast_struct_decorations),
std::move(ast_members));
namer_.SuggestSanitizedName(type_id, "S");
auto ast_struct_type = std::make_unique<ast::type::StructType>(
@ -971,8 +969,8 @@ bool ParserImpl::EmitScalarSpecConstants() {
case SpvOpSpecConstantTrue:
case SpvOpSpecConstantFalse: {
ast_type = ConvertType(inst.type_id());
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::BoolLiteral>(
ast_expr =
create<ast::ScalarConstructorExpression>(create<ast::BoolLiteral>(
ast_type, inst.opcode() == SpvOpSpecConstantTrue));
break;
}
@ -980,19 +978,19 @@ bool ParserImpl::EmitScalarSpecConstants() {
ast_type = ConvertType(inst.type_id());
const uint32_t literal_value = inst.GetSingleWordInOperand(0);
if (ast_type->IsI32()) {
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(
ast_expr =
create<ast::ScalarConstructorExpression>(create<ast::SintLiteral>(
ast_type, static_cast<int32_t>(literal_value)));
} else if (ast_type->IsU32()) {
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::UintLiteral>(
ast_expr =
create<ast::ScalarConstructorExpression>(create<ast::UintLiteral>(
ast_type, static_cast<uint32_t>(literal_value)));
} else if (ast_type->IsF32()) {
float float_value;
// Copy the bits so we can read them as a float.
std::memcpy(&float_value, &literal_value, sizeof(float_value));
ast_expr = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(ast_type, float_value));
ast_expr = create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(ast_type, float_value));
} else {
return Fail() << " invalid result type for OpSpecConstant "
<< inst.PrettyPrint();
@ -1008,8 +1006,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
ast::VariableDecorationList spec_id_decos;
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
auto cid =
std::make_unique<ast::ConstantIdDecoration>(deco[1], Source{});
auto cid = create<ast::ConstantIdDecoration>(deco[1], Source{});
spec_id_decos.push_back(std::move(cid));
break;
}
@ -1020,8 +1017,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
ast_var->set_constructor(std::move(ast_expr));
ast_module_.AddGlobalVariable(std::move(ast_var));
} else {
auto ast_deco_var =
std::make_unique<ast::DecoratedVariable>(std::move(ast_var));
auto ast_deco_var = create<ast::DecoratedVariable>(std::move(ast_var));
ast_deco_var->set_is_const(true);
ast_deco_var->set_constructor(std::move(ast_expr));
ast_deco_var->set_decorations(std::move(spec_id_decos));
@ -1140,13 +1136,13 @@ bool ParserImpl::EmitModuleScopeVariables() {
// Make sure the variable has a name.
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
"gl_Position");
auto var = std::make_unique<ast::DecoratedVariable>(MakeVariable(
auto var = create<ast::DecoratedVariable>(MakeVariable(
builtin_position_.per_vertex_var_id,
enum_converter_.ToStorageClass(builtin_position_.storage_class),
ConvertType(builtin_position_.member_type_id)));
ast::VariableDecorationList decos;
decos.push_back(std::make_unique<ast::BuiltinDecoration>(
ast::Builtin::kPosition, Source{}));
decos.push_back(
create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
var->set_decorations(std::move(decos));
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));
}
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;
for (auto& deco : GetDecorationsFor(id)) {
@ -1191,7 +1187,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
return nullptr;
}
ast_decorations.emplace_back(
std::make_unique<ast::BuiltinDecoration>(ast_builtin, Source{}));
create<ast::BuiltinDecoration>(ast_builtin, Source{}));
}
if (deco[0] == SpvDecorationLocation) {
if (deco.size() != 2) {
@ -1200,7 +1196,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
return nullptr;
}
ast_decorations.emplace_back(
std::make_unique<ast::LocationDecoration>(deco[1], Source{}));
create<ast::LocationDecoration>(deco[1], Source{}));
}
if (deco[0] == SpvDecorationDescriptorSet) {
if (deco.size() == 1) {
@ -1209,7 +1205,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
return nullptr;
}
ast_decorations.emplace_back(
std::make_unique<ast::SetDecoration>(deco[1], Source{}));
create<ast::SetDecoration>(deco[1], Source{}));
}
if (deco[0] == SpvDecorationBinding) {
if (deco.size() == 1) {
@ -1218,12 +1214,11 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
return nullptr;
}
ast_decorations.emplace_back(
std::make_unique<ast::BindingDecoration>(deco[1], Source{}));
create<ast::BindingDecoration>(deco[1], Source{}));
}
}
if (!ast_decorations.empty()) {
auto decorated_var =
std::make_unique<ast::DecoratedVariable>(std::move(ast_var));
auto decorated_var = create<ast::DecoratedVariable>(std::move(ast_var));
decorated_var->set_decorations(std::move(ast_decorations));
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.
// See https://bugs.chromium.org/p/tint/issues/detail?id=34
if (ast_type->IsU32()) {
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::UintLiteral>(
ast_type, spirv_const->GetU32()))};
return {ast_type,
create<ast::ScalarConstructorExpression>(
create<ast::UintLiteral>(ast_type, spirv_const->GetU32()))};
}
if (ast_type->IsI32()) {
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(
ast_type, spirv_const->GetS32()))};
return {ast_type,
create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(ast_type, spirv_const->GetS32()))};
}
if (ast_type->IsF32()) {
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(
ast_type, spirv_const->GetFloat()))};
return {ast_type,
create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(ast_type, spirv_const->GetFloat()))};
}
if (ast_type->IsBool()) {
const bool value = spirv_const->AsNullConstant()
? false
: spirv_const->AsBoolConstant()->value();
return {ast_type, std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::BoolLiteral>(ast_type, value))};
return {ast_type, create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(ast_type, value))};
}
auto* spirv_composite_const = spirv_const->AsCompositeConstant();
if (spirv_composite_const != nullptr) {
@ -1308,8 +1303,8 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
ast_components.emplace_back(std::move(ast_component.expr));
}
return {original_ast_type,
std::make_unique<ast::TypeConstructorExpression>(
original_ast_type, std::move(ast_components))};
create<ast::TypeConstructorExpression>(original_ast_type,
std::move(ast_components))};
}
auto* spirv_null_const = spirv_const->AsNullConstant();
if (spirv_null_const != nullptr) {
@ -1336,20 +1331,20 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
type = type->UnwrapIfNeeded();
if (type->IsBool()) {
return std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::BoolLiteral>(type, false));
return create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(type, false));
}
if (type->IsU32()) {
return std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::UintLiteral>(type, 0u));
return create<ast::ScalarConstructorExpression>(
create<ast::UintLiteral>(type, 0u));
}
if (type->IsI32()) {
return std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(type, 0));
return create<ast::ScalarConstructorExpression>(
create<ast::SintLiteral>(type, 0));
}
if (type->IsF32()) {
return std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(type, 0.0f));
return create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(type, 0.0f));
}
if (type->IsVector()) {
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) {
ast_components.emplace_back(MakeNullValue(vec_ty->type()));
}
return std::make_unique<ast::TypeConstructorExpression>(
type, std::move(ast_components));
return create<ast::TypeConstructorExpression>(type,
std::move(ast_components));
}
if (type->IsMatrix()) {
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) {
ast_components.emplace_back(MakeNullValue(column_ty));
}
return std::make_unique<ast::TypeConstructorExpression>(
type, std::move(ast_components));
return create<ast::TypeConstructorExpression>(type,
std::move(ast_components));
}
if (type->IsArray()) {
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) {
ast_components.emplace_back(MakeNullValue(arr_ty->type()));
}
return std::make_unique<ast::TypeConstructorExpression>(
original_type, std::move(ast_components));
return create<ast::TypeConstructorExpression>(original_type,
std::move(ast_components));
}
if (type->IsStruct()) {
auto* struct_ty = type->AsStruct();
@ -1388,8 +1383,8 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
for (auto& member : struct_ty->impl()->members()) {
ast_components.emplace_back(MakeNullValue(member->type()));
}
return std::make_unique<ast::TypeConstructorExpression>(
original_type, std::move(ast_components));
return create<ast::TypeConstructorExpression>(original_type,
std::move(ast_components));
}
Fail() << "can't make null value for type: " << type->type_name();
return nullptr;
@ -1416,15 +1411,15 @@ TypedExpression ParserImpl::RectifyOperandSignedness(SpvOp op,
auto* unsigned_ty = unsigned_type_for_[type];
if (unsigned_ty != nullptr) {
// Conversion is required.
return {unsigned_ty, std::make_unique<ast::BitcastExpression>(
return {unsigned_ty, create<ast::BitcastExpression>(
unsigned_ty, std::move(expr.expr))};
}
} else if (requires_signed) {
auto* signed_ty = signed_type_for_[type];
if (signed_ty != nullptr) {
// Conversion is required.
return {signed_ty, std::make_unique<ast::BitcastExpression>(
signed_ty, std::move(expr.expr))};
return {signed_ty,
create<ast::BitcastExpression>(signed_ty, std::move(expr.expr))};
}
}
// We should not reach here.
@ -1487,8 +1482,8 @@ TypedExpression ParserImpl::RectifyForcedResultType(
if ((forced_result_ty == nullptr) || (forced_result_ty == expr.type)) {
return expr;
}
return {expr.type, std::make_unique<ast::BitcastExpression>(
expr.type, std::move(expr.expr))};
return {expr.type,
create<ast::BitcastExpression>(expr.type, std::move(expr.expr))};
}
bool ParserImpl::EmitFunctions() {

View File

@ -432,6 +432,13 @@ class ParserImpl : Reader {
bool ApplyArrayDecorations(const spvtools::opt::analysis::Type* spv_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
std::vector<uint32_t> spv_binary_;