mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
Replace use of std::unique_ptr<T> with T* for AST nodes
This is a minimal effort to fix up the code. There's substantial code cleanup which can now be done, which is done in the next change. Bug: tint:322 Change-Id: Iafcf5e814837d9534889e8c21333de4931a19cfa Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32864 Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
0613890eed
commit
b053acf796
@@ -16,6 +16,7 @@
|
||||
#define SRC_READER_READER_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "src/ast/module.h"
|
||||
#include "src/context.h"
|
||||
@@ -58,6 +59,15 @@ class Reader {
|
||||
/// @param diags the list of diagnostic messages
|
||||
void set_diagnostics(const diag::List& diags) { diags_ = diags; }
|
||||
|
||||
/// Creates a new `ast::Node` owned by the Context. When the Context is
|
||||
/// destructed, the `ast::Node` will also be destructed.
|
||||
/// @param args the arguments to pass to the type constructor
|
||||
/// @returns the node pointer
|
||||
template <typename T, typename... ARGS>
|
||||
T* create(ARGS&&... args) const {
|
||||
return ctx_.create<T>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// The Tint context object
|
||||
Context& ctx_;
|
||||
|
||||
|
||||
@@ -487,8 +487,8 @@ FunctionEmitter::StatementBlock::StatementBlock(
|
||||
const Construct* construct,
|
||||
uint32_t end_id,
|
||||
CompletionAction completion_action,
|
||||
std::unique_ptr<ast::BlockStatement> statements,
|
||||
std::unique_ptr<ast::CaseStatementList> cases)
|
||||
ast::BlockStatement* statements,
|
||||
ast::CaseStatementList* cases)
|
||||
: construct_(construct),
|
||||
end_id_(end_id),
|
||||
completion_action_(completion_action),
|
||||
@@ -514,8 +514,8 @@ 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 = create<ast::IdentifierExpression>(guard_name);
|
||||
auto body = create<ast::BlockStatement>();
|
||||
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();
|
||||
@@ -528,8 +528,8 @@ void FunctionEmitter::PushGuard(const std::string& guard_name,
|
||||
void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
|
||||
assert(!statements_stack_.empty());
|
||||
const auto& top = statements_stack_.back();
|
||||
auto cond = MakeTrue();
|
||||
auto body = create<ast::BlockStatement>();
|
||||
auto* cond = MakeTrue();
|
||||
auto* body = create<ast::BlockStatement>();
|
||||
auto* const guard_stmt =
|
||||
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
|
||||
->AsIf();
|
||||
@@ -542,13 +542,12 @@ void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
|
||||
|
||||
const ast::BlockStatement* FunctionEmitter::ast_body() {
|
||||
assert(!statements_stack_.empty());
|
||||
return statements_stack_[0].statements_.get();
|
||||
return statements_stack_[0].statements_;
|
||||
}
|
||||
|
||||
ast::Statement* FunctionEmitter::AddStatement(
|
||||
std::unique_ptr<ast::Statement> statement) {
|
||||
ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
|
||||
assert(!statements_stack_.empty());
|
||||
auto* result = statement.get();
|
||||
auto* result = statement;
|
||||
if (result != nullptr) {
|
||||
statements_stack_.back().statements_->append(std::move(statement));
|
||||
}
|
||||
@@ -556,7 +555,7 @@ ast::Statement* FunctionEmitter::AddStatement(
|
||||
}
|
||||
|
||||
ast::Statement* FunctionEmitter::AddStatementForInstruction(
|
||||
std::unique_ptr<ast::Statement> statement,
|
||||
ast::Statement* statement,
|
||||
const spvtools::opt::Instruction& inst) {
|
||||
auto* node = AddStatement(std::move(statement));
|
||||
ApplySourceForInstruction(node, inst);
|
||||
@@ -565,7 +564,7 @@ ast::Statement* FunctionEmitter::AddStatementForInstruction(
|
||||
|
||||
ast::Statement* FunctionEmitter::LastStatement() {
|
||||
assert(!statements_stack_.empty());
|
||||
const auto& statement_list = statements_stack_.back().statements_;
|
||||
auto* statement_list = statements_stack_.back().statements_;
|
||||
assert(!statement_list->empty());
|
||||
return statement_list->last();
|
||||
}
|
||||
@@ -593,7 +592,7 @@ bool FunctionEmitter::Emit() {
|
||||
"element but has "
|
||||
<< statements_stack_.size();
|
||||
}
|
||||
auto body = std::move(statements_stack_[0].statements_);
|
||||
auto* body = std::move(statements_stack_[0].statements_);
|
||||
parser_impl_.get_module().functions().back()->set_body(std::move(body));
|
||||
// Maintain the invariant by repopulating the one and only element.
|
||||
statements_stack_.clear();
|
||||
@@ -632,7 +631,7 @@ bool FunctionEmitter::EmitFunctionDeclaration() {
|
||||
[this, &ast_params](const spvtools::opt::Instruction* param) {
|
||||
auto* ast_type = parser_impl_.ConvertType(param->type_id());
|
||||
if (ast_type != nullptr) {
|
||||
auto ast_param = parser_impl_.MakeVariable(
|
||||
auto* ast_param = parser_impl_.MakeVariable(
|
||||
param->result_id(), ast::StorageClass::kNone, ast_type);
|
||||
// Parameters are treated as const declarations.
|
||||
ast_param->set_is_const(true);
|
||||
@@ -648,8 +647,8 @@ bool FunctionEmitter::EmitFunctionDeclaration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ast_fn = create<ast::Function>(name, std::move(ast_params), ret_ty,
|
||||
create<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(
|
||||
@@ -1695,7 +1694,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
|
||||
if (failed()) {
|
||||
return false;
|
||||
}
|
||||
auto var = parser_impl_.MakeVariable(
|
||||
auto* var = parser_impl_.MakeVariable(
|
||||
inst.result_id(), ast::StorageClass::kFunction, var_store_type);
|
||||
if (inst.NumInOperands() > 1) {
|
||||
// SPIR-V initializers are always constants.
|
||||
@@ -1705,7 +1704,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
|
||||
parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
|
||||
.expr);
|
||||
}
|
||||
auto var_decl_stmt = create<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());
|
||||
@@ -1718,9 +1717,9 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
|
||||
return {};
|
||||
}
|
||||
if (identifier_values_.count(id) || parser_impl_.IsScalarSpecConstant(id)) {
|
||||
return TypedExpression(
|
||||
return TypedExpression{
|
||||
parser_impl_.ConvertType(def_use_mgr_->GetDef(id)->type_id()),
|
||||
create<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]);
|
||||
@@ -1739,9 +1738,9 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
|
||||
switch (inst->opcode()) {
|
||||
case SpvOpVariable:
|
||||
// This occurs for module-scope variables.
|
||||
return TypedExpression(
|
||||
return TypedExpression{
|
||||
parser_impl_.ConvertType(inst->type_id()),
|
||||
create<ast::IdentifierExpression>(namer_.Name(inst->result_id())));
|
||||
create<ast::IdentifierExpression>(namer_.Name(inst->result_id()))};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1970,17 +1969,17 @@ 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 = create<ast::Variable>(
|
||||
auto* guard_var = create<ast::Variable>(
|
||||
guard_name, ast::StorageClass::kFunction, parser_impl_.BoolType());
|
||||
guard_var->set_constructor(MakeTrue());
|
||||
auto guard_decl = create<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 = create<ast::BlockStatement>();
|
||||
auto* cond = MakeExpression(condition_id).expr;
|
||||
auto* body = create<ast::BlockStatement>();
|
||||
auto* const if_stmt =
|
||||
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
|
||||
->AsIf();
|
||||
@@ -2108,7 +2107,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_ = create<ast::CaseStatementList>();
|
||||
statements_stack_.back().cases_ = std::make_unique<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();
|
||||
@@ -2156,7 +2155,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
|
||||
// on the case statement list.
|
||||
cases->emplace_back(
|
||||
create<ast::CaseStatement>(create<ast::BlockStatement>()));
|
||||
auto* clause = cases->back().get();
|
||||
auto* clause = cases->back();
|
||||
|
||||
// Create a list of integer literals for the selector values leading to
|
||||
// this case clause.
|
||||
@@ -2192,9 +2191,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 = create<ast::BlockStatement>();
|
||||
auto* stmts = create<ast::BlockStatement>();
|
||||
stmts->append(create<ast::FallthroughStatement>());
|
||||
auto case_stmt = create<ast::CaseStatement>(std::move(stmts));
|
||||
auto* case_stmt = create<ast::CaseStatement>(std::move(stmts));
|
||||
cases->emplace_back(std::move(case_stmt));
|
||||
}
|
||||
|
||||
@@ -2287,7 +2286,7 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
|
||||
const EdgeKind false_kind = block_info.succ_edge.find(false_dest)->second;
|
||||
auto* const true_info = GetBlockInfo(true_dest);
|
||||
auto* const false_info = GetBlockInfo(false_dest);
|
||||
auto cond = MakeExpression(terminator.GetSingleWordInOperand(0)).expr;
|
||||
auto* cond = MakeExpression(terminator.GetSingleWordInOperand(0)).expr;
|
||||
|
||||
// We have two distinct destinations. But we only get here if this
|
||||
// is a normal terminator; in particular the source block is *not* the
|
||||
@@ -2313,9 +2312,9 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
|
||||
// requiring a flow guard, then get that flow guard name too. It will
|
||||
// come from at most one of these two branches.
|
||||
std::string flow_guard;
|
||||
auto true_branch =
|
||||
auto* true_branch =
|
||||
MakeBranchDetailed(block_info, *true_info, false, &flow_guard);
|
||||
auto false_branch =
|
||||
auto* false_branch =
|
||||
MakeBranchDetailed(block_info, *false_info, false, &flow_guard);
|
||||
|
||||
AddStatement(MakeSimpleIf(std::move(cond), std::move(true_branch),
|
||||
@@ -2334,7 +2333,7 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
|
||||
return success();
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
|
||||
ast::Statement* FunctionEmitter::MakeBranchDetailed(
|
||||
const BlockInfo& src_info,
|
||||
const BlockInfo& dest_info,
|
||||
bool forced,
|
||||
@@ -2405,25 +2404,24 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
|
||||
// Unconditional forward branch is implicit.
|
||||
break;
|
||||
}
|
||||
return {nullptr};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::Statement> FunctionEmitter::MakeSimpleIf(
|
||||
std::unique_ptr<ast::Expression> condition,
|
||||
std::unique_ptr<ast::Statement> then_stmt,
|
||||
std::unique_ptr<ast::Statement> else_stmt) const {
|
||||
ast::Statement* FunctionEmitter::MakeSimpleIf(ast::Expression* condition,
|
||||
ast::Statement* then_stmt,
|
||||
ast::Statement* else_stmt) const {
|
||||
if ((then_stmt == nullptr) && (else_stmt == nullptr)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto if_stmt = create<ast::IfStatement>(std::move(condition),
|
||||
create<ast::BlockStatement>());
|
||||
auto* if_stmt = create<ast::IfStatement>(std::move(condition),
|
||||
create<ast::BlockStatement>());
|
||||
if (then_stmt != nullptr) {
|
||||
auto stmts = create<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 = create<ast::BlockStatement>();
|
||||
auto* stmts = create<ast::BlockStatement>();
|
||||
stmts->append(std::move(else_stmt));
|
||||
ast::ElseStatementList else_stmts;
|
||||
else_stmts.emplace_back(
|
||||
@@ -2435,7 +2433,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeSimpleIf(
|
||||
|
||||
bool FunctionEmitter::EmitConditionalCaseFallThrough(
|
||||
const BlockInfo& src_info,
|
||||
std::unique_ptr<ast::Expression> cond,
|
||||
ast::Expression* cond,
|
||||
EdgeKind other_edge_kind,
|
||||
const BlockInfo& other_dest,
|
||||
bool fall_through_is_true_branch) {
|
||||
@@ -2462,7 +2460,7 @@ bool FunctionEmitter::EmitConditionalCaseFallThrough(
|
||||
<< "internal error: normal terminator OpBranchConditional has "
|
||||
"both backedge and fallthrough edges. Violates nesting rule";
|
||||
}
|
||||
auto other_branch = MakeForcedBranch(src_info, other_dest);
|
||||
auto* other_branch = MakeForcedBranch(src_info, other_dest);
|
||||
if (other_branch == nullptr) {
|
||||
return Fail() << "internal error: expected a branch for edge-kind "
|
||||
<< int(other_edge_kind);
|
||||
@@ -2512,7 +2510,7 @@ 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 =
|
||||
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)));
|
||||
@@ -2560,7 +2558,7 @@ bool FunctionEmitter::EmitConstDefinition(
|
||||
if (!ast_expr.expr) {
|
||||
return false;
|
||||
}
|
||||
auto ast_const = parser_impl_.MakeVariable(
|
||||
auto* ast_const = parser_impl_.MakeVariable(
|
||||
inst.result_id(), ast::StorageClass::kNone, ast_expr.type);
|
||||
if (!ast_const) {
|
||||
return false;
|
||||
@@ -2672,9 +2670,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()),
|
||||
create<ast::IdentifierExpression>(def_info->phi_var));
|
||||
TypedExpression expr{
|
||||
parser_impl_.ConvertType(inst.type_id()),
|
||||
create<ast::IdentifierExpression>(def_info->phi_var)};
|
||||
return EmitConstDefOrWriteToHoistedVar(inst, std::move(expr));
|
||||
}
|
||||
case SpvOpFunctionCall:
|
||||
@@ -2708,9 +2706,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||
if (binary_op != ast::BinaryOp::kNone) {
|
||||
auto arg0 = MakeOperand(inst, 0);
|
||||
auto arg1 = MakeOperand(inst, 1);
|
||||
auto binary_expr = create<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));
|
||||
TypedExpression result{ast_type, std::move(binary_expr)};
|
||||
return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
|
||||
arg0.type);
|
||||
}
|
||||
@@ -2718,9 +2716,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||
auto unary_op = ast::UnaryOp::kNegation;
|
||||
if (GetUnaryOp(opcode, &unary_op)) {
|
||||
auto arg0 = MakeOperand(inst, 0);
|
||||
auto unary_expr =
|
||||
auto* unary_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,
|
||||
arg0.type);
|
||||
}
|
||||
@@ -2752,10 +2750,10 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
||||
if (negated_op != ast::BinaryOp::kNone) {
|
||||
auto arg0 = MakeOperand(inst, 0);
|
||||
auto arg1 = MakeOperand(inst, 1);
|
||||
auto binary_expr = create<ast::BinaryExpression>(
|
||||
auto* binary_expr = create<ast::BinaryExpression>(
|
||||
negated_op, std::move(arg0.expr), std::move(arg1.expr));
|
||||
auto negated_expr = create<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)};
|
||||
}
|
||||
|
||||
@@ -2831,14 +2829,15 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
|
||||
return {};
|
||||
}
|
||||
|
||||
auto func = create<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 = create<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)};
|
||||
}
|
||||
|
||||
@@ -2928,7 +2927,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||
constants[index] ? constants[index]->AsIntConstant() : nullptr;
|
||||
const int64_t index_const_val =
|
||||
index_const ? index_const->GetSignExtendedValue() : 0;
|
||||
std::unique_ptr<ast::Expression> next_expr;
|
||||
ast::Expression* next_expr = nullptr;
|
||||
|
||||
const auto* pointee_type_inst = def_use_mgr_->GetDef(pointee_type_id);
|
||||
if (!pointee_type_inst) {
|
||||
@@ -2955,7 +2954,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||
<< " is too big. Max handled index is "
|
||||
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
||||
}
|
||||
auto letter_index =
|
||||
auto* letter_index =
|
||||
create<ast::IdentifierExpression>(swizzles[index_const_val]);
|
||||
next_expr = create<ast::MemberAccessorExpression>(
|
||||
std::move(current_expr.expr), std::move(letter_index));
|
||||
@@ -3003,7 +3002,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||
<< pointee_type_id << " having " << num_members << " members";
|
||||
return {};
|
||||
}
|
||||
auto member_access = create<ast::IdentifierExpression>(
|
||||
auto* member_access = create<ast::IdentifierExpression>(
|
||||
namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val)));
|
||||
|
||||
next_expr = create<ast::MemberAccessorExpression>(
|
||||
@@ -3022,7 +3021,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
|
||||
auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id);
|
||||
assert(ast_pointer_type);
|
||||
assert(ast_pointer_type->IsPointer());
|
||||
current_expr.reset(TypedExpression(ast_pointer_type, std::move(next_expr)));
|
||||
current_expr = TypedExpression{ast_pointer_type, std::move(next_expr)};
|
||||
}
|
||||
return current_expr;
|
||||
}
|
||||
@@ -3062,7 +3061,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||
<< " indices: " << inst.PrettyPrint();
|
||||
return {};
|
||||
}
|
||||
std::unique_ptr<ast::Expression> next_expr;
|
||||
ast::Expression* next_expr = nullptr;
|
||||
switch (current_type_inst->opcode()) {
|
||||
case SpvOpTypeVector: {
|
||||
// Try generating a MemberAccessor expression. That result in something
|
||||
@@ -3079,7 +3078,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||
<< " is too big. Max handled index is "
|
||||
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
|
||||
}
|
||||
auto letter_index =
|
||||
auto* letter_index =
|
||||
create<ast::IdentifierExpression>(swizzles[index_val]);
|
||||
next_expr = create<ast::MemberAccessorExpression>(
|
||||
std::move(current_expr.expr), std::move(letter_index));
|
||||
@@ -3127,7 +3126,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||
<< current_type_id << " having " << num_members << " members";
|
||||
return {};
|
||||
}
|
||||
auto member_access = create<ast::IdentifierExpression>(
|
||||
auto* member_access = create<ast::IdentifierExpression>(
|
||||
namer_.GetMemberName(current_type_id, uint32_t(index_val)));
|
||||
|
||||
next_expr = create<ast::MemberAccessorExpression>(
|
||||
@@ -3140,18 +3139,18 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
|
||||
<< current_type_inst->PrettyPrint();
|
||||
return {};
|
||||
}
|
||||
current_expr.reset(TypedExpression(
|
||||
parser_impl_.ConvertType(current_type_id), std::move(next_expr)));
|
||||
current_expr = TypedExpression{parser_impl_.ConvertType(current_type_id),
|
||||
std::move(next_expr)};
|
||||
}
|
||||
return current_expr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::Expression> FunctionEmitter::MakeTrue() const {
|
||||
ast::Expression* FunctionEmitter::MakeTrue() const {
|
||||
return create<ast::ScalarConstructorExpression>(
|
||||
create<ast::BoolLiteral>(parser_impl_.BoolType(), true));
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::Expression> FunctionEmitter::MakeFalse() const {
|
||||
ast::Expression* FunctionEmitter::MakeFalse() const {
|
||||
ast::type::BoolType bool_type;
|
||||
return create<ast::ScalarConstructorExpression>(
|
||||
create<ast::BoolLiteral>(parser_impl_.BoolType(), false));
|
||||
@@ -3489,8 +3488,8 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
|
||||
|
||||
ast::ExpressionList params;
|
||||
params.push_back(std::move(arg_expr.expr));
|
||||
TypedExpression result(expr_type, create<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;
|
||||
@@ -3501,14 +3500,14 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
|
||||
|
||||
bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
|
||||
// We ignore function attributes such as Inline, DontInline, Pure, Const.
|
||||
auto function = create<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 =
|
||||
auto* call_expr =
|
||||
create<ast::CallExpression>(std::move(function), std::move(params));
|
||||
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||
if (!result_type) {
|
||||
@@ -3531,14 +3530,14 @@ TypedExpression FunctionEmitter::MakeIntrinsicCall(
|
||||
const auto intrinsic = GetIntrinsic(inst.opcode());
|
||||
std::ostringstream ss;
|
||||
ss << intrinsic;
|
||||
auto ident = create<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 =
|
||||
auto* call_expr =
|
||||
create<ast::CallExpression>(std::move(ident), std::move(params));
|
||||
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||
if (!result_type) {
|
||||
|
||||
@@ -496,8 +496,8 @@ class FunctionEmitter {
|
||||
/// @param src_info the source block
|
||||
/// @param dest_info the destination block
|
||||
/// @returns the new statement, or a null statement
|
||||
std::unique_ptr<ast::Statement> MakeBranch(const BlockInfo& src_info,
|
||||
const BlockInfo& dest_info) const {
|
||||
ast::Statement* MakeBranch(const BlockInfo& src_info,
|
||||
const BlockInfo& dest_info) const {
|
||||
return MakeBranchDetailed(src_info, dest_info, false, nullptr);
|
||||
}
|
||||
|
||||
@@ -507,9 +507,8 @@ class FunctionEmitter {
|
||||
/// @param src_info the source block
|
||||
/// @param dest_info the destination block
|
||||
/// @returns the new statement, or a null statement
|
||||
std::unique_ptr<ast::Statement> MakeForcedBranch(
|
||||
const BlockInfo& src_info,
|
||||
const BlockInfo& dest_info) const {
|
||||
ast::Statement* MakeForcedBranch(const BlockInfo& src_info,
|
||||
const BlockInfo& dest_info) const {
|
||||
return MakeBranchDetailed(src_info, dest_info, true, nullptr);
|
||||
}
|
||||
|
||||
@@ -527,11 +526,10 @@ class FunctionEmitter {
|
||||
/// @param forced if true, always emit the branch (if it exists in WGSL)
|
||||
/// @param flow_guard_name_ptr return parameter for control flow guard name
|
||||
/// @returns the new statement, or a null statement
|
||||
std::unique_ptr<ast::Statement> MakeBranchDetailed(
|
||||
const BlockInfo& src_info,
|
||||
const BlockInfo& dest_info,
|
||||
bool forced,
|
||||
std::string* flow_guard_name_ptr) const;
|
||||
ast::Statement* MakeBranchDetailed(const BlockInfo& src_info,
|
||||
const BlockInfo& dest_info,
|
||||
bool forced,
|
||||
std::string* flow_guard_name_ptr) const;
|
||||
|
||||
/// Returns a new if statement with the given statements as the then-clause
|
||||
/// and the else-clause. Either or both clauses might be nullptr. If both
|
||||
@@ -540,10 +538,9 @@ class FunctionEmitter {
|
||||
/// @param then_stmt the statement for the then clause of the if, or nullptr
|
||||
/// @param else_stmt the statement for the else clause of the if, or nullptr
|
||||
/// @returns the new statement, or nullptr
|
||||
std::unique_ptr<ast::Statement> MakeSimpleIf(
|
||||
std::unique_ptr<ast::Expression> condition,
|
||||
std::unique_ptr<ast::Statement> then_stmt,
|
||||
std::unique_ptr<ast::Statement> else_stmt) const;
|
||||
ast::Statement* MakeSimpleIf(ast::Expression* condition,
|
||||
ast::Statement* then_stmt,
|
||||
ast::Statement* else_stmt) const;
|
||||
|
||||
/// Emits the statements for an normal-terminator OpBranchConditional
|
||||
/// where one branch is a case fall through (the true branch if and only
|
||||
@@ -558,7 +555,7 @@ class FunctionEmitter {
|
||||
/// branch
|
||||
/// @returns the false if emission fails
|
||||
bool EmitConditionalCaseFallThrough(const BlockInfo& src_info,
|
||||
std::unique_ptr<ast::Expression> cond,
|
||||
ast::Expression* cond,
|
||||
EdgeKind other_edge_kind,
|
||||
const BlockInfo& other_dest,
|
||||
bool fall_through_is_true_branch);
|
||||
@@ -719,7 +716,7 @@ class FunctionEmitter {
|
||||
/// Does nothing if the statement is null.
|
||||
/// @param statement the new statement
|
||||
/// @returns a pointer to the statement.
|
||||
ast::Statement* AddStatement(std::unique_ptr<ast::Statement> statement);
|
||||
ast::Statement* AddStatement(ast::Statement* statement);
|
||||
|
||||
/// Appends a new statement to the top of the statement stack, and attaches
|
||||
/// source location information from the given instruction. Does nothing if
|
||||
@@ -727,7 +724,7 @@ class FunctionEmitter {
|
||||
/// @param statement the new statement
|
||||
/// @returns a pointer to the statement.
|
||||
ast::Statement* AddStatementForInstruction(
|
||||
std::unique_ptr<ast::Statement> statement,
|
||||
ast::Statement* statement,
|
||||
const spvtools::opt::Instruction& inst);
|
||||
|
||||
/// Sets the source information for the given instruction to the given
|
||||
@@ -750,8 +747,8 @@ class FunctionEmitter {
|
||||
StatementBlock(const Construct* construct,
|
||||
uint32_t end_id,
|
||||
CompletionAction completion_action,
|
||||
std::unique_ptr<ast::BlockStatement> statements,
|
||||
std::unique_ptr<ast::CaseStatementList> cases);
|
||||
ast::BlockStatement* statements,
|
||||
ast::CaseStatementList* cases);
|
||||
StatementBlock(StatementBlock&&);
|
||||
~StatementBlock();
|
||||
|
||||
@@ -767,12 +764,12 @@ class FunctionEmitter {
|
||||
// Only one of |statements| or |cases| is active.
|
||||
|
||||
// The list of statements being built, if this construct is not a switch.
|
||||
std::unique_ptr<ast::BlockStatement> statements_;
|
||||
ast::BlockStatement* statements_ = nullptr;
|
||||
// The list of switch cases being built, if this construct is a switch.
|
||||
// The algorithm will cache a pointer to the vector. We want that pointer
|
||||
// to be stable no matter how |statements_stack_| is resized. That's
|
||||
// why we make this a unique_ptr rather than just a plain vector.
|
||||
std::unique_ptr<ast::CaseStatementList> cases_;
|
||||
std::unique_ptr<ast::CaseStatementList> cases_ = nullptr;
|
||||
};
|
||||
|
||||
/// Pushes an empty statement block onto the statements stack.
|
||||
@@ -795,16 +792,19 @@ class FunctionEmitter {
|
||||
void PushTrueGuard(uint32_t end_id);
|
||||
|
||||
/// @returns a boolean true expression.
|
||||
std::unique_ptr<ast::Expression> MakeTrue() const;
|
||||
ast::Expression* MakeTrue() const;
|
||||
|
||||
/// @returns a boolean false expression.
|
||||
std::unique_ptr<ast::Expression> MakeFalse() const;
|
||||
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`
|
||||
/// Creates a new `ast::Node` owned by the Context. When the Context is
|
||||
/// destructed, the `ast::Node` will also be destructed.
|
||||
/// @param args the arguments to pass to the type constructor
|
||||
/// @returns the node pointer
|
||||
template <typename T, typename... ARGS>
|
||||
std::unique_ptr<T> create(ARGS&&... args) const {
|
||||
return std::make_unique<T>(std::forward<ARGS>(args)...);
|
||||
T* create(ARGS&&... args) const {
|
||||
auto& ctx = parser_impl_.context();
|
||||
return ctx.create<T>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
ParserImpl& parser_impl_;
|
||||
|
||||
@@ -187,22 +187,6 @@ bool AssumesResultSignednessMatchesBinaryFirstOperand(SpvOp opcode) {
|
||||
|
||||
} // namespace
|
||||
|
||||
TypedExpression::TypedExpression() : type(nullptr), expr(nullptr) {}
|
||||
|
||||
TypedExpression::TypedExpression(ast::type::Type* t,
|
||||
std::unique_ptr<ast::Expression> e)
|
||||
: type(t), expr(std::move(e)) {}
|
||||
|
||||
TypedExpression::TypedExpression(TypedExpression&& other)
|
||||
: type(other.type), expr(std::move(other.expr)) {}
|
||||
|
||||
TypedExpression::~TypedExpression() {}
|
||||
|
||||
void TypedExpression::reset(TypedExpression&& other) {
|
||||
type = other.type;
|
||||
expr = std::move(other.expr);
|
||||
}
|
||||
|
||||
ParserImpl::ParserImpl(Context* ctx, const std::vector<uint32_t>& spv_binary)
|
||||
: Reader(ctx),
|
||||
spv_binary_(spv_binary),
|
||||
@@ -375,10 +359,10 @@ std::string ParserImpl::ShowType(uint32_t type_id) {
|
||||
return "SPIR-V type " + std::to_string(type_id);
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::StructMemberDecoration>
|
||||
ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id,
|
||||
uint32_t member_index,
|
||||
const Decoration& decoration) {
|
||||
ast::StructMemberDecoration* ParserImpl::ConvertMemberDecoration(
|
||||
uint32_t struct_type_id,
|
||||
uint32_t member_index,
|
||||
const Decoration& decoration) {
|
||||
if (decoration.empty()) {
|
||||
Fail() << "malformed SPIR-V decoration: it's empty";
|
||||
return nullptr;
|
||||
@@ -861,7 +845,7 @@ ast::type::Type* ParserImpl::ConvertType(
|
||||
// the members are non-writable.
|
||||
is_non_writable = true;
|
||||
} else {
|
||||
auto ast_member_decoration =
|
||||
auto* ast_member_decoration =
|
||||
ConvertMemberDecoration(type_id, member_index, decoration);
|
||||
if (!success_) {
|
||||
return nullptr;
|
||||
@@ -877,14 +861,14 @@ ast::type::Type* ParserImpl::ConvertType(
|
||||
++num_non_writable_members;
|
||||
}
|
||||
const auto member_name = namer_.GetMemberName(type_id, member_index);
|
||||
auto ast_struct_member = create<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 = create<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>(
|
||||
@@ -963,7 +947,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||
for (auto& inst : module_->types_values()) {
|
||||
// These will be populated for a valid scalar spec constant.
|
||||
ast::type::Type* ast_type = nullptr;
|
||||
std::unique_ptr<ast::ScalarConstructorExpression> ast_expr;
|
||||
ast::ScalarConstructorExpression* ast_expr = nullptr;
|
||||
|
||||
switch (inst.opcode()) {
|
||||
case SpvOpSpecConstantTrue:
|
||||
@@ -1001,12 +985,12 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||
break;
|
||||
}
|
||||
if (ast_type && ast_expr) {
|
||||
auto ast_var =
|
||||
auto* ast_var =
|
||||
MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type);
|
||||
ast::VariableDecorationList spec_id_decos;
|
||||
for (const auto& deco : GetDecorationsFor(inst.result_id())) {
|
||||
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
|
||||
auto cid = create<ast::ConstantIdDecoration>(deco[1], Source{});
|
||||
auto* cid = create<ast::ConstantIdDecoration>(deco[1], Source{});
|
||||
spec_id_decos.push_back(std::move(cid));
|
||||
break;
|
||||
}
|
||||
@@ -1017,7 +1001,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
|
||||
ast_var->set_constructor(std::move(ast_expr));
|
||||
ast_module_.AddGlobalVariable(std::move(ast_var));
|
||||
} else {
|
||||
auto ast_deco_var = create<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));
|
||||
@@ -1118,7 +1102,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
||||
}
|
||||
auto* ast_store_type = ast_type->AsPointer()->type();
|
||||
auto ast_storage_class = ast_type->AsPointer()->storage_class();
|
||||
auto ast_var =
|
||||
auto* ast_var =
|
||||
MakeVariable(var.result_id(), ast_storage_class, ast_store_type);
|
||||
if (var.NumInOperands() > 1) {
|
||||
// SPIR-V initializers are always constants.
|
||||
@@ -1136,7 +1120,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
||||
// Make sure the variable has a name.
|
||||
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
|
||||
"gl_Position");
|
||||
auto var = create<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)));
|
||||
@@ -1150,9 +1134,9 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
||||
return success_;
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||
ast::StorageClass sc,
|
||||
ast::type::Type* type) {
|
||||
ast::Variable* ParserImpl::MakeVariable(uint32_t id,
|
||||
ast::StorageClass sc,
|
||||
ast::type::Type* type) {
|
||||
if (type == nullptr) {
|
||||
Fail() << "internal error: can't make ast::Variable for null type";
|
||||
return nullptr;
|
||||
@@ -1167,7 +1151,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||
std::make_unique<ast::type::AccessControlType>(access, type));
|
||||
}
|
||||
|
||||
auto ast_var = create<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)) {
|
||||
@@ -1218,7 +1202,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
|
||||
}
|
||||
}
|
||||
if (!ast_decorations.empty()) {
|
||||
auto decorated_var = create<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);
|
||||
}
|
||||
@@ -1315,8 +1299,7 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||
ast::type::Type* type) {
|
||||
ast::Expression* ParserImpl::MakeNullValue(ast::type::Type* type) {
|
||||
// TODO(dneto): Use the no-operands constructor syntax when it becomes
|
||||
// available in Tint.
|
||||
// https://github.com/gpuweb/gpuweb/issues/685
|
||||
@@ -1380,7 +1363,7 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||
if (type->IsStruct()) {
|
||||
auto* struct_ty = type->AsStruct();
|
||||
ast::ExpressionList ast_components;
|
||||
for (auto& member : struct_ty->impl()->members()) {
|
||||
for (auto* member : struct_ty->impl()->members()) {
|
||||
ast_components.emplace_back(MakeNullValue(member->type()));
|
||||
}
|
||||
return create<ast::TypeConstructorExpression>(original_type,
|
||||
|
||||
@@ -56,24 +56,10 @@ using DecorationList = std::vector<Decoration>;
|
||||
|
||||
/// An AST expression with its type.
|
||||
struct TypedExpression {
|
||||
/// Constructor
|
||||
TypedExpression();
|
||||
/// Constructor
|
||||
/// @param t the type
|
||||
/// @param e the expression
|
||||
TypedExpression(ast::type::Type* t, std::unique_ptr<ast::Expression> e);
|
||||
/// Move constructor
|
||||
/// @param other the other typed expression
|
||||
TypedExpression(TypedExpression&& other);
|
||||
/// Destructor
|
||||
~TypedExpression();
|
||||
/// Takes values from another typed expression.
|
||||
/// @param other the other typed expression
|
||||
void reset(TypedExpression&& other);
|
||||
/// The type
|
||||
ast::type::Type* type;
|
||||
ast::type::Type* type = nullptr;
|
||||
/// The expression
|
||||
std::unique_ptr<ast::Expression> expr;
|
||||
ast::Expression* expr = nullptr;
|
||||
};
|
||||
|
||||
/// Parser implementation for SPIR-V.
|
||||
@@ -187,7 +173,7 @@ class ParserImpl : Reader {
|
||||
/// @param member_index the index of the member
|
||||
/// @param decoration an encoded SPIR-V Decoration
|
||||
/// @returns the corresponding ast::StructuMemberDecoration
|
||||
std::unique_ptr<ast::StructMemberDecoration> ConvertMemberDecoration(
|
||||
ast::StructMemberDecoration* ConvertMemberDecoration(
|
||||
uint32_t struct_type_id,
|
||||
uint32_t member_index,
|
||||
const Decoration& decoration);
|
||||
@@ -274,9 +260,9 @@ class ParserImpl : Reader {
|
||||
/// @param sc the storage class, which cannot be ast::StorageClass::kNone
|
||||
/// @param type the type
|
||||
/// @returns a new Variable node, or null in the error case
|
||||
std::unique_ptr<ast::Variable> MakeVariable(uint32_t id,
|
||||
ast::StorageClass sc,
|
||||
ast::type::Type* type);
|
||||
ast::Variable* MakeVariable(uint32_t id,
|
||||
ast::StorageClass sc,
|
||||
ast::type::Type* type);
|
||||
|
||||
/// Creates an AST expression node for a SPIR-V constant.
|
||||
/// @param id the SPIR-V ID of the constant
|
||||
@@ -286,7 +272,7 @@ class ParserImpl : Reader {
|
||||
/// Creates an AST expression node for the null value for the given type.
|
||||
/// @param type the AST type
|
||||
/// @returns a new expression
|
||||
std::unique_ptr<ast::Expression> MakeNullValue(ast::type::Type* type);
|
||||
ast::Expression* MakeNullValue(ast::type::Type* type);
|
||||
|
||||
/// Converts a given expression to the signedness demanded for an operand
|
||||
/// of the given SPIR-V opcode, if required. If the operation assumes
|
||||
@@ -432,13 +418,6 @@ 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_;
|
||||
|
||||
|
||||
@@ -34,16 +34,16 @@ using ::testing::Eq;
|
||||
TEST_F(SpvParserTest, ConvertMemberDecoration_Empty) {
|
||||
auto* p = parser(std::vector<uint32_t>{});
|
||||
|
||||
auto result = p->ConvertMemberDecoration(1, 1, {});
|
||||
EXPECT_EQ(result.get(), nullptr);
|
||||
auto* result = p->ConvertMemberDecoration(1, 1, {});
|
||||
EXPECT_EQ(result, nullptr);
|
||||
EXPECT_THAT(p->error(), Eq("malformed SPIR-V decoration: it's empty"));
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
|
||||
auto* p = parser(std::vector<uint32_t>{});
|
||||
|
||||
auto result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset});
|
||||
EXPECT_EQ(result.get(), nullptr);
|
||||
auto* result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset});
|
||||
EXPECT_EQ(result, nullptr);
|
||||
EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
|
||||
"operand, has 0: member 13 of SPIR-V type 12"));
|
||||
}
|
||||
@@ -51,8 +51,9 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
|
||||
TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
|
||||
auto* p = parser(std::vector<uint32_t>{});
|
||||
|
||||
auto result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset, 3, 4});
|
||||
EXPECT_EQ(result.get(), nullptr);
|
||||
auto* result =
|
||||
p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset, 3, 4});
|
||||
EXPECT_EQ(result, nullptr);
|
||||
EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
|
||||
"operand, has 2: member 13 of SPIR-V type 12"));
|
||||
}
|
||||
@@ -60,8 +61,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
|
||||
TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
|
||||
auto* p = parser(std::vector<uint32_t>{});
|
||||
|
||||
auto result = p->ConvertMemberDecoration(1, 1, {SpvDecorationOffset, 8});
|
||||
ASSERT_NE(result.get(), nullptr);
|
||||
auto* result = p->ConvertMemberDecoration(1, 1, {SpvDecorationOffset, 8});
|
||||
ASSERT_NE(result, nullptr);
|
||||
EXPECT_TRUE(result->IsOffset());
|
||||
auto* offset_deco = result->AsOffset();
|
||||
ASSERT_NE(offset_deco, nullptr);
|
||||
@@ -72,8 +73,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
|
||||
TEST_F(SpvParserTest, ConvertMemberDecoration_UnhandledDecoration) {
|
||||
auto* p = parser(std::vector<uint32_t>{});
|
||||
|
||||
auto result = p->ConvertMemberDecoration(12, 13, {12345678});
|
||||
EXPECT_EQ(result.get(), nullptr);
|
||||
auto* result = p->ConvertMemberDecoration(12, 13, {12345678});
|
||||
EXPECT_EQ(result, nullptr);
|
||||
EXPECT_THAT(p->error(), Eq("unhandled member decoration: 12345678 on member "
|
||||
"13 of SPIR-V type 12"));
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ using SpvParserTest = SpvParserTestBase<::testing::Test>;
|
||||
/// @returnss the string dump of a function body.
|
||||
inline std::string ToString(const ast::BlockStatement* body) {
|
||||
std::ostringstream outs;
|
||||
for (const auto& stmt : *body) {
|
||||
for (const auto* stmt : *body) {
|
||||
stmt->to_str(outs, 0);
|
||||
}
|
||||
return outs.str();
|
||||
|
||||
@@ -340,7 +340,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
|
||||
// global_variable_decl
|
||||
// : variable_decoration_list* variable_decl
|
||||
// | variable_decoration_list* variable_decl EQUAL const_expr
|
||||
Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_variable_decl(
|
||||
Maybe<ast::Variable*> ParserImpl::global_variable_decl(
|
||||
ast::DecorationList& decos) {
|
||||
auto decl = variable_decl();
|
||||
if (decl.errored)
|
||||
@@ -348,14 +348,14 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_variable_decl(
|
||||
if (!decl.matched)
|
||||
return Failure::kNoMatch;
|
||||
|
||||
auto var = std::move(decl.value);
|
||||
auto* var = std::move(decl.value);
|
||||
|
||||
auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
|
||||
if (var_decos.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
if (var_decos.value.size() > 0) {
|
||||
auto dv = create<ast::DecoratedVariable>(std::move(var));
|
||||
auto* dv = create<ast::DecoratedVariable>(std::move(var));
|
||||
dv->set_decorations(std::move(var_decos.value));
|
||||
var = std::move(dv);
|
||||
}
|
||||
@@ -371,7 +371,7 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_variable_decl(
|
||||
|
||||
// global_constant_decl
|
||||
// : CONST variable_ident_decl EQUAL const_expr
|
||||
Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_constant_decl() {
|
||||
Maybe<ast::Variable*> ParserImpl::global_constant_decl() {
|
||||
if (!match(Token::Type::kConst))
|
||||
return Failure::kNoMatch;
|
||||
|
||||
@@ -381,8 +381,8 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_constant_decl() {
|
||||
if (decl.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
auto var = create<ast::Variable>(decl->source, decl->name,
|
||||
ast::StorageClass::kNone, decl->type);
|
||||
auto* var = create<ast::Variable>(decl->source, decl->name,
|
||||
ast::StorageClass::kNone, decl->type);
|
||||
var->set_is_const(true);
|
||||
|
||||
if (!expect(use, Token::Type::kEqual))
|
||||
@@ -399,7 +399,7 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_constant_decl() {
|
||||
|
||||
// variable_decl
|
||||
// : VAR variable_storage_decoration? variable_ident_decl
|
||||
Maybe<std::unique_ptr<ast::Variable>> ParserImpl::variable_decl() {
|
||||
Maybe<ast::Variable*> ParserImpl::variable_decl() {
|
||||
if (!match(Token::Type::kVar))
|
||||
return Failure::kNoMatch;
|
||||
|
||||
@@ -1100,16 +1100,15 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
|
||||
ast::StructMemberList members;
|
||||
|
||||
while (synchronized_ && !peek().IsBraceRight() && !peek().IsEof()) {
|
||||
auto member =
|
||||
sync(Token::Type::kSemicolon,
|
||||
[&]() -> Expect<std::unique_ptr<ast::StructMember>> {
|
||||
auto decos = decoration_list();
|
||||
if (decos.errored)
|
||||
errored = true;
|
||||
if (!synchronized_)
|
||||
return Failure::kErrored;
|
||||
return expect_struct_member(decos.value);
|
||||
});
|
||||
auto member = sync(Token::Type::kSemicolon,
|
||||
[&]() -> Expect<ast::StructMember*> {
|
||||
auto decos = decoration_list();
|
||||
if (decos.errored)
|
||||
errored = true;
|
||||
if (!synchronized_)
|
||||
return Failure::kErrored;
|
||||
return expect_struct_member(decos.value);
|
||||
});
|
||||
|
||||
if (member.errored) {
|
||||
errored = true;
|
||||
@@ -1127,7 +1126,7 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
|
||||
|
||||
// struct_member
|
||||
// : struct_member_decoration_decl+ variable_ident_decl SEMICOLON
|
||||
Expect<std::unique_ptr<ast::StructMember>> ParserImpl::expect_struct_member(
|
||||
Expect<ast::StructMember*> ParserImpl::expect_struct_member(
|
||||
ast::DecorationList& decos) {
|
||||
auto decl = expect_variable_ident_decl("struct member");
|
||||
if (decl.errored)
|
||||
@@ -1146,8 +1145,7 @@ Expect<std::unique_ptr<ast::StructMember>> ParserImpl::expect_struct_member(
|
||||
|
||||
// function_decl
|
||||
// : function_header body_stmt
|
||||
Maybe<std::unique_ptr<ast::Function>> ParserImpl::function_decl(
|
||||
ast::DecorationList& decos) {
|
||||
Maybe<ast::Function*> ParserImpl::function_decl(ast::DecorationList& decos) {
|
||||
auto f = function_header();
|
||||
if (f.errored) {
|
||||
if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
|
||||
@@ -1195,7 +1193,7 @@ Maybe<ast::type::Type*> ParserImpl::function_type_decl() {
|
||||
|
||||
// function_header
|
||||
// : FN IDENT PAREN_LEFT param_list PAREN_RIGHT ARROW function_type_decl
|
||||
Maybe<std::unique_ptr<ast::Function>> ParserImpl::function_header() {
|
||||
Maybe<ast::Function*> ParserImpl::function_header() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kFn, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1247,8 +1245,8 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
|
||||
|
||||
ast::VariableList ret;
|
||||
for (;;) {
|
||||
auto var = create<ast::Variable>(decl->source, decl->name,
|
||||
ast::StorageClass::kNone, decl->type);
|
||||
auto* var = create<ast::Variable>(decl->source, decl->name,
|
||||
ast::StorageClass::kNone, decl->type);
|
||||
// Formal parameters are treated like a const declaration where the
|
||||
// initializer value is provided by the call's argument. The key point is
|
||||
// that it's not updatable after intially set. This is unlike C or GLSL
|
||||
@@ -1299,30 +1297,29 @@ Expect<ast::Builtin> ParserImpl::expect_builtin() {
|
||||
|
||||
// body_stmt
|
||||
// : BRACKET_LEFT statements BRACKET_RIGHT
|
||||
Expect<std::unique_ptr<ast::BlockStatement>> ParserImpl::expect_body_stmt() {
|
||||
Expect<ast::BlockStatement*> ParserImpl::expect_body_stmt() {
|
||||
return expect_brace_block("", [&] { return expect_statements(); });
|
||||
}
|
||||
|
||||
// paren_rhs_stmt
|
||||
// : PAREN_LEFT logical_or_expression PAREN_RIGHT
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_paren_rhs_stmt() {
|
||||
return expect_paren_block(
|
||||
"", [&]() -> Expect<std::unique_ptr<ast::Expression>> {
|
||||
auto expr = logical_or_expression();
|
||||
if (expr.errored)
|
||||
return Failure::kErrored;
|
||||
if (!expr.matched)
|
||||
return add_error(peek(), "unable to parse expression");
|
||||
Expect<ast::Expression*> ParserImpl::expect_paren_rhs_stmt() {
|
||||
return expect_paren_block("", [&]() -> Expect<ast::Expression*> {
|
||||
auto expr = logical_or_expression();
|
||||
if (expr.errored)
|
||||
return Failure::kErrored;
|
||||
if (!expr.matched)
|
||||
return add_error(peek(), "unable to parse expression");
|
||||
|
||||
return std::move(expr.value);
|
||||
});
|
||||
return std::move(expr.value);
|
||||
});
|
||||
}
|
||||
|
||||
// statements
|
||||
// : statement*
|
||||
Expect<std::unique_ptr<ast::BlockStatement>> ParserImpl::expect_statements() {
|
||||
Expect<ast::BlockStatement*> ParserImpl::expect_statements() {
|
||||
bool errored = false;
|
||||
auto ret = create<ast::BlockStatement>();
|
||||
auto* ret = create<ast::BlockStatement>();
|
||||
|
||||
while (synchronized_) {
|
||||
auto stmt = statement();
|
||||
@@ -1356,7 +1353,7 @@ Expect<std::unique_ptr<ast::BlockStatement>> ParserImpl::expect_statements() {
|
||||
// | continue_stmt SEMICOLON
|
||||
// | DISCARD SEMICOLON
|
||||
// | assignment_stmt SEMICOLON
|
||||
Maybe<std::unique_ptr<ast::Statement>> ParserImpl::statement() {
|
||||
Maybe<ast::Statement*> ParserImpl::statement() {
|
||||
while (match(Token::Type::kSemicolon)) {
|
||||
// Skip empty statements
|
||||
}
|
||||
@@ -1412,8 +1409,8 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::statement() {
|
||||
// | continue_stmt SEMICOLON
|
||||
// | DISCARD SEMICOLON
|
||||
// | assignment_stmt SEMICOLON
|
||||
Maybe<std::unique_ptr<ast::Statement>> ParserImpl::non_block_statement() {
|
||||
auto stmt = [&]() -> Maybe<std::unique_ptr<ast::Statement>> {
|
||||
Maybe<ast::Statement*> ParserImpl::non_block_statement() {
|
||||
auto stmt = [&]() -> Maybe<ast::Statement*> {
|
||||
auto ret_stmt = return_stmt();
|
||||
if (ret_stmt.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -1465,7 +1462,7 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::non_block_statement() {
|
||||
|
||||
// return_stmt
|
||||
// : RETURN logical_or_expression?
|
||||
Maybe<std::unique_ptr<ast::ReturnStatement>> ParserImpl::return_stmt() {
|
||||
Maybe<ast::ReturnStatement*> ParserImpl::return_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kReturn, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1485,7 +1482,7 @@ Maybe<std::unique_ptr<ast::ReturnStatement>> ParserImpl::return_stmt() {
|
||||
// : variable_decl
|
||||
// | variable_decl EQUAL logical_or_expression
|
||||
// | CONST variable_ident_decl EQUAL logical_or_expression
|
||||
Maybe<std::unique_ptr<ast::VariableDeclStatement>> ParserImpl::variable_stmt() {
|
||||
Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
|
||||
if (match(Token::Type::kConst)) {
|
||||
auto decl = expect_variable_ident_decl("constant declaration");
|
||||
if (decl.errored)
|
||||
@@ -1500,8 +1497,8 @@ Maybe<std::unique_ptr<ast::VariableDeclStatement>> ParserImpl::variable_stmt() {
|
||||
if (!constructor.matched)
|
||||
return add_error(peek(), "missing constructor for const declaration");
|
||||
|
||||
auto var = create<ast::Variable>(decl->source, decl->name,
|
||||
ast::StorageClass::kNone, decl->type);
|
||||
auto* var = create<ast::Variable>(decl->source, decl->name,
|
||||
ast::StorageClass::kNone, decl->type);
|
||||
var->set_is_const(true);
|
||||
var->set_constructor(std::move(constructor.value));
|
||||
|
||||
@@ -1530,7 +1527,7 @@ Maybe<std::unique_ptr<ast::VariableDeclStatement>> ParserImpl::variable_stmt() {
|
||||
|
||||
// if_stmt
|
||||
// : IF paren_rhs_stmt body_stmt elseif_stmt? else_stmt?
|
||||
Maybe<std::unique_ptr<ast::IfStatement>> ParserImpl::if_stmt() {
|
||||
Maybe<ast::IfStatement*> ParserImpl::if_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kIf, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1551,8 +1548,8 @@ Maybe<std::unique_ptr<ast::IfStatement>> ParserImpl::if_stmt() {
|
||||
if (el.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
auto stmt = create<ast::IfStatement>(source, std::move(condition.value),
|
||||
std::move(body.value));
|
||||
auto* stmt = create<ast::IfStatement>(source, std::move(condition.value),
|
||||
std::move(body.value));
|
||||
if (el.matched) {
|
||||
elseif.value.push_back(std::move(el.value));
|
||||
}
|
||||
@@ -1590,7 +1587,7 @@ Maybe<ast::ElseStatementList> ParserImpl::elseif_stmt() {
|
||||
|
||||
// else_stmt
|
||||
// : ELSE body_stmt
|
||||
Maybe<std::unique_ptr<ast::ElseStatement>> ParserImpl::else_stmt() {
|
||||
Maybe<ast::ElseStatement*> ParserImpl::else_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kElse, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1604,7 +1601,7 @@ Maybe<std::unique_ptr<ast::ElseStatement>> ParserImpl::else_stmt() {
|
||||
|
||||
// switch_stmt
|
||||
// : SWITCH paren_rhs_stmt BRACKET_LEFT switch_body+ BRACKET_RIGHT
|
||||
Maybe<std::unique_ptr<ast::SwitchStatement>> ParserImpl::switch_stmt() {
|
||||
Maybe<ast::SwitchStatement*> ParserImpl::switch_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kSwitch, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1642,7 +1639,7 @@ Maybe<std::unique_ptr<ast::SwitchStatement>> ParserImpl::switch_stmt() {
|
||||
// switch_body
|
||||
// : CASE case_selectors COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
||||
// | DEFAULT COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
||||
Maybe<std::unique_ptr<ast::CaseStatement>> ParserImpl::switch_body() {
|
||||
Maybe<ast::CaseStatement*> ParserImpl::switch_body() {
|
||||
auto t = peek();
|
||||
if (!t.IsCase() && !t.IsDefault())
|
||||
return Failure::kNoMatch;
|
||||
@@ -1650,7 +1647,7 @@ Maybe<std::unique_ptr<ast::CaseStatement>> ParserImpl::switch_body() {
|
||||
auto source = t.source();
|
||||
next(); // Consume the peek
|
||||
|
||||
auto stmt = create<ast::CaseStatement>(create<ast::BlockStatement>());
|
||||
auto* stmt = create<ast::CaseStatement>(create<ast::BlockStatement>());
|
||||
stmt->set_source(source);
|
||||
if (t.IsCase()) {
|
||||
auto selectors = expect_case_selectors();
|
||||
@@ -1692,8 +1689,7 @@ Expect<ast::CaseSelectorList> ParserImpl::expect_case_selectors() {
|
||||
if (!cond->IsInt())
|
||||
return add_error(t, "invalid case selector must be an integer value");
|
||||
|
||||
std::unique_ptr<ast::IntLiteral> selector(cond.value.release()->AsInt());
|
||||
selectors.push_back(std::move(selector));
|
||||
selectors.push_back(cond.value->AsInt());
|
||||
}
|
||||
|
||||
if (selectors.empty())
|
||||
@@ -1706,8 +1702,8 @@ Expect<ast::CaseSelectorList> ParserImpl::expect_case_selectors() {
|
||||
// :
|
||||
// | statement case_body
|
||||
// | FALLTHROUGH SEMICOLON
|
||||
Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::case_body() {
|
||||
auto ret = create<ast::BlockStatement>();
|
||||
Maybe<ast::BlockStatement*> ParserImpl::case_body() {
|
||||
auto* ret = create<ast::BlockStatement>();
|
||||
for (;;) {
|
||||
Source source;
|
||||
if (match(Token::Type::kFallthrough, &source)) {
|
||||
@@ -1732,29 +1728,28 @@ Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::case_body() {
|
||||
|
||||
// loop_stmt
|
||||
// : LOOP BRACKET_LEFT statements continuing_stmt? BRACKET_RIGHT
|
||||
Maybe<std::unique_ptr<ast::LoopStatement>> ParserImpl::loop_stmt() {
|
||||
Maybe<ast::LoopStatement*> ParserImpl::loop_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kLoop, &source))
|
||||
return Failure::kNoMatch;
|
||||
|
||||
return expect_brace_block(
|
||||
"loop", [&]() -> Maybe<std::unique_ptr<ast::LoopStatement>> {
|
||||
auto body = expect_statements();
|
||||
if (body.errored)
|
||||
return Failure::kErrored;
|
||||
return expect_brace_block("loop", [&]() -> Maybe<ast::LoopStatement*> {
|
||||
auto body = expect_statements();
|
||||
if (body.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
auto continuing = continuing_stmt();
|
||||
if (continuing.errored)
|
||||
return Failure::kErrored;
|
||||
auto continuing = continuing_stmt();
|
||||
if (continuing.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ast::LoopStatement>(source, std::move(body.value),
|
||||
std::move(continuing.value));
|
||||
});
|
||||
return create<ast::LoopStatement>(source, std::move(body.value),
|
||||
std::move(continuing.value));
|
||||
});
|
||||
}
|
||||
|
||||
ForHeader::ForHeader(std::unique_ptr<ast::Statement> init,
|
||||
std::unique_ptr<ast::Expression> cond,
|
||||
std::unique_ptr<ast::Statement> cont)
|
||||
ForHeader::ForHeader(ast::Statement* init,
|
||||
ast::Expression* cond,
|
||||
ast::Statement* cont)
|
||||
: initializer(std::move(init)),
|
||||
condition(std::move(cond)),
|
||||
continuing(std::move(cont)) {}
|
||||
@@ -1762,7 +1757,7 @@ ForHeader::ForHeader(std::unique_ptr<ast::Statement> init,
|
||||
ForHeader::~ForHeader() = default;
|
||||
|
||||
// (variable_stmt | assignment_stmt | func_call_stmt)?
|
||||
Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_header_initializer() {
|
||||
Maybe<ast::Statement*> ParserImpl::for_header_initializer() {
|
||||
auto call = func_call_stmt();
|
||||
if (call.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -1785,7 +1780,7 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_header_initializer() {
|
||||
}
|
||||
|
||||
// (assignment_stmt | func_call_stmt)?
|
||||
Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_header_continuing() {
|
||||
Maybe<ast::Statement*> ParserImpl::for_header_continuing() {
|
||||
auto call_stmt = func_call_stmt();
|
||||
if (call_stmt.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -1825,14 +1820,14 @@ Expect<std::unique_ptr<ForHeader>> ParserImpl::expect_for_header() {
|
||||
if (continuing.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return create<ForHeader>(std::move(initializer.value),
|
||||
std::move(condition.value),
|
||||
std::move(continuing.value));
|
||||
return std::make_unique<ForHeader>(std::move(initializer.value),
|
||||
std::move(condition.value),
|
||||
std::move(continuing.value));
|
||||
}
|
||||
|
||||
// for_statement
|
||||
// : FOR PAREN_LEFT for_header PAREN_RIGHT BRACE_LEFT statements BRACE_RIGHT
|
||||
Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_stmt() {
|
||||
Maybe<ast::Statement*> ParserImpl::for_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kFor, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1852,31 +1847,31 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_stmt() {
|
||||
// as we would expect from the loop statement.
|
||||
if (header->condition != nullptr) {
|
||||
// !condition
|
||||
auto not_condition = create<ast::UnaryOpExpression>(
|
||||
auto* not_condition = create<ast::UnaryOpExpression>(
|
||||
header->condition->source(), ast::UnaryOp::kNot,
|
||||
std::move(header->condition));
|
||||
// { break; }
|
||||
auto break_stmt = create<ast::BreakStatement>(not_condition->source());
|
||||
auto break_body = create<ast::BlockStatement>(not_condition->source());
|
||||
auto* break_stmt = create<ast::BreakStatement>(not_condition->source());
|
||||
auto* break_body = create<ast::BlockStatement>(not_condition->source());
|
||||
break_body->append(std::move(break_stmt));
|
||||
// if (!condition) { break; }
|
||||
auto break_if_not_condition = create<ast::IfStatement>(
|
||||
auto* break_if_not_condition = create<ast::IfStatement>(
|
||||
not_condition->source(), std::move(not_condition),
|
||||
std::move(break_body));
|
||||
body->insert(0, std::move(break_if_not_condition));
|
||||
}
|
||||
|
||||
std::unique_ptr<ast::BlockStatement> continuing_body = nullptr;
|
||||
ast::BlockStatement* continuing_body = nullptr;
|
||||
if (header->continuing != nullptr) {
|
||||
continuing_body = create<ast::BlockStatement>(header->continuing->source());
|
||||
continuing_body->append(std::move(header->continuing));
|
||||
}
|
||||
|
||||
auto loop = create<ast::LoopStatement>(source, std::move(body.value),
|
||||
std::move(continuing_body));
|
||||
auto* loop = create<ast::LoopStatement>(source, std::move(body.value),
|
||||
std::move(continuing_body));
|
||||
|
||||
if (header->initializer != nullptr) {
|
||||
auto result = create<ast::BlockStatement>(source);
|
||||
auto* result = create<ast::BlockStatement>(source);
|
||||
result->append(std::move(header->initializer));
|
||||
result->append(std::move(loop));
|
||||
return result;
|
||||
@@ -1887,7 +1882,7 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_stmt() {
|
||||
|
||||
// func_call_stmt
|
||||
// : IDENT PAREN_LEFT argument_expression_list* PAREN_RIGHT
|
||||
Maybe<std::unique_ptr<ast::CallStatement>> ParserImpl::func_call_stmt() {
|
||||
Maybe<ast::CallStatement*> ParserImpl::func_call_stmt() {
|
||||
auto t = peek();
|
||||
auto t2 = peek(1);
|
||||
if (!t.IsIdentifier() || !t2.IsParenLeft())
|
||||
@@ -1919,7 +1914,7 @@ Maybe<std::unique_ptr<ast::CallStatement>> ParserImpl::func_call_stmt() {
|
||||
|
||||
// break_stmt
|
||||
// : BREAK
|
||||
Maybe<std::unique_ptr<ast::BreakStatement>> ParserImpl::break_stmt() {
|
||||
Maybe<ast::BreakStatement*> ParserImpl::break_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kBreak, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1929,7 +1924,7 @@ Maybe<std::unique_ptr<ast::BreakStatement>> ParserImpl::break_stmt() {
|
||||
|
||||
// continue_stmt
|
||||
// : CONTINUE
|
||||
Maybe<std::unique_ptr<ast::ContinueStatement>> ParserImpl::continue_stmt() {
|
||||
Maybe<ast::ContinueStatement*> ParserImpl::continue_stmt() {
|
||||
Source source;
|
||||
if (!match(Token::Type::kContinue, &source))
|
||||
return Failure::kNoMatch;
|
||||
@@ -1939,7 +1934,7 @@ Maybe<std::unique_ptr<ast::ContinueStatement>> ParserImpl::continue_stmt() {
|
||||
|
||||
// continuing_stmt
|
||||
// : CONTINUING body_stmt
|
||||
Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::continuing_stmt() {
|
||||
Maybe<ast::BlockStatement*> ParserImpl::continuing_stmt() {
|
||||
if (!match(Token::Type::kContinuing))
|
||||
return create<ast::BlockStatement>();
|
||||
|
||||
@@ -1952,7 +1947,7 @@ Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::continuing_stmt() {
|
||||
// | const_literal
|
||||
// | paren_rhs_stmt
|
||||
// | BITCAST LESS_THAN type_decl GREATER_THAN paren_rhs_stmt
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::primary_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::primary_expression() {
|
||||
auto t = peek();
|
||||
auto source = t.source();
|
||||
|
||||
@@ -1994,8 +1989,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::primary_expression() {
|
||||
return Failure::kErrored;
|
||||
if (type.matched) {
|
||||
auto expr = expect_paren_block(
|
||||
"type constructor",
|
||||
[&]() -> Expect<std::unique_ptr<ast::TypeConstructorExpression>> {
|
||||
"type constructor", [&]() -> Expect<ast::TypeConstructorExpression*> {
|
||||
t = peek();
|
||||
if (t.IsParenRight() || t.IsEof())
|
||||
return create<ast::TypeConstructorExpression>(
|
||||
@@ -2023,8 +2017,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::primary_expression() {
|
||||
// | BRACE_LEFT logical_or_expression BRACE_RIGHT postfix_expr
|
||||
// | PAREN_LEFT argument_expression_list* PAREN_RIGHT postfix_expr
|
||||
// | PERIOD IDENTIFIER postfix_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expr(
|
||||
std::unique_ptr<ast::Expression> prefix) {
|
||||
Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
|
||||
Source source;
|
||||
if (match(Token::Type::kBracketLeft, &source)) {
|
||||
auto param = logical_or_expression();
|
||||
@@ -2073,7 +2066,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expr(
|
||||
|
||||
// postfix_expression
|
||||
// : primary_expression postfix_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::postfix_expression() {
|
||||
auto prefix = primary_expression();
|
||||
if (prefix.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2112,7 +2105,7 @@ Expect<ast::ExpressionList> ParserImpl::expect_argument_expression_list() {
|
||||
// : postfix_expression
|
||||
// | MINUS unary_expression
|
||||
// | BANG unary_expression
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::unary_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::unary_expression() {
|
||||
auto t = peek();
|
||||
auto source = t.source();
|
||||
if (t.IsMinus() || t.IsBang()) {
|
||||
@@ -2141,8 +2134,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::unary_expression() {
|
||||
// | STAR unary_expression multiplicative_expr
|
||||
// | FORWARD_SLASH unary_expression multiplicative_expr
|
||||
// | MODULO unary_expression multiplicative_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_multiplicative_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_multiplicative_expr(
|
||||
ast::Expression* lhs) {
|
||||
auto t = peek();
|
||||
|
||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||
@@ -2173,8 +2166,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_multiplicative_expr(
|
||||
|
||||
// multiplicative_expression
|
||||
// : unary_expression multiplicative_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>>
|
||||
ParserImpl::multiplicative_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::multiplicative_expression() {
|
||||
auto lhs = unary_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2188,8 +2180,8 @@ ParserImpl::multiplicative_expression() {
|
||||
// :
|
||||
// | PLUS multiplicative_expression additive_expr
|
||||
// | MINUS multiplicative_expression additive_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_additive_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_additive_expr(
|
||||
ast::Expression* lhs) {
|
||||
auto t = peek();
|
||||
|
||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||
@@ -2215,7 +2207,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_additive_expr(
|
||||
|
||||
// additive_expression
|
||||
// : multiplicative_expression additive_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::additive_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::additive_expression() {
|
||||
auto lhs = multiplicative_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2229,8 +2221,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::additive_expression() {
|
||||
// :
|
||||
// | LESS_THAN LESS_THAN additive_expression shift_expr
|
||||
// | GREATER_THAN GREATER_THAN additive_expression shift_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_shift_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_shift_expr(ast::Expression* lhs) {
|
||||
auto t = peek();
|
||||
auto source = t.source();
|
||||
auto t2 = peek(1);
|
||||
@@ -2264,7 +2255,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_shift_expr(
|
||||
|
||||
// shift_expression
|
||||
// : additive_expression shift_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::shift_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::shift_expression() {
|
||||
auto lhs = additive_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2280,8 +2271,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::shift_expression() {
|
||||
// | GREATER_THAN shift_expression relational_expr
|
||||
// | LESS_THAN_EQUAL shift_expression relational_expr
|
||||
// | GREATER_THAN_EQUAL shift_expression relational_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_relational_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_relational_expr(
|
||||
ast::Expression* lhs) {
|
||||
auto t = peek();
|
||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||
if (t.IsLessThan())
|
||||
@@ -2313,7 +2304,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_relational_expr(
|
||||
|
||||
// relational_expression
|
||||
// : shift_expression relational_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::relational_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::relational_expression() {
|
||||
auto lhs = shift_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2327,8 +2318,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::relational_expression() {
|
||||
// :
|
||||
// | EQUAL_EQUAL relational_expression equality_expr
|
||||
// | NOT_EQUAL relational_expression equality_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_equality_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_equality_expr(
|
||||
ast::Expression* lhs) {
|
||||
auto t = peek();
|
||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||
if (t.IsEqualEqual())
|
||||
@@ -2356,7 +2347,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_equality_expr(
|
||||
|
||||
// equality_expression
|
||||
// : relational_expression equality_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::equality_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::equality_expression() {
|
||||
auto lhs = relational_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2369,8 +2360,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::equality_expression() {
|
||||
// and_expr
|
||||
// :
|
||||
// | AND equality_expression and_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_and_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_and_expr(ast::Expression* lhs) {
|
||||
auto t = peek();
|
||||
if (!t.IsAnd())
|
||||
return lhs;
|
||||
@@ -2390,7 +2380,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_and_expr(
|
||||
|
||||
// and_expression
|
||||
// : equality_expression and_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::and_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::and_expression() {
|
||||
auto lhs = equality_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2403,8 +2393,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::and_expression() {
|
||||
// exclusive_or_expr
|
||||
// :
|
||||
// | XOR and_expression exclusive_or_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_exclusive_or_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_exclusive_or_expr(
|
||||
ast::Expression* lhs) {
|
||||
Source source;
|
||||
if (!match(Token::Type::kXor, &source))
|
||||
return lhs;
|
||||
@@ -2421,7 +2411,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_exclusive_or_expr(
|
||||
|
||||
// exclusive_or_expression
|
||||
// : and_expression exclusive_or_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::exclusive_or_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::exclusive_or_expression() {
|
||||
auto lhs = and_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2434,8 +2424,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::exclusive_or_expression() {
|
||||
// inclusive_or_expr
|
||||
// :
|
||||
// | OR exclusive_or_expression inclusive_or_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_inclusive_or_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_inclusive_or_expr(
|
||||
ast::Expression* lhs) {
|
||||
Source source;
|
||||
if (!match(Token::Type::kOr))
|
||||
return lhs;
|
||||
@@ -2452,7 +2442,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_inclusive_or_expr(
|
||||
|
||||
// inclusive_or_expression
|
||||
// : exclusive_or_expression inclusive_or_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::inclusive_or_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::inclusive_or_expression() {
|
||||
auto lhs = exclusive_or_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2465,8 +2455,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::inclusive_or_expression() {
|
||||
// logical_and_expr
|
||||
// :
|
||||
// | AND_AND inclusive_or_expression logical_and_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_and_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_logical_and_expr(
|
||||
ast::Expression* lhs) {
|
||||
auto t = peek();
|
||||
if (!t.IsAndAnd())
|
||||
return lhs;
|
||||
@@ -2487,7 +2477,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_and_expr(
|
||||
|
||||
// logical_and_expression
|
||||
// : inclusive_or_expression logical_and_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_and_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::logical_and_expression() {
|
||||
auto lhs = inclusive_or_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2500,8 +2490,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_and_expression() {
|
||||
// logical_or_expr
|
||||
// :
|
||||
// | OR_OR logical_and_expression logical_or_expr
|
||||
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_or_expr(
|
||||
std::unique_ptr<ast::Expression> lhs) {
|
||||
Expect<ast::Expression*> ParserImpl::expect_logical_or_expr(
|
||||
ast::Expression* lhs) {
|
||||
Source source;
|
||||
if (!match(Token::Type::kOrOr))
|
||||
return lhs;
|
||||
@@ -2518,7 +2508,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_or_expr(
|
||||
|
||||
// logical_or_expression
|
||||
// : logical_and_expression logical_or_expr
|
||||
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_or_expression() {
|
||||
Maybe<ast::Expression*> ParserImpl::logical_or_expression() {
|
||||
auto lhs = logical_and_expression();
|
||||
if (lhs.errored)
|
||||
return Failure::kErrored;
|
||||
@@ -2530,7 +2520,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_or_expression() {
|
||||
|
||||
// assignment_stmt
|
||||
// : unary_expression EQUAL logical_or_expression
|
||||
Maybe<std::unique_ptr<ast::AssignmentStatement>> ParserImpl::assignment_stmt() {
|
||||
Maybe<ast::AssignmentStatement*> ParserImpl::assignment_stmt() {
|
||||
auto t = peek();
|
||||
auto source = t.source();
|
||||
|
||||
@@ -2559,7 +2549,7 @@ Maybe<std::unique_ptr<ast::AssignmentStatement>> ParserImpl::assignment_stmt() {
|
||||
// | FLOAT_LITERAL
|
||||
// | TRUE
|
||||
// | FALSE
|
||||
Maybe<std::unique_ptr<ast::Literal>> ParserImpl::const_literal() {
|
||||
Maybe<ast::Literal*> ParserImpl::const_literal() {
|
||||
auto t = peek();
|
||||
if (match(Token::Type::kTrue)) {
|
||||
auto* type = ctx_.type_mgr().Get(std::make_unique<ast::type::BoolType>());
|
||||
@@ -2587,13 +2577,12 @@ Maybe<std::unique_ptr<ast::Literal>> ParserImpl::const_literal() {
|
||||
// const_expr
|
||||
// : type_decl PAREN_LEFT (const_expr COMMA)? const_expr PAREN_RIGHT
|
||||
// | const_literal
|
||||
Expect<std::unique_ptr<ast::ConstructorExpression>>
|
||||
ParserImpl::expect_const_expr() {
|
||||
Expect<ast::ConstructorExpression*> ParserImpl::expect_const_expr() {
|
||||
return expect_const_expr_internal(0);
|
||||
}
|
||||
|
||||
Expect<std::unique_ptr<ast::ConstructorExpression>>
|
||||
ParserImpl::expect_const_expr_internal(uint32_t depth) {
|
||||
Expect<ast::ConstructorExpression*> ParserImpl::expect_const_expr_internal(
|
||||
uint32_t depth) {
|
||||
auto t = peek();
|
||||
|
||||
if (depth > kMaxConstExprDepth) {
|
||||
@@ -2706,7 +2695,7 @@ Maybe<bool> ParserImpl::decoration_bracketed_list(ast::DecorationList& decos) {
|
||||
});
|
||||
}
|
||||
|
||||
Expect<std::unique_ptr<ast::Decoration>> ParserImpl::expect_decoration() {
|
||||
Expect<ast::Decoration*> ParserImpl::expect_decoration() {
|
||||
auto t = peek();
|
||||
auto deco = decoration();
|
||||
if (deco.errored)
|
||||
@@ -2716,8 +2705,8 @@ Expect<std::unique_ptr<ast::Decoration>> ParserImpl::expect_decoration() {
|
||||
return add_error(t, "expected decoration");
|
||||
}
|
||||
|
||||
Maybe<std::unique_ptr<ast::Decoration>> ParserImpl::decoration() {
|
||||
using Result = Maybe<std::unique_ptr<ast::Decoration>>;
|
||||
Maybe<ast::Decoration*> ParserImpl::decoration() {
|
||||
using Result = Maybe<ast::Decoration*>;
|
||||
auto t = next();
|
||||
if (t.IsLocation()) {
|
||||
const char* use = "location decoration";
|
||||
@@ -2822,12 +2811,11 @@ Maybe<std::unique_ptr<ast::Decoration>> ParserImpl::decoration() {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Expect<std::vector<std::unique_ptr<T>>> ParserImpl::cast_decorations(
|
||||
ast::DecorationList& in) {
|
||||
Expect<std::vector<T*>> ParserImpl::cast_decorations(ast::DecorationList& in) {
|
||||
bool ok = true;
|
||||
std::vector<std::unique_ptr<T>> out;
|
||||
std::vector<T*> out;
|
||||
out.reserve(in.size());
|
||||
for (auto& deco : in) {
|
||||
for (auto* deco : in) {
|
||||
if (!deco->Is<T>()) {
|
||||
std::stringstream msg;
|
||||
msg << deco->GetKind() << " decoration type cannot be used for "
|
||||
|
||||
@@ -65,18 +65,16 @@ struct ForHeader {
|
||||
/// @param init the initializer statement
|
||||
/// @param cond the condition statement
|
||||
/// @param cont the continuing statement
|
||||
ForHeader(std::unique_ptr<ast::Statement> init,
|
||||
std::unique_ptr<ast::Expression> cond,
|
||||
std::unique_ptr<ast::Statement> cont);
|
||||
ForHeader(ast::Statement* init, ast::Expression* cond, ast::Statement* cont);
|
||||
|
||||
~ForHeader();
|
||||
|
||||
/// The for loop initializer
|
||||
std::unique_ptr<ast::Statement> initializer;
|
||||
ast::Statement* initializer = nullptr;
|
||||
/// The for loop condition
|
||||
std::unique_ptr<ast::Expression> condition;
|
||||
ast::Expression* condition = nullptr;
|
||||
/// The for loop continuing statement
|
||||
std::unique_ptr<ast::Statement> continuing;
|
||||
ast::Statement* continuing = nullptr;
|
||||
};
|
||||
|
||||
/// ParserImpl for WGSL source data
|
||||
@@ -301,14 +299,13 @@ class ParserImpl {
|
||||
/// `variable_decoration_list*` provided as |decos|.
|
||||
/// @returns the variable parsed or nullptr
|
||||
/// @param decos the list of decorations for the variable declaration.
|
||||
Maybe<std::unique_ptr<ast::Variable>> global_variable_decl(
|
||||
ast::DecorationList& decos);
|
||||
Maybe<ast::Variable*> global_variable_decl(ast::DecorationList& decos);
|
||||
/// Parses a `global_constant_decl` grammar element
|
||||
/// @returns the const object or nullptr
|
||||
Maybe<std::unique_ptr<ast::Variable>> global_constant_decl();
|
||||
Maybe<ast::Variable*> global_constant_decl();
|
||||
/// Parses a `variable_decl` grammar element
|
||||
/// @returns the parsed variable or nullptr otherwise
|
||||
Maybe<std::unique_ptr<ast::Variable>> variable_decl();
|
||||
Maybe<ast::Variable*> variable_decl();
|
||||
/// Parses a `variable_ident_decl` grammar element, erroring on parse
|
||||
/// failure.
|
||||
/// @param use a description of what was being parsed if an error was raised.
|
||||
@@ -341,14 +338,12 @@ class ParserImpl {
|
||||
/// failure.
|
||||
/// @param decos the list of decorations for the struct member.
|
||||
/// @returns the struct member or nullptr
|
||||
Expect<std::unique_ptr<ast::StructMember>> expect_struct_member(
|
||||
ast::DecorationList& decos);
|
||||
Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos);
|
||||
/// Parses a `function_decl` grammar element with the initial
|
||||
/// `function_decoration_decl*` provided as |decos|.
|
||||
/// @param decos the list of decorations for the function declaration.
|
||||
/// @returns the parsed function, nullptr otherwise
|
||||
Maybe<std::unique_ptr<ast::Function>> function_decl(
|
||||
ast::DecorationList& decos);
|
||||
Maybe<ast::Function*> function_decl(ast::DecorationList& decos);
|
||||
/// Parses a `texture_sampler_types` grammar element
|
||||
/// @returns the parsed Type or nullptr if none matched.
|
||||
Maybe<ast::type::Type*> texture_sampler_types();
|
||||
@@ -380,7 +375,7 @@ class ParserImpl {
|
||||
Maybe<ast::type::Type*> function_type_decl();
|
||||
/// Parses a `function_header` grammar element
|
||||
/// @returns the parsed function nullptr otherwise
|
||||
Maybe<std::unique_ptr<ast::Function>> function_header();
|
||||
Maybe<ast::Function*> function_header();
|
||||
/// Parses a `param_list` grammar element, erroring on parse failure.
|
||||
/// @returns the parsed variables
|
||||
Expect<ast::VariableList> expect_param_list();
|
||||
@@ -394,73 +389,73 @@ class ParserImpl {
|
||||
Expect<ast::Builtin> expect_builtin();
|
||||
/// Parses a `body_stmt` grammar element, erroring on parse failure.
|
||||
/// @returns the parsed statements
|
||||
Expect<std::unique_ptr<ast::BlockStatement>> expect_body_stmt();
|
||||
Expect<ast::BlockStatement*> expect_body_stmt();
|
||||
/// Parses a `paren_rhs_stmt` grammar element, erroring on parse failure.
|
||||
/// @returns the parsed element or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_paren_rhs_stmt();
|
||||
Expect<ast::Expression*> expect_paren_rhs_stmt();
|
||||
/// Parses a `statements` grammar element
|
||||
/// @returns the statements parsed
|
||||
Expect<std::unique_ptr<ast::BlockStatement>> expect_statements();
|
||||
Expect<ast::BlockStatement*> expect_statements();
|
||||
/// Parses a `statement` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::Statement>> statement();
|
||||
Maybe<ast::Statement*> statement();
|
||||
/// Parses a `break_stmt` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::BreakStatement>> break_stmt();
|
||||
Maybe<ast::BreakStatement*> break_stmt();
|
||||
/// Parses a `return_stmt` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::ReturnStatement>> return_stmt();
|
||||
Maybe<ast::ReturnStatement*> return_stmt();
|
||||
/// Parses a `continue_stmt` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::ContinueStatement>> continue_stmt();
|
||||
Maybe<ast::ContinueStatement*> continue_stmt();
|
||||
/// Parses a `variable_stmt` grammar element
|
||||
/// @returns the parsed variable or nullptr
|
||||
Maybe<std::unique_ptr<ast::VariableDeclStatement>> variable_stmt();
|
||||
Maybe<ast::VariableDeclStatement*> variable_stmt();
|
||||
/// Parses a `if_stmt` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::IfStatement>> if_stmt();
|
||||
Maybe<ast::IfStatement*> if_stmt();
|
||||
/// Parses a `elseif_stmt` grammar element
|
||||
/// @returns the parsed elements
|
||||
Maybe<ast::ElseStatementList> elseif_stmt();
|
||||
/// Parses a `else_stmt` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::ElseStatement>> else_stmt();
|
||||
Maybe<ast::ElseStatement*> else_stmt();
|
||||
/// Parses a `switch_stmt` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::SwitchStatement>> switch_stmt();
|
||||
Maybe<ast::SwitchStatement*> switch_stmt();
|
||||
/// Parses a `switch_body` grammar element
|
||||
/// @returns the parsed statement or nullptr
|
||||
Maybe<std::unique_ptr<ast::CaseStatement>> switch_body();
|
||||
Maybe<ast::CaseStatement*> switch_body();
|
||||
/// Parses a `case_selectors` grammar element
|
||||
/// @returns the list of literals
|
||||
Expect<ast::CaseSelectorList> expect_case_selectors();
|
||||
/// Parses a `case_body` grammar element
|
||||
/// @returns the parsed statements
|
||||
Maybe<std::unique_ptr<ast::BlockStatement>> case_body();
|
||||
Maybe<ast::BlockStatement*> case_body();
|
||||
/// Parses a `func_call_stmt` grammar element
|
||||
/// @returns the parsed function call or nullptr
|
||||
Maybe<std::unique_ptr<ast::CallStatement>> func_call_stmt();
|
||||
Maybe<ast::CallStatement*> func_call_stmt();
|
||||
/// Parses a `loop_stmt` grammar element
|
||||
/// @returns the parsed loop or nullptr
|
||||
Maybe<std::unique_ptr<ast::LoopStatement>> loop_stmt();
|
||||
Maybe<ast::LoopStatement*> loop_stmt();
|
||||
/// Parses a `for_header` grammar element, erroring on parse failure.
|
||||
/// @returns the parsed for header or nullptr
|
||||
Expect<std::unique_ptr<ForHeader>> expect_for_header();
|
||||
/// Parses a `for_stmt` grammar element
|
||||
/// @returns the parsed for loop or nullptr
|
||||
Maybe<std::unique_ptr<ast::Statement>> for_stmt();
|
||||
Maybe<ast::Statement*> for_stmt();
|
||||
/// Parses a `continuing_stmt` grammar element
|
||||
/// @returns the parsed statements
|
||||
Maybe<std::unique_ptr<ast::BlockStatement>> continuing_stmt();
|
||||
Maybe<ast::BlockStatement*> continuing_stmt();
|
||||
/// Parses a `const_literal` grammar element
|
||||
/// @returns the const literal parsed or nullptr if none found
|
||||
Maybe<std::unique_ptr<ast::Literal>> const_literal();
|
||||
Maybe<ast::Literal*> const_literal();
|
||||
/// Parses a `const_expr` grammar element, erroring on parse failure.
|
||||
/// @returns the parsed constructor expression or nullptr on error
|
||||
Expect<std::unique_ptr<ast::ConstructorExpression>> expect_const_expr();
|
||||
Expect<ast::ConstructorExpression*> expect_const_expr();
|
||||
/// Parses a `primary_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> primary_expression();
|
||||
Maybe<ast::Expression*> primary_expression();
|
||||
/// Parses a `argument_expression_list` grammar element, erroring on parse
|
||||
/// failure.
|
||||
/// @returns the list of arguments
|
||||
@@ -468,107 +463,96 @@ class ParserImpl {
|
||||
/// Parses the recursive portion of the postfix_expression
|
||||
/// @param prefix the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> postfix_expr(
|
||||
std::unique_ptr<ast::Expression> prefix);
|
||||
Maybe<ast::Expression*> postfix_expr(ast::Expression* prefix);
|
||||
/// Parses a `postfix_expression` grammar elment
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> postfix_expression();
|
||||
Maybe<ast::Expression*> postfix_expression();
|
||||
/// Parses a `unary_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> unary_expression();
|
||||
Maybe<ast::Expression*> unary_expression();
|
||||
/// Parses the recursive part of the `multiplicative_expression`, erroring on
|
||||
/// parse failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_multiplicative_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_multiplicative_expr(ast::Expression* lhs);
|
||||
/// Parses the `multiplicative_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> multiplicative_expression();
|
||||
Maybe<ast::Expression*> multiplicative_expression();
|
||||
/// Parses the recursive part of the `additive_expression`, erroring on parse
|
||||
/// failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_additive_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_additive_expr(ast::Expression* lhs);
|
||||
/// Parses the `additive_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> additive_expression();
|
||||
Maybe<ast::Expression*> additive_expression();
|
||||
/// Parses the recursive part of the `shift_expression`, erroring on parse
|
||||
/// failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_shift_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_shift_expr(ast::Expression* lhs);
|
||||
/// Parses the `shift_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> shift_expression();
|
||||
Maybe<ast::Expression*> shift_expression();
|
||||
/// Parses the recursive part of the `relational_expression`, erroring on
|
||||
/// parse failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_relational_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_relational_expr(ast::Expression* lhs);
|
||||
/// Parses the `relational_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> relational_expression();
|
||||
Maybe<ast::Expression*> relational_expression();
|
||||
/// Parses the recursive part of the `equality_expression`, erroring on parse
|
||||
/// failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_equality_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_equality_expr(ast::Expression* lhs);
|
||||
/// Parses the `equality_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> equality_expression();
|
||||
Maybe<ast::Expression*> equality_expression();
|
||||
/// Parses the recursive part of the `and_expression`, erroring on parse
|
||||
/// failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_and_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_and_expr(ast::Expression* lhs);
|
||||
/// Parses the `and_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> and_expression();
|
||||
Maybe<ast::Expression*> and_expression();
|
||||
/// Parses the recursive part of the `exclusive_or_expression`, erroring on
|
||||
/// parse failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_exclusive_or_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_exclusive_or_expr(ast::Expression* lhs);
|
||||
/// Parses the `exclusive_or_expression` grammar elememnt
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> exclusive_or_expression();
|
||||
Maybe<ast::Expression*> exclusive_or_expression();
|
||||
/// Parses the recursive part of the `inclusive_or_expression`, erroring on
|
||||
/// parse failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_inclusive_or_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_inclusive_or_expr(ast::Expression* lhs);
|
||||
/// Parses the `inclusive_or_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> inclusive_or_expression();
|
||||
Maybe<ast::Expression*> inclusive_or_expression();
|
||||
/// Parses the recursive part of the `logical_and_expression`, erroring on
|
||||
/// parse failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_logical_and_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_logical_and_expr(ast::Expression* lhs);
|
||||
/// Parses a `logical_and_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> logical_and_expression();
|
||||
Maybe<ast::Expression*> logical_and_expression();
|
||||
/// Parses the recursive part of the `logical_or_expression`, erroring on
|
||||
/// parse failure.
|
||||
/// @param lhs the left side of the expression
|
||||
/// @returns the parsed expression or nullptr
|
||||
Expect<std::unique_ptr<ast::Expression>> expect_logical_or_expr(
|
||||
std::unique_ptr<ast::Expression> lhs);
|
||||
Expect<ast::Expression*> expect_logical_or_expr(ast::Expression* lhs);
|
||||
/// Parses a `logical_or_expression` grammar element
|
||||
/// @returns the parsed expression or nullptr
|
||||
Maybe<std::unique_ptr<ast::Expression>> logical_or_expression();
|
||||
Maybe<ast::Expression*> logical_or_expression();
|
||||
/// Parses a `assignment_stmt` grammar element
|
||||
/// @returns the parsed assignment or nullptr
|
||||
Maybe<std::unique_ptr<ast::AssignmentStatement>> assignment_stmt();
|
||||
Maybe<ast::AssignmentStatement*> assignment_stmt();
|
||||
/// Parses one or more bracketed decoration lists.
|
||||
/// @return the parsed decoration list, or an empty list on error.
|
||||
Maybe<ast::DecorationList> decoration_list();
|
||||
@@ -585,12 +569,12 @@ class ParserImpl {
|
||||
/// * `global_const_decoration`
|
||||
/// * `function_decoration`
|
||||
/// @return the parsed decoration, or nullptr.
|
||||
Maybe<std::unique_ptr<ast::Decoration>> decoration();
|
||||
Maybe<ast::Decoration*> decoration();
|
||||
/// Parses a single decoration, reporting an error if the next token does not
|
||||
/// represent a decoration.
|
||||
/// @see #decoration for the full list of decorations this method parses.
|
||||
/// @return the parsed decoration, or nullptr on error.
|
||||
Expect<std::unique_ptr<ast::Decoration>> expect_decoration();
|
||||
Expect<ast::Decoration*> expect_decoration();
|
||||
|
||||
private:
|
||||
/// ReturnType resolves to the return type for the function or lambda F.
|
||||
@@ -730,8 +714,7 @@ class ParserImpl {
|
||||
/// Downcasts all the decorations in |list| to the type |T|, raising a parser
|
||||
/// error if any of the decorations aren't of the type |T|.
|
||||
template <typename T>
|
||||
Expect<std::vector<std::unique_ptr<T>>> cast_decorations(
|
||||
ast::DecorationList& in);
|
||||
Expect<std::vector<T*>> cast_decorations(ast::DecorationList& in);
|
||||
/// Reports an error if the decoration list |list| is not empty.
|
||||
/// Used to ensure that all decorations are consumed.
|
||||
bool expect_decorations_consumed(const ast::DecorationList& list);
|
||||
@@ -742,20 +725,22 @@ class ParserImpl {
|
||||
ast::ArrayDecorationList decos);
|
||||
Expect<ast::type::Type*> expect_type_decl_matrix(Token t);
|
||||
|
||||
Expect<std::unique_ptr<ast::ConstructorExpression>>
|
||||
expect_const_expr_internal(uint32_t depth);
|
||||
Expect<ast::ConstructorExpression*> expect_const_expr_internal(
|
||||
uint32_t depth);
|
||||
|
||||
Expect<ast::type::Type*> expect_type(const std::string& use);
|
||||
|
||||
Maybe<std::unique_ptr<ast::Statement>> non_block_statement();
|
||||
Maybe<std::unique_ptr<ast::Statement>> for_header_initializer();
|
||||
Maybe<std::unique_ptr<ast::Statement>> for_header_continuing();
|
||||
Maybe<ast::Statement*> non_block_statement();
|
||||
Maybe<ast::Statement*> for_header_initializer();
|
||||
Maybe<ast::Statement*> for_header_continuing();
|
||||
|
||||
/// @return a `std::unique_ptr` to a new `T` constructed with `args`
|
||||
/// @param args the arguments to forward to the constructor for `T`
|
||||
/// Creates a new `ast::Node` owned by the Context. When the Context is
|
||||
/// destructed, the `ast::Node` will also be destructed.
|
||||
/// @param args the arguments to pass to the type constructor
|
||||
/// @returns the node pointer
|
||||
template <typename T, typename... ARGS>
|
||||
std::unique_ptr<T> create(ARGS&&... args) const {
|
||||
return std::make_unique<T>(std::forward<ARGS>(args)...);
|
||||
T* create(ARGS&&... args) {
|
||||
return ctx_.create<T>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
Context& ctx_;
|
||||
|
||||
@@ -30,8 +30,8 @@ TEST_F(ParserImplTest, FunctionDecorationList_Parses) {
|
||||
EXPECT_TRUE(decos.matched);
|
||||
ASSERT_EQ(decos.value.size(), 2u);
|
||||
|
||||
auto deco_0 = ast::As<ast::FunctionDecoration>(std::move(decos.value[0]));
|
||||
auto deco_1 = ast::As<ast::FunctionDecoration>(std::move(decos.value[1]));
|
||||
auto* deco_0 = ast::As<ast::FunctionDecoration>(std::move(decos.value[0]));
|
||||
auto* deco_1 = ast::As<ast::FunctionDecoration>(std::move(decos.value[1]));
|
||||
ASSERT_NE(deco_0, nullptr);
|
||||
ASSERT_NE(deco_1, nullptr);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Workgroup) {
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr) << p->error();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(func_deco, nullptr);
|
||||
ASSERT_TRUE(func_deco->IsWorkgroup());
|
||||
|
||||
@@ -50,7 +50,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Workgroup_2Param) {
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr) << p->error();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(func_deco, nullptr) << p->error();
|
||||
ASSERT_TRUE(func_deco->IsWorkgroup());
|
||||
|
||||
@@ -70,7 +70,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Workgroup_3Param) {
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr) << p->error();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(func_deco, nullptr);
|
||||
ASSERT_TRUE(func_deco->IsWorkgroup());
|
||||
|
||||
@@ -257,7 +257,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Stage) {
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr) << p->error();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
auto func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
auto* func_deco = ast::As<ast::FunctionDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(func_deco, nullptr);
|
||||
ASSERT_TRUE(func_deco->IsStage());
|
||||
EXPECT_EQ(func_deco->AsStage()->value(), ast::PipelineStage::kCompute);
|
||||
|
||||
@@ -37,7 +37,7 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalVariable) {
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.global_variables().size(), 1u);
|
||||
|
||||
auto* v = m.global_variables()[0].get();
|
||||
auto* v = m.global_variables()[0];
|
||||
EXPECT_EQ(v->name(), "a");
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalConstant) {
|
||||
auto m = p->module();
|
||||
ASSERT_EQ(m.global_variables().size(), 1u);
|
||||
|
||||
auto* v = m.global_variables()[0].get();
|
||||
auto* v = m.global_variables()[0];
|
||||
EXPECT_EQ(v->name(), "a");
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ TEST_F(ParserImplTest, Statement) {
|
||||
|
||||
TEST_F(ParserImplTest, Statement_Semicolon) {
|
||||
auto* p = parser(";");
|
||||
auto e = p->statement();
|
||||
p->statement();
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ TEST_F(ParserImplTest, StructBodyDecl_Parses) {
|
||||
ASSERT_FALSE(m.errored);
|
||||
ASSERT_EQ(m.value.size(), 1u);
|
||||
|
||||
const auto& mem = m.value[0];
|
||||
const auto* mem = m.value[0];
|
||||
EXPECT_EQ(mem->name(), "a");
|
||||
EXPECT_EQ(mem->type(), i32);
|
||||
EXPECT_EQ(mem->decorations().size(), 0u);
|
||||
|
||||
@@ -28,7 +28,7 @@ TEST_F(ParserImplTest, StructDecorationDecl_Parses) {
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
ASSERT_EQ(decos.value.size(), 1u);
|
||||
auto struct_deco = ast::As<ast::StructDecoration>(std::move(decos.value[0]));
|
||||
auto* struct_deco = ast::As<ast::StructDecoration>(std::move(decos.value[0]));
|
||||
EXPECT_TRUE(struct_deco->IsBlock());
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ TEST_P(StructDecorationTest, Parses) {
|
||||
EXPECT_TRUE(deco.matched);
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr);
|
||||
auto struct_deco = ast::As<ast::StructDecoration>(std::move(deco.value));
|
||||
auto* struct_deco = ast::As<ast::StructDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(struct_deco, nullptr);
|
||||
EXPECT_EQ(struct_deco->IsBlock(), params.is_block);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ TEST_F(ParserImplTest, StructMemberDecorationDecl_Single) {
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
ASSERT_EQ(decos.value.size(), 1u);
|
||||
auto deco = ast::As<ast::StructMemberDecoration>(std::move(decos.value[0]));
|
||||
auto* deco = ast::As<ast::StructMemberDecoration>(std::move(decos.value[0]));
|
||||
ASSERT_NE(deco, nullptr);
|
||||
EXPECT_TRUE(deco->IsOffset());
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ TEST_F(ParserImplTest, StructMemberDecoration_Offset) {
|
||||
ASSERT_NE(deco.value, nullptr);
|
||||
ASSERT_FALSE(p->has_error());
|
||||
|
||||
auto member_deco =
|
||||
auto* member_deco =
|
||||
ast::As<ast::StructMemberDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(member_deco, nullptr);
|
||||
ASSERT_TRUE(member_deco->IsOffset());
|
||||
|
||||
@@ -31,8 +31,8 @@ TEST_F(ParserImplTest, VariableDecorationList_Parses) {
|
||||
ASSERT_TRUE(decos.matched);
|
||||
ASSERT_EQ(decos.value.size(), 2u);
|
||||
|
||||
auto deco_0 = ast::As<ast::VariableDecoration>(std::move(decos.value[0]));
|
||||
auto deco_1 = ast::As<ast::VariableDecoration>(std::move(decos.value[1]));
|
||||
auto* deco_0 = ast::As<ast::VariableDecoration>(std::move(decos.value[0]));
|
||||
auto* deco_1 = ast::As<ast::VariableDecoration>(std::move(decos.value[1]));
|
||||
ASSERT_NE(deco_0, nullptr);
|
||||
ASSERT_NE(deco_1, nullptr);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ TEST_F(ParserImplTest, VariableDecoration_Location) {
|
||||
EXPECT_TRUE(deco.matched);
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr);
|
||||
auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(var_deco, nullptr);
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_TRUE(var_deco->IsLocation());
|
||||
@@ -101,7 +101,7 @@ TEST_P(BuiltinTest, VariableDecoration_Builtin) {
|
||||
EXPECT_TRUE(deco.matched);
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr);
|
||||
auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(var_deco, nullptr);
|
||||
ASSERT_TRUE(var_deco->IsBuiltin());
|
||||
@@ -180,7 +180,7 @@ TEST_F(ParserImplTest, VariableDecoration_Binding) {
|
||||
EXPECT_TRUE(deco.matched);
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr);
|
||||
auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
ASSERT_NE(var_deco, nullptr);
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_TRUE(var_deco->IsBinding());
|
||||
@@ -237,9 +237,9 @@ TEST_F(ParserImplTest, VariableDecoration_set) {
|
||||
EXPECT_TRUE(deco.matched);
|
||||
EXPECT_FALSE(deco.errored);
|
||||
ASSERT_NE(deco.value, nullptr);
|
||||
auto var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
auto* var_deco = ast::As<ast::VariableDecoration>(std::move(deco.value));
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(var_deco.get(), nullptr);
|
||||
ASSERT_NE(var_deco, nullptr);
|
||||
ASSERT_TRUE(var_deco->IsSet());
|
||||
|
||||
auto* set = var_deco->AsSet();
|
||||
|
||||
Reference in New Issue
Block a user