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:
Ben Clayton 2020-11-16 16:31:07 +00:00 committed by Commit Bot service account
parent 0613890eed
commit b053acf796
209 changed files with 3469 additions and 3608 deletions

View File

@ -19,18 +19,14 @@ namespace ast {
ArrayAccessorExpression::ArrayAccessorExpression() : Expression() {} ArrayAccessorExpression::ArrayAccessorExpression() : Expression() {}
ArrayAccessorExpression::ArrayAccessorExpression( ArrayAccessorExpression::ArrayAccessorExpression(Expression* array,
std::unique_ptr<Expression> array, Expression* idx_expr)
std::unique_ptr<Expression> idx_expr) : Expression(), array_(array), idx_expr_(idx_expr) {}
: Expression(), array_(std::move(array)), idx_expr_(std::move(idx_expr)) {}
ArrayAccessorExpression::ArrayAccessorExpression( ArrayAccessorExpression::ArrayAccessorExpression(const Source& source,
const Source& source, Expression* array,
std::unique_ptr<Expression> array, Expression* idx_expr)
std::unique_ptr<Expression> idx_expr) : Expression(source), array_(array), idx_expr_(idx_expr) {}
: Expression(source),
array_(std::move(array)),
idx_expr_(std::move(idx_expr)) {}
ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) = ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) =
default; default;

View File

@ -32,37 +32,29 @@ class ArrayAccessorExpression : public Expression {
/// Constructor /// Constructor
/// @param array the array /// @param array the array
/// @param idx_expr the index expression /// @param idx_expr the index expression
ArrayAccessorExpression(std::unique_ptr<Expression> array, ArrayAccessorExpression(Expression* array, Expression* idx_expr);
std::unique_ptr<Expression> idx_expr);
/// Constructor /// Constructor
/// @param source the array accessor source /// @param source the array accessor source
/// @param array the array /// @param array the array
/// @param idx_expr the index expression /// @param idx_expr the index expression
ArrayAccessorExpression(const Source& source, ArrayAccessorExpression(const Source& source,
std::unique_ptr<Expression> array, Expression* array,
std::unique_ptr<Expression> idx_expr); Expression* idx_expr);
/// Move constructor /// Move constructor
ArrayAccessorExpression(ArrayAccessorExpression&&); ArrayAccessorExpression(ArrayAccessorExpression&&);
~ArrayAccessorExpression() override; ~ArrayAccessorExpression() override;
/// Sets the array /// Sets the array
/// @param array the array /// @param array the array
void set_array(std::unique_ptr<Expression> array) { void set_array(Expression* array) { array_ = array; }
array_ = std::move(array);
}
/// @returns the array /// @returns the array
Expression* array() const { return array_.get(); } Expression* array() const { return array_; }
/// Sets the index expression /// Sets the index expression
/// @param idx_expr the index expression /// @param idx_expr the index expression
void set_idx_expr(std::unique_ptr<Expression> idx_expr) { void set_idx_expr(Expression* idx_expr) { idx_expr_ = idx_expr; }
idx_expr_ = std::move(idx_expr);
}
/// @returns the index expression /// @returns the index expression
Expression* idx_expr() const { return idx_expr_.get(); } Expression* idx_expr() const { return idx_expr_; }
/// Removes the index expression from the array accessor
/// @returns the unique pointer to the index expression
std::unique_ptr<Expression> take_idx_expr() { return std::move(idx_expr_); }
/// @returns true if this is an array accessor expression /// @returns true if this is an array accessor expression
bool IsArrayAccessor() const override; bool IsArrayAccessor() const override;
@ -78,8 +70,8 @@ class ArrayAccessorExpression : public Expression {
private: private:
ArrayAccessorExpression(const ArrayAccessorExpression&) = delete; ArrayAccessorExpression(const ArrayAccessorExpression&) = delete;
std::unique_ptr<Expression> array_; Expression* array_ = nullptr;
std::unique_ptr<Expression> idx_expr_; Expression* idx_expr_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -24,19 +24,19 @@ namespace {
using ArrayAccessorExpressionTest = TestHelper; using ArrayAccessorExpressionTest = TestHelper;
TEST_F(ArrayAccessorExpressionTest, Create) { TEST_F(ArrayAccessorExpressionTest, Create) {
auto ary = create<IdentifierExpression>("ary"); auto* ary = create<IdentifierExpression>("ary");
auto idx = create<IdentifierExpression>("idx"); auto* idx = create<IdentifierExpression>("idx");
auto* ary_ptr = ary.get(); auto* ary_ptr = ary;
auto* idx_ptr = idx.get(); auto* idx_ptr = idx;
ArrayAccessorExpression exp(std::move(ary), std::move(idx)); ArrayAccessorExpression exp(std::move(ary), std::move(idx));
ASSERT_EQ(exp.array(), ary_ptr); ASSERT_EQ(exp.array(), ary_ptr);
ASSERT_EQ(exp.idx_expr(), idx_ptr); ASSERT_EQ(exp.idx_expr(), idx_ptr);
} }
TEST_F(ArrayAccessorExpressionTest, CreateWithSource) { TEST_F(ArrayAccessorExpressionTest, CreateWithSource) {
auto ary = create<IdentifierExpression>("ary"); auto* ary = create<IdentifierExpression>("ary");
auto idx = create<IdentifierExpression>("idx"); auto* idx = create<IdentifierExpression>("idx");
ArrayAccessorExpression exp(Source{Source::Location{20, 2}}, std::move(ary), ArrayAccessorExpression exp(Source{Source::Location{20, 2}}, std::move(ary),
std::move(idx)); std::move(idx));
@ -51,15 +51,15 @@ TEST_F(ArrayAccessorExpressionTest, IsArrayAccessor) {
} }
TEST_F(ArrayAccessorExpressionTest, IsValid) { TEST_F(ArrayAccessorExpressionTest, IsValid) {
auto ary = create<IdentifierExpression>("ary"); auto* ary = create<IdentifierExpression>("ary");
auto idx = create<IdentifierExpression>("idx"); auto* idx = create<IdentifierExpression>("idx");
ArrayAccessorExpression exp(std::move(ary), std::move(idx)); ArrayAccessorExpression exp(std::move(ary), std::move(idx));
EXPECT_TRUE(exp.IsValid()); EXPECT_TRUE(exp.IsValid());
} }
TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) { TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) {
auto idx = create<IdentifierExpression>("idx"); auto* idx = create<IdentifierExpression>("idx");
ArrayAccessorExpression exp; ArrayAccessorExpression exp;
exp.set_idx_expr(std::move(idx)); exp.set_idx_expr(std::move(idx));
@ -67,7 +67,7 @@ TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) {
} }
TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) { TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) {
auto ary = create<IdentifierExpression>("ary"); auto* ary = create<IdentifierExpression>("ary");
ArrayAccessorExpression exp; ArrayAccessorExpression exp;
exp.set_array(std::move(ary)); exp.set_array(std::move(ary));
@ -75,22 +75,22 @@ TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) {
} }
TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidArray) { TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidArray) {
auto ary = create<IdentifierExpression>(""); auto* ary = create<IdentifierExpression>("");
auto idx = create<IdentifierExpression>("idx"); auto* idx = create<IdentifierExpression>("idx");
ArrayAccessorExpression exp(std::move(ary), std::move(idx)); ArrayAccessorExpression exp(std::move(ary), std::move(idx));
EXPECT_FALSE(exp.IsValid()); EXPECT_FALSE(exp.IsValid());
} }
TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidIndex) { TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidIndex) {
auto ary = create<IdentifierExpression>("ary"); auto* ary = create<IdentifierExpression>("ary");
auto idx = create<IdentifierExpression>(""); auto* idx = create<IdentifierExpression>("");
ArrayAccessorExpression exp(std::move(ary), std::move(idx)); ArrayAccessorExpression exp(std::move(ary), std::move(idx));
EXPECT_FALSE(exp.IsValid()); EXPECT_FALSE(exp.IsValid());
} }
TEST_F(ArrayAccessorExpressionTest, ToStr) { TEST_F(ArrayAccessorExpressionTest, ToStr) {
auto ary = create<IdentifierExpression>("ary"); auto* ary = create<IdentifierExpression>("ary");
auto idx = create<IdentifierExpression>("idx"); auto* idx = create<IdentifierExpression>("idx");
ArrayAccessorExpression exp(std::move(ary), std::move(idx)); ArrayAccessorExpression exp(std::move(ary), std::move(idx));
std::ostringstream out; std::ostringstream out;

View File

@ -46,8 +46,8 @@ class ArrayDecoration : public Decoration {
explicit ArrayDecoration(const Source& source); explicit ArrayDecoration(const Source& source);
}; };
/// A list of unique array decorations /// A list of array decorations
using ArrayDecorationList = std::vector<std::unique_ptr<ArrayDecoration>>; using ArrayDecorationList = std::vector<ArrayDecoration*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -19,14 +19,13 @@ namespace ast {
AssignmentStatement::AssignmentStatement() : Statement() {} AssignmentStatement::AssignmentStatement() : Statement() {}
AssignmentStatement::AssignmentStatement(std::unique_ptr<Expression> lhs, AssignmentStatement::AssignmentStatement(Expression* lhs, Expression* rhs)
std::unique_ptr<Expression> rhs) : Statement(), lhs_(lhs), rhs_(rhs) {}
: Statement(), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
AssignmentStatement::AssignmentStatement(const Source& source, AssignmentStatement::AssignmentStatement(const Source& source,
std::unique_ptr<Expression> lhs, Expression* lhs,
std::unique_ptr<Expression> rhs) Expression* rhs)
: Statement(source), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {} : Statement(source), lhs_(lhs), rhs_(rhs) {}
AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default; AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;

View File

@ -33,30 +33,27 @@ class AssignmentStatement : public Statement {
/// Constructor /// Constructor
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @param rhs the right side of the expression /// @param rhs the right side of the expression
AssignmentStatement(std::unique_ptr<Expression> lhs, AssignmentStatement(Expression* lhs, Expression* rhs);
std::unique_ptr<Expression> rhs);
/// Constructor /// Constructor
/// @param source the assignment statement source /// @param source the assignment statement source
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @param rhs the right side of the expression /// @param rhs the right side of the expression
AssignmentStatement(const Source& source, AssignmentStatement(const Source& source, Expression* lhs, Expression* rhs);
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs);
/// Move constructor /// Move constructor
AssignmentStatement(AssignmentStatement&&); AssignmentStatement(AssignmentStatement&&);
~AssignmentStatement() override; ~AssignmentStatement() override;
/// Sets the left side of the statement /// Sets the left side of the statement
/// @param lhs the left side to set /// @param lhs the left side to set
void set_lhs(std::unique_ptr<Expression> lhs) { lhs_ = std::move(lhs); } void set_lhs(Expression* lhs) { lhs_ = lhs; }
/// @returns the left side expression /// @returns the left side expression
Expression* lhs() const { return lhs_.get(); } Expression* lhs() const { return lhs_; }
/// Sets the right side of the statement /// Sets the right side of the statement
/// @param rhs the right side to set /// @param rhs the right side to set
void set_rhs(std::unique_ptr<Expression> rhs) { rhs_ = std::move(rhs); } void set_rhs(Expression* rhs) { rhs_ = rhs; }
/// @returns the right side expression /// @returns the right side expression
Expression* rhs() const { return rhs_.get(); } Expression* rhs() const { return rhs_; }
/// @returns true if this is an assignment statement /// @returns true if this is an assignment statement
bool IsAssign() const override; bool IsAssign() const override;
@ -72,8 +69,8 @@ class AssignmentStatement : public Statement {
private: private:
AssignmentStatement(const AssignmentStatement&) = delete; AssignmentStatement(const AssignmentStatement&) = delete;
std::unique_ptr<Expression> lhs_; Expression* lhs_ = nullptr;
std::unique_ptr<Expression> rhs_; Expression* rhs_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -24,11 +24,11 @@ namespace {
using AssignmentStatementTest = TestHelper; using AssignmentStatementTest = TestHelper;
TEST_F(AssignmentStatementTest, Creation) { TEST_F(AssignmentStatementTest, Creation) {
auto lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");
auto* lhs_ptr = lhs.get(); auto* lhs_ptr = lhs;
auto* rhs_ptr = rhs.get(); auto* rhs_ptr = rhs;
AssignmentStatement stmt(std::move(lhs), std::move(rhs)); AssignmentStatement stmt(std::move(lhs), std::move(rhs));
EXPECT_EQ(stmt.lhs(), lhs_ptr); EXPECT_EQ(stmt.lhs(), lhs_ptr);
@ -36,8 +36,8 @@ TEST_F(AssignmentStatementTest, Creation) {
} }
TEST_F(AssignmentStatementTest, CreationWithSource) { TEST_F(AssignmentStatementTest, CreationWithSource) {
auto lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");
AssignmentStatement stmt(Source{Source::Location{20, 2}}, std::move(lhs), AssignmentStatement stmt(Source{Source::Location{20, 2}}, std::move(lhs),
std::move(rhs)); std::move(rhs));
@ -47,23 +47,23 @@ TEST_F(AssignmentStatementTest, CreationWithSource) {
} }
TEST_F(AssignmentStatementTest, IsAssign) { TEST_F(AssignmentStatementTest, IsAssign) {
auto lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");
AssignmentStatement stmt(std::move(lhs), std::move(rhs)); AssignmentStatement stmt(std::move(lhs), std::move(rhs));
EXPECT_TRUE(stmt.IsAssign()); EXPECT_TRUE(stmt.IsAssign());
} }
TEST_F(AssignmentStatementTest, IsValid) { TEST_F(AssignmentStatementTest, IsValid) {
auto lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");
AssignmentStatement stmt(std::move(lhs), std::move(rhs)); AssignmentStatement stmt(std::move(lhs), std::move(rhs));
EXPECT_TRUE(stmt.IsValid()); EXPECT_TRUE(stmt.IsValid());
} }
TEST_F(AssignmentStatementTest, IsValid_MissingLHS) { TEST_F(AssignmentStatementTest, IsValid_MissingLHS) {
auto rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");
AssignmentStatement stmt; AssignmentStatement stmt;
stmt.set_rhs(std::move(rhs)); stmt.set_rhs(std::move(rhs));
@ -71,7 +71,7 @@ TEST_F(AssignmentStatementTest, IsValid_MissingLHS) {
} }
TEST_F(AssignmentStatementTest, IsValid_MissingRHS) { TEST_F(AssignmentStatementTest, IsValid_MissingRHS) {
auto lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
AssignmentStatement stmt; AssignmentStatement stmt;
stmt.set_lhs(std::move(lhs)); stmt.set_lhs(std::move(lhs));
@ -79,22 +79,22 @@ TEST_F(AssignmentStatementTest, IsValid_MissingRHS) {
} }
TEST_F(AssignmentStatementTest, IsValid_InvalidLHS) { TEST_F(AssignmentStatementTest, IsValid_InvalidLHS) {
auto lhs = create<ast::IdentifierExpression>(""); auto* lhs = create<ast::IdentifierExpression>("");
auto rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");
AssignmentStatement stmt(std::move(lhs), std::move(rhs)); AssignmentStatement stmt(std::move(lhs), std::move(rhs));
EXPECT_FALSE(stmt.IsValid()); EXPECT_FALSE(stmt.IsValid());
} }
TEST_F(AssignmentStatementTest, IsValid_InvalidRHS) { TEST_F(AssignmentStatementTest, IsValid_InvalidRHS) {
auto lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto rhs = create<ast::IdentifierExpression>(""); auto* rhs = create<ast::IdentifierExpression>("");
AssignmentStatement stmt(std::move(lhs), std::move(rhs)); AssignmentStatement stmt(std::move(lhs), std::move(rhs));
EXPECT_FALSE(stmt.IsValid()); EXPECT_FALSE(stmt.IsValid());
} }
TEST_F(AssignmentStatementTest, ToStr) { TEST_F(AssignmentStatementTest, ToStr) {
auto lhs = create<ast::IdentifierExpression>("lhs"); auto* lhs = create<ast::IdentifierExpression>("lhs");
auto rhs = create<ast::IdentifierExpression>("rhs"); auto* rhs = create<ast::IdentifierExpression>("rhs");
AssignmentStatement stmt(std::move(lhs), std::move(rhs)); AssignmentStatement stmt(std::move(lhs), std::move(rhs));
std::ostringstream out; std::ostringstream out;

View File

@ -20,15 +20,15 @@ namespace ast {
BinaryExpression::BinaryExpression() : Expression() {} BinaryExpression::BinaryExpression() : Expression() {}
BinaryExpression::BinaryExpression(BinaryOp op, BinaryExpression::BinaryExpression(BinaryOp op,
std::unique_ptr<Expression> lhs, Expression* lhs,
std::unique_ptr<Expression> rhs) Expression* rhs)
: Expression(), op_(op), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {} : Expression(), op_(op), lhs_(lhs), rhs_(rhs) {}
BinaryExpression::BinaryExpression(const Source& source, BinaryExpression::BinaryExpression(const Source& source,
BinaryOp op, BinaryOp op,
std::unique_ptr<Expression> lhs, Expression* lhs,
std::unique_ptr<Expression> rhs) Expression* rhs)
: Expression(source), op_(op), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {} : Expression(source), op_(op), lhs_(lhs), rhs_(rhs) {}
BinaryExpression::BinaryExpression(BinaryExpression&&) = default; BinaryExpression::BinaryExpression(BinaryExpression&&) = default;

View File

@ -56,9 +56,7 @@ class BinaryExpression : public Expression {
/// @param op the operation type /// @param op the operation type
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @param rhs the right side of the expression /// @param rhs the right side of the expression
BinaryExpression(BinaryOp op, BinaryExpression(BinaryOp op, Expression* lhs, Expression* rhs);
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs);
/// Constructor /// Constructor
/// @param source the binary expression source /// @param source the binary expression source
/// @param op the operation type /// @param op the operation type
@ -66,8 +64,8 @@ class BinaryExpression : public Expression {
/// @param rhs the right side of the expression /// @param rhs the right side of the expression
BinaryExpression(const Source& source, BinaryExpression(const Source& source,
BinaryOp op, BinaryOp op,
std::unique_ptr<Expression> lhs, Expression* lhs,
std::unique_ptr<Expression> rhs); Expression* rhs);
/// Move constructor /// Move constructor
BinaryExpression(BinaryExpression&&); BinaryExpression(BinaryExpression&&);
~BinaryExpression() override; ~BinaryExpression() override;
@ -117,15 +115,15 @@ class BinaryExpression : public Expression {
/// Sets the left side of the expression /// Sets the left side of the expression
/// @param lhs the left side to set /// @param lhs the left side to set
void set_lhs(std::unique_ptr<Expression> lhs) { lhs_ = std::move(lhs); } void set_lhs(Expression* lhs) { lhs_ = lhs; }
/// @returns the left side expression /// @returns the left side expression
Expression* lhs() const { return lhs_.get(); } Expression* lhs() const { return lhs_; }
/// Sets the right side of the expression /// Sets the right side of the expression
/// @param rhs the right side to set /// @param rhs the right side to set
void set_rhs(std::unique_ptr<Expression> rhs) { rhs_ = std::move(rhs); } void set_rhs(Expression* rhs) { rhs_ = rhs; }
/// @returns the right side expression /// @returns the right side expression
Expression* rhs() const { return rhs_.get(); } Expression* rhs() const { return rhs_; }
/// @returns true if this is a op expression /// @returns true if this is a op expression
bool IsBinary() const override; bool IsBinary() const override;
@ -142,8 +140,8 @@ class BinaryExpression : public Expression {
BinaryExpression(const BinaryExpression&) = delete; BinaryExpression(const BinaryExpression&) = delete;
BinaryOp op_ = BinaryOp::kNone; BinaryOp op_ = BinaryOp::kNone;
std::unique_ptr<Expression> lhs_; Expression* lhs_ = nullptr;
std::unique_ptr<Expression> rhs_; Expression* rhs_ = nullptr;
}; };
inline std::ostream& operator<<(std::ostream& out, BinaryOp op) { inline std::ostream& operator<<(std::ostream& out, BinaryOp op) {

View File

@ -26,11 +26,11 @@ namespace {
using BinaryExpressionTest = TestHelper; using BinaryExpressionTest = TestHelper;
TEST_F(BinaryExpressionTest, Creation) { TEST_F(BinaryExpressionTest, Creation) {
auto lhs = create<IdentifierExpression>("lhs"); auto* lhs = create<IdentifierExpression>("lhs");
auto rhs = create<IdentifierExpression>("rhs"); auto* rhs = create<IdentifierExpression>("rhs");
auto* lhs_ptr = lhs.get(); auto* lhs_ptr = lhs;
auto* rhs_ptr = rhs.get(); auto* rhs_ptr = rhs;
BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs)); BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
EXPECT_EQ(r.lhs(), lhs_ptr); EXPECT_EQ(r.lhs(), lhs_ptr);
@ -39,8 +39,8 @@ TEST_F(BinaryExpressionTest, Creation) {
} }
TEST_F(BinaryExpressionTest, Creation_WithSource) { TEST_F(BinaryExpressionTest, Creation_WithSource) {
auto lhs = create<IdentifierExpression>("lhs"); auto* lhs = create<IdentifierExpression>("lhs");
auto rhs = create<IdentifierExpression>("rhs"); auto* rhs = create<IdentifierExpression>("rhs");
BinaryExpression r(Source{Source::Location{20, 2}}, BinaryOp::kEqual, BinaryExpression r(Source{Source::Location{20, 2}}, BinaryOp::kEqual,
std::move(lhs), std::move(rhs)); std::move(lhs), std::move(rhs));
@ -55,15 +55,15 @@ TEST_F(BinaryExpressionTest, IsBinaryal) {
} }
TEST_F(BinaryExpressionTest, IsValid) { TEST_F(BinaryExpressionTest, IsValid) {
auto lhs = create<IdentifierExpression>("lhs"); auto* lhs = create<IdentifierExpression>("lhs");
auto rhs = create<IdentifierExpression>("rhs"); auto* rhs = create<IdentifierExpression>("rhs");
BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs)); BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
EXPECT_TRUE(r.IsValid()); EXPECT_TRUE(r.IsValid());
} }
TEST_F(BinaryExpressionTest, IsValid_Null_LHS) { TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
auto rhs = create<IdentifierExpression>("rhs"); auto* rhs = create<IdentifierExpression>("rhs");
BinaryExpression r; BinaryExpression r;
r.set_op(BinaryOp::kEqual); r.set_op(BinaryOp::kEqual);
@ -72,15 +72,15 @@ TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
} }
TEST_F(BinaryExpressionTest, IsValid_Invalid_LHS) { TEST_F(BinaryExpressionTest, IsValid_Invalid_LHS) {
auto lhs = create<IdentifierExpression>(""); auto* lhs = create<IdentifierExpression>("");
auto rhs = create<IdentifierExpression>("rhs"); auto* rhs = create<IdentifierExpression>("rhs");
BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs)); BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
EXPECT_FALSE(r.IsValid()); EXPECT_FALSE(r.IsValid());
} }
TEST_F(BinaryExpressionTest, IsValid_Null_RHS) { TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
auto lhs = create<IdentifierExpression>("lhs"); auto* lhs = create<IdentifierExpression>("lhs");
BinaryExpression r; BinaryExpression r;
r.set_op(BinaryOp::kEqual); r.set_op(BinaryOp::kEqual);
@ -89,24 +89,24 @@ TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
} }
TEST_F(BinaryExpressionTest, IsValid_Invalid_RHS) { TEST_F(BinaryExpressionTest, IsValid_Invalid_RHS) {
auto lhs = create<IdentifierExpression>("lhs"); auto* lhs = create<IdentifierExpression>("lhs");
auto rhs = create<IdentifierExpression>(""); auto* rhs = create<IdentifierExpression>("");
BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs)); BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
EXPECT_FALSE(r.IsValid()); EXPECT_FALSE(r.IsValid());
} }
TEST_F(BinaryExpressionTest, IsValid_Binary_None) { TEST_F(BinaryExpressionTest, IsValid_Binary_None) {
auto lhs = create<IdentifierExpression>("lhs"); auto* lhs = create<IdentifierExpression>("lhs");
auto rhs = create<IdentifierExpression>("rhs"); auto* rhs = create<IdentifierExpression>("rhs");
BinaryExpression r(BinaryOp::kNone, std::move(lhs), std::move(rhs)); BinaryExpression r(BinaryOp::kNone, std::move(lhs), std::move(rhs));
EXPECT_FALSE(r.IsValid()); EXPECT_FALSE(r.IsValid());
} }
TEST_F(BinaryExpressionTest, ToStr) { TEST_F(BinaryExpressionTest, ToStr) {
auto lhs = create<IdentifierExpression>("lhs"); auto* lhs = create<IdentifierExpression>("lhs");
auto rhs = create<IdentifierExpression>("rhs"); auto* rhs = create<IdentifierExpression>("rhs");
BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs)); BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
std::ostringstream out; std::ostringstream out;

View File

@ -19,14 +19,13 @@ namespace ast {
BitcastExpression::BitcastExpression() : Expression() {} BitcastExpression::BitcastExpression() : Expression() {}
BitcastExpression::BitcastExpression(type::Type* type, BitcastExpression::BitcastExpression(type::Type* type, Expression* expr)
std::unique_ptr<Expression> expr) : Expression(), type_(type), expr_(expr) {}
: Expression(), type_(type), expr_(std::move(expr)) {}
BitcastExpression::BitcastExpression(const Source& source, BitcastExpression::BitcastExpression(const Source& source,
type::Type* type, type::Type* type,
std::unique_ptr<Expression> expr) Expression* expr)
: Expression(source), type_(type), expr_(std::move(expr)) {} : Expression(source), type_(type), expr_(expr) {}
BitcastExpression::BitcastExpression(BitcastExpression&&) = default; BitcastExpression::BitcastExpression(BitcastExpression&&) = default;
BitcastExpression::~BitcastExpression() = default; BitcastExpression::~BitcastExpression() = default;

View File

@ -33,29 +33,27 @@ class BitcastExpression : public Expression {
/// Constructor /// Constructor
/// @param type the type /// @param type the type
/// @param expr the expr /// @param expr the expr
BitcastExpression(type::Type* type, std::unique_ptr<Expression> expr); BitcastExpression(type::Type* type, Expression* expr);
/// Constructor /// Constructor
/// @param source the bitcast expression source /// @param source the bitcast expression source
/// @param type the type /// @param type the type
/// @param expr the expr /// @param expr the expr
BitcastExpression(const Source& source, BitcastExpression(const Source& source, type::Type* type, Expression* expr);
type::Type* type,
std::unique_ptr<Expression> expr);
/// Move constructor /// Move constructor
BitcastExpression(BitcastExpression&&); BitcastExpression(BitcastExpression&&);
~BitcastExpression() override; ~BitcastExpression() override;
/// Sets the type /// Sets the type
/// @param type the type /// @param type the type
void set_type(type::Type* type) { type_ = std::move(type); } void set_type(type::Type* type) { type_ = type; }
/// @returns the left side expression /// @returns the left side expression
type::Type* type() const { return type_; } type::Type* type() const { return type_; }
/// Sets the expr /// Sets the expr
/// @param expr the expression /// @param expr the expression
void set_expr(std::unique_ptr<Expression> expr) { expr_ = std::move(expr); } void set_expr(Expression* expr) { expr_ = expr; }
/// @returns the expression /// @returns the expression
Expression* expr() const { return expr_.get(); } Expression* expr() const { return expr_; }
/// @returns true if this is a bitcast expression /// @returns true if this is a bitcast expression
bool IsBitcast() const override; bool IsBitcast() const override;
@ -72,7 +70,7 @@ class BitcastExpression : public Expression {
BitcastExpression(const BitcastExpression&) = delete; BitcastExpression(const BitcastExpression&) = delete;
type::Type* type_ = nullptr; type::Type* type_ = nullptr;
std::unique_ptr<Expression> expr_; Expression* expr_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -26,9 +26,9 @@ using BitcastExpressionTest = TestHelper;
TEST_F(BitcastExpressionTest, Create) { TEST_F(BitcastExpressionTest, Create) {
type::F32Type f32; type::F32Type f32;
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
auto* expr_ptr = expr.get(); auto* expr_ptr = expr;
BitcastExpression exp(&f32, std::move(expr)); BitcastExpression exp(&f32, std::move(expr));
ASSERT_EQ(exp.type(), &f32); ASSERT_EQ(exp.type(), &f32);
@ -37,7 +37,7 @@ TEST_F(BitcastExpressionTest, Create) {
TEST_F(BitcastExpressionTest, CreateWithSource) { TEST_F(BitcastExpressionTest, CreateWithSource) {
type::F32Type f32; type::F32Type f32;
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
BitcastExpression exp(Source{Source::Location{20, 2}}, &f32, std::move(expr)); BitcastExpression exp(Source{Source::Location{20, 2}}, &f32, std::move(expr));
auto src = exp.source(); auto src = exp.source();
@ -52,14 +52,14 @@ TEST_F(BitcastExpressionTest, IsBitcast) {
TEST_F(BitcastExpressionTest, IsValid) { TEST_F(BitcastExpressionTest, IsValid) {
type::F32Type f32; type::F32Type f32;
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
BitcastExpression exp(&f32, std::move(expr)); BitcastExpression exp(&f32, std::move(expr));
EXPECT_TRUE(exp.IsValid()); EXPECT_TRUE(exp.IsValid());
} }
TEST_F(BitcastExpressionTest, IsValid_MissingType) { TEST_F(BitcastExpressionTest, IsValid_MissingType) {
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
BitcastExpression exp; BitcastExpression exp;
exp.set_expr(std::move(expr)); exp.set_expr(std::move(expr));
@ -76,14 +76,14 @@ TEST_F(BitcastExpressionTest, IsValid_MissingExpr) {
TEST_F(BitcastExpressionTest, IsValid_InvalidExpr) { TEST_F(BitcastExpressionTest, IsValid_InvalidExpr) {
type::F32Type f32; type::F32Type f32;
auto expr = create<IdentifierExpression>(""); auto* expr = create<IdentifierExpression>("");
BitcastExpression e(&f32, std::move(expr)); BitcastExpression e(&f32, std::move(expr));
EXPECT_FALSE(e.IsValid()); EXPECT_FALSE(e.IsValid());
} }
TEST_F(BitcastExpressionTest, ToStr) { TEST_F(BitcastExpressionTest, ToStr) {
type::F32Type f32; type::F32Type f32;
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
BitcastExpression exp(&f32, std::move(expr)); BitcastExpression exp(&f32, std::move(expr));
std::ostringstream out; std::ostringstream out;

View File

@ -30,7 +30,7 @@ bool BlockStatement::IsBlock() const {
} }
bool BlockStatement::IsValid() const { bool BlockStatement::IsValid() const {
for (const auto& stmt : *this) { for (auto* stmt : *this) {
if (stmt == nullptr || !stmt->IsValid()) { if (stmt == nullptr || !stmt->IsValid()) {
return false; return false;
} }
@ -42,7 +42,7 @@ void BlockStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent); make_indent(out, indent);
out << "Block{" << std::endl; out << "Block{" << std::endl;
for (const auto& stmt : *this) { for (auto* stmt : *this) {
stmt->to_str(out, indent + 2); stmt->to_str(out, indent + 2);
} }

View File

@ -38,16 +38,14 @@ class BlockStatement : public Statement {
/// Appends a statement to the block /// Appends a statement to the block
/// @param stmt the statement to append /// @param stmt the statement to append
void append(std::unique_ptr<ast::Statement> stmt) { void append(ast::Statement* stmt) { statements_.push_back(stmt); }
statements_.push_back(std::move(stmt));
}
/// Insert a statement to the block /// Insert a statement to the block
/// @param index the index to insert at /// @param index the index to insert at
/// @param stmt the statement to insert /// @param stmt the statement to insert
void insert(size_t index, std::unique_ptr<ast::Statement> stmt) { void insert(size_t index, ast::Statement* stmt) {
auto offset = static_cast<decltype(statements_)::difference_type>(index); auto offset = static_cast<decltype(statements_)::difference_type>(index);
statements_.insert(statements_.begin() + offset, std::move(stmt)); statements_.insert(statements_.begin() + offset, stmt);
} }
/// @returns true if the block is empty /// @returns true if the block is empty
@ -57,35 +55,35 @@ class BlockStatement : public Statement {
/// @returns the last statement in the block or nullptr if block empty /// @returns the last statement in the block or nullptr if block empty
const ast::Statement* last() const { const ast::Statement* last() const {
return statements_.empty() ? nullptr : statements_.back().get(); return statements_.empty() ? nullptr : statements_.back();
} }
/// @returns the last statement in the block or nullptr if block empty /// @returns the last statement in the block or nullptr if block empty
ast::Statement* last() { ast::Statement* last() {
return statements_.empty() ? nullptr : statements_.back().get(); return statements_.empty() ? nullptr : statements_.back();
} }
/// Retrieves the statement at |idx| /// Retrieves the statement at |idx|
/// @param idx the index. The index is not bounds checked. /// @param idx the index. The index is not bounds checked.
/// @returns the statement at |idx| /// @returns the statement at |idx|
const ast::Statement* get(size_t idx) const { return statements_[idx].get(); } const ast::Statement* get(size_t idx) const { return statements_[idx]; }
/// Retrieves the statement at |idx| /// Retrieves the statement at |idx|
/// @param idx the index. The index is not bounds checked. /// @param idx the index. The index is not bounds checked.
/// @returns the statement at |idx| /// @returns the statement at |idx|
ast::Statement* operator[](size_t idx) { return statements_[idx].get(); } ast::Statement* operator[](size_t idx) { return statements_[idx]; }
/// Retrieves the statement at |idx| /// Retrieves the statement at |idx|
/// @param idx the index. The index is not bounds checked. /// @param idx the index. The index is not bounds checked.
/// @returns the statement at |idx| /// @returns the statement at |idx|
const ast::Statement* operator[](size_t idx) const { const ast::Statement* operator[](size_t idx) const {
return statements_[idx].get(); return statements_[idx];
} }
/// @returns the beginning iterator /// @returns the beginning iterator
std::vector<std::unique_ptr<ast::Statement>>::const_iterator begin() const { std::vector<ast::Statement*>::const_iterator begin() const {
return statements_.begin(); return statements_.begin();
} }
/// @returns the ending iterator /// @returns the ending iterator
std::vector<std::unique_ptr<ast::Statement>>::const_iterator end() const { std::vector<ast::Statement*>::const_iterator end() const {
return statements_.end(); return statements_.end();
} }
@ -103,7 +101,7 @@ class BlockStatement : public Statement {
private: private:
BlockStatement(const BlockStatement&) = delete; BlockStatement(const BlockStatement&) = delete;
std::vector<std::unique_ptr<ast::Statement>> statements_; std::vector<ast::Statement*> statements_;
}; };
} // namespace ast } // namespace ast

View File

@ -28,8 +28,8 @@ namespace {
using BlockStatementTest = TestHelper; using BlockStatementTest = TestHelper;
TEST_F(BlockStatementTest, Creation) { TEST_F(BlockStatementTest, Creation) {
auto d = create<DiscardStatement>(); auto* d = create<DiscardStatement>();
auto* ptr = d.get(); auto* ptr = d;
BlockStatement b; BlockStatement b;
b.append(std::move(d)); b.append(std::move(d));
@ -39,12 +39,12 @@ TEST_F(BlockStatementTest, Creation) {
} }
TEST_F(BlockStatementTest, Creation_WithInsert) { TEST_F(BlockStatementTest, Creation_WithInsert) {
auto s1 = create<DiscardStatement>(); auto* s1 = create<DiscardStatement>();
auto s2 = create<DiscardStatement>(); auto* s2 = create<DiscardStatement>();
auto s3 = create<DiscardStatement>(); auto* s3 = create<DiscardStatement>();
auto* p1 = s1.get(); auto* p1 = s1;
auto* p2 = s2.get(); auto* p2 = s2;
auto* p3 = s3.get(); auto* p3 = s3;
BlockStatement b; BlockStatement b;
b.insert(0, std::move(s1)); b.insert(0, std::move(s1));

View File

@ -19,15 +19,14 @@ namespace ast {
Builder::Builder() = default; Builder::Builder() = default;
Builder::Builder(Context* ctx) : ctx_(ctx) {} Builder::Builder(tint::Context* ctx) : ctx_(ctx) {}
Builder::~Builder() = default; Builder::~Builder() = default;
std::unique_ptr<ast::Variable> Builder::make_var(const std::string& name, ast::Variable* Builder::make_var(const std::string& name,
ast::StorageClass storage, ast::StorageClass storage,
ast::type::Type* type) { ast::type::Type* type) {
auto var = create<ast::Variable>(name, storage, type); return create<ast::Variable>(name, storage, type);
return var;
} }
} // namespace ast } // namespace ast

View File

@ -51,12 +51,12 @@ class Builder {
Builder(); Builder();
/// Constructor /// Constructor
/// @param ctx the context to use in the builder /// @param ctx the context to use in the builder
explicit Builder(Context* ctx); explicit Builder(tint::Context* ctx);
virtual ~Builder(); virtual ~Builder();
/// Sets the given context into the builder /// Sets the given context into the builder
/// @param ctx the context to set /// @param ctx the context to set
void set_context(Context* ctx) { ctx_ = ctx; } void set_context(tint::Context* ctx) { ctx_ = ctx; }
/// Creates a new type /// Creates a new type
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
@ -106,63 +106,59 @@ class Builder {
/// @param expr the expression /// @param expr the expression
/// @return expr /// @return expr
std::unique_ptr<ast::Expression> make_expr( ast::Expression* make_expr(ast::Expression* expr) { return expr; }
std::unique_ptr<ast::Expression> expr) {
return expr;
}
/// @param name the identifier name /// @param name the identifier name
/// @return an IdentifierExpression with the given name /// @return an IdentifierExpression with the given name
std::unique_ptr<ast::IdentifierExpression> make_expr( ast::IdentifierExpression* make_expr(const std::string& name) {
const std::string& name) {
return create<ast::IdentifierExpression>(name); return create<ast::IdentifierExpression>(name);
} }
/// @param name the identifier name /// @param name the identifier name
/// @return an IdentifierExpression with the given name /// @return an IdentifierExpression with the given name
std::unique_ptr<ast::IdentifierExpression> make_expr(const char* name) { ast::IdentifierExpression* make_expr(const char* name) {
return create<ast::IdentifierExpression>(name); return create<ast::IdentifierExpression>(name);
} }
/// @param value the float value /// @param value the float value
/// @return a Scalar constructor for the given value /// @return a Scalar constructor for the given value
std::unique_ptr<ast::ScalarConstructorExpression> make_expr(float value) { ast::ScalarConstructorExpression* make_expr(float value) {
return create<ast::ScalarConstructorExpression>(make_literal(value)); return create<ast::ScalarConstructorExpression>(make_literal(value));
} }
/// @param value the int value /// @param value the int value
/// @return a Scalar constructor for the given value /// @return a Scalar constructor for the given value
std::unique_ptr<ast::ScalarConstructorExpression> make_expr(int32_t value) { ast::ScalarConstructorExpression* make_expr(int32_t value) {
return create<ast::ScalarConstructorExpression>(make_literal(value)); return create<ast::ScalarConstructorExpression>(make_literal(value));
} }
/// @param value the unsigned int value /// @param value the unsigned int value
/// @return a Scalar constructor for the given value /// @return a Scalar constructor for the given value
std::unique_ptr<ast::ScalarConstructorExpression> make_expr(uint32_t value) { ast::ScalarConstructorExpression* make_expr(uint32_t value) {
return create<ast::ScalarConstructorExpression>(make_literal(value)); return create<ast::ScalarConstructorExpression>(make_literal(value));
} }
/// @param val the boolan value /// @param val the boolan value
/// @return a boolean literal with the given value /// @return a boolean literal with the given value
std::unique_ptr<ast::BoolLiteral> make_literal(bool val) { ast::BoolLiteral* make_literal(bool val) {
return create<ast::BoolLiteral>(bool_type(), val); return create<ast::BoolLiteral>(bool_type(), val);
} }
/// @param val the float value /// @param val the float value
/// @return a float literal with the given value /// @return a float literal with the given value
std::unique_ptr<ast::FloatLiteral> make_literal(float val) { ast::FloatLiteral* make_literal(float val) {
return create<ast::FloatLiteral>(f32(), val); return create<ast::FloatLiteral>(f32(), val);
} }
/// @param val the unsigned int value /// @param val the unsigned int value
/// @return a UintLiteral with the given value /// @return a UintLiteral with the given value
std::unique_ptr<ast::UintLiteral> make_literal(uint32_t val) { ast::UintLiteral* make_literal(uint32_t val) {
return create<ast::UintLiteral>(u32(), val); return create<ast::UintLiteral>(u32(), val);
} }
/// @param val the integer value /// @param val the integer value
/// @return the SintLiteral with the given value /// @return the SintLiteral with the given value
std::unique_ptr<ast::SintLiteral> make_literal(int32_t val) { ast::SintLiteral* make_literal(int32_t val) {
return create<ast::SintLiteral>(i32(), val); return create<ast::SintLiteral>(i32(), val);
} }
@ -191,7 +187,7 @@ class Builder {
/// @return an `ast::TypeConstructorExpression` of type `ty`, with the values /// @return an `ast::TypeConstructorExpression` of type `ty`, with the values
/// of `args` converted to `ast::Expression`s using `make_expr()` /// of `args` converted to `ast::Expression`s using `make_expr()`
template <typename... ARGS> template <typename... ARGS>
std::unique_ptr<ast::TypeConstructorExpression> construct(ast::type::Type* ty, ast::TypeConstructorExpression* construct(ast::type::Type* ty,
ARGS&&... args) { ARGS&&... args) {
ast::ExpressionList vals; ast::ExpressionList vals;
append_expr(vals, std::forward<ARGS>(args)...); append_expr(vals, std::forward<ARGS>(args)...);
@ -202,7 +198,7 @@ class Builder {
/// @param storage the variable storage class /// @param storage the variable storage class
/// @param type the variable type /// @param type the variable type
/// @returns a `ast::Variable` with the given name, storage and type /// @returns a `ast::Variable` with the given name, storage and type
virtual std::unique_ptr<ast::Variable> make_var(const std::string& name, virtual ast::Variable* make_var(const std::string& name,
ast::StorageClass storage, ast::StorageClass storage,
ast::type::Type* type); ast::type::Type* type);
@ -217,15 +213,17 @@ class Builder {
return ast::CallExpression{make_expr(func), std::move(params)}; return ast::CallExpression{make_expr(func), std::move(params)};
} }
/// @return a `std::unique_ptr` to a new `T` constructed with `args` /// Creates a new `ast::Node` owned by the Context. When the Context is
/// @param args the arguments to forward to the constructor for `T` /// 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> template <typename T, typename... ARGS>
std::unique_ptr<T> create(ARGS&&... args) { T* create(ARGS&&... args) {
return std::make_unique<T>(std::forward<ARGS>(args)...); return ctx_->create<T>(std::forward<ARGS>(args)...);
} }
private: private:
Context* ctx_ = nullptr; tint::Context* ctx_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -19,14 +19,13 @@ namespace ast {
CallExpression::CallExpression() : Expression() {} CallExpression::CallExpression() : Expression() {}
CallExpression::CallExpression(std::unique_ptr<Expression> func, CallExpression::CallExpression(Expression* func, ExpressionList params)
ExpressionList params) : Expression(), func_(func), params_(params) {}
: Expression(), func_(std::move(func)), params_(std::move(params)) {}
CallExpression::CallExpression(const Source& source, CallExpression::CallExpression(const Source& source,
std::unique_ptr<Expression> func, Expression* func,
ExpressionList params) ExpressionList params)
: Expression(source), func_(std::move(func)), params_(std::move(params)) {} : Expression(source), func_(func), params_(params) {}
CallExpression::CallExpression(CallExpression&&) = default; CallExpression::CallExpression(CallExpression&&) = default;
@ -41,7 +40,7 @@ bool CallExpression::IsValid() const {
return false; return false;
// All params must be valid // All params must be valid
for (const auto& param : params_) { for (auto* param : params_) {
if (param == nullptr || !param->IsValid()) if (param == nullptr || !param->IsValid())
return false; return false;
} }
@ -55,7 +54,7 @@ void CallExpression::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent + 2); make_indent(out, indent + 2);
out << "(" << std::endl; out << "(" << std::endl;
for (const auto& param : params_) for (auto* param : params_)
param->to_str(out, indent + 4); param->to_str(out, indent + 4);
make_indent(out, indent + 2); make_indent(out, indent + 2);

View File

@ -32,27 +32,25 @@ class CallExpression : public Expression {
/// Constructor /// Constructor
/// @param func the function /// @param func the function
/// @param params the parameters /// @param params the parameters
CallExpression(std::unique_ptr<Expression> func, ExpressionList params); CallExpression(Expression* func, ExpressionList params);
/// Constructor /// Constructor
/// @param source the call expression source /// @param source the call expression source
/// @param func the function /// @param func the function
/// @param params the parameters /// @param params the parameters
CallExpression(const Source& source, CallExpression(const Source& source, Expression* func, ExpressionList params);
std::unique_ptr<Expression> func,
ExpressionList params);
/// Move constructor /// Move constructor
CallExpression(CallExpression&&); CallExpression(CallExpression&&);
~CallExpression() override; ~CallExpression() override;
/// Sets the func /// Sets the func
/// @param func the func /// @param func the func
void set_func(std::unique_ptr<Expression> func) { func_ = std::move(func); } void set_func(Expression* func) { func_ = func; }
/// @returns the func /// @returns the func
Expression* func() const { return func_.get(); } Expression* func() const { return func_; }
/// Sets the parameters /// Sets the parameters
/// @param params the parameters /// @param params the parameters
void set_params(ExpressionList params) { params_ = std::move(params); } void set_params(ExpressionList params) { params_ = params; }
/// @returns the parameters /// @returns the parameters
const ExpressionList& params() const { return params_; } const ExpressionList& params() const { return params_; }
@ -70,7 +68,7 @@ class CallExpression : public Expression {
private: private:
CallExpression(const CallExpression&) = delete; CallExpression(const CallExpression&) = delete;
std::unique_ptr<Expression> func_; Expression* func_ = nullptr;
ExpressionList params_; ExpressionList params_;
}; };

View File

@ -24,26 +24,26 @@ namespace {
using CallExpressionTest = TestHelper; using CallExpressionTest = TestHelper;
TEST_F(CallExpressionTest, Creation) { TEST_F(CallExpressionTest, Creation) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
ExpressionList params; ExpressionList params;
params.push_back(create<IdentifierExpression>("param1")); params.push_back(create<IdentifierExpression>("param1"));
params.push_back(create<IdentifierExpression>("param2")); params.push_back(create<IdentifierExpression>("param2"));
auto* func_ptr = func.get(); auto* func_ptr = func;
auto* param1_ptr = params[0].get(); auto* param1_ptr = params[0];
auto* param2_ptr = params[1].get(); auto* param2_ptr = params[1];
CallExpression stmt(std::move(func), std::move(params)); CallExpression stmt(std::move(func), std::move(params));
EXPECT_EQ(stmt.func(), func_ptr); EXPECT_EQ(stmt.func(), func_ptr);
const auto& vec = stmt.params(); const auto& vec = stmt.params();
ASSERT_EQ(vec.size(), 2u); ASSERT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0].get(), param1_ptr); EXPECT_EQ(vec[0], param1_ptr);
EXPECT_EQ(vec[1].get(), param2_ptr); EXPECT_EQ(vec[1], param2_ptr);
} }
TEST_F(CallExpressionTest, Creation_WithSource) { TEST_F(CallExpressionTest, Creation_WithSource) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
CallExpression stmt(Source{Source::Location{20, 2}}, std::move(func), {}); CallExpression stmt(Source{Source::Location{20, 2}}, std::move(func), {});
auto src = stmt.source(); auto src = stmt.source();
EXPECT_EQ(src.range.begin.line, 20u); EXPECT_EQ(src.range.begin.line, 20u);
@ -51,13 +51,13 @@ TEST_F(CallExpressionTest, Creation_WithSource) {
} }
TEST_F(CallExpressionTest, IsCall) { TEST_F(CallExpressionTest, IsCall) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
CallExpression stmt(std::move(func), {}); CallExpression stmt(std::move(func), {});
EXPECT_TRUE(stmt.IsCall()); EXPECT_TRUE(stmt.IsCall());
} }
TEST_F(CallExpressionTest, IsValid) { TEST_F(CallExpressionTest, IsValid) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
CallExpression stmt(std::move(func), {}); CallExpression stmt(std::move(func), {});
EXPECT_TRUE(stmt.IsValid()); EXPECT_TRUE(stmt.IsValid());
} }
@ -68,7 +68,7 @@ TEST_F(CallExpressionTest, IsValid_MissingFunction) {
} }
TEST_F(CallExpressionTest, IsValid_NullParam) { TEST_F(CallExpressionTest, IsValid_NullParam) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
ExpressionList params; ExpressionList params;
params.push_back(create<IdentifierExpression>("param1")); params.push_back(create<IdentifierExpression>("param1"));
params.push_back(nullptr); params.push_back(nullptr);
@ -79,7 +79,7 @@ TEST_F(CallExpressionTest, IsValid_NullParam) {
} }
TEST_F(CallExpressionTest, IsValid_InvalidFunction) { TEST_F(CallExpressionTest, IsValid_InvalidFunction) {
auto func = create<IdentifierExpression>(""); auto* func = create<IdentifierExpression>("");
ExpressionList params; ExpressionList params;
params.push_back(create<IdentifierExpression>("param1")); params.push_back(create<IdentifierExpression>("param1"));
@ -88,7 +88,7 @@ TEST_F(CallExpressionTest, IsValid_InvalidFunction) {
} }
TEST_F(CallExpressionTest, IsValid_InvalidParam) { TEST_F(CallExpressionTest, IsValid_InvalidParam) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
ExpressionList params; ExpressionList params;
params.push_back(create<IdentifierExpression>("")); params.push_back(create<IdentifierExpression>(""));
@ -97,7 +97,7 @@ TEST_F(CallExpressionTest, IsValid_InvalidParam) {
} }
TEST_F(CallExpressionTest, ToStr_NoParams) { TEST_F(CallExpressionTest, ToStr_NoParams) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
CallExpression stmt(std::move(func), {}); CallExpression stmt(std::move(func), {});
std::ostringstream out; std::ostringstream out;
stmt.to_str(out, 2); stmt.to_str(out, 2);
@ -110,7 +110,7 @@ TEST_F(CallExpressionTest, ToStr_NoParams) {
} }
TEST_F(CallExpressionTest, ToStr_WithParams) { TEST_F(CallExpressionTest, ToStr_WithParams) {
auto func = create<IdentifierExpression>("func"); auto* func = create<IdentifierExpression>("func");
ExpressionList params; ExpressionList params;
params.push_back(create<IdentifierExpression>("param1")); params.push_back(create<IdentifierExpression>("param1"));
params.push_back(create<IdentifierExpression>("param2")); params.push_back(create<IdentifierExpression>("param2"));

View File

@ -21,8 +21,7 @@ namespace ast {
CallStatement::CallStatement() : Statement() {} CallStatement::CallStatement() : Statement() {}
CallStatement::CallStatement(std::unique_ptr<CallExpression> call) CallStatement::CallStatement(CallExpression* call) : Statement(), call_(call) {}
: Statement(), call_(std::move(call)) {}
CallStatement::CallStatement(CallStatement&&) = default; CallStatement::CallStatement(CallStatement&&) = default;

View File

@ -31,18 +31,16 @@ class CallStatement : public Statement {
CallStatement(); CallStatement();
/// Constructor /// Constructor
/// @param call the function /// @param call the function
explicit CallStatement(std::unique_ptr<CallExpression> call); explicit CallStatement(CallExpression* call);
/// Move constructor /// Move constructor
CallStatement(CallStatement&&); CallStatement(CallStatement&&);
~CallStatement() override; ~CallStatement() override;
/// Sets the call expression /// Sets the call expression
/// @param call the call /// @param call the call
void set_expr(std::unique_ptr<CallExpression> call) { void set_expr(CallExpression* call) { call_ = call; }
call_ = std::move(call);
}
/// @returns the call expression /// @returns the call expression
CallExpression* expr() const { return call_.get(); } CallExpression* expr() const { return call_; }
/// @returns true if this is a call statement /// @returns true if this is a call statement
bool IsCall() const override; bool IsCall() const override;
@ -58,7 +56,7 @@ class CallStatement : public Statement {
private: private:
CallStatement(const CallStatement&) = delete; CallStatement(const CallStatement&) = delete;
std::unique_ptr<CallExpression> call_; CallExpression* call_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -25,9 +25,9 @@ namespace {
using CallStatementTest = TestHelper; using CallStatementTest = TestHelper;
TEST_F(CallStatementTest, Creation) { TEST_F(CallStatementTest, Creation) {
auto expr = create<ast::CallExpression>( auto* expr = create<ast::CallExpression>(
create<ast::IdentifierExpression>("func"), ExpressionList{}); create<ast::IdentifierExpression>("func"), ExpressionList{});
auto* expr_ptr = expr.get(); auto* expr_ptr = expr;
CallStatement c(std::move(expr)); CallStatement c(std::move(expr));
EXPECT_EQ(c.expr(), expr_ptr); EXPECT_EQ(c.expr(), expr_ptr);

View File

@ -17,19 +17,15 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
CaseStatement::CaseStatement(std::unique_ptr<BlockStatement> body) CaseStatement::CaseStatement(BlockStatement* body) : Statement(), body_(body) {}
: Statement(), body_(std::move(body)) {}
CaseStatement::CaseStatement(CaseSelectorList selectors, CaseStatement::CaseStatement(CaseSelectorList selectors, BlockStatement* body)
std::unique_ptr<BlockStatement> body) : Statement(), selectors_(selectors), body_(body) {}
: Statement(), selectors_(std::move(selectors)), body_(std::move(body)) {}
CaseStatement::CaseStatement(const Source& source, CaseStatement::CaseStatement(const Source& source,
CaseSelectorList selectors, CaseSelectorList selectors,
std::unique_ptr<BlockStatement> body) BlockStatement* body)
: Statement(source), : Statement(source), selectors_(selectors), body_(body) {}
selectors_(std::move(selectors)),
body_(std::move(body)) {}
CaseStatement::CaseStatement(CaseStatement&&) = default; CaseStatement::CaseStatement(CaseStatement&&) = default;
@ -51,7 +47,7 @@ void CaseStatement::to_str(std::ostream& out, size_t indent) const {
} else { } else {
out << "Case "; out << "Case ";
bool first = true; bool first = true;
for (const auto& selector : selectors_) { for (auto* selector : selectors_) {
if (!first) if (!first)
out << ", "; out << ", ";
@ -62,7 +58,7 @@ void CaseStatement::to_str(std::ostream& out, size_t indent) const {
} }
if (body_ != nullptr) { if (body_ != nullptr) {
for (const auto& stmt : *body_) { for (auto* stmt : *body_) {
stmt->to_str(out, indent + 2); stmt->to_str(out, indent + 2);
} }
} }

View File

@ -28,7 +28,7 @@ namespace tint {
namespace ast { namespace ast {
/// A list of case literals /// A list of case literals
using CaseSelectorList = std::vector<std::unique_ptr<ast::IntLiteral>>; using CaseSelectorList = std::vector<IntLiteral*>;
/// A case statement /// A case statement
class CaseStatement : public Statement { class CaseStatement : public Statement {
@ -36,19 +36,18 @@ class CaseStatement : public Statement {
/// Constructor /// Constructor
/// Creates a default case statement /// Creates a default case statement
/// @param body the case body /// @param body the case body
explicit CaseStatement(std::unique_ptr<BlockStatement> body); explicit CaseStatement(BlockStatement* body);
/// Constructor /// Constructor
/// @param selectors the case selectors /// @param selectors the case selectors
/// @param body the case body /// @param body the case body
CaseStatement(CaseSelectorList selectors, CaseStatement(CaseSelectorList selectors, BlockStatement* body);
std::unique_ptr<BlockStatement> body);
/// Constructor /// Constructor
/// @param source the source information /// @param source the source information
/// @param selectors the case selectors /// @param selectors the case selectors
/// @param body the case body /// @param body the case body
CaseStatement(const Source& source, CaseStatement(const Source& source,
CaseSelectorList selectors, CaseSelectorList selectors,
std::unique_ptr<BlockStatement> body); BlockStatement* body);
/// Move constructor /// Move constructor
CaseStatement(CaseStatement&&); CaseStatement(CaseStatement&&);
~CaseStatement() override; ~CaseStatement() override;
@ -65,13 +64,11 @@ class CaseStatement : public Statement {
/// Sets the case body /// Sets the case body
/// @param body the case body /// @param body the case body
void set_body(std::unique_ptr<BlockStatement> body) { void set_body(BlockStatement* body) { body_ = body; }
body_ = std::move(body);
}
/// @returns the case body /// @returns the case body
const BlockStatement* body() const { return body_.get(); } const BlockStatement* body() const { return body_; }
/// @returns the case body /// @returns the case body
BlockStatement* body() { return body_.get(); } BlockStatement* body() { return body_; }
/// @returns true if this is a case statement /// @returns true if this is a case statement
bool IsCase() const override; bool IsCase() const override;
@ -88,11 +85,11 @@ class CaseStatement : public Statement {
CaseStatement(const CaseStatement&) = delete; CaseStatement(const CaseStatement&) = delete;
CaseSelectorList selectors_; CaseSelectorList selectors_;
std::unique_ptr<BlockStatement> body_; BlockStatement* body_ = nullptr;
}; };
/// A list of unique case statements /// A list of case statements
using CaseStatementList = std::vector<std::unique_ptr<CaseStatement>>; using CaseStatementList = std::vector<CaseStatement*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -34,15 +34,15 @@ TEST_F(CaseStatementTest, Creation_i32) {
CaseSelectorList b; CaseSelectorList b;
b.push_back(create<SintLiteral>(&i32, 2)); b.push_back(create<SintLiteral>(&i32, 2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto* int_ptr = b.back().get(); auto* int_ptr = b.back();
auto* discard_ptr = body->get(0); auto* discard_ptr = body->get(0);
CaseStatement c(std::move(b), std::move(body)); CaseStatement c(std::move(b), std::move(body));
ASSERT_EQ(c.selectors().size(), 1u); ASSERT_EQ(c.selectors().size(), 1u);
EXPECT_EQ(c.selectors()[0].get(), int_ptr); EXPECT_EQ(c.selectors()[0], int_ptr);
ASSERT_EQ(c.body()->size(), 1u); ASSERT_EQ(c.body()->size(), 1u);
EXPECT_EQ(c.body()->get(0), discard_ptr); EXPECT_EQ(c.body()->get(0), discard_ptr);
} }
@ -53,15 +53,15 @@ TEST_F(CaseStatementTest, Creation_u32) {
CaseSelectorList b; CaseSelectorList b;
b.push_back(create<UintLiteral>(&u32, 2)); b.push_back(create<UintLiteral>(&u32, 2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto* int_ptr = b.back().get(); auto* int_ptr = b.back();
auto* discard_ptr = body->get(0); auto* discard_ptr = body->get(0);
CaseStatement c(std::move(b), std::move(body)); CaseStatement c(std::move(b), std::move(body));
ASSERT_EQ(c.selectors().size(), 1u); ASSERT_EQ(c.selectors().size(), 1u);
EXPECT_EQ(c.selectors()[0].get(), int_ptr); EXPECT_EQ(c.selectors()[0], int_ptr);
ASSERT_EQ(c.body()->size(), 1u); ASSERT_EQ(c.body()->size(), 1u);
EXPECT_EQ(c.body()->get(0), discard_ptr); EXPECT_EQ(c.body()->get(0), discard_ptr);
} }
@ -71,7 +71,7 @@ TEST_F(CaseStatementTest, Creation_WithSource) {
CaseSelectorList b; CaseSelectorList b;
b.push_back(create<SintLiteral>(&i32, 2)); b.push_back(create<SintLiteral>(&i32, 2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
CaseStatement c(Source{Source::Location{20, 2}}, std::move(b), CaseStatement c(Source{Source::Location{20, 2}}, std::move(b),
@ -82,7 +82,7 @@ TEST_F(CaseStatementTest, Creation_WithSource) {
} }
TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) { TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
CaseStatement c(create<ast::BlockStatement>()); CaseStatement c(create<ast::BlockStatement>());
@ -115,7 +115,7 @@ TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
CaseSelectorList b; CaseSelectorList b;
b.push_back(create<SintLiteral>(&i32, 2)); b.push_back(create<SintLiteral>(&i32, 2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
body->append(nullptr); body->append(nullptr);
@ -128,7 +128,7 @@ TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
CaseSelectorList b; CaseSelectorList b;
b.push_back(create<SintLiteral>(&i32, 2)); b.push_back(create<SintLiteral>(&i32, 2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<IfStatement>(nullptr, create<ast::BlockStatement>())); body->append(create<IfStatement>(nullptr, create<ast::BlockStatement>()));
CaseStatement c({std::move(b)}, std::move(body)); CaseStatement c({std::move(b)}, std::move(body));
@ -140,7 +140,7 @@ TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
CaseSelectorList b; CaseSelectorList b;
b.push_back(create<SintLiteral>(&i32, -2)); b.push_back(create<SintLiteral>(&i32, -2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
CaseStatement c({std::move(b)}, std::move(body)); CaseStatement c({std::move(b)}, std::move(body));
@ -157,7 +157,7 @@ TEST_F(CaseStatementTest, ToStr_WithSelectors_u32) {
CaseSelectorList b; CaseSelectorList b;
b.push_back(create<UintLiteral>(&u32, 2)); b.push_back(create<UintLiteral>(&u32, 2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
CaseStatement c({std::move(b)}, std::move(body)); CaseStatement c({std::move(b)}, std::move(body));
@ -176,7 +176,7 @@ TEST_F(CaseStatementTest, ToStr_WithMultipleSelectors) {
b.push_back(create<SintLiteral>(&i32, 1)); b.push_back(create<SintLiteral>(&i32, 1));
b.push_back(create<SintLiteral>(&i32, 2)); b.push_back(create<SintLiteral>(&i32, 2));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
CaseStatement c(std::move(b), std::move(body)); CaseStatement c(std::move(b), std::move(body));
@ -189,7 +189,7 @@ TEST_F(CaseStatementTest, ToStr_WithMultipleSelectors) {
} }
TEST_F(CaseStatementTest, ToStr_WithoutSelectors) { TEST_F(CaseStatementTest, ToStr_WithoutSelectors) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
CaseStatement c(CaseSelectorList{}, std::move(body)); CaseStatement c(CaseSelectorList{}, std::move(body));

View File

@ -23,7 +23,7 @@ namespace ast {
DecoratedVariable::DecoratedVariable() = default; DecoratedVariable::DecoratedVariable() = default;
DecoratedVariable::DecoratedVariable(std::unique_ptr<Variable> var) DecoratedVariable::DecoratedVariable(Variable* var)
: Variable(var->source(), var->name(), var->storage_class(), var->type()) {} : Variable(var->source(), var->name(), var->storage_class(), var->type()) {}
DecoratedVariable::DecoratedVariable(DecoratedVariable&&) = default; DecoratedVariable::DecoratedVariable(DecoratedVariable&&) = default;
@ -31,7 +31,7 @@ DecoratedVariable::DecoratedVariable(DecoratedVariable&&) = default;
DecoratedVariable::~DecoratedVariable() = default; DecoratedVariable::~DecoratedVariable() = default;
bool DecoratedVariable::HasLocationDecoration() const { bool DecoratedVariable::HasLocationDecoration() const {
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsLocation()) { if (deco->IsLocation()) {
return true; return true;
} }
@ -40,7 +40,7 @@ bool DecoratedVariable::HasLocationDecoration() const {
} }
bool DecoratedVariable::HasBuiltinDecoration() const { bool DecoratedVariable::HasBuiltinDecoration() const {
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsBuiltin()) { if (deco->IsBuiltin()) {
return true; return true;
} }
@ -49,7 +49,7 @@ bool DecoratedVariable::HasBuiltinDecoration() const {
} }
bool DecoratedVariable::HasConstantIdDecoration() const { bool DecoratedVariable::HasConstantIdDecoration() const {
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsConstantId()) { if (deco->IsConstantId()) {
return true; return true;
} }
@ -59,7 +59,7 @@ bool DecoratedVariable::HasConstantIdDecoration() const {
uint32_t DecoratedVariable::constant_id() const { uint32_t DecoratedVariable::constant_id() const {
assert(HasConstantIdDecoration()); assert(HasConstantIdDecoration());
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsConstantId()) { if (deco->IsConstantId()) {
return deco->AsConstantId()->value(); return deco->AsConstantId()->value();
} }
@ -85,7 +85,7 @@ void DecoratedVariable::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent + 2); make_indent(out, indent + 2);
out << "Decorations{" << std::endl; out << "Decorations{" << std::endl;
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
deco->to_str(out, indent + 4); deco->to_str(out, indent + 4);
} }

View File

@ -31,7 +31,7 @@ class DecoratedVariable : public Variable {
DecoratedVariable(); DecoratedVariable();
/// Create a decorated variable from an existing variable /// Create a decorated variable from an existing variable
/// @param var the variable to initialize from /// @param var the variable to initialize from
explicit DecoratedVariable(std::unique_ptr<Variable> var); explicit DecoratedVariable(Variable* var);
/// Move constructor /// Move constructor
DecoratedVariable(DecoratedVariable&&); DecoratedVariable(DecoratedVariable&&);

View File

@ -34,7 +34,7 @@ using DecoratedVariableTest = TestHelper;
TEST_F(DecoratedVariableTest, Creation) { TEST_F(DecoratedVariableTest, Creation) {
type::I32Type t; type::I32Type t;
auto var = create<Variable>("my_var", StorageClass::kFunction, &t); auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
DecoratedVariable dv(std::move(var)); DecoratedVariable dv(std::move(var));
EXPECT_EQ(dv.name(), "my_var"); EXPECT_EQ(dv.name(), "my_var");
@ -49,7 +49,7 @@ TEST_F(DecoratedVariableTest, Creation) {
TEST_F(DecoratedVariableTest, CreationWithSource) { TEST_F(DecoratedVariableTest, CreationWithSource) {
Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}; Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
type::F32Type t; type::F32Type t;
auto var = create<Variable>(s, "i", StorageClass::kPrivate, &t); auto* var = create<Variable>(s, "i", StorageClass::kPrivate, &t);
DecoratedVariable dv(std::move(var)); DecoratedVariable dv(std::move(var));
EXPECT_EQ(dv.name(), "i"); EXPECT_EQ(dv.name(), "i");
@ -63,7 +63,7 @@ TEST_F(DecoratedVariableTest, CreationWithSource) {
TEST_F(DecoratedVariableTest, NoDecorations) { TEST_F(DecoratedVariableTest, NoDecorations) {
type::I32Type t; type::I32Type t;
auto var = create<Variable>("my_var", StorageClass::kFunction, &t); auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
DecoratedVariable dv(std::move(var)); DecoratedVariable dv(std::move(var));
EXPECT_FALSE(dv.HasLocationDecoration()); EXPECT_FALSE(dv.HasLocationDecoration());
EXPECT_FALSE(dv.HasBuiltinDecoration()); EXPECT_FALSE(dv.HasBuiltinDecoration());
@ -72,7 +72,7 @@ TEST_F(DecoratedVariableTest, NoDecorations) {
TEST_F(DecoratedVariableTest, WithDecorations) { TEST_F(DecoratedVariableTest, WithDecorations) {
type::F32Type t; type::F32Type t;
auto var = create<Variable>("my_var", StorageClass::kFunction, &t); auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
DecoratedVariable dv(std::move(var)); DecoratedVariable dv(std::move(var));
VariableDecorationList decos; VariableDecorationList decos;
@ -89,7 +89,7 @@ TEST_F(DecoratedVariableTest, WithDecorations) {
TEST_F(DecoratedVariableTest, ConstantId) { TEST_F(DecoratedVariableTest, ConstantId) {
type::F32Type t; type::F32Type t;
auto var = create<Variable>("my_var", StorageClass::kFunction, &t); auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
DecoratedVariable dv(std::move(var)); DecoratedVariable dv(std::move(var));
VariableDecorationList decos; VariableDecorationList decos;
@ -101,7 +101,7 @@ TEST_F(DecoratedVariableTest, ConstantId) {
TEST_F(DecoratedVariableTest, IsValid) { TEST_F(DecoratedVariableTest, IsValid) {
type::I32Type t; type::I32Type t;
auto var = create<Variable>("my_var", StorageClass::kNone, &t); auto* var = create<Variable>("my_var", StorageClass::kNone, &t);
DecoratedVariable dv(std::move(var)); DecoratedVariable dv(std::move(var));
EXPECT_TRUE(dv.IsValid()); EXPECT_TRUE(dv.IsValid());
} }
@ -113,7 +113,7 @@ TEST_F(DecoratedVariableTest, IsDecorated) {
TEST_F(DecoratedVariableTest, to_str) { TEST_F(DecoratedVariableTest, to_str) {
type::F32Type t; type::F32Type t;
auto var = create<Variable>("my_var", StorageClass::kFunction, &t); auto* var = create<Variable>("my_var", StorageClass::kFunction, &t);
DecoratedVariable dv(std::move(var)); DecoratedVariable dv(std::move(var));
dv.set_constructor(create<IdentifierExpression>("expr")); dv.set_constructor(create<IdentifierExpression>("expr"));

View File

@ -65,22 +65,20 @@ class Decoration : public Node {
}; };
/// As dynamically casts |deco| to the target type |TO|. /// As dynamically casts |deco| to the target type |TO|.
/// @return the dynamically cast decoration, or nullptr if |deco| is not of the /// @return the cast decoration, or nullptr if |deco| is not of the type |TO|.
/// type |TO|.
template <typename TO> template <typename TO>
std::unique_ptr<TO> As(std::unique_ptr<Decoration>&& deco) { TO* As(Decoration* deco) {
if (deco == nullptr) { if (deco == nullptr) {
return nullptr; return nullptr;
} }
if (deco->Is<TO>()) { if (deco->Is<TO>()) {
auto ptr = static_cast<TO*>(deco.release()); return static_cast<TO*>(deco);
return std::unique_ptr<TO>(ptr);
} }
return nullptr; return nullptr;
} }
/// A list of unique decorations /// A list of decorations
using DecorationList = std::vector<std::unique_ptr<Decoration>>; using DecorationList = std::vector<Decoration*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -28,21 +28,21 @@ namespace {
using DecorationTest = TestHelper; using DecorationTest = TestHelper;
TEST_F(DecorationTest, AsCorrectType) { TEST_F(DecorationTest, AsCorrectType) {
auto* decoration = new ConstantIdDecoration(1, Source{}); auto* decoration = create<ConstantIdDecoration>(1, Source{});
auto upcast = std::unique_ptr<Decoration>(decoration); auto* upcast = static_cast<Decoration*>(decoration);
auto downcast = As<VariableDecoration>(std::move(upcast)); auto* downcast = As<VariableDecoration>(upcast);
EXPECT_EQ(decoration, downcast.get()); EXPECT_EQ(decoration, downcast);
} }
TEST_F(DecorationTest, AsIncorrectType) { TEST_F(DecorationTest, AsIncorrectType) {
auto* decoration = new ConstantIdDecoration(1, Source{}); auto* decoration = create<ConstantIdDecoration>(1, Source{});
auto upcast = std::unique_ptr<Decoration>(decoration); auto* upcast = static_cast<Decoration*>(decoration);
auto downcast = As<ArrayDecoration>(std::move(upcast)); auto* downcast = As<ArrayDecoration>(upcast);
EXPECT_EQ(nullptr, downcast.get()); EXPECT_EQ(nullptr, downcast);
} }
TEST_F(DecorationTest, Is) { TEST_F(DecorationTest, Is) {
auto decoration = create<ConstantIdDecoration>(1, Source{}); auto* decoration = create<ConstantIdDecoration>(1, Source{});
EXPECT_TRUE(decoration->Is<VariableDecoration>()); EXPECT_TRUE(decoration->Is<VariableDecoration>());
EXPECT_FALSE(decoration->Is<ArrayDecoration>()); EXPECT_FALSE(decoration->Is<ArrayDecoration>());
} }

View File

@ -17,23 +17,18 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
ElseStatement::ElseStatement(std::unique_ptr<BlockStatement> body) ElseStatement::ElseStatement(BlockStatement* body) : Statement(), body_(body) {}
: Statement(), body_(std::move(body)) {}
ElseStatement::ElseStatement(std::unique_ptr<Expression> condition, ElseStatement::ElseStatement(Expression* condition, BlockStatement* body)
std::unique_ptr<BlockStatement> body) : Statement(), condition_(condition), body_(body) {}
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
ElseStatement::ElseStatement(const Source& source, BlockStatement* body)
: Statement(source), body_(body) {}
ElseStatement::ElseStatement(const Source& source, ElseStatement::ElseStatement(const Source& source,
std::unique_ptr<BlockStatement> body) Expression* condition,
: Statement(source), body_(std::move(body)) {} BlockStatement* body)
: Statement(source), condition_(condition), body_(body) {}
ElseStatement::ElseStatement(const Source& source,
std::unique_ptr<Expression> condition,
std::unique_ptr<BlockStatement> body)
: Statement(source),
condition_(std::move(condition)),
body_(std::move(body)) {}
ElseStatement::ElseStatement(ElseStatement&&) = default; ElseStatement::ElseStatement(ElseStatement&&) = default;
@ -67,7 +62,7 @@ void ElseStatement::to_str(std::ostream& out, size_t indent) const {
out << "{" << std::endl; out << "{" << std::endl;
if (body_ != nullptr) { if (body_ != nullptr) {
for (const auto& stmt : *body_) { for (auto* stmt : *body_) {
stmt->to_str(out, indent + 4); stmt->to_str(out, indent + 4);
} }
} }

View File

@ -31,46 +31,41 @@ class ElseStatement : public Statement {
public: public:
/// Constructor /// Constructor
/// @param body the else body /// @param body the else body
explicit ElseStatement(std::unique_ptr<BlockStatement> body); explicit ElseStatement(BlockStatement* body);
/// Constructor /// Constructor
/// @param condition the else condition /// @param condition the else condition
/// @param body the else body /// @param body the else body
ElseStatement(std::unique_ptr<Expression> condition, ElseStatement(Expression* condition, BlockStatement* body);
std::unique_ptr<BlockStatement> body);
/// Constructor /// Constructor
/// @param source the source information /// @param source the source information
/// @param body the else body /// @param body the else body
ElseStatement(const Source& source, std::unique_ptr<BlockStatement> body); ElseStatement(const Source& source, BlockStatement* body);
/// Constructor /// Constructor
/// @param source the source information /// @param source the source information
/// @param condition the else condition /// @param condition the else condition
/// @param body the else body /// @param body the else body
ElseStatement(const Source& source, ElseStatement(const Source& source,
std::unique_ptr<Expression> condition, Expression* condition,
std::unique_ptr<BlockStatement> body); BlockStatement* body);
/// Move constructor /// Move constructor
ElseStatement(ElseStatement&&); ElseStatement(ElseStatement&&);
~ElseStatement() override; ~ElseStatement() override;
/// Sets the condition for the else statement /// Sets the condition for the else statement
/// @param condition the condition to set /// @param condition the condition to set
void set_condition(std::unique_ptr<Expression> condition) { void set_condition(Expression* condition) { condition_ = condition; }
condition_ = std::move(condition);
}
/// @returns the else condition or nullptr if none set /// @returns the else condition or nullptr if none set
Expression* condition() const { return condition_.get(); } Expression* condition() const { return condition_; }
/// @returns true if the else has a condition /// @returns true if the else has a condition
bool HasCondition() const { return condition_ != nullptr; } bool HasCondition() const { return condition_ != nullptr; }
/// Sets the else body /// Sets the else body
/// @param body the else body /// @param body the else body
void set_body(std::unique_ptr<BlockStatement> body) { void set_body(BlockStatement* body) { body_ = body; }
body_ = std::move(body);
}
/// @returns the else body /// @returns the else body
const BlockStatement* body() const { return body_.get(); } const BlockStatement* body() const { return body_; }
/// @returns the else body /// @returns the else body
BlockStatement* body() { return body_.get(); } BlockStatement* body() { return body_; }
/// @returns true if this is a else statement /// @returns true if this is a else statement
bool IsElse() const override; bool IsElse() const override;
@ -86,12 +81,12 @@ class ElseStatement : public Statement {
private: private:
ElseStatement(const ElseStatement&) = delete; ElseStatement(const ElseStatement&) = delete;
std::unique_ptr<Expression> condition_; Expression* condition_ = nullptr;
std::unique_ptr<BlockStatement> body_; BlockStatement* body_ = nullptr;
}; };
/// A list of unique else statements /// A list of else statements
using ElseStatementList = std::vector<std::unique_ptr<ElseStatement>>; using ElseStatementList = std::vector<ElseStatement*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -29,12 +29,12 @@ using ElseStatementTest = TestHelper;
TEST_F(ElseStatementTest, Creation) { TEST_F(ElseStatementTest, Creation) {
ast::type::BoolType bool_type; ast::type::BoolType bool_type;
auto cond = create<ScalarConstructorExpression>( auto* cond = create<ScalarConstructorExpression>(
create<BoolLiteral>(&bool_type, true)); create<BoolLiteral>(&bool_type, true));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto* cond_ptr = cond.get(); auto* cond_ptr = cond;
auto* discard_ptr = body->get(0); auto* discard_ptr = body->get(0);
ElseStatement e(std::move(cond), std::move(body)); ElseStatement e(std::move(cond), std::move(body));
@ -57,7 +57,7 @@ TEST_F(ElseStatementTest, IsElse) {
TEST_F(ElseStatementTest, HasCondition) { TEST_F(ElseStatementTest, HasCondition) {
ast::type::BoolType bool_type; ast::type::BoolType bool_type;
auto cond = create<ScalarConstructorExpression>( auto* cond = create<ScalarConstructorExpression>(
create<BoolLiteral>(&bool_type, true)); create<BoolLiteral>(&bool_type, true));
ElseStatement e(std::move(cond), create<BlockStatement>()); ElseStatement e(std::move(cond), create<BlockStatement>());
EXPECT_TRUE(e.HasCondition()); EXPECT_TRUE(e.HasCondition());
@ -74,7 +74,7 @@ TEST_F(ElseStatementTest, IsValid) {
} }
TEST_F(ElseStatementTest, IsValid_WithBody) { TEST_F(ElseStatementTest, IsValid_WithBody) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatement e(std::move(body)); ElseStatement e(std::move(body));
@ -82,7 +82,7 @@ TEST_F(ElseStatementTest, IsValid_WithBody) {
} }
TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) { TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
body->append(nullptr); body->append(nullptr);
@ -91,13 +91,13 @@ TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) {
} }
TEST_F(ElseStatementTest, IsValid_InvalidCondition) { TEST_F(ElseStatementTest, IsValid_InvalidCondition) {
auto cond = create<ScalarConstructorExpression>(); auto* cond = create<ScalarConstructorExpression>();
ElseStatement e(std::move(cond), create<BlockStatement>()); ElseStatement e(std::move(cond), create<BlockStatement>());
EXPECT_FALSE(e.IsValid()); EXPECT_FALSE(e.IsValid());
} }
TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) { TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<IfStatement>(nullptr, create<ast::BlockStatement>())); body->append(create<IfStatement>(nullptr, create<ast::BlockStatement>()));
ElseStatement e(std::move(body)); ElseStatement e(std::move(body));
@ -106,9 +106,9 @@ TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) {
TEST_F(ElseStatementTest, ToStr) { TEST_F(ElseStatementTest, ToStr) {
ast::type::BoolType bool_type; ast::type::BoolType bool_type;
auto cond = create<ScalarConstructorExpression>( auto* cond = create<ScalarConstructorExpression>(
create<BoolLiteral>(&bool_type, true)); create<BoolLiteral>(&bool_type, true));
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatement e(std::move(cond), std::move(body)); ElseStatement e(std::move(cond), std::move(body));
@ -126,7 +126,7 @@ TEST_F(ElseStatementTest, ToStr) {
} }
TEST_F(ElseStatementTest, ToStr_NoCondition) { TEST_F(ElseStatementTest, ToStr_NoCondition) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatement e(std::move(body)); ElseStatement e(std::move(body));

View File

@ -117,8 +117,8 @@ class Expression : public Node {
type::Type* result_type_ = nullptr; type::Type* result_type_ = nullptr;
}; };
/// A list of unique expressions /// A list of expressions
using ExpressionList = std::vector<std::unique_ptr<Expression>>; using ExpressionList = std::vector<Expression*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -29,30 +29,30 @@ Function::Function() = default;
Function::Function(const std::string& name, Function::Function(const std::string& name,
VariableList params, VariableList params,
type::Type* return_type, type::Type* return_type,
std::unique_ptr<BlockStatement> body) BlockStatement* body)
: Node(), : Node(),
name_(name), name_(name),
params_(std::move(params)), params_(std::move(params)),
return_type_(return_type), return_type_(return_type),
body_(std::move(body)) {} body_(body) {}
Function::Function(const Source& source, Function::Function(const Source& source,
const std::string& name, const std::string& name,
VariableList params, VariableList params,
type::Type* return_type, type::Type* return_type,
std::unique_ptr<BlockStatement> body) BlockStatement* body)
: Node(source), : Node(source),
name_(name), name_(name),
params_(std::move(params)), params_(std::move(params)),
return_type_(return_type), return_type_(return_type),
body_(std::move(body)) {} body_(body) {}
Function::Function(Function&&) = default; Function::Function(Function&&) = default;
Function::~Function() = default; Function::~Function() = default;
std::tuple<uint32_t, uint32_t, uint32_t> Function::workgroup_size() const { std::tuple<uint32_t, uint32_t, uint32_t> Function::workgroup_size() const {
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsWorkgroup()) { if (deco->IsWorkgroup()) {
return deco->AsWorkgroup()->values(); return deco->AsWorkgroup()->values();
} }
@ -61,7 +61,7 @@ std::tuple<uint32_t, uint32_t, uint32_t> Function::workgroup_size() const {
} }
ast::PipelineStage Function::pipeline_stage() const { ast::PipelineStage Function::pipeline_stage() const {
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsStage()) { if (deco->IsStage()) {
return deco->AsStage()->value(); return deco->AsStage()->value();
} }
@ -86,9 +86,9 @@ Function::referenced_location_variables() const {
if (!var->IsDecorated()) { if (!var->IsDecorated()) {
continue; continue;
} }
for (auto& deco : var->AsDecorated()->decorations()) { for (auto* deco : var->AsDecorated()->decorations()) {
if (deco->IsLocation()) { if (deco->IsLocation()) {
ret.push_back({var, deco.get()->AsLocation()}); ret.push_back({var, deco->AsLocation()});
break; break;
} }
} }
@ -108,7 +108,7 @@ Function::referenced_uniform_variables() const {
BindingDecoration* binding = nullptr; BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr; SetDecoration* set = nullptr;
for (const auto& deco : var->AsDecorated()->decorations()) { for (auto* deco : var->AsDecorated()->decorations()) {
if (deco->IsBinding()) { if (deco->IsBinding()) {
binding = deco->AsBinding(); binding = deco->AsBinding();
} else if (deco->IsSet()) { } else if (deco->IsSet()) {
@ -136,7 +136,7 @@ Function::referenced_storagebuffer_variables() const {
BindingDecoration* binding = nullptr; BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr; SetDecoration* set = nullptr;
for (const auto& deco : var->AsDecorated()->decorations()) { for (auto* deco : var->AsDecorated()->decorations()) {
if (deco->IsBinding()) { if (deco->IsBinding()) {
binding = deco->AsBinding(); binding = deco->AsBinding();
} else if (deco->IsSet()) { } else if (deco->IsSet()) {
@ -160,9 +160,9 @@ Function::referenced_builtin_variables() const {
if (!var->IsDecorated()) { if (!var->IsDecorated()) {
continue; continue;
} }
for (auto& deco : var->AsDecorated()->decorations()) { for (auto* deco : var->AsDecorated()->decorations()) {
if (deco->IsBuiltin()) { if (deco->IsBuiltin()) {
ret.push_back({var, deco.get()->AsBuiltin()}); ret.push_back({var, deco->AsBuiltin()});
break; break;
} }
} }
@ -213,7 +213,7 @@ const Statement* Function::get_last_statement() const {
} }
bool Function::IsValid() const { bool Function::IsValid() const {
for (const auto& param : params_) { for (auto* param : params_) {
if (param == nullptr || !param->IsValid()) if (param == nullptr || !param->IsValid())
return false; return false;
} }
@ -234,7 +234,7 @@ void Function::to_str(std::ostream& out, size_t indent) const {
out << "Function " << name_ << " -> " << return_type_->type_name() out << "Function " << name_ << " -> " << return_type_->type_name()
<< std::endl; << std::endl;
for (const auto& deco : decorations()) { for (auto* deco : decorations()) {
deco->to_str(out, indent); deco->to_str(out, indent);
} }
@ -244,7 +244,7 @@ void Function::to_str(std::ostream& out, size_t indent) const {
if (params_.size() > 0) { if (params_.size() > 0) {
out << std::endl; out << std::endl;
for (const auto& param : params_) for (auto* param : params_)
param->to_str(out, indent + 2); param->to_str(out, indent + 2);
make_indent(out, indent); make_indent(out, indent);
@ -255,7 +255,7 @@ void Function::to_str(std::ostream& out, size_t indent) const {
out << "{" << std::endl; out << "{" << std::endl;
if (body_ != nullptr) { if (body_ != nullptr) {
for (const auto& stmt : *body_) { for (auto* stmt : *body_) {
stmt->to_str(out, indent + 2); stmt->to_str(out, indent + 2);
} }
} }
@ -268,7 +268,7 @@ std::string Function::type_name() const {
std::ostringstream out; std::ostringstream out;
out << "__func" + return_type_->type_name(); out << "__func" + return_type_->type_name();
for (const auto& param : params_) { for (auto* param : params_) {
out << param->type()->type_name(); out << param->type()->type_name();
} }
@ -288,7 +288,7 @@ Function::ReferencedSamplerVariablesImpl(type::SamplerKind kind) const {
BindingDecoration* binding = nullptr; BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr; SetDecoration* set = nullptr;
for (const auto& deco : var->AsDecorated()->decorations()) { for (auto* deco : var->AsDecorated()->decorations()) {
if (deco->IsBinding()) { if (deco->IsBinding()) {
binding = deco->AsBinding(); binding = deco->AsBinding();
} else if (deco->IsSet()) { } else if (deco->IsSet()) {
@ -321,7 +321,7 @@ Function::ReferencedSampledTextureVariablesImpl(bool multisampled) const {
BindingDecoration* binding = nullptr; BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr; SetDecoration* set = nullptr;
for (const auto& deco : var->AsDecorated()->decorations()) { for (auto* deco : var->AsDecorated()->decorations()) {
if (deco->IsBinding()) { if (deco->IsBinding()) {
binding = deco->AsBinding(); binding = deco->AsBinding();
} else if (deco->IsSet()) { } else if (deco->IsSet()) {

View File

@ -51,8 +51,7 @@ class Function : public Node {
}; };
/// Create a new empty function statement /// Create a new empty function statement
Function(); Function(); /// Create a function
/// Create a function
/// @param name the function name /// @param name the function name
/// @param params the function parameters /// @param params the function parameters
/// @param return_type the return type /// @param return_type the return type
@ -60,7 +59,7 @@ class Function : public Node {
Function(const std::string& name, Function(const std::string& name,
VariableList params, VariableList params,
type::Type* return_type, type::Type* return_type,
std::unique_ptr<BlockStatement> body); BlockStatement* body);
/// Create a function /// Create a function
/// @param source the variable source /// @param source the variable source
/// @param name the function name /// @param name the function name
@ -71,7 +70,7 @@ class Function : public Node {
const std::string& name, const std::string& name,
VariableList params, VariableList params,
type::Type* return_type, type::Type* return_type,
std::unique_ptr<BlockStatement> body); BlockStatement* body);
/// Move constructor /// Move constructor
Function(Function&&); Function(Function&&);
@ -97,8 +96,8 @@ class Function : public Node {
} }
/// Adds a decoration to the function /// Adds a decoration to the function
/// @param deco the decoration to set /// @param deco the decoration to set
void add_decoration(std::unique_ptr<FunctionDecoration> deco) { void add_decoration(FunctionDecoration* deco) {
decorations_.push_back(std::move(deco)); decorations_.push_back(deco);
} }
/// @returns the decorations attached to this function /// @returns the decorations attached to this function
const FunctionDecorationList& decorations() const { return decorations_; } const FunctionDecorationList& decorations() const { return decorations_; }
@ -187,13 +186,11 @@ class Function : public Node {
/// Sets the body of the function /// Sets the body of the function
/// @param body the function body /// @param body the function body
void set_body(std::unique_ptr<BlockStatement> body) { void set_body(BlockStatement* body) { body_ = body; }
body_ = std::move(body);
}
/// @returns the function body /// @returns the function body
const BlockStatement* body() const { return body_.get(); } const BlockStatement* body() const { return body_; }
/// @returns the function body /// @returns the function body
BlockStatement* body() { return body_.get(); } BlockStatement* body() { return body_; }
/// @returns true if the name and type are both present /// @returns true if the name and type are both present
bool IsValid() const override; bool IsValid() const override;
@ -216,14 +213,14 @@ class Function : public Node {
std::string name_; std::string name_;
VariableList params_; VariableList params_;
type::Type* return_type_ = nullptr; type::Type* return_type_ = nullptr;
std::unique_ptr<BlockStatement> body_; BlockStatement* body_ = nullptr;
std::vector<Variable*> referenced_module_vars_; std::vector<Variable*> referenced_module_vars_;
std::vector<std::string> ancestor_entry_points_; std::vector<std::string> ancestor_entry_points_;
FunctionDecorationList decorations_; FunctionDecorationList decorations_;
}; };
/// A list of unique functions /// A list of functions
using FunctionList = std::vector<std::unique_ptr<Function>>; using FunctionList = std::vector<Function*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -51,8 +51,8 @@ class FunctionDecoration : public Decoration {
explicit FunctionDecoration(const Source& source); explicit FunctionDecoration(const Source& source);
}; };
/// A list of unique function decorations /// A list of function decorations
using FunctionDecorationList = std::vector<std::unique_ptr<FunctionDecoration>>; using FunctionDecorationList = std::vector<FunctionDecoration*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -38,14 +38,14 @@ TEST_F(FunctionTest, Creation) {
VariableList params; VariableList params;
params.push_back(create<Variable>("var", StorageClass::kNone, &i32)); params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
auto* var_ptr = params[0].get(); auto* var_ptr = params[0];
Function f("func", std::move(params), &void_type, Function f("func", std::move(params), &void_type,
create<ast::BlockStatement>()); create<ast::BlockStatement>());
EXPECT_EQ(f.name(), "func"); EXPECT_EQ(f.name(), "func");
ASSERT_EQ(f.params().size(), 1u); ASSERT_EQ(f.params().size(), 1u);
EXPECT_EQ(f.return_type(), &void_type); EXPECT_EQ(f.return_type(), &void_type);
EXPECT_EQ(f.params()[0].get(), var_ptr); EXPECT_EQ(f.params()[0], var_ptr);
} }
TEST_F(FunctionTest, Creation_WithSource) { TEST_F(FunctionTest, Creation_WithSource) {
@ -188,7 +188,7 @@ TEST_F(FunctionTest, IsValid) {
VariableList params; VariableList params;
params.push_back(create<Variable>("var", StorageClass::kNone, &i32)); params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
auto block = create<ast::BlockStatement>(); auto* block = create<ast::BlockStatement>();
block->append(create<DiscardStatement>()); block->append(create<DiscardStatement>());
Function f("func", std::move(params), &void_type, Function f("func", std::move(params), &void_type,
@ -249,7 +249,7 @@ TEST_F(FunctionTest, IsValid_NullBodyStatement) {
VariableList params; VariableList params;
params.push_back(create<Variable>("var", StorageClass::kNone, &i32)); params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
auto block = create<ast::BlockStatement>(); auto* block = create<ast::BlockStatement>();
block->append(create<DiscardStatement>()); block->append(create<DiscardStatement>());
block->append(nullptr); block->append(nullptr);
@ -266,7 +266,7 @@ TEST_F(FunctionTest, IsValid_InvalidBodyStatement) {
VariableList params; VariableList params;
params.push_back(create<Variable>("var", StorageClass::kNone, &i32)); params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
auto block = create<ast::BlockStatement>(); auto* block = create<ast::BlockStatement>();
block->append(create<DiscardStatement>()); block->append(create<DiscardStatement>());
block->append(nullptr); block->append(nullptr);
@ -280,7 +280,7 @@ TEST_F(FunctionTest, ToStr) {
type::VoidType void_type; type::VoidType void_type;
type::I32Type i32; type::I32Type i32;
auto block = create<ast::BlockStatement>(); auto* block = create<ast::BlockStatement>();
block->append(create<DiscardStatement>()); block->append(create<DiscardStatement>());
Function f("func", {}, &void_type, create<ast::BlockStatement>()); Function f("func", {}, &void_type, create<ast::BlockStatement>());
@ -300,7 +300,7 @@ TEST_F(FunctionTest, ToStr_WithDecoration) {
type::VoidType void_type; type::VoidType void_type;
type::I32Type i32; type::I32Type i32;
auto block = create<ast::BlockStatement>(); auto* block = create<ast::BlockStatement>();
block->append(create<DiscardStatement>()); block->append(create<DiscardStatement>());
Function f("func", {}, &void_type, create<ast::BlockStatement>()); Function f("func", {}, &void_type, create<ast::BlockStatement>());
@ -325,7 +325,7 @@ TEST_F(FunctionTest, ToStr_WithParams) {
VariableList params; VariableList params;
params.push_back(create<Variable>("var", StorageClass::kNone, &i32)); params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
auto block = create<ast::BlockStatement>(); auto* block = create<ast::BlockStatement>();
block->append(create<DiscardStatement>()); block->append(create<DiscardStatement>());
Function f("func", std::move(params), &void_type, Function f("func", std::move(params), &void_type,
@ -373,9 +373,9 @@ TEST_F(FunctionTest, GetLastStatement) {
type::VoidType void_type; type::VoidType void_type;
VariableList params; VariableList params;
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
auto stmt = create<DiscardStatement>(); auto* stmt = create<DiscardStatement>();
auto* stmt_ptr = stmt.get(); auto* stmt_ptr = stmt;
body->append(std::move(stmt)); body->append(std::move(stmt));
Function f("func", std::move(params), &void_type, Function f("func", std::move(params), &void_type,
create<ast::BlockStatement>()); create<ast::BlockStatement>());
@ -388,7 +388,7 @@ TEST_F(FunctionTest, GetLastStatement_nullptr) {
type::VoidType void_type; type::VoidType void_type;
VariableList params; VariableList params;
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
Function f("func", std::move(params), &void_type, Function f("func", std::move(params), &void_type,
create<ast::BlockStatement>()); create<ast::BlockStatement>());
f.set_body(std::move(body)); f.set_body(std::move(body));

View File

@ -19,16 +19,13 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
IfStatement::IfStatement(std::unique_ptr<Expression> condition, IfStatement::IfStatement(Expression* condition, BlockStatement* body)
std::unique_ptr<BlockStatement> body) : Statement(), condition_(condition), body_(body) {}
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
IfStatement::IfStatement(const Source& source, IfStatement::IfStatement(const Source& source,
std::unique_ptr<Expression> condition, Expression* condition,
std::unique_ptr<BlockStatement> body) BlockStatement* body)
: Statement(source), : Statement(source), condition_(condition), body_(body) {}
condition_(std::move(condition)),
body_(std::move(body)) {}
IfStatement::IfStatement(IfStatement&&) = default; IfStatement::IfStatement(IfStatement&&) = default;
@ -47,7 +44,7 @@ bool IfStatement::IsValid() const {
} }
bool found_else = false; bool found_else = false;
for (const auto& el : else_statements_) { for (auto* el : else_statements_) {
// Else statement must be last // Else statement must be last
if (found_else) if (found_else)
return false; return false;
@ -81,7 +78,7 @@ void IfStatement::to_str(std::ostream& out, size_t indent) const {
out << "{" << std::endl; out << "{" << std::endl;
if (body_ != nullptr) { if (body_ != nullptr) {
for (const auto& stmt : *body_) { for (auto* stmt : *body_) {
stmt->to_str(out, indent + 4); stmt->to_str(out, indent + 4);
} }
} }
@ -94,7 +91,7 @@ void IfStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent); make_indent(out, indent);
out << "}" << std::endl; out << "}" << std::endl;
for (const auto& e : else_statements_) { for (auto* e : else_statements_) {
e->to_str(out, indent); e->to_str(out, indent);
} }
} }

View File

@ -32,36 +32,31 @@ class IfStatement : public Statement {
/// Constructor /// Constructor
/// @param condition the if condition /// @param condition the if condition
/// @param body the if body /// @param body the if body
IfStatement(std::unique_ptr<Expression> condition, IfStatement(Expression* condition, BlockStatement* body);
std::unique_ptr<BlockStatement> body);
/// Constructor /// Constructor
/// @param source the source information /// @param source the source information
/// @param condition the if condition /// @param condition the if condition
/// @param body the if body /// @param body the if body
IfStatement(const Source& source, IfStatement(const Source& source,
std::unique_ptr<Expression> condition, Expression* condition,
std::unique_ptr<BlockStatement> body); BlockStatement* body);
/// Move constructor /// Move constructor
IfStatement(IfStatement&&); IfStatement(IfStatement&&);
~IfStatement() override; ~IfStatement() override;
/// Sets the condition for the if statement /// Sets the condition for the if statement
/// @param condition the condition to set /// @param condition the condition to set
void set_condition(std::unique_ptr<Expression> condition) { void set_condition(Expression* condition) { condition_ = condition; }
condition_ = std::move(condition);
}
/// @returns the if condition or nullptr if none set /// @returns the if condition or nullptr if none set
Expression* condition() const { return condition_.get(); } Expression* condition() const { return condition_; }
/// Sets the if body /// Sets the if body
/// @param body the if body /// @param body the if body
void set_body(std::unique_ptr<BlockStatement> body) { void set_body(BlockStatement* body) { body_ = body; }
body_ = std::move(body);
}
/// @returns the if body /// @returns the if body
const BlockStatement* body() const { return body_.get(); } const BlockStatement* body() const { return body_; }
/// @returns the if body /// @returns the if body
BlockStatement* body() { return body_.get(); } BlockStatement* body() { return body_; }
/// Sets the else statements /// Sets the else statements
/// @param else_statements the else statements to set /// @param else_statements the else statements to set
@ -90,8 +85,8 @@ class IfStatement : public Statement {
private: private:
IfStatement(const IfStatement&) = delete; IfStatement(const IfStatement&) = delete;
std::unique_ptr<Expression> condition_; Expression* condition_ = nullptr;
std::unique_ptr<BlockStatement> body_; BlockStatement* body_ = nullptr;
ElseStatementList else_statements_; ElseStatementList else_statements_;
}; };

View File

@ -25,11 +25,11 @@ namespace {
using IfStatementTest = TestHelper; using IfStatementTest = TestHelper;
TEST_F(IfStatementTest, Creation) { TEST_F(IfStatementTest, Creation) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto* cond_ptr = cond.get(); auto* cond_ptr = cond;
auto* stmt_ptr = body->get(0); auto* stmt_ptr = body->get(0);
IfStatement stmt(std::move(cond), std::move(body)); IfStatement stmt(std::move(cond), std::move(body));
@ -39,8 +39,8 @@ TEST_F(IfStatementTest, Creation) {
} }
TEST_F(IfStatementTest, Creation_WithSource) { TEST_F(IfStatementTest, Creation_WithSource) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
IfStatement stmt(Source{Source::Location{20, 2}}, std::move(cond), IfStatement stmt(Source{Source::Location{20, 2}}, std::move(cond),
@ -56,8 +56,8 @@ TEST_F(IfStatementTest, IsIf) {
} }
TEST_F(IfStatementTest, IsValid) { TEST_F(IfStatementTest, IsValid) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
IfStatement stmt(std::move(cond), std::move(body)); IfStatement stmt(std::move(cond), std::move(body));
@ -65,8 +65,8 @@ TEST_F(IfStatementTest, IsValid) {
} }
TEST_F(IfStatementTest, IsValid_WithElseStatements) { TEST_F(IfStatementTest, IsValid_WithElseStatements) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatementList else_stmts; ElseStatementList else_stmts;
@ -80,7 +80,7 @@ TEST_F(IfStatementTest, IsValid_WithElseStatements) {
} }
TEST_F(IfStatementTest, IsValid_MissingCondition) { TEST_F(IfStatementTest, IsValid_MissingCondition) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
IfStatement stmt(nullptr, std::move(body)); IfStatement stmt(nullptr, std::move(body));
@ -88,8 +88,8 @@ TEST_F(IfStatementTest, IsValid_MissingCondition) {
} }
TEST_F(IfStatementTest, IsValid_InvalidCondition) { TEST_F(IfStatementTest, IsValid_InvalidCondition) {
auto cond = create<IdentifierExpression>(""); auto* cond = create<IdentifierExpression>("");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
IfStatement stmt(std::move(cond), std::move(body)); IfStatement stmt(std::move(cond), std::move(body));
@ -97,8 +97,8 @@ TEST_F(IfStatementTest, IsValid_InvalidCondition) {
} }
TEST_F(IfStatementTest, IsValid_NullBodyStatement) { TEST_F(IfStatementTest, IsValid_NullBodyStatement) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
body->append(nullptr); body->append(nullptr);
@ -107,8 +107,8 @@ TEST_F(IfStatementTest, IsValid_NullBodyStatement) {
} }
TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) { TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
body->append(create<IfStatement>(nullptr, create<BlockStatement>())); body->append(create<IfStatement>(nullptr, create<BlockStatement>()));
@ -117,8 +117,8 @@ TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) {
} }
TEST_F(IfStatementTest, IsValid_NullElseStatement) { TEST_F(IfStatementTest, IsValid_NullElseStatement) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatementList else_stmts; ElseStatementList else_stmts;
@ -133,8 +133,8 @@ TEST_F(IfStatementTest, IsValid_NullElseStatement) {
} }
TEST_F(IfStatementTest, IsValid_InvalidElseStatement) { TEST_F(IfStatementTest, IsValid_InvalidElseStatement) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatementList else_stmts; ElseStatementList else_stmts;
@ -147,8 +147,8 @@ TEST_F(IfStatementTest, IsValid_InvalidElseStatement) {
} }
TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) { TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatementList else_stmts; ElseStatementList else_stmts;
@ -161,8 +161,8 @@ TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) {
} }
TEST_F(IfStatementTest, IsValid_ElseNotLast) { TEST_F(IfStatementTest, IsValid_ElseNotLast) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
ElseStatementList else_stmts; ElseStatementList else_stmts;
@ -176,8 +176,8 @@ TEST_F(IfStatementTest, IsValid_ElseNotLast) {
} }
TEST_F(IfStatementTest, ToStr) { TEST_F(IfStatementTest, ToStr) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
IfStatement stmt(std::move(cond), std::move(body)); IfStatement stmt(std::move(cond), std::move(body));
@ -196,14 +196,14 @@ TEST_F(IfStatementTest, ToStr) {
} }
TEST_F(IfStatementTest, ToStr_WithElseStatements) { TEST_F(IfStatementTest, ToStr_WithElseStatements) {
auto cond = create<IdentifierExpression>("cond"); auto* cond = create<IdentifierExpression>("cond");
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto else_if_body = create<BlockStatement>(); auto* else_if_body = create<BlockStatement>();
else_if_body->append(create<DiscardStatement>()); else_if_body->append(create<DiscardStatement>());
auto else_body = create<BlockStatement>(); auto* else_body = create<BlockStatement>();
else_body->append(create<DiscardStatement>()); else_body->append(create<DiscardStatement>());
else_body->append(create<DiscardStatement>()); else_body->append(create<DiscardStatement>());

View File

@ -17,16 +17,13 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
LoopStatement::LoopStatement(std::unique_ptr<BlockStatement> body, LoopStatement::LoopStatement(BlockStatement* body, BlockStatement* continuing)
std::unique_ptr<BlockStatement> continuing) : Statement(), body_(body), continuing_(continuing) {}
: Statement(), body_(std::move(body)), continuing_(std::move(continuing)) {}
LoopStatement::LoopStatement(const Source& source, LoopStatement::LoopStatement(const Source& source,
std::unique_ptr<BlockStatement> body, BlockStatement* body,
std::unique_ptr<BlockStatement> continuing) BlockStatement* continuing)
: Statement(source), : Statement(source), body_(body), continuing_(continuing) {}
body_(std::move(body)),
continuing_(std::move(continuing)) {}
LoopStatement::LoopStatement(LoopStatement&&) = default; LoopStatement::LoopStatement(LoopStatement&&) = default;
@ -51,7 +48,7 @@ void LoopStatement::to_str(std::ostream& out, size_t indent) const {
out << "Loop{" << std::endl; out << "Loop{" << std::endl;
if (body_ != nullptr) { if (body_ != nullptr) {
for (const auto& stmt : *body_) { for (auto* stmt : *body_) {
stmt->to_str(out, indent + 2); stmt->to_str(out, indent + 2);
} }
} }
@ -60,7 +57,7 @@ void LoopStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent + 2); make_indent(out, indent + 2);
out << "continuing {" << std::endl; out << "continuing {" << std::endl;
for (const auto& stmt : *continuing_) { for (auto* stmt : *continuing_) {
stmt->to_str(out, indent + 4); stmt->to_str(out, indent + 4);
} }

View File

@ -30,38 +30,33 @@ class LoopStatement : public Statement {
/// Constructor /// Constructor
/// @param body the body statements /// @param body the body statements
/// @param continuing the continuing statements /// @param continuing the continuing statements
LoopStatement(std::unique_ptr<BlockStatement> body, LoopStatement(BlockStatement* body, BlockStatement* continuing);
std::unique_ptr<BlockStatement> continuing);
/// Constructor /// Constructor
/// @param source the loop statement source /// @param source the loop statement source
/// @param body the body statements /// @param body the body statements
/// @param continuing the continuing statements /// @param continuing the continuing statements
LoopStatement(const Source& source, LoopStatement(const Source& source,
std::unique_ptr<BlockStatement> body, BlockStatement* body,
std::unique_ptr<BlockStatement> continuing); BlockStatement* continuing);
/// Move constructor /// Move constructor
LoopStatement(LoopStatement&&); LoopStatement(LoopStatement&&);
~LoopStatement() override; ~LoopStatement() override;
/// Sets the body statements /// Sets the body statements
/// @param body the body statements /// @param body the body statements
void set_body(std::unique_ptr<BlockStatement> body) { void set_body(BlockStatement* body) { body_ = body; }
body_ = std::move(body);
}
/// @returns the body statements /// @returns the body statements
const BlockStatement* body() const { return body_.get(); } const BlockStatement* body() const { return body_; }
/// @returns the body statements /// @returns the body statements
BlockStatement* body() { return body_.get(); } BlockStatement* body() { return body_; }
/// Sets the continuing statements /// Sets the continuing statements
/// @param continuing the continuing statements /// @param continuing the continuing statements
void set_continuing(std::unique_ptr<BlockStatement> continuing) { void set_continuing(BlockStatement* continuing) { continuing_ = continuing; }
continuing_ = std::move(continuing);
}
/// @returns the continuing statements /// @returns the continuing statements
const BlockStatement* continuing() const { return continuing_.get(); } const BlockStatement* continuing() const { return continuing_; }
/// @returns the continuing statements /// @returns the continuing statements
BlockStatement* continuing() { return continuing_.get(); } BlockStatement* continuing() { return continuing_; }
/// @returns true if there are continuing statements in the loop /// @returns true if there are continuing statements in the loop
bool has_continuing() const { bool has_continuing() const {
return continuing_ != nullptr && !continuing_->empty(); return continuing_ != nullptr && !continuing_->empty();
@ -81,8 +76,8 @@ class LoopStatement : public Statement {
private: private:
LoopStatement(const LoopStatement&) = delete; LoopStatement(const LoopStatement&) = delete;
std::unique_ptr<BlockStatement> body_; BlockStatement* body_ = nullptr;
std::unique_ptr<BlockStatement> continuing_; BlockStatement* continuing_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -28,11 +28,11 @@ namespace {
using LoopStatementTest = TestHelper; using LoopStatementTest = TestHelper;
TEST_F(LoopStatementTest, Creation) { TEST_F(LoopStatementTest, Creation) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto* b_ptr = body->last(); auto* b_ptr = body->last();
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
auto* c_ptr = continuing->last(); auto* c_ptr = continuing->last();
@ -44,10 +44,10 @@ TEST_F(LoopStatementTest, Creation) {
} }
TEST_F(LoopStatementTest, Creation_WithSource) { TEST_F(LoopStatementTest, Creation_WithSource) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
LoopStatement l(Source{Source::Location{20, 2}}, std::move(body), LoopStatement l(Source{Source::Location{20, 2}}, std::move(body),
@ -63,7 +63,7 @@ TEST_F(LoopStatementTest, IsLoop) {
} }
TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) { TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
LoopStatement l(std::move(body), {}); LoopStatement l(std::move(body), {});
@ -71,10 +71,10 @@ TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) {
} }
TEST_F(LoopStatementTest, HasContinuing_WithContinuing) { TEST_F(LoopStatementTest, HasContinuing_WithContinuing) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
LoopStatement l(std::move(body), std::move(continuing)); LoopStatement l(std::move(body), std::move(continuing));
@ -82,10 +82,10 @@ TEST_F(LoopStatementTest, HasContinuing_WithContinuing) {
} }
TEST_F(LoopStatementTest, IsValid) { TEST_F(LoopStatementTest, IsValid) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
LoopStatement l(std::move(body), std::move(continuing)); LoopStatement l(std::move(body), std::move(continuing));
@ -93,7 +93,7 @@ TEST_F(LoopStatementTest, IsValid) {
} }
TEST_F(LoopStatementTest, IsValid_WithoutContinuing) { TEST_F(LoopStatementTest, IsValid_WithoutContinuing) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
LoopStatement l(std::move(body), create<BlockStatement>()); LoopStatement l(std::move(body), create<BlockStatement>());
@ -106,11 +106,11 @@ TEST_F(LoopStatementTest, IsValid_WithoutBody) {
} }
TEST_F(LoopStatementTest, IsValid_NullBodyStatement) { TEST_F(LoopStatementTest, IsValid_NullBodyStatement) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
body->append(nullptr); body->append(nullptr);
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
LoopStatement l(std::move(body), std::move(continuing)); LoopStatement l(std::move(body), std::move(continuing));
@ -118,11 +118,11 @@ TEST_F(LoopStatementTest, IsValid_NullBodyStatement) {
} }
TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) { TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
body->append(create<IfStatement>(nullptr, create<BlockStatement>())); body->append(create<IfStatement>(nullptr, create<BlockStatement>()));
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
LoopStatement l(std::move(body), std::move(continuing)); LoopStatement l(std::move(body), std::move(continuing));
@ -130,10 +130,10 @@ TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) {
} }
TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) { TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
continuing->append(nullptr); continuing->append(nullptr);
@ -142,10 +142,10 @@ TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) {
} }
TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) { TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
continuing->append(create<IfStatement>(nullptr, create<BlockStatement>())); continuing->append(create<IfStatement>(nullptr, create<BlockStatement>()));
@ -154,7 +154,7 @@ TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) {
} }
TEST_F(LoopStatementTest, ToStr) { TEST_F(LoopStatementTest, ToStr) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
LoopStatement l(std::move(body), {}); LoopStatement l(std::move(body), {});
@ -167,10 +167,10 @@ TEST_F(LoopStatementTest, ToStr) {
} }
TEST_F(LoopStatementTest, ToStr_WithContinuing) { TEST_F(LoopStatementTest, ToStr_WithContinuing) {
auto body = create<BlockStatement>(); auto* body = create<BlockStatement>();
body->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
auto continuing = create<BlockStatement>(); auto* continuing = create<BlockStatement>();
continuing->append(create<DiscardStatement>()); continuing->append(create<DiscardStatement>());
LoopStatement l(std::move(body), std::move(continuing)); LoopStatement l(std::move(body), std::move(continuing));

View File

@ -19,18 +19,14 @@ namespace ast {
MemberAccessorExpression::MemberAccessorExpression() = default; MemberAccessorExpression::MemberAccessorExpression() = default;
MemberAccessorExpression::MemberAccessorExpression( MemberAccessorExpression::MemberAccessorExpression(Expression* structure,
std::unique_ptr<Expression> structure, IdentifierExpression* member)
std::unique_ptr<IdentifierExpression> member) : Expression(), struct_(structure), member_(member) {}
: Expression(), struct_(std::move(structure)), member_(std::move(member)) {}
MemberAccessorExpression::MemberAccessorExpression( MemberAccessorExpression::MemberAccessorExpression(const Source& source,
const Source& source, Expression* structure,
std::unique_ptr<Expression> structure, IdentifierExpression* member)
std::unique_ptr<IdentifierExpression> member) : Expression(source), struct_(structure), member_(member) {}
: Expression(source),
struct_(std::move(structure)),
member_(std::move(member)) {}
MemberAccessorExpression::MemberAccessorExpression(MemberAccessorExpression&&) = MemberAccessorExpression::MemberAccessorExpression(MemberAccessorExpression&&) =
default; default;

View File

@ -34,34 +34,29 @@ class MemberAccessorExpression : public Expression {
/// Constructor /// Constructor
/// @param structure the structure /// @param structure the structure
/// @param member the member /// @param member the member
MemberAccessorExpression(std::unique_ptr<Expression> structure, MemberAccessorExpression(Expression* structure, IdentifierExpression* member);
std::unique_ptr<IdentifierExpression> member);
/// Constructor /// Constructor
/// @param source the member accessor expression source /// @param source the member accessor expression source
/// @param structure the structure /// @param structure the structure
/// @param member the member /// @param member the member
MemberAccessorExpression(const Source& source, MemberAccessorExpression(const Source& source,
std::unique_ptr<Expression> structure, Expression* structure,
std::unique_ptr<IdentifierExpression> member); IdentifierExpression* member);
/// Move constructor /// Move constructor
MemberAccessorExpression(MemberAccessorExpression&&); MemberAccessorExpression(MemberAccessorExpression&&);
~MemberAccessorExpression() override; ~MemberAccessorExpression() override;
/// Sets the structure /// Sets the structure
/// @param structure the structure /// @param structure the structure
void set_structure(std::unique_ptr<Expression> structure) { void set_structure(Expression* structure) { struct_ = structure; }
struct_ = std::move(structure);
}
/// @returns the structure /// @returns the structure
Expression* structure() const { return struct_.get(); } Expression* structure() const { return struct_; }
/// Sets the member /// Sets the member
/// @param member the member /// @param member the member
void set_member(std::unique_ptr<IdentifierExpression> member) { void set_member(IdentifierExpression* member) { member_ = member; }
member_ = std::move(member);
}
/// @returns the member expression /// @returns the member expression
IdentifierExpression* member() const { return member_.get(); } IdentifierExpression* member() const { return member_; }
/// @returns true if this is a member accessor expression /// @returns true if this is a member accessor expression
bool IsMemberAccessor() const override; bool IsMemberAccessor() const override;
@ -77,8 +72,8 @@ class MemberAccessorExpression : public Expression {
private: private:
MemberAccessorExpression(const MemberAccessorExpression&) = delete; MemberAccessorExpression(const MemberAccessorExpression&) = delete;
std::unique_ptr<Expression> struct_; Expression* struct_ = nullptr;
std::unique_ptr<IdentifierExpression> member_; IdentifierExpression* member_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -26,11 +26,11 @@ namespace {
using MemberAccessorExpressionTest = TestHelper; using MemberAccessorExpressionTest = TestHelper;
TEST_F(MemberAccessorExpressionTest, Creation) { TEST_F(MemberAccessorExpressionTest, Creation) {
auto str = create<IdentifierExpression>("structure"); auto* str = create<IdentifierExpression>("structure");
auto mem = create<IdentifierExpression>("member"); auto* mem = create<IdentifierExpression>("member");
auto* str_ptr = str.get(); auto* str_ptr = str;
auto* mem_ptr = mem.get(); auto* mem_ptr = mem;
MemberAccessorExpression stmt(std::move(str), std::move(mem)); MemberAccessorExpression stmt(std::move(str), std::move(mem));
EXPECT_EQ(stmt.structure(), str_ptr); EXPECT_EQ(stmt.structure(), str_ptr);
@ -38,8 +38,8 @@ TEST_F(MemberAccessorExpressionTest, Creation) {
} }
TEST_F(MemberAccessorExpressionTest, Creation_WithSource) { TEST_F(MemberAccessorExpressionTest, Creation_WithSource) {
auto str = create<IdentifierExpression>("structure"); auto* str = create<IdentifierExpression>("structure");
auto mem = create<IdentifierExpression>("member"); auto* mem = create<IdentifierExpression>("member");
MemberAccessorExpression stmt(Source{Source::Location{20, 2}}, std::move(str), MemberAccessorExpression stmt(Source{Source::Location{20, 2}}, std::move(str),
std::move(mem)); std::move(mem));
@ -54,15 +54,15 @@ TEST_F(MemberAccessorExpressionTest, IsMemberAccessor) {
} }
TEST_F(MemberAccessorExpressionTest, IsValid) { TEST_F(MemberAccessorExpressionTest, IsValid) {
auto str = create<IdentifierExpression>("structure"); auto* str = create<IdentifierExpression>("structure");
auto mem = create<IdentifierExpression>("member"); auto* mem = create<IdentifierExpression>("member");
MemberAccessorExpression stmt(std::move(str), std::move(mem)); MemberAccessorExpression stmt(std::move(str), std::move(mem));
EXPECT_TRUE(stmt.IsValid()); EXPECT_TRUE(stmt.IsValid());
} }
TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) { TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) {
auto mem = create<IdentifierExpression>("member"); auto* mem = create<IdentifierExpression>("member");
MemberAccessorExpression stmt; MemberAccessorExpression stmt;
stmt.set_member(std::move(mem)); stmt.set_member(std::move(mem));
@ -70,15 +70,15 @@ TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) {
} }
TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) { TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) {
auto str = create<IdentifierExpression>(""); auto* str = create<IdentifierExpression>("");
auto mem = create<IdentifierExpression>("member"); auto* mem = create<IdentifierExpression>("member");
MemberAccessorExpression stmt(std::move(str), std::move(mem)); MemberAccessorExpression stmt(std::move(str), std::move(mem));
EXPECT_FALSE(stmt.IsValid()); EXPECT_FALSE(stmt.IsValid());
} }
TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) { TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) {
auto str = create<IdentifierExpression>("structure"); auto* str = create<IdentifierExpression>("structure");
MemberAccessorExpression stmt; MemberAccessorExpression stmt;
stmt.set_structure(std::move(str)); stmt.set_structure(std::move(str));
@ -86,16 +86,16 @@ TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) {
} }
TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) { TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) {
auto str = create<IdentifierExpression>("structure"); auto* str = create<IdentifierExpression>("structure");
auto mem = create<IdentifierExpression>(""); auto* mem = create<IdentifierExpression>("");
MemberAccessorExpression stmt(std::move(str), std::move(mem)); MemberAccessorExpression stmt(std::move(str), std::move(mem));
EXPECT_FALSE(stmt.IsValid()); EXPECT_FALSE(stmt.IsValid());
} }
TEST_F(MemberAccessorExpressionTest, ToStr) { TEST_F(MemberAccessorExpressionTest, ToStr) {
auto str = create<IdentifierExpression>("structure"); auto* str = create<IdentifierExpression>("structure");
auto mem = create<IdentifierExpression>("member"); auto* mem = create<IdentifierExpression>("member");
MemberAccessorExpression stmt(std::move(str), std::move(mem)); MemberAccessorExpression stmt(std::move(str), std::move(mem));
std::ostringstream out; std::ostringstream out;

View File

@ -28,9 +28,9 @@ Module::Module(Module&&) = default;
Module::~Module() = default; Module::~Module() = default;
Function* Module::FindFunctionByName(const std::string& name) const { Function* Module::FindFunctionByName(const std::string& name) const {
for (const auto& func : functions_) { for (auto* func : functions_) {
if (func->name() == name) { if (func->name() == name) {
return func.get(); return func;
} }
} }
return nullptr; return nullptr;
@ -38,16 +38,16 @@ Function* Module::FindFunctionByName(const std::string& name) const {
Function* Module::FindFunctionByNameAndStage(const std::string& name, Function* Module::FindFunctionByNameAndStage(const std::string& name,
ast::PipelineStage stage) const { ast::PipelineStage stage) const {
for (const auto& func : functions_) { for (auto* func : functions_) {
if (func->name() == name && func->pipeline_stage() == stage) { if (func->name() == name && func->pipeline_stage() == stage) {
return func.get(); return func;
} }
} }
return nullptr; return nullptr;
} }
bool Module::IsValid() const { bool Module::IsValid() const {
for (const auto& var : global_variables_) { for (auto* var : global_variables_) {
if (var == nullptr || !var->IsValid()) { if (var == nullptr || !var->IsValid()) {
return false; return false;
} }
@ -74,7 +74,7 @@ bool Module::IsValid() const {
return false; return false;
} }
} }
for (const auto& func : functions_) { for (auto* func : functions_) {
if (func == nullptr || !func->IsValid()) { if (func == nullptr || !func->IsValid()) {
return false; return false;
} }
@ -103,10 +103,10 @@ std::string Module::to_str() const {
str->impl()->to_str(out, indent); str->impl()->to_str(out, indent);
} }
} }
for (const auto& var : global_variables_) { for (auto* var : global_variables_) {
var->to_str(out, indent); var->to_str(out, indent);
} }
for (const auto& func : functions_) { for (auto* func : functions_) {
func->to_str(out, indent); func->to_str(out, indent);
} }
out << "}" << std::endl; out << "}" << std::endl;

View File

@ -37,9 +37,7 @@ class Module {
/// Add a global variable to the module /// Add a global variable to the module
/// @param var the variable to add /// @param var the variable to add
void AddGlobalVariable(std::unique_ptr<Variable> var) { void AddGlobalVariable(Variable* var) { global_variables_.push_back(var); }
global_variables_.push_back(std::move(var));
}
/// @returns the global variables for the module /// @returns the global variables for the module
const VariableList& global_variables() const { return global_variables_; } const VariableList& global_variables() const { return global_variables_; }
@ -59,9 +57,7 @@ class Module {
/// Adds a function to the module /// Adds a function to the module
/// @param func the function /// @param func the function
void AddFunction(std::unique_ptr<Function> func) { void AddFunction(Function* func) { functions_.push_back(func); }
functions_.push_back(std::move(func));
}
/// @returns the modules functions /// @returns the modules functions
const FunctionList& functions() const { return functions_; } const FunctionList& functions() const { return functions_; }
/// Returns the function with the given name /// Returns the function with the given name

View File

@ -48,9 +48,9 @@ TEST_F(ModuleTest, LookupFunction) {
type::F32Type f32; type::F32Type f32;
Module m; Module m;
auto func = create<Function>("main", VariableList{}, &f32, auto* func = create<Function>("main", VariableList{}, &f32,
create<ast::BlockStatement>()); create<ast::BlockStatement>());
auto* func_ptr = func.get(); auto* func_ptr = func;
m.AddFunction(std::move(func)); m.AddFunction(std::move(func));
EXPECT_EQ(func_ptr, m.FindFunctionByName("main")); EXPECT_EQ(func_ptr, m.FindFunctionByName("main"));
} }
@ -67,7 +67,7 @@ TEST_F(ModuleTest, IsValid_Empty) {
TEST_F(ModuleTest, IsValid_GlobalVariable) { TEST_F(ModuleTest, IsValid_GlobalVariable) {
type::F32Type f32; type::F32Type f32;
auto var = create<Variable>("var", StorageClass::kInput, &f32); auto* var = create<Variable>("var", StorageClass::kInput, &f32);
Module m; Module m;
m.AddGlobalVariable(std::move(var)); m.AddGlobalVariable(std::move(var));
@ -81,7 +81,7 @@ TEST_F(ModuleTest, IsValid_Null_GlobalVariable) {
} }
TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) { TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
auto var = create<Variable>("var", StorageClass::kInput, nullptr); auto* var = create<Variable>("var", StorageClass::kInput, nullptr);
Module m; Module m;
m.AddGlobalVariable(std::move(var)); m.AddGlobalVariable(std::move(var));
@ -125,7 +125,7 @@ TEST_F(ModuleTest, IsValid_Struct_EmptyName) {
TEST_F(ModuleTest, IsValid_Function) { TEST_F(ModuleTest, IsValid_Function) {
type::F32Type f32; type::F32Type f32;
auto func = create<Function>("main", VariableList(), &f32, auto* func = create<Function>("main", VariableList(), &f32,
create<ast::BlockStatement>()); create<ast::BlockStatement>());
Module m; Module m;
@ -140,7 +140,7 @@ TEST_F(ModuleTest, IsValid_Null_Function) {
} }
TEST_F(ModuleTest, IsValid_Invalid_Function) { TEST_F(ModuleTest, IsValid_Invalid_Function) {
auto func = create<Function>(); auto* func = create<Function>();
Module m; Module m;
m.AddFunction(std::move(func)); m.AddFunction(std::move(func));

View File

@ -21,12 +21,11 @@ ReturnStatement::ReturnStatement() : Statement() {}
ReturnStatement::ReturnStatement(const Source& source) : Statement(source) {} ReturnStatement::ReturnStatement(const Source& source) : Statement(source) {}
ReturnStatement::ReturnStatement(std::unique_ptr<Expression> value) ReturnStatement::ReturnStatement(Expression* value)
: Statement(), value_(std::move(value)) {} : Statement(), value_(value) {}
ReturnStatement::ReturnStatement(const Source& source, ReturnStatement::ReturnStatement(const Source& source, Expression* value)
std::unique_ptr<Expression> value) : Statement(source), value_(value) {}
: Statement(source), value_(std::move(value)) {}
ReturnStatement::ReturnStatement(ReturnStatement&&) = default; ReturnStatement::ReturnStatement(ReturnStatement&&) = default;

View File

@ -34,22 +34,20 @@ class ReturnStatement : public Statement {
explicit ReturnStatement(const Source& source); explicit ReturnStatement(const Source& source);
/// Constructor /// Constructor
/// @param value the return value /// @param value the return value
explicit ReturnStatement(std::unique_ptr<Expression> value); explicit ReturnStatement(Expression* value);
/// Constructor /// Constructor
/// @param source the return statement source /// @param source the return statement source
/// @param value the return value /// @param value the return value
ReturnStatement(const Source& source, std::unique_ptr<Expression> value); ReturnStatement(const Source& source, Expression* value);
/// Move constructor /// Move constructor
ReturnStatement(ReturnStatement&&); ReturnStatement(ReturnStatement&&);
~ReturnStatement() override; ~ReturnStatement() override;
/// Sets the value /// Sets the value
/// @param value the value /// @param value the value
void set_value(std::unique_ptr<Expression> value) { void set_value(Expression* value) { value_ = value; }
value_ = std::move(value);
}
/// @returns the value /// @returns the value
Expression* value() const { return value_.get(); } Expression* value() const { return value_; }
/// @returns true if the return has a value /// @returns true if the return has a value
bool has_value() const { return value_ != nullptr; } bool has_value() const { return value_ != nullptr; }
@ -67,7 +65,7 @@ class ReturnStatement : public Statement {
private: private:
ReturnStatement(const ReturnStatement&) = delete; ReturnStatement(const ReturnStatement&) = delete;
std::unique_ptr<Expression> value_; Expression* value_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -26,8 +26,8 @@ namespace {
using ReturnStatementTest = TestHelper; using ReturnStatementTest = TestHelper;
TEST_F(ReturnStatementTest, Creation) { TEST_F(ReturnStatementTest, Creation) {
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
auto* expr_ptr = expr.get(); auto* expr_ptr = expr;
ReturnStatement r(std::move(expr)); ReturnStatement r(std::move(expr));
EXPECT_EQ(r.value(), expr_ptr); EXPECT_EQ(r.value(), expr_ptr);
@ -51,7 +51,7 @@ TEST_F(ReturnStatementTest, HasValue_WithoutValue) {
} }
TEST_F(ReturnStatementTest, HasValue_WithValue) { TEST_F(ReturnStatementTest, HasValue_WithValue) {
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
ReturnStatement r(std::move(expr)); ReturnStatement r(std::move(expr));
EXPECT_TRUE(r.has_value()); EXPECT_TRUE(r.has_value());
} }
@ -62,19 +62,19 @@ TEST_F(ReturnStatementTest, IsValid_WithoutValue) {
} }
TEST_F(ReturnStatementTest, IsValid_WithValue) { TEST_F(ReturnStatementTest, IsValid_WithValue) {
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
ReturnStatement r(std::move(expr)); ReturnStatement r(std::move(expr));
EXPECT_TRUE(r.IsValid()); EXPECT_TRUE(r.IsValid());
} }
TEST_F(ReturnStatementTest, IsValid_InvalidValue) { TEST_F(ReturnStatementTest, IsValid_InvalidValue) {
auto expr = create<IdentifierExpression>(""); auto* expr = create<IdentifierExpression>("");
ReturnStatement r(std::move(expr)); ReturnStatement r(std::move(expr));
EXPECT_FALSE(r.IsValid()); EXPECT_FALSE(r.IsValid());
} }
TEST_F(ReturnStatementTest, ToStr_WithValue) { TEST_F(ReturnStatementTest, ToStr_WithValue) {
auto expr = create<IdentifierExpression>("expr"); auto* expr = create<IdentifierExpression>("expr");
ReturnStatement r(std::move(expr)); ReturnStatement r(std::move(expr));
std::ostringstream out; std::ostringstream out;
r.to_str(out, 2); r.to_str(out, 2);

View File

@ -20,14 +20,12 @@ namespace ast {
ScalarConstructorExpression::ScalarConstructorExpression() ScalarConstructorExpression::ScalarConstructorExpression()
: ConstructorExpression() {} : ConstructorExpression() {}
ScalarConstructorExpression::ScalarConstructorExpression( ScalarConstructorExpression::ScalarConstructorExpression(Literal* literal)
std::unique_ptr<Literal> literal) : literal_(literal) {}
: ConstructorExpression(), literal_(std::move(literal)) {}
ScalarConstructorExpression::ScalarConstructorExpression( ScalarConstructorExpression::ScalarConstructorExpression(const Source& source,
const Source& source, Literal* litearl)
std::unique_ptr<Literal> litearl) : ConstructorExpression(source), literal_(litearl) {}
: ConstructorExpression(source), literal_(std::move(litearl)) {}
ScalarConstructorExpression::ScalarConstructorExpression( ScalarConstructorExpression::ScalarConstructorExpression(
ScalarConstructorExpression&&) = default; ScalarConstructorExpression&&) = default;

View File

@ -31,12 +31,11 @@ class ScalarConstructorExpression : public ConstructorExpression {
ScalarConstructorExpression(); ScalarConstructorExpression();
/// Constructor /// Constructor
/// @param literal the const literal /// @param literal the const literal
explicit ScalarConstructorExpression(std::unique_ptr<Literal> literal); explicit ScalarConstructorExpression(Literal* literal);
/// Constructor /// Constructor
/// @param source the constructor source /// @param source the constructor source
/// @param literal the const literal /// @param literal the const literal
ScalarConstructorExpression(const Source& source, ScalarConstructorExpression(const Source& source, Literal* literal);
std::unique_ptr<Literal> literal);
/// Move constructor /// Move constructor
ScalarConstructorExpression(ScalarConstructorExpression&&); ScalarConstructorExpression(ScalarConstructorExpression&&);
~ScalarConstructorExpression() override; ~ScalarConstructorExpression() override;
@ -46,11 +45,9 @@ class ScalarConstructorExpression : public ConstructorExpression {
/// Set the literal value /// Set the literal value
/// @param literal the literal /// @param literal the literal
void set_literal(std::unique_ptr<Literal> literal) { void set_literal(Literal* literal) { literal_ = literal; }
literal_ = std::move(literal);
}
/// @returns the literal value /// @returns the literal value
Literal* literal() const { return literal_.get(); } Literal* literal() const { return literal_; }
/// @returns true if the node is valid /// @returns true if the node is valid
bool IsValid() const override; bool IsValid() const override;
@ -63,7 +60,7 @@ class ScalarConstructorExpression : public ConstructorExpression {
private: private:
ScalarConstructorExpression(const ScalarConstructorExpression&) = delete; ScalarConstructorExpression(const ScalarConstructorExpression&) = delete;
std::unique_ptr<Literal> literal_; Literal* literal_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -26,15 +26,15 @@ using ScalarConstructorExpressionTest = TestHelper;
TEST_F(ScalarConstructorExpressionTest, Creation) { TEST_F(ScalarConstructorExpressionTest, Creation) {
ast::type::BoolType bool_type; ast::type::BoolType bool_type;
auto b = create<BoolLiteral>(&bool_type, true); auto* b = create<BoolLiteral>(&bool_type, true);
auto* b_ptr = b.get(); auto* b_ptr = b;
ScalarConstructorExpression c(std::move(b)); ScalarConstructorExpression c(std::move(b));
EXPECT_EQ(c.literal(), b_ptr); EXPECT_EQ(c.literal(), b_ptr);
} }
TEST_F(ScalarConstructorExpressionTest, Creation_WithSource) { TEST_F(ScalarConstructorExpressionTest, Creation_WithSource) {
ast::type::BoolType bool_type; ast::type::BoolType bool_type;
auto b = create<BoolLiteral>(&bool_type, true); auto* b = create<BoolLiteral>(&bool_type, true);
ScalarConstructorExpression c(Source{Source::Location{20, 2}}, std::move(b)); ScalarConstructorExpression c(Source{Source::Location{20, 2}}, std::move(b));
auto src = c.source(); auto src = c.source();
EXPECT_EQ(src.range.begin.line, 20u); EXPECT_EQ(src.range.begin.line, 20u);
@ -43,7 +43,7 @@ TEST_F(ScalarConstructorExpressionTest, Creation_WithSource) {
TEST_F(ScalarConstructorExpressionTest, IsValid) { TEST_F(ScalarConstructorExpressionTest, IsValid) {
ast::type::BoolType bool_type; ast::type::BoolType bool_type;
auto b = create<BoolLiteral>(&bool_type, true); auto* b = create<BoolLiteral>(&bool_type, true);
ScalarConstructorExpression c(std::move(b)); ScalarConstructorExpression c(std::move(b));
EXPECT_TRUE(c.IsValid()); EXPECT_TRUE(c.IsValid());
} }
@ -55,7 +55,7 @@ TEST_F(ScalarConstructorExpressionTest, IsValid_MissingLiteral) {
TEST_F(ScalarConstructorExpressionTest, ToStr) { TEST_F(ScalarConstructorExpressionTest, ToStr) {
ast::type::BoolType bool_type; ast::type::BoolType bool_type;
auto b = create<BoolLiteral>(&bool_type, true); auto* b = create<BoolLiteral>(&bool_type, true);
ScalarConstructorExpression c(std::move(b)); ScalarConstructorExpression c(std::move(b));
std::ostringstream out; std::ostringstream out;
c.to_str(out, 2); c.to_str(out, 2);

View File

@ -42,16 +42,16 @@ Struct::Struct(Struct&&) = default;
Struct::~Struct() = default; Struct::~Struct() = default;
StructMember* Struct::get_member(const std::string& name) const { StructMember* Struct::get_member(const std::string& name) const {
for (auto& mem : members_) { for (auto* mem : members_) {
if (mem->name() == name) { if (mem->name() == name) {
return mem.get(); return mem;
} }
} }
return nullptr; return nullptr;
} }
bool Struct::IsBlockDecorated() const { bool Struct::IsBlockDecorated() const {
for (auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsBlock()) { if (deco->IsBlock()) {
return true; return true;
} }
@ -60,7 +60,7 @@ bool Struct::IsBlockDecorated() const {
} }
bool Struct::IsValid() const { bool Struct::IsValid() const {
for (const auto& mem : members_) { for (auto* mem : members_) {
if (mem == nullptr || !mem->IsValid()) { if (mem == nullptr || !mem->IsValid()) {
return false; return false;
} }
@ -70,13 +70,13 @@ bool Struct::IsValid() const {
void Struct::to_str(std::ostream& out, size_t indent) const { void Struct::to_str(std::ostream& out, size_t indent) const {
out << "Struct{" << std::endl; out << "Struct{" << std::endl;
for (auto& deco : decorations_) { for (auto* deco : decorations_) {
make_indent(out, indent + 2); make_indent(out, indent + 2);
out << "[["; out << "[[";
deco->to_str(out, 0); deco->to_str(out, 0);
out << "]]" << std::endl; out << "]]" << std::endl;
} }
for (const auto& member : members_) { for (auto* member : members_) {
member->to_str(out, indent + 2); member->to_str(out, indent + 2);
} }
make_indent(out, indent); make_indent(out, indent);

View File

@ -42,7 +42,7 @@ class StructBlockDecoration : public StructDecoration {
}; };
/// List of struct decorations /// List of struct decorations
using StructDecorationList = std::vector<std::unique_ptr<StructDecoration>>; using StructDecorationList = std::vector<StructDecoration*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -42,7 +42,7 @@ class StructDecoration : public Decoration {
}; };
/// List of struct decorations /// List of struct decorations
using StructDecorationList = std::vector<std::unique_ptr<StructDecoration>>; using StructDecorationList = std::vector<StructDecoration*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -40,7 +40,7 @@ StructMember::StructMember(StructMember&&) = default;
StructMember::~StructMember() = default; StructMember::~StructMember() = default;
bool StructMember::has_offset_decoration() const { bool StructMember::has_offset_decoration() const {
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsOffset()) { if (deco->IsOffset()) {
return true; return true;
} }
@ -49,7 +49,7 @@ bool StructMember::has_offset_decoration() const {
} }
uint32_t StructMember::offset() const { uint32_t StructMember::offset() const {
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco->IsOffset()) { if (deco->IsOffset()) {
return deco->AsOffset()->offset(); return deco->AsOffset()->offset();
} }
@ -61,7 +61,7 @@ bool StructMember::IsValid() const {
if (name_.empty() || type_ == nullptr) { if (name_.empty() || type_ == nullptr) {
return false; return false;
} }
for (const auto& deco : decorations_) { for (auto* deco : decorations_) {
if (deco == nullptr) { if (deco == nullptr) {
return false; return false;
} }
@ -74,7 +74,7 @@ void StructMember::to_str(std::ostream& out, size_t indent) const {
out << "StructMember{"; out << "StructMember{";
if (decorations_.size() > 0) { if (decorations_.size() > 0) {
out << "[[ "; out << "[[ ";
for (const auto& deco : decorations_) for (auto* deco : decorations_)
out << deco->str() << " "; out << deco->str() << " ";
out << "]] "; out << "]] ";
} }

View File

@ -93,8 +93,8 @@ class StructMember : public Node {
StructMemberDecorationList decorations_; StructMemberDecorationList decorations_;
}; };
/// A list of unique struct members /// A list of struct members
using StructMemberList = std::vector<std::unique_ptr<StructMember>>; using StructMemberList = std::vector<StructMember*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -46,9 +46,8 @@ class StructMemberDecoration : public Decoration {
explicit StructMemberDecoration(const Source& source); explicit StructMemberDecoration(const Source& source);
}; };
/// A list of unique struct member decorations /// A list of struct member decorations
using StructMemberDecorationList = using StructMemberDecorationList = std::vector<StructMemberDecoration*>;
std::vector<std::unique_ptr<StructMemberDecoration>>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -35,7 +35,7 @@ TEST_F(StructTest, Creation) {
members.push_back( members.push_back(
create<StructMember>("a", &i32, StructMemberDecorationList())); create<StructMember>("a", &i32, StructMemberDecorationList()));
Struct s{std::move(members)}; Struct s{members};
EXPECT_EQ(s.members().size(), 1u); EXPECT_EQ(s.members().size(), 1u);
EXPECT_TRUE(s.decorations().empty()); EXPECT_TRUE(s.decorations().empty());
EXPECT_EQ(s.source().range.begin.line, 0u); EXPECT_EQ(s.source().range.begin.line, 0u);
@ -54,7 +54,7 @@ TEST_F(StructTest, Creation_WithDecorations) {
StructDecorationList decos; StructDecorationList decos;
decos.push_back(create<StructBlockDecoration>(Source{})); decos.push_back(create<StructBlockDecoration>(Source{}));
Struct s{std::move(decos), std::move(members)}; Struct s{decos, members};
EXPECT_EQ(s.members().size(), 1u); EXPECT_EQ(s.members().size(), 1u);
ASSERT_EQ(s.decorations().size(), 1u); ASSERT_EQ(s.decorations().size(), 1u);
EXPECT_TRUE(s.decorations()[0]->IsBlock()); EXPECT_TRUE(s.decorations()[0]->IsBlock());
@ -76,7 +76,7 @@ TEST_F(StructTest, CreationWithSourceAndDecorations) {
Struct s{ Struct s{
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}}, Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
std::move(decos), std::move(members)}; decos, members};
EXPECT_EQ(s.members().size(), 1u); EXPECT_EQ(s.members().size(), 1u);
ASSERT_EQ(s.decorations().size(), 1u); ASSERT_EQ(s.decorations().size(), 1u);
EXPECT_TRUE(s.decorations()[0]->IsBlock()); EXPECT_TRUE(s.decorations()[0]->IsBlock());
@ -99,7 +99,7 @@ TEST_F(StructTest, IsValid_Null_StructMember) {
create<StructMember>("a", &i32, StructMemberDecorationList())); create<StructMember>("a", &i32, StructMemberDecorationList()));
members.push_back(nullptr); members.push_back(nullptr);
Struct s{std::move(members)}; Struct s{members};
EXPECT_FALSE(s.IsValid()); EXPECT_FALSE(s.IsValid());
} }
@ -110,7 +110,7 @@ TEST_F(StructTest, IsValid_Invalid_StructMember) {
members.push_back( members.push_back(
create<StructMember>("", &i32, StructMemberDecorationList())); create<StructMember>("", &i32, StructMemberDecorationList()));
Struct s{std::move(members)}; Struct s{members};
EXPECT_FALSE(s.IsValid()); EXPECT_FALSE(s.IsValid());
} }
@ -124,7 +124,7 @@ TEST_F(StructTest, ToStr) {
StructDecorationList decos; StructDecorationList decos;
decos.push_back(create<StructBlockDecoration>(Source{})); decos.push_back(create<StructBlockDecoration>(Source{}));
Struct s{std::move(decos), std::move(members)}; Struct s{decos, members};
std::ostringstream out; std::ostringstream out;
s.to_str(out, 2); s.to_str(out, 2);

View File

@ -21,16 +21,13 @@ namespace ast {
SwitchStatement::SwitchStatement() : Statement() {} SwitchStatement::SwitchStatement() : Statement() {}
SwitchStatement::SwitchStatement(std::unique_ptr<Expression> condition, SwitchStatement::SwitchStatement(Expression* condition, CaseStatementList body)
CaseStatementList body) : condition_(condition), body_(body) {}
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
SwitchStatement::SwitchStatement(const Source& source, SwitchStatement::SwitchStatement(const Source& source,
std::unique_ptr<Expression> condition, Expression* condition,
CaseStatementList body) CaseStatementList body)
: Statement(source), : Statement(source), condition_(condition), body_(body) {}
condition_(std::move(condition)),
body_(std::move(body)) {}
bool SwitchStatement::IsSwitch() const { bool SwitchStatement::IsSwitch() const {
return true; return true;
@ -44,7 +41,7 @@ bool SwitchStatement::IsValid() const {
if (condition_ == nullptr || !condition_->IsValid()) { if (condition_ == nullptr || !condition_->IsValid()) {
return false; return false;
} }
for (const auto& stmt : body_) { for (auto* stmt : body_) {
if (stmt == nullptr || !stmt->IsValid()) { if (stmt == nullptr || !stmt->IsValid()) {
return false; return false;
} }
@ -60,7 +57,7 @@ void SwitchStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent + 2); make_indent(out, indent + 2);
out << "{" << std::endl; out << "{" << std::endl;
for (const auto& stmt : body_) { for (auto* stmt : body_) {
stmt->to_str(out, indent + 4); stmt->to_str(out, indent + 4);
} }

View File

@ -34,14 +34,13 @@ class SwitchStatement : public Statement {
/// Constructor /// Constructor
/// @param condition the switch condition /// @param condition the switch condition
/// @param body the switch body /// @param body the switch body
SwitchStatement(std::unique_ptr<Expression> condition, SwitchStatement(Expression* condition, CaseStatementList body);
CaseStatementList body);
/// Constructor /// Constructor
/// @param source the source information /// @param source the source information
/// @param condition the switch condition /// @param condition the switch condition
/// @param body the switch body /// @param body the switch body
SwitchStatement(const Source& source, SwitchStatement(const Source& source,
std::unique_ptr<Expression> condition, Expression* condition,
CaseStatementList body); CaseStatementList body);
/// Move constructor /// Move constructor
SwitchStatement(SwitchStatement&&); SwitchStatement(SwitchStatement&&);
@ -49,11 +48,9 @@ class SwitchStatement : public Statement {
/// Sets the condition for the switch statement /// Sets the condition for the switch statement
/// @param condition the condition to set /// @param condition the condition to set
void set_condition(std::unique_ptr<Expression> condition) { void set_condition(Expression* condition) { condition_ = condition; }
condition_ = std::move(condition);
}
/// @returns the switch condition or nullptr if none set /// @returns the switch condition or nullptr if none set
Expression* condition() const { return condition_.get(); } Expression* condition() const { return condition_; }
/// @returns true if this is a default statement /// @returns true if this is a default statement
bool IsDefault() const { return condition_ == nullptr; } bool IsDefault() const { return condition_ == nullptr; }
@ -77,7 +74,7 @@ class SwitchStatement : public Statement {
private: private:
SwitchStatement(const SwitchStatement&) = delete; SwitchStatement(const SwitchStatement&) = delete;
std::unique_ptr<Expression> condition_; Expression* condition_ = nullptr;
CaseStatementList body_; CaseStatementList body_;
}; };

View File

@ -34,22 +34,22 @@ TEST_F(SwitchStatementTest, Creation) {
CaseSelectorList lit; CaseSelectorList lit;
lit.push_back(create<SintLiteral>(&i32, 1)); lit.push_back(create<SintLiteral>(&i32, 1));
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
CaseStatementList body; CaseStatementList body;
body.push_back( body.push_back(
create<CaseStatement>(std::move(lit), create<ast::BlockStatement>())); create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
auto* ident_ptr = ident.get(); auto* ident_ptr = ident;
auto* case_ptr = body[0].get(); auto* case_ptr = body[0];
SwitchStatement stmt(std::move(ident), std::move(body)); SwitchStatement stmt(std::move(ident), std::move(body));
EXPECT_EQ(stmt.condition(), ident_ptr); EXPECT_EQ(stmt.condition(), ident_ptr);
ASSERT_EQ(stmt.body().size(), 1u); ASSERT_EQ(stmt.body().size(), 1u);
EXPECT_EQ(stmt.body()[0].get(), case_ptr); EXPECT_EQ(stmt.body()[0], case_ptr);
} }
TEST_F(SwitchStatementTest, Creation_WithSource) { TEST_F(SwitchStatementTest, Creation_WithSource) {
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
SwitchStatement stmt(Source{Source::Location{20, 2}}, std::move(ident), SwitchStatement stmt(Source{Source::Location{20, 2}}, std::move(ident),
CaseStatementList()); CaseStatementList());
@ -69,7 +69,7 @@ TEST_F(SwitchStatementTest, IsValid) {
CaseSelectorList lit; CaseSelectorList lit;
lit.push_back(create<SintLiteral>(&i32, 2)); lit.push_back(create<SintLiteral>(&i32, 2));
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
CaseStatementList body; CaseStatementList body;
body.push_back( body.push_back(
create<CaseStatement>(std::move(lit), create<ast::BlockStatement>())); create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
@ -99,7 +99,7 @@ TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) {
CaseSelectorList lit; CaseSelectorList lit;
lit.push_back(create<SintLiteral>(&i32, 2)); lit.push_back(create<SintLiteral>(&i32, 2));
auto ident = create<IdentifierExpression>(""); auto* ident = create<IdentifierExpression>("");
CaseStatementList body; CaseStatementList body;
body.push_back( body.push_back(
create<CaseStatement>(std::move(lit), create<ast::BlockStatement>())); create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
@ -114,7 +114,7 @@ TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) {
CaseSelectorList lit; CaseSelectorList lit;
lit.push_back(create<SintLiteral>(&i32, 2)); lit.push_back(create<SintLiteral>(&i32, 2));
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
CaseStatementList body; CaseStatementList body;
body.push_back( body.push_back(
create<CaseStatement>(std::move(lit), create<ast::BlockStatement>())); create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
@ -125,9 +125,9 @@ TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) {
} }
TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) { TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) {
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
auto case_body = create<ast::BlockStatement>(); auto* case_body = create<ast::BlockStatement>();
case_body->append(nullptr); case_body->append(nullptr);
CaseStatementList body; CaseStatementList body;
@ -139,7 +139,7 @@ TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) {
} }
TEST_F(SwitchStatementTest, ToStr_Empty) { TEST_F(SwitchStatementTest, ToStr_Empty) {
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
SwitchStatement stmt(std::move(ident), {}); SwitchStatement stmt(std::move(ident), {});
std::ostringstream out; std::ostringstream out;
@ -158,7 +158,7 @@ TEST_F(SwitchStatementTest, ToStr) {
CaseSelectorList lit; CaseSelectorList lit;
lit.push_back(create<SintLiteral>(&i32, 2)); lit.push_back(create<SintLiteral>(&i32, 2));
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
CaseStatementList body; CaseStatementList body;
body.push_back( body.push_back(
create<CaseStatement>(std::move(lit), create<ast::BlockStatement>())); create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));

View File

@ -19,6 +19,7 @@
#include <utility> #include <utility>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/context.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -30,12 +31,17 @@ class TestHelperBase : public BASE {
TestHelperBase() {} TestHelperBase() {}
~TestHelperBase() = default; ~TestHelperBase() = default;
/// @return a `std::unique_ptr` to a new `T` constructed with `args` /// Creates a new `ast::Node` owned by the Context. When the Context is
/// @param args the arguments to forward to the constructor for `T` /// 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> template <typename T, typename... ARGS>
std::unique_ptr<T> create(ARGS&&... args) { T* create(ARGS&&... args) {
return std::make_unique<T>(std::forward<ARGS>(args)...); return ctx.create<T>(std::forward<ARGS>(args)...);
} }
/// The context
Context ctx;
}; };
using TestHelper = TestHelperBase<testing::Test>; using TestHelper = TestHelperBase<testing::Test>;

View File

@ -132,7 +132,7 @@ TEST_F(AccessControlTypeTest, MinBufferBindingSizeStruct) {
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
AccessControlType at{AccessControl::kReadOnly, &struct_type}; AccessControlType at{AccessControl::kReadOnly, &struct_type};
EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@ -181,7 +181,7 @@ TEST_F(AccessControlTypeTest, BaseAlignmentStruct) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
AccessControlType at{AccessControl::kReadOnly, &struct_type}; AccessControlType at{AccessControl::kReadOnly, &struct_type};
EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));

View File

@ -197,7 +197,7 @@ TEST_F(AliasTypeTest, MinBufferBindingSizeStruct) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
AliasType alias{"alias", &struct_type}; AliasType alias{"alias", &struct_type};
EXPECT_EQ(16u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@ -246,7 +246,7 @@ TEST_F(AliasTypeTest, BaseAlignmentStruct) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
AliasType alias{"alias", &struct_type}; AliasType alias{"alias", &struct_type};
EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer));

View File

@ -68,7 +68,7 @@ uint64_t ArrayType::BaseAlignment(MemoryLayout mem_layout) const {
} }
uint32_t ArrayType::array_stride() const { uint32_t ArrayType::array_stride() const {
for (const auto& deco : decos_) { for (auto* deco : decos_) {
if (deco->IsStride()) { if (deco->IsStride()) {
return deco->AsStride()->stride(); return deco->AsStride()->stride();
} }
@ -77,7 +77,7 @@ uint32_t ArrayType::array_stride() const {
} }
bool ArrayType::has_array_stride() const { bool ArrayType::has_array_stride() const {
for (const auto& deco : decos_) { for (auto* deco : decos_) {
if (deco->IsStride()) { if (deco->IsStride()) {
return true; return true;
} }

View File

@ -26,8 +26,8 @@ namespace tint {
namespace ast { namespace ast {
namespace type { namespace type {
StructType::StructType(const std::string& name, std::unique_ptr<Struct> impl) StructType::StructType(const std::string& name, Struct* impl)
: name_(name), struct_(std::move(impl)) {} : name_(name), struct_(impl) {}
StructType::StructType(StructType&&) = default; StructType::StructType(StructType&&) = default;
@ -46,7 +46,7 @@ uint64_t StructType::MinBufferBindingSize(MemoryLayout mem_layout) const {
return 0; return 0;
} }
const auto& last_member = struct_->members().back(); auto* last_member = struct_->members().back();
// If there is no offset, then this is not a host-shareable struct, returning // If there is no offset, then this is not a host-shareable struct, returning
// 0 indicates this to the caller. // 0 indicates this to the caller.
@ -67,7 +67,7 @@ uint64_t StructType::MinBufferBindingSize(MemoryLayout mem_layout) const {
uint64_t StructType::BaseAlignment(MemoryLayout mem_layout) const { uint64_t StructType::BaseAlignment(MemoryLayout mem_layout) const {
uint64_t max = 0; uint64_t max = 0;
for (const auto& member : struct_->members()) { for (auto* member : struct_->members()) {
if (member->type()->BaseAlignment(mem_layout) > max) { if (member->type()->BaseAlignment(mem_layout) > max) {
max = member->type()->BaseAlignment(mem_layout); max = member->type()->BaseAlignment(mem_layout);
} }

View File

@ -31,7 +31,7 @@ class StructType : public Type {
/// Constructor /// Constructor
/// @param name the name of the struct /// @param name the name of the struct
/// @param impl the struct data /// @param impl the struct data
StructType(const std::string& name, std::unique_ptr<Struct> impl); StructType(const std::string& name, Struct* impl);
/// Move constructor /// Move constructor
StructType(StructType&&); StructType(StructType&&);
~StructType() override; ~StructType() override;
@ -46,7 +46,7 @@ class StructType : public Type {
bool IsStruct() const override; bool IsStruct() const override;
/// @returns the struct name /// @returns the struct name
Struct* impl() const { return struct_.get(); } Struct* impl() const { return struct_; }
/// @returns the name for the type /// @returns the name for the type
std::string type_name() const override; std::string type_name() const override;
@ -63,7 +63,7 @@ class StructType : public Type {
private: private:
std::string name_; std::string name_;
std::unique_ptr<Struct> struct_; Struct* struct_ = nullptr;
uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const; uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const;
}; };

View File

@ -34,14 +34,14 @@ namespace {
using StructTypeTest = TestHelper; using StructTypeTest = TestHelper;
TEST_F(StructTypeTest, Creation) { TEST_F(StructTypeTest, Creation) {
auto impl = create<Struct>(); auto* impl = create<Struct>();
auto* ptr = impl.get(); auto* ptr = impl;
StructType s{"S", std::move(impl)}; StructType s{"S", std::move(impl)};
EXPECT_EQ(s.impl(), ptr); EXPECT_EQ(s.impl(), ptr);
} }
TEST_F(StructTypeTest, Is) { TEST_F(StructTypeTest, Is) {
auto impl = create<Struct>(); auto* impl = create<Struct>();
StructType s{"S", std::move(impl)}; StructType s{"S", std::move(impl)};
EXPECT_FALSE(s.IsAccessControl()); EXPECT_FALSE(s.IsAccessControl());
EXPECT_FALSE(s.IsAlias()); EXPECT_FALSE(s.IsAlias());
@ -59,7 +59,7 @@ TEST_F(StructTypeTest, Is) {
} }
TEST_F(StructTypeTest, TypeName) { TEST_F(StructTypeTest, TypeName) {
auto impl = create<Struct>(); auto* impl = create<Struct>();
StructType s{"my_struct", std::move(impl)}; StructType s{"my_struct", std::move(impl)};
EXPECT_EQ(s.type_name(), "__struct_my_struct"); EXPECT_EQ(s.type_name(), "__struct_my_struct");
} }
@ -80,7 +80,7 @@ TEST_F(StructTypeTest, MinBufferBindingSize) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@ -114,7 +114,7 @@ TEST_F(StructTypeTest, MinBufferBindingSizeArray) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(32u, EXPECT_EQ(32u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@ -149,7 +149,7 @@ TEST_F(StructTypeTest, MinBufferBindingSizeRuntimeArray) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(12u, EXPECT_EQ(12u,
struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer)); struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
@ -167,7 +167,7 @@ TEST_F(StructTypeTest, MinBufferBindingSizeVec2) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@ -186,7 +186,7 @@ TEST_F(StructTypeTest, MinBufferBindingSizeVec3) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@ -206,7 +206,7 @@ TEST_F(StructTypeTest, MinBufferBindingSizeVec4) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@ -230,7 +230,7 @@ TEST_F(StructTypeTest, BaseAlignment) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer)); EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@ -263,7 +263,7 @@ TEST_F(StructTypeTest, BaseAlignmentArray) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer)); EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@ -296,7 +296,7 @@ TEST_F(StructTypeTest, BaseAlignmentRuntimeArray) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer)); EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
@ -313,7 +313,7 @@ TEST_F(StructTypeTest, BaseAlignmentVec2) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(8u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer)); EXPECT_EQ(8u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@ -331,7 +331,7 @@ TEST_F(StructTypeTest, BaseAlignmentVec3) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer)); EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
@ -349,7 +349,7 @@ TEST_F(StructTypeTest, BaseAlignmentVec4) {
} }
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
StructType struct_type("struct_type", std::move(str)); StructType struct_type("struct_type", std::move(str));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer)); EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));

View File

@ -45,7 +45,7 @@ bool TypeConstructorExpression::IsValid() const {
if (type_ == nullptr) { if (type_ == nullptr) {
return false; return false;
} }
for (const auto& val : values_) { for (auto* val : values_) {
if (val == nullptr || !val->IsValid()) { if (val == nullptr || !val->IsValid()) {
return false; return false;
} }
@ -59,7 +59,7 @@ void TypeConstructorExpression::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent + 2); make_indent(out, indent + 2);
out << type_->type_name() << std::endl; out << type_->type_name() << std::endl;
for (const auto& val : values_) { for (auto* val : values_) {
val->to_str(out, indent + 2); val->to_str(out, indent + 2);
} }
make_indent(out, indent); make_indent(out, indent);

View File

@ -33,12 +33,12 @@ TEST_F(TypeConstructorExpressionTest, Creation) {
type::F32Type f32; type::F32Type f32;
ExpressionList expr; ExpressionList expr;
expr.push_back(create<IdentifierExpression>("expr")); expr.push_back(create<IdentifierExpression>("expr"));
auto* expr_ptr = expr[0].get(); auto* expr_ptr = expr[0];
TypeConstructorExpression t(&f32, std::move(expr)); TypeConstructorExpression t(&f32, std::move(expr));
EXPECT_EQ(t.type(), &f32); EXPECT_EQ(t.type(), &f32);
ASSERT_EQ(t.values().size(), 1u); ASSERT_EQ(t.values().size(), 1u);
EXPECT_EQ(t.values()[0].get(), expr_ptr); EXPECT_EQ(t.values()[0], expr_ptr);
} }
TEST_F(TypeConstructorExpressionTest, Creation_WithSource) { TEST_F(TypeConstructorExpressionTest, Creation_WithSource) {

View File

@ -19,14 +19,13 @@ namespace ast {
UnaryOpExpression::UnaryOpExpression() : Expression() {} UnaryOpExpression::UnaryOpExpression() : Expression() {}
UnaryOpExpression::UnaryOpExpression(UnaryOp op, UnaryOpExpression::UnaryOpExpression(UnaryOp op, Expression* expr)
std::unique_ptr<Expression> expr) : Expression(), op_(op), expr_(expr) {}
: Expression(), op_(op), expr_(std::move(expr)) {}
UnaryOpExpression::UnaryOpExpression(const Source& source, UnaryOpExpression::UnaryOpExpression(const Source& source,
UnaryOp op, UnaryOp op,
std::unique_ptr<Expression> expr) Expression* expr)
: Expression(source), op_(op), expr_(std::move(expr)) {} : Expression(source), op_(op), expr_(expr) {}
UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default; UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default;

View File

@ -33,14 +33,12 @@ class UnaryOpExpression : public Expression {
/// Constructor /// Constructor
/// @param op the op /// @param op the op
/// @param expr the expr /// @param expr the expr
UnaryOpExpression(UnaryOp op, std::unique_ptr<Expression> expr); UnaryOpExpression(UnaryOp op, Expression* expr);
/// Constructor /// Constructor
/// @param source the unary op expression source /// @param source the unary op expression source
/// @param op the op /// @param op the op
/// @param expr the expr /// @param expr the expr
UnaryOpExpression(const Source& source, UnaryOpExpression(const Source& source, UnaryOp op, Expression* expr);
UnaryOp op,
std::unique_ptr<Expression> expr);
/// Move constructor /// Move constructor
UnaryOpExpression(UnaryOpExpression&&); UnaryOpExpression(UnaryOpExpression&&);
~UnaryOpExpression() override; ~UnaryOpExpression() override;
@ -53,9 +51,9 @@ class UnaryOpExpression : public Expression {
/// Sets the expr /// Sets the expr
/// @param expr the expression /// @param expr the expression
void set_expr(std::unique_ptr<Expression> expr) { expr_ = std::move(expr); } void set_expr(Expression* expr) { expr_ = expr; }
/// @returns the expression /// @returns the expression
Expression* expr() const { return expr_.get(); } Expression* expr() const { return expr_; }
/// @returns true if this is an as expression /// @returns true if this is an as expression
bool IsUnaryOp() const override; bool IsUnaryOp() const override;
@ -72,7 +70,7 @@ class UnaryOpExpression : public Expression {
UnaryOpExpression(const UnaryOpExpression&) = delete; UnaryOpExpression(const UnaryOpExpression&) = delete;
UnaryOp op_ = UnaryOp::kNegation; UnaryOp op_ = UnaryOp::kNegation;
std::unique_ptr<Expression> expr_; Expression* expr_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -26,8 +26,8 @@ namespace {
using UnaryOpExpressionTest = TestHelper; using UnaryOpExpressionTest = TestHelper;
TEST_F(UnaryOpExpressionTest, Creation) { TEST_F(UnaryOpExpressionTest, Creation) {
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
auto* ident_ptr = ident.get(); auto* ident_ptr = ident;
UnaryOpExpression u(UnaryOp::kNot, std::move(ident)); UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
EXPECT_EQ(u.op(), UnaryOp::kNot); EXPECT_EQ(u.op(), UnaryOp::kNot);
@ -35,7 +35,7 @@ TEST_F(UnaryOpExpressionTest, Creation) {
} }
TEST_F(UnaryOpExpressionTest, Creation_WithSource) { TEST_F(UnaryOpExpressionTest, Creation_WithSource) {
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
UnaryOpExpression u(Source{Source::Location{20, 2}}, UnaryOp::kNot, UnaryOpExpression u(Source{Source::Location{20, 2}}, UnaryOp::kNot,
std::move(ident)); std::move(ident));
auto src = u.source(); auto src = u.source();
@ -49,7 +49,7 @@ TEST_F(UnaryOpExpressionTest, IsUnaryOp) {
} }
TEST_F(UnaryOpExpressionTest, IsValid) { TEST_F(UnaryOpExpressionTest, IsValid) {
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
UnaryOpExpression u(UnaryOp::kNot, std::move(ident)); UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
EXPECT_TRUE(u.IsValid()); EXPECT_TRUE(u.IsValid());
} }
@ -61,13 +61,13 @@ TEST_F(UnaryOpExpressionTest, IsValid_NullExpression) {
} }
TEST_F(UnaryOpExpressionTest, IsValid_InvalidExpression) { TEST_F(UnaryOpExpressionTest, IsValid_InvalidExpression) {
auto ident = create<IdentifierExpression>(""); auto* ident = create<IdentifierExpression>("");
UnaryOpExpression u(UnaryOp::kNot, std::move(ident)); UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
EXPECT_FALSE(u.IsValid()); EXPECT_FALSE(u.IsValid());
} }
TEST_F(UnaryOpExpressionTest, ToStr) { TEST_F(UnaryOpExpressionTest, ToStr) {
auto ident = create<IdentifierExpression>("ident"); auto* ident = create<IdentifierExpression>("ident");
UnaryOpExpression u(UnaryOp::kNot, std::move(ident)); UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
std::ostringstream out; std::ostringstream out;
u.to_str(out, 2); u.to_str(out, 2);

View File

@ -122,11 +122,9 @@ class Variable : public Node {
/// Sets the constructor /// Sets the constructor
/// @param expr the constructor expression /// @param expr the constructor expression
void set_constructor(std::unique_ptr<Expression> expr) { void set_constructor(Expression* expr) { constructor_ = expr; }
constructor_ = std::move(expr);
}
/// @returns the constructor expression or nullptr if none set /// @returns the constructor expression or nullptr if none set
Expression* constructor() const { return constructor_.get(); } Expression* constructor() const { return constructor_; }
/// @returns true if the variable has an constructor /// @returns true if the variable has an constructor
bool has_constructor() const { return constructor_ != nullptr; } bool has_constructor() const { return constructor_ != nullptr; }
@ -170,11 +168,11 @@ class Variable : public Node {
StorageClass storage_class_ = StorageClass::kNone; StorageClass storage_class_ = StorageClass::kNone;
// The value type if a const or formal paramter, and the store type if a var // The value type if a const or formal paramter, and the store type if a var
type::Type* type_ = nullptr; type::Type* type_ = nullptr;
std::unique_ptr<Expression> constructor_; Expression* constructor_ = nullptr;
}; };
/// A list of unique variables /// A list of variables
using VariableList = std::vector<std::unique_ptr<Variable>>; using VariableList = std::vector<Variable*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -19,12 +19,12 @@ namespace ast {
VariableDeclStatement::VariableDeclStatement() : Statement() {} VariableDeclStatement::VariableDeclStatement() : Statement() {}
VariableDeclStatement::VariableDeclStatement(std::unique_ptr<Variable> variable) VariableDeclStatement::VariableDeclStatement(Variable* variable)
: Statement(), variable_(std::move(variable)) {} : Statement(), variable_(variable) {}
VariableDeclStatement::VariableDeclStatement(const Source& source, VariableDeclStatement::VariableDeclStatement(const Source& source,
std::unique_ptr<Variable> variable) Variable* variable)
: Statement(source), variable_(std::move(variable)) {} : Statement(source), variable_(variable) {}
VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default; VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default;

View File

@ -32,23 +32,20 @@ class VariableDeclStatement : public Statement {
VariableDeclStatement(); VariableDeclStatement();
/// Constructor /// Constructor
/// @param variable the variable /// @param variable the variable
explicit VariableDeclStatement(std::unique_ptr<Variable> variable); explicit VariableDeclStatement(Variable* variable);
/// Constructor /// Constructor
/// @param source the variable statement source /// @param source the variable statement source
/// @param variable the variable /// @param variable the variable
VariableDeclStatement(const Source& source, VariableDeclStatement(const Source& source, Variable* variable);
std::unique_ptr<Variable> variable);
/// Move constructor /// Move constructor
VariableDeclStatement(VariableDeclStatement&&); VariableDeclStatement(VariableDeclStatement&&);
~VariableDeclStatement() override; ~VariableDeclStatement() override;
/// Sets the variable /// Sets the variable
/// @param variable the variable to set /// @param variable the variable to set
void set_variable(std::unique_ptr<Variable> variable) { void set_variable(Variable* variable) { variable_ = variable; }
variable_ = std::move(variable);
}
/// @returns the variable /// @returns the variable
Variable* variable() const { return variable_.get(); } Variable* variable() const { return variable_; }
/// @returns true if this is an variable statement /// @returns true if this is an variable statement
bool IsVariableDecl() const override; bool IsVariableDecl() const override;
@ -64,7 +61,7 @@ class VariableDeclStatement : public Statement {
private: private:
VariableDeclStatement(const VariableDeclStatement&) = delete; VariableDeclStatement(const VariableDeclStatement&) = delete;
std::unique_ptr<Variable> variable_; Variable* variable_ = nullptr;
}; };
} // namespace ast } // namespace ast

View File

@ -26,8 +26,8 @@ using VariableDeclStatementTest = TestHelper;
TEST_F(VariableDeclStatementTest, Creation) { TEST_F(VariableDeclStatementTest, Creation) {
type::F32Type f32; type::F32Type f32;
auto var = create<Variable>("a", StorageClass::kNone, &f32); auto* var = create<Variable>("a", StorageClass::kNone, &f32);
auto* var_ptr = var.get(); auto* var_ptr = var;
VariableDeclStatement stmt(std::move(var)); VariableDeclStatement stmt(std::move(var));
EXPECT_EQ(stmt.variable(), var_ptr); EXPECT_EQ(stmt.variable(), var_ptr);
@ -35,7 +35,7 @@ TEST_F(VariableDeclStatementTest, Creation) {
TEST_F(VariableDeclStatementTest, Creation_WithSource) { TEST_F(VariableDeclStatementTest, Creation_WithSource) {
type::F32Type f32; type::F32Type f32;
auto var = create<Variable>("a", StorageClass::kNone, &f32); auto* var = create<Variable>("a", StorageClass::kNone, &f32);
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var)); VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var));
auto src = stmt.source(); auto src = stmt.source();
@ -50,14 +50,14 @@ TEST_F(VariableDeclStatementTest, IsVariableDecl) {
TEST_F(VariableDeclStatementTest, IsValid) { TEST_F(VariableDeclStatementTest, IsValid) {
type::F32Type f32; type::F32Type f32;
auto var = create<Variable>("a", StorageClass::kNone, &f32); auto* var = create<Variable>("a", StorageClass::kNone, &f32);
VariableDeclStatement stmt(std::move(var)); VariableDeclStatement stmt(std::move(var));
EXPECT_TRUE(stmt.IsValid()); EXPECT_TRUE(stmt.IsValid());
} }
TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) { TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
type::F32Type f32; type::F32Type f32;
auto var = create<Variable>("", StorageClass::kNone, &f32); auto* var = create<Variable>("", StorageClass::kNone, &f32);
VariableDeclStatement stmt(std::move(var)); VariableDeclStatement stmt(std::move(var));
EXPECT_FALSE(stmt.IsValid()); EXPECT_FALSE(stmt.IsValid());
} }
@ -69,7 +69,7 @@ TEST_F(VariableDeclStatementTest, IsValid_NullVariable) {
TEST_F(VariableDeclStatementTest, ToStr) { TEST_F(VariableDeclStatementTest, ToStr) {
type::F32Type f32; type::F32Type f32;
auto var = create<Variable>("a", StorageClass::kNone, &f32); auto* var = create<Variable>("a", StorageClass::kNone, &f32);
VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var)); VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var));
std::ostringstream out; std::ostringstream out;

View File

@ -67,8 +67,8 @@ class VariableDecoration : public Decoration {
explicit VariableDecoration(const Source& source); explicit VariableDecoration(const Source& source);
}; };
/// A list of unique variable decorations /// A list of variable decorations
using VariableDecorationList = std::vector<std::unique_ptr<VariableDecoration>>; using VariableDecorationList = std::vector<VariableDecoration*>;
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -16,6 +16,7 @@
#include <utility> #include <utility>
#include "src/ast/node.h"
#include "src/namer.h" #include "src/namer.h"
#include "src/type_manager.h" #include "src/type_manager.h"

View File

@ -15,13 +15,22 @@
#ifndef SRC_CONTEXT_H_ #ifndef SRC_CONTEXT_H_
#define SRC_CONTEXT_H_ #define SRC_CONTEXT_H_
#include <assert.h>
#include <memory> #include <memory>
#include <type_traits>
#include <utility>
#include <vector>
#include "src/namer.h" #include "src/namer.h"
#include "src/type_manager.h" #include "src/type_manager.h"
namespace tint { namespace tint {
namespace ast {
class Node;
}
/// Context object for Tint. Holds various global resources used through /// Context object for Tint. Holds various global resources used through
/// the system. /// the system.
class Context { class Context {
@ -42,9 +51,24 @@ class Context {
/// @returns the namer object /// @returns the namer object
Namer* namer() const { return namer_.get(); } Namer* namer() const { return namer_.get(); }
/// 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) {
static_assert(std::is_base_of<ast::Node, T>::value,
"T does not derive from ast::Node");
auto uptr = std::make_unique<T>(std::forward<ARGS>(args)...);
auto ptr = uptr.get();
ast_nodes_.emplace_back(std::move(uptr));
return ptr;
}
private: private:
TypeManager type_mgr_; TypeManager type_mgr_;
std::unique_ptr<Namer> namer_; std::unique_ptr<Namer> namer_;
std::vector<std::unique_ptr<ast::Node>> ast_nodes_;
}; };
} // namespace tint } // namespace tint

View File

@ -56,7 +56,7 @@ Inspector::~Inspector() {
std::vector<EntryPoint> Inspector::GetEntryPoints() { std::vector<EntryPoint> Inspector::GetEntryPoints() {
std::vector<EntryPoint> result; std::vector<EntryPoint> result;
for (const auto& func : module_.functions()) { for (auto* func : module_.functions()) {
if (!func->IsEntryPoint()) { if (!func->IsEntryPoint()) {
continue; continue;
} }
@ -96,7 +96,7 @@ std::string Inspector::GetRemappedNameForEntryPoint(
std::map<uint32_t, Scalar> Inspector::GetConstantIDs() { std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
std::map<uint32_t, Scalar> result; std::map<uint32_t, Scalar> result;
for (auto& var : module_.global_variables()) { for (auto* var : module_.global_variables()) {
if (!var->IsDecorated()) { if (!var->IsDecorated()) {
continue; continue;
} }

View File

@ -78,8 +78,8 @@ class InspectorHelper {
/// Generates an empty function /// Generates an empty function
/// @param name name of the function created /// @param name name of the function created
/// @returns a function object /// @returns a function object
std::unique_ptr<ast::Function> MakeEmptyBodyFunction(std::string name) { ast::Function* MakeEmptyBodyFunction(std::string name) {
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append(create<ast::ReturnStatement>()); body->append(create<ast::ReturnStatement>());
return create<ast::Function>(name, ast::VariableList(), void_type(), return create<ast::Function>(name, ast::VariableList(), void_type(),
std::move(body)); std::move(body));
@ -89,11 +89,11 @@ class InspectorHelper {
/// @param caller name of the function created /// @param caller name of the function created
/// @param callee name of the function to be called /// @param callee name of the function to be called
/// @returns a function object /// @returns a function object
std::unique_ptr<ast::Function> MakeCallerBodyFunction(std::string caller, ast::Function* MakeCallerBodyFunction(std::string caller,
std::string callee) { std::string callee) {
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
auto ident_expr = create<ast::IdentifierExpression>(callee); auto* ident_expr = create<ast::IdentifierExpression>(callee);
auto call_expr = create<ast::CallExpression>(std::move(ident_expr), auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
ast::ExpressionList()); ast::ExpressionList());
body->append(create<ast::CallStatement>(std::move(call_expr))); body->append(create<ast::CallStatement>(std::move(call_expr)));
body->append(create<ast::ReturnStatement>()); body->append(create<ast::ReturnStatement>());
@ -109,9 +109,9 @@ class InspectorHelper {
for (auto inout : inout_vars) { for (auto inout : inout_vars) {
std::string in, out; std::string in, out;
std::tie(in, out) = inout; std::tie(in, out) = inout;
auto in_var = auto* in_var =
create<ast::Variable>(in, ast::StorageClass::kInput, u32_type()); create<ast::Variable>(in, ast::StorageClass::kInput, u32_type());
auto out_var = auto* out_var =
create<ast::Variable>(out, ast::StorageClass::kOutput, u32_type()); create<ast::Variable>(out, ast::StorageClass::kOutput, u32_type());
mod()->AddGlobalVariable(std::move(in_var)); mod()->AddGlobalVariable(std::move(in_var));
mod()->AddGlobalVariable(std::move(out_var)); mod()->AddGlobalVariable(std::move(out_var));
@ -123,10 +123,10 @@ class InspectorHelper {
/// @param inout_vars tuples of {in, out} that will be converted into out = in /// @param inout_vars tuples of {in, out} that will be converted into out = in
/// calls in the function body /// calls in the function body
/// @returns a function object /// @returns a function object
std::unique_ptr<ast::Function> MakeInOutVariableBodyFunction( ast::Function* MakeInOutVariableBodyFunction(
std::string name, std::string name,
std::vector<std::tuple<std::string, std::string>> inout_vars) { std::vector<std::tuple<std::string, std::string>> inout_vars) {
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
for (auto inout : inout_vars) { for (auto inout : inout_vars) {
std::string in, out; std::string in, out;
std::tie(in, out) = inout; std::tie(in, out) = inout;
@ -146,11 +146,11 @@ class InspectorHelper {
/// @param inout_vars tuples of {in, out} that will be converted into out = in /// @param inout_vars tuples of {in, out} that will be converted into out = in
/// calls in the function body /// calls in the function body
/// @returns a function object /// @returns a function object
std::unique_ptr<ast::Function> MakeInOutVariableCallerBodyFunction( ast::Function* MakeInOutVariableCallerBodyFunction(
std::string caller, std::string caller,
std::string callee, std::string callee,
std::vector<std::tuple<std::string, std::string>> inout_vars) { std::vector<std::tuple<std::string, std::string>> inout_vars) {
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
for (auto inout : inout_vars) { for (auto inout : inout_vars) {
std::string in, out; std::string in, out;
std::tie(in, out) = inout; std::tie(in, out) = inout;
@ -158,8 +158,8 @@ class InspectorHelper {
create<ast::IdentifierExpression>(out), create<ast::IdentifierExpression>(out),
create<ast::IdentifierExpression>(in))); create<ast::IdentifierExpression>(in)));
} }
auto ident_expr = create<ast::IdentifierExpression>(callee); auto* ident_expr = create<ast::IdentifierExpression>(callee);
auto call_expr = create<ast::CallExpression>(std::move(ident_expr), auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
ast::ExpressionList()); ast::ExpressionList());
body->append(create<ast::CallStatement>(std::move(call_expr))); body->append(create<ast::CallStatement>(std::move(call_expr)));
body->append(create<ast::ReturnStatement>()); body->append(create<ast::ReturnStatement>());
@ -178,7 +178,7 @@ class InspectorHelper {
uint32_t id, uint32_t id,
ast::type::Type* type, ast::type::Type* type,
T* val) { T* val) {
auto dvar = create<ast::DecoratedVariable>( auto* dvar = create<ast::DecoratedVariable>(
create<ast::Variable>(name, ast::StorageClass::kNone, type)); create<ast::Variable>(name, ast::StorageClass::kNone, type));
dvar->set_is_const(true); dvar->set_is_const(true);
ast::VariableDecorationList decos; ast::VariableDecorationList decos;
@ -194,30 +194,28 @@ class InspectorHelper {
/// @param type AST type of the literal, must resolve to BoolLiteral /// @param type AST type of the literal, must resolve to BoolLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type, bool* val) { ast::Literal* MakeLiteral(ast::type::Type* type, bool* val) {
return create<ast::BoolLiteral>(type, *val); return create<ast::BoolLiteral>(type, *val);
} }
/// @param type AST type of the literal, must resolve to UIntLiteral /// @param type AST type of the literal, must resolve to UIntLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type, ast::Literal* MakeLiteral(ast::type::Type* type, uint32_t* val) {
uint32_t* val) {
return create<ast::UintLiteral>(type, *val); return create<ast::UintLiteral>(type, *val);
} }
/// @param type AST type of the literal, must resolve to IntLiteral /// @param type AST type of the literal, must resolve to IntLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type, ast::Literal* MakeLiteral(ast::type::Type* type, int32_t* val) {
int32_t* val) {
return create<ast::SintLiteral>(type, *val); return create<ast::SintLiteral>(type, *val);
} }
/// @param type AST type of the literal, must resolve to FloattLiteral /// @param type AST type of the literal, must resolve to FloattLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
std::unique_ptr<ast::Literal> MakeLiteral(ast::type::Type* type, float* val) { ast::Literal* MakeLiteral(ast::type::Type* type, float* val) {
return create<ast::FloatLiteral>(type, *val); return create<ast::FloatLiteral>(type, *val);
} }
@ -271,7 +269,7 @@ class InspectorHelper {
decos.push_back(create<ast::StructBlockDecoration>(Source{})); decos.push_back(create<ast::StructBlockDecoration>(Source{}));
} }
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
return std::make_unique<ast::type::StructType>(name, std::move(str)); return std::make_unique<ast::type::StructType>(name, std::move(str));
} }
@ -341,7 +339,7 @@ class InspectorHelper {
ast::StorageClass storage_class, ast::StorageClass storage_class,
uint32_t set, uint32_t set,
uint32_t binding) { uint32_t binding) {
auto var = create<ast::DecoratedVariable>( auto* var = create<ast::DecoratedVariable>(
create<ast::Variable>(name, storage_class, type)); create<ast::Variable>(name, storage_class, type));
ast::VariableDecorationList decorations; ast::VariableDecorationList decorations;
@ -381,11 +379,11 @@ class InspectorHelper {
/// @param struct_name name of the struct variabler to be accessed /// @param struct_name name of the struct variabler to be accessed
/// @param members list of members to access, by index and type /// @param members list of members to access, by index and type
/// @returns a function that references all of the members specified /// @returns a function that references all of the members specified
std::unique_ptr<ast::Function> MakeStructVariableReferenceBodyFunction( ast::Function* MakeStructVariableReferenceBodyFunction(
std::string func_name, std::string func_name,
std::string struct_name, std::string struct_name,
std::vector<std::tuple<size_t, ast::type::Type*>> members) { std::vector<std::tuple<size_t, ast::type::Type*>> members) {
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
for (auto member : members) { for (auto member : members) {
size_t member_idx; size_t member_idx;
@ -504,7 +502,7 @@ class InspectorHelper {
/// @param sampler_name name of the sampler to use /// @param sampler_name name of the sampler to use
/// @param coords_name name of the coords variable to use /// @param coords_name name of the coords variable to use
/// @returns a function that references all of the values specified /// @returns a function that references all of the values specified
std::unique_ptr<ast::Function> MakeSamplerReferenceBodyFunction( ast::Function* MakeSamplerReferenceBodyFunction(
const std::string& func_name, const std::string& func_name,
const std::string& texture_name, const std::string& texture_name,
const std::string& sampler_name, const std::string& sampler_name,
@ -512,9 +510,9 @@ class InspectorHelper {
ast::type::Type* base_type) { ast::type::Type* base_type) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
auto call_result = create<ast::Variable>( auto* call_result = create<ast::Variable>(
"sampler_result", ast::StorageClass::kFunction, vec_type(base_type, 4)); "sampler_result", ast::StorageClass::kFunction, vec_type(base_type, 4));
body->append(create<ast::VariableDeclStatement>(std::move(call_result))); body->append(create<ast::VariableDeclStatement>(std::move(call_result)));
@ -522,7 +520,7 @@ class InspectorHelper {
call_params.push_back(create<ast::IdentifierExpression>(texture_name)); call_params.push_back(create<ast::IdentifierExpression>(texture_name));
call_params.push_back(create<ast::IdentifierExpression>(sampler_name)); call_params.push_back(create<ast::IdentifierExpression>(sampler_name));
call_params.push_back(create<ast::IdentifierExpression>(coords_name)); call_params.push_back(create<ast::IdentifierExpression>(coords_name));
auto call_expr = create<ast::CallExpression>( auto* call_expr = create<ast::CallExpression>(
create<ast::IdentifierExpression>("textureSample"), create<ast::IdentifierExpression>("textureSample"),
std::move(call_params)); std::move(call_params));
@ -543,7 +541,7 @@ class InspectorHelper {
/// @param coords_name name of the coords variable to use /// @param coords_name name of the coords variable to use
/// @param depth_name name of the depth reference to use /// @param depth_name name of the depth reference to use
/// @returns a function that references all of the values specified /// @returns a function that references all of the values specified
std::unique_ptr<ast::Function> MakeComparisonSamplerReferenceBodyFunction( ast::Function* MakeComparisonSamplerReferenceBodyFunction(
const std::string& func_name, const std::string& func_name,
const std::string& texture_name, const std::string& texture_name,
const std::string& sampler_name, const std::string& sampler_name,
@ -552,9 +550,9 @@ class InspectorHelper {
ast::type::Type* base_type) { ast::type::Type* base_type) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
auto call_result = create<ast::Variable>( auto* call_result = create<ast::Variable>(
"sampler_result", ast::StorageClass::kFunction, base_type); "sampler_result", ast::StorageClass::kFunction, base_type);
body->append(create<ast::VariableDeclStatement>(std::move(call_result))); body->append(create<ast::VariableDeclStatement>(std::move(call_result)));
@ -563,7 +561,7 @@ class InspectorHelper {
call_params.push_back(create<ast::IdentifierExpression>(sampler_name)); call_params.push_back(create<ast::IdentifierExpression>(sampler_name));
call_params.push_back(create<ast::IdentifierExpression>(coords_name)); call_params.push_back(create<ast::IdentifierExpression>(coords_name));
call_params.push_back(create<ast::IdentifierExpression>(depth_name)); call_params.push_back(create<ast::IdentifierExpression>(depth_name));
auto call_expr = create<ast::CallExpression>( auto* call_expr = create<ast::CallExpression>(
create<ast::IdentifierExpression>("textureSampleCompare"), create<ast::IdentifierExpression>("textureSampleCompare"),
std::move(call_params)); std::move(call_params));
@ -643,11 +641,13 @@ class InspectorHelper {
return &comparison_sampler_type_; return &comparison_sampler_type_;
} }
/// @return a `std::unique_ptr` to a new `T` constructed with `args` /// Creates a new `ast::Node` owned by the Context. When the Context is
/// @param args the arguments to forward to the constructor for `T` /// 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> template <typename T, typename... ARGS>
std::unique_ptr<T> create(ARGS&&... args) { T* create(ARGS&&... args) {
return std::make_unique<T>(std::forward<ARGS>(args)...); return ctx_.create<T>(std::forward<ARGS>(args)...);
} }
private: private:
@ -723,7 +723,7 @@ TEST_F(InspectorGetEntryPointTest, NoEntryPoints) {
} }
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) { TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
auto foo = MakeEmptyBodyFunction("foo"); auto* foo = MakeEmptyBodyFunction("foo");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -738,12 +738,12 @@ TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
} }
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) { TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
auto foo = MakeEmptyBodyFunction("foo"); auto* foo = MakeEmptyBodyFunction("foo");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
auto bar = MakeEmptyBodyFunction("bar"); auto* bar = MakeEmptyBodyFunction("bar");
bar->add_decoration( bar->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
mod()->AddFunction(std::move(bar)); mod()->AddFunction(std::move(bar));
@ -761,15 +761,15 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
} }
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) { TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
auto func = MakeEmptyBodyFunction("func"); auto* func = MakeEmptyBodyFunction("func");
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
auto foo = MakeCallerBodyFunction("foo", "func"); auto* foo = MakeCallerBodyFunction("foo", "func");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
auto bar = MakeCallerBodyFunction("bar", "func"); auto* bar = MakeCallerBodyFunction("bar", "func");
bar->add_decoration( bar->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
mod()->AddFunction(std::move(bar)); mod()->AddFunction(std::move(bar));
@ -787,7 +787,7 @@ TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
} }
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) { TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
auto foo = MakeCallerBodyFunction("foo", "func"); auto* foo = MakeCallerBodyFunction("foo", "func");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -804,7 +804,7 @@ TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
} }
TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) { TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
auto foo = MakeEmptyBodyFunction("foo"); auto* foo = MakeEmptyBodyFunction("foo");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
foo->add_decoration(create<ast::WorkgroupDecoration>(8u, 2u, 1u, Source{})); foo->add_decoration(create<ast::WorkgroupDecoration>(8u, 2u, 1u, Source{}));
@ -822,10 +822,10 @@ TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
} }
TEST_F(InspectorGetEntryPointTest, NoInOutVariables) { TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
auto func = MakeEmptyBodyFunction("func"); auto* func = MakeEmptyBodyFunction("func");
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
auto foo = MakeCallerBodyFunction("foo", "func"); auto* foo = MakeCallerBodyFunction("foo", "func");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -841,7 +841,7 @@ TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
TEST_F(InspectorGetEntryPointTest, EntryPointInOutVariables) { TEST_F(InspectorGetEntryPointTest, EntryPointInOutVariables) {
AddInOutVariables({{"in_var", "out_var"}}); AddInOutVariables({{"in_var", "out_var"}});
auto foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out_var"}}); auto* foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out_var"}});
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -862,10 +862,10 @@ TEST_F(InspectorGetEntryPointTest, EntryPointInOutVariables) {
TEST_F(InspectorGetEntryPointTest, FunctionInOutVariables) { TEST_F(InspectorGetEntryPointTest, FunctionInOutVariables) {
AddInOutVariables({{"in_var", "out_var"}}); AddInOutVariables({{"in_var", "out_var"}});
auto func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}}); auto* func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
auto foo = MakeCallerBodyFunction("foo", "func"); auto* foo = MakeCallerBodyFunction("foo", "func");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -886,10 +886,10 @@ TEST_F(InspectorGetEntryPointTest, FunctionInOutVariables) {
TEST_F(InspectorGetEntryPointTest, RepeatedInOutVariables) { TEST_F(InspectorGetEntryPointTest, RepeatedInOutVariables) {
AddInOutVariables({{"in_var", "out_var"}}); AddInOutVariables({{"in_var", "out_var"}});
auto func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}}); auto* func = MakeInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
auto foo = MakeInOutVariableCallerBodyFunction("foo", "func", auto* foo = MakeInOutVariableCallerBodyFunction("foo", "func",
{{"in_var", "out_var"}}); {{"in_var", "out_var"}});
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -911,7 +911,7 @@ TEST_F(InspectorGetEntryPointTest, RepeatedInOutVariables) {
TEST_F(InspectorGetEntryPointTest, EntryPointMultipleInOutVariables) { TEST_F(InspectorGetEntryPointTest, EntryPointMultipleInOutVariables) {
AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}}); AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
auto foo = MakeInOutVariableBodyFunction( auto* foo = MakeInOutVariableBodyFunction(
"foo", {{"in_var", "out_var"}, {"in2_var", "out2_var"}}); "foo", {{"in_var", "out_var"}, {"in2_var", "out2_var"}});
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -935,11 +935,11 @@ TEST_F(InspectorGetEntryPointTest, EntryPointMultipleInOutVariables) {
TEST_F(InspectorGetEntryPointTest, FunctionMultipleInOutVariables) { TEST_F(InspectorGetEntryPointTest, FunctionMultipleInOutVariables) {
AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}}); AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
auto func = MakeInOutVariableBodyFunction( auto* func = MakeInOutVariableBodyFunction(
"func", {{"in_var", "out_var"}, {"in2_var", "out2_var"}}); "func", {{"in_var", "out_var"}, {"in2_var", "out2_var"}});
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
auto foo = MakeCallerBodyFunction("foo", "func"); auto* foo = MakeCallerBodyFunction("foo", "func");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -962,12 +962,12 @@ TEST_F(InspectorGetEntryPointTest, FunctionMultipleInOutVariables) {
TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) { TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) {
AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}}); AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
auto foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out2_var"}}); auto* foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out2_var"}});
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
auto bar = MakeInOutVariableBodyFunction("bar", {{"in2_var", "out_var"}}); auto* bar = MakeInOutVariableBodyFunction("bar", {{"in2_var", "out_var"}});
bar->add_decoration( bar->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
mod()->AddFunction(std::move(bar)); mod()->AddFunction(std::move(bar));
@ -997,16 +997,16 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) {
TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsSharedInOutVariables) { TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsSharedInOutVariables) {
AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}}); AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
auto func = MakeInOutVariableBodyFunction("func", {{"in2_var", "out2_var"}}); auto* func = MakeInOutVariableBodyFunction("func", {{"in2_var", "out2_var"}});
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
auto foo = MakeInOutVariableCallerBodyFunction("foo", "func", auto* foo = MakeInOutVariableCallerBodyFunction("foo", "func",
{{"in_var", "out_var"}}); {{"in_var", "out_var"}});
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
auto bar = MakeCallerBodyFunction("bar", "func"); auto* bar = MakeCallerBodyFunction("bar", "func");
bar->add_decoration( bar->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
mod()->AddFunction(std::move(bar)); mod()->AddFunction(std::move(bar));
@ -1058,7 +1058,7 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_NoEntryPoints) {
// TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass // TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
// through // through
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) { TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
auto foo = MakeEmptyBodyFunction("foo"); auto* foo = MakeEmptyBodyFunction("foo");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -1073,12 +1073,12 @@ TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_OneEntryPoint) {
// through // through
TEST_F(InspectorGetRemappedNameForEntryPointTest, TEST_F(InspectorGetRemappedNameForEntryPointTest,
DISABLED_MultipleEntryPoints) { DISABLED_MultipleEntryPoints) {
auto foo = MakeEmptyBodyFunction("foo"); auto* foo = MakeEmptyBodyFunction("foo");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
auto bar = MakeEmptyBodyFunction("bar"); auto* bar = MakeEmptyBodyFunction("bar");
bar->add_decoration( bar->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
mod()->AddFunction(std::move(bar)); mod()->AddFunction(std::move(bar));
@ -1197,11 +1197,11 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
MakeUniformBufferTypes("foo_type", {{i32_type(), 0}}); MakeUniformBufferTypes("foo_type", {{i32_type(), 0}});
AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0); AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(ub_func)); mod()->AddFunction(std::move(ub_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1224,17 +1224,17 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MissingBlockDeco) {
ast::StructDecorationList decos; ast::StructDecorationList decos;
auto str = create<ast::Struct>(std::move(decos), std::move(members)); auto* str = create<ast::Struct>(std::move(decos), std::move(members));
auto foo_type = auto foo_type =
std::make_unique<ast::type::StructType>("foo_type", std::move(str)); std::make_unique<ast::type::StructType>("foo_type", std::move(str));
AddUniformBuffer("foo_ub", foo_type.get(), 0, 0); AddUniformBuffer("foo_ub", foo_type.get(), 0, 0);
auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(ub_func)); mod()->AddFunction(std::move(ub_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1253,11 +1253,11 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple) {
MakeUniformBufferTypes("foo_type", {{i32_type(), 0}}); MakeUniformBufferTypes("foo_type", {{i32_type(), 0}});
AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0); AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(ub_func)); mod()->AddFunction(std::move(ub_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1280,11 +1280,11 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
"foo_type", {{i32_type(), 0}, {u32_type(), 4}, {f32_type(), 8}}); "foo_type", {{i32_type(), 0}, {u32_type(), 4}, {f32_type(), 8}});
AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0); AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
auto ub_func = MakeStructVariableReferenceBodyFunction( auto* ub_func = MakeStructVariableReferenceBodyFunction(
"ub_func", "foo_ub", {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}}); "ub_func", "foo_ub", {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
mod()->AddFunction(std::move(ub_func)); mod()->AddFunction(std::move(ub_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1311,7 +1311,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
auto AddReferenceFunc = [this](const std::string& func_name, auto AddReferenceFunc = [this](const std::string& func_name,
const std::string& var_name) { const std::string& var_name) {
auto ub_func = MakeStructVariableReferenceBodyFunction( auto* ub_func = MakeStructVariableReferenceBodyFunction(
func_name, var_name, func_name, var_name,
{{0, i32_type()}, {1, u32_type()}, {2, f32_type()}}); {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
mod()->AddFunction(std::move(ub_func)); mod()->AddFunction(std::move(ub_func));
@ -1321,20 +1321,20 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
AddReferenceFunc("ub_baz_func", "ub_baz"); AddReferenceFunc("ub_baz_func", "ub_baz");
auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) { auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) {
auto ident_expr = create<ast::IdentifierExpression>(callee); auto* ident_expr = create<ast::IdentifierExpression>(callee);
auto call_expr = create<ast::CallExpression>(std::move(ident_expr), auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
ast::ExpressionList()); ast::ExpressionList());
body->append(create<ast::CallStatement>(std::move(call_expr))); body->append(create<ast::CallStatement>(std::move(call_expr)));
}; };
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
AddFuncCall(body.get(), "ub_foo_func"); AddFuncCall(body, "ub_foo_func");
AddFuncCall(body.get(), "ub_bar_func"); AddFuncCall(body, "ub_bar_func");
AddFuncCall(body.get(), "ub_baz_func"); AddFuncCall(body, "ub_baz_func");
body->append(create<ast::ReturnStatement>()); body->append(create<ast::ReturnStatement>());
std::unique_ptr<ast::Function> func = create<ast::Function>( ast::Function* func = create<ast::Function>("ep_func", ast::VariableList(),
"ep_func", ast::VariableList(), void_type(), std::move(body)); void_type(), std::move(body));
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -1366,11 +1366,11 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
"foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}}); "foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}});
AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0); AddUniformBuffer("foo_ub", foo_control_type.get(), 0, 0);
auto ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", auto* ub_func = MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(ub_func)); mod()->AddFunction(std::move(ub_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1393,11 +1393,11 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) {
MakeStorageBufferTypes("foo_type", {{i32_type(), 0}}); MakeStorageBufferTypes("foo_type", {{i32_type(), 0}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1420,11 +1420,11 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
"foo_type", {{i32_type(), 0}, {u32_type(), 4}, {f32_type(), 8}}); "foo_type", {{i32_type(), 0}, {u32_type(), 4}, {f32_type(), 8}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction( auto* sb_func = MakeStructVariableReferenceBodyFunction(
"sb_func", "foo_sb", {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}}); "sb_func", "foo_sb", {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1451,7 +1451,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
auto AddReferenceFunc = [this](const std::string& func_name, auto AddReferenceFunc = [this](const std::string& func_name,
const std::string& var_name) { const std::string& var_name) {
auto sb_func = MakeStructVariableReferenceBodyFunction( auto* sb_func = MakeStructVariableReferenceBodyFunction(
func_name, var_name, func_name, var_name,
{{0, i32_type()}, {1, u32_type()}, {2, f32_type()}}); {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
@ -1461,20 +1461,20 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
AddReferenceFunc("sb_baz_func", "sb_baz"); AddReferenceFunc("sb_baz_func", "sb_baz");
auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) { auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) {
auto ident_expr = create<ast::IdentifierExpression>(callee); auto* ident_expr = create<ast::IdentifierExpression>(callee);
auto call_expr = create<ast::CallExpression>(std::move(ident_expr), auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
ast::ExpressionList()); ast::ExpressionList());
body->append(create<ast::CallStatement>(std::move(call_expr))); body->append(create<ast::CallStatement>(std::move(call_expr)));
}; };
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
AddFuncCall(body.get(), "sb_foo_func"); AddFuncCall(body, "sb_foo_func");
AddFuncCall(body.get(), "sb_bar_func"); AddFuncCall(body, "sb_bar_func");
AddFuncCall(body.get(), "sb_baz_func"); AddFuncCall(body, "sb_baz_func");
body->append(create<ast::ReturnStatement>()); body->append(create<ast::ReturnStatement>());
std::unique_ptr<ast::Function> func = create<ast::Function>( ast::Function* func = create<ast::Function>("ep_func", ast::VariableList(),
"ep_func", ast::VariableList(), void_type(), std::move(body)); void_type(), std::move(body));
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -1506,11 +1506,11 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
"foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}}); "foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1533,11 +1533,11 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
"foo_type", {{i32_type(), 0}, {u32_array_type(0), 4}}); "foo_type", {{i32_type(), 0}, {u32_array_type(0), 4}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1560,11 +1560,11 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
MakeReadOnlyStorageBufferTypes("foo_type", {{i32_type(), 0}}); MakeReadOnlyStorageBufferTypes("foo_type", {{i32_type(), 0}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1583,11 +1583,11 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
MakeReadOnlyStorageBufferTypes("foo_type", {{i32_type(), 0}}); MakeReadOnlyStorageBufferTypes("foo_type", {{i32_type(), 0}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1616,7 +1616,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
auto AddReferenceFunc = [this](const std::string& func_name, auto AddReferenceFunc = [this](const std::string& func_name,
const std::string& var_name) { const std::string& var_name) {
auto sb_func = MakeStructVariableReferenceBodyFunction( auto* sb_func = MakeStructVariableReferenceBodyFunction(
func_name, var_name, func_name, var_name,
{{0, i32_type()}, {1, u32_type()}, {2, f32_type()}}); {{0, i32_type()}, {1, u32_type()}, {2, f32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
@ -1626,20 +1626,20 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
AddReferenceFunc("sb_baz_func", "sb_baz"); AddReferenceFunc("sb_baz_func", "sb_baz");
auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) { auto AddFuncCall = [&](ast::BlockStatement* body, const std::string& callee) {
auto ident_expr = create<ast::IdentifierExpression>(callee); auto* ident_expr = create<ast::IdentifierExpression>(callee);
auto call_expr = create<ast::CallExpression>(std::move(ident_expr), auto* call_expr = create<ast::CallExpression>(std::move(ident_expr),
ast::ExpressionList()); ast::ExpressionList());
body->append(create<ast::CallStatement>(std::move(call_expr))); body->append(create<ast::CallStatement>(std::move(call_expr)));
}; };
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
AddFuncCall(body.get(), "sb_foo_func"); AddFuncCall(body, "sb_foo_func");
AddFuncCall(body.get(), "sb_bar_func"); AddFuncCall(body, "sb_bar_func");
AddFuncCall(body.get(), "sb_baz_func"); AddFuncCall(body, "sb_baz_func");
body->append(create<ast::ReturnStatement>()); body->append(create<ast::ReturnStatement>());
std::unique_ptr<ast::Function> func = create<ast::Function>( ast::Function* func = create<ast::Function>("ep_func", ast::VariableList(),
"ep_func", ast::VariableList(), void_type(), std::move(body)); void_type(), std::move(body));
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -1672,11 +1672,11 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
"foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}}); "foo_type", {{i32_type(), 0}, {u32_array_type(4), 4}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1701,11 +1701,11 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
"foo_type", {{i32_type(), 0}, {u32_array_type(0), 4}}); "foo_type", {{i32_type(), 0}, {u32_array_type(0), 4}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1729,11 +1729,11 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
MakeStorageBufferTypes("foo_type", {{i32_type(), 0}}); MakeStorageBufferTypes("foo_type", {{i32_type(), 0}});
AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0); AddStorageBuffer("foo_sb", foo_control_type.get(), 0, 0);
auto sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", auto* sb_func = MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, i32_type()}}); {{0, i32_type()}});
mod()->AddFunction(std::move(sb_func)); mod()->AddFunction(std::move(sb_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1753,7 +1753,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
auto func = MakeSamplerReferenceBodyFunction( auto* func = MakeSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", f32_type()); "ep", "foo_texture", "foo_sampler", "foo_coords", f32_type());
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -1770,7 +1770,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) { TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
auto func = MakeEmptyBodyFunction("ep_func"); auto* func = MakeEmptyBodyFunction("ep_func");
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
@ -1790,11 +1790,11 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
auto foo_func = MakeSamplerReferenceBodyFunction( auto* foo_func = MakeSamplerReferenceBodyFunction(
"foo_func", "foo_texture", "foo_sampler", "foo_coords", f32_type()); "foo_func", "foo_texture", "foo_sampler", "foo_coords", f32_type());
mod()->AddFunction(std::move(foo_func)); mod()->AddFunction(std::move(foo_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "foo_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "foo_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1816,7 +1816,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
auto func = MakeSamplerReferenceBodyFunction( auto* func = MakeSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", f32_type()); "ep", "foo_texture", "foo_sampler", "foo_coords", f32_type());
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -1836,7 +1836,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
AddGlobalVariable("foo_depth", f32_type()); AddGlobalVariable("foo_depth", f32_type());
auto func = MakeComparisonSamplerReferenceBodyFunction( auto* func = MakeComparisonSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
f32_type()); f32_type());
func->add_decoration( func->add_decoration(
@ -1859,7 +1859,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
AddGlobalVariable("foo_depth", f32_type()); AddGlobalVariable("foo_depth", f32_type());
auto func = MakeComparisonSamplerReferenceBodyFunction( auto* func = MakeComparisonSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
f32_type()); f32_type());
func->add_decoration( func->add_decoration(
@ -1877,7 +1877,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
auto func = MakeEmptyBodyFunction("ep_func"); auto* func = MakeEmptyBodyFunction("ep_func");
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(func)); mod()->AddFunction(std::move(func));
@ -1898,12 +1898,12 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
AddGlobalVariable("foo_depth", f32_type()); AddGlobalVariable("foo_depth", f32_type());
auto foo_func = MakeComparisonSamplerReferenceBodyFunction( auto* foo_func = MakeComparisonSamplerReferenceBodyFunction(
"foo_func", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", "foo_func", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
f32_type()); f32_type());
mod()->AddFunction(std::move(foo_func)); mod()->AddFunction(std::move(foo_func));
auto ep_func = MakeCallerBodyFunction("ep_func", "foo_func"); auto* ep_func = MakeCallerBodyFunction("ep_func", "foo_func");
ep_func->add_decoration( ep_func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(ep_func)); mod()->AddFunction(std::move(ep_func));
@ -1926,7 +1926,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
AddGlobalVariable("foo_depth", f32_type()); AddGlobalVariable("foo_depth", f32_type());
auto func = MakeComparisonSamplerReferenceBodyFunction( auto* func = MakeComparisonSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth", "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth",
f32_type()); f32_type());
func->add_decoration( func->add_decoration(
@ -1946,7 +1946,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", f32_type()); AddGlobalVariable("foo_coords", f32_type());
auto func = MakeSamplerReferenceBodyFunction( auto* func = MakeSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", f32_type()); "ep", "foo_texture", "foo_sampler", "foo_coords", f32_type());
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
@ -1961,7 +1961,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
} }
TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) { TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
auto foo = MakeEmptyBodyFunction("foo"); auto* foo = MakeEmptyBodyFunction("foo");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -1981,7 +1981,7 @@ TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) {
GetCoordsType(GetParam().type_dim, GetParam().sampled_kind); GetCoordsType(GetParam().type_dim, GetParam().sampled_kind);
AddGlobalVariable("foo_coords", coord_type); AddGlobalVariable("foo_coords", coord_type);
auto func = MakeSamplerReferenceBodyFunction( auto* func = MakeSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "ep", "foo_texture", "foo_sampler", "foo_coords",
GetBaseType(GetParam().sampled_kind)); GetBaseType(GetParam().sampled_kind));
func->add_decoration( func->add_decoration(
@ -2090,7 +2090,7 @@ INSTANTIATE_TEST_SUITE_P(
inspector::ResourceBinding::SampledKind::kUInt})); inspector::ResourceBinding::SampledKind::kUInt}));
TEST_F(InspectorGetMultisampledTextureResourceBindingsTest, Empty) { TEST_F(InspectorGetMultisampledTextureResourceBindingsTest, Empty) {
auto foo = MakeEmptyBodyFunction("foo"); auto* foo = MakeEmptyBodyFunction("foo");
foo->add_decoration( foo->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(foo)); mod()->AddFunction(std::move(foo));
@ -2111,7 +2111,7 @@ TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam,
GetCoordsType(GetParam().type_dim, GetParam().sampled_kind); GetCoordsType(GetParam().type_dim, GetParam().sampled_kind);
AddGlobalVariable("foo_coords", coord_type); AddGlobalVariable("foo_coords", coord_type);
auto func = MakeSamplerReferenceBodyFunction( auto* func = MakeSamplerReferenceBodyFunction(
"ep", "foo_texture", "foo_sampler", "foo_coords", "ep", "foo_texture", "foo_sampler", "foo_coords",
GetBaseType(GetParam().sampled_kind)); GetBaseType(GetParam().sampled_kind));
func->add_decoration( func->add_decoration(

View File

@ -16,6 +16,7 @@
#define SRC_READER_READER_H_ #define SRC_READER_READER_H_
#include <string> #include <string>
#include <utility>
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/context.h" #include "src/context.h"
@ -58,6 +59,15 @@ class Reader {
/// @param diags the list of diagnostic messages /// @param diags the list of diagnostic messages
void set_diagnostics(const diag::List& diags) { diags_ = diags; } 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 /// The Tint context object
Context& ctx_; Context& ctx_;

View File

@ -487,8 +487,8 @@ FunctionEmitter::StatementBlock::StatementBlock(
const Construct* construct, const Construct* construct,
uint32_t end_id, uint32_t end_id,
CompletionAction completion_action, CompletionAction completion_action,
std::unique_ptr<ast::BlockStatement> statements, ast::BlockStatement* statements,
std::unique_ptr<ast::CaseStatementList> cases) ast::CaseStatementList* cases)
: construct_(construct), : construct_(construct),
end_id_(end_id), end_id_(end_id),
completion_action_(completion_action), 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 // if-selection with a then-clause ending at the same block
// as the statement block at the top of the stack. // as the statement block at the top of the stack.
const auto& top = statements_stack_.back(); const auto& top = statements_stack_.back();
auto cond = create<ast::IdentifierExpression>(guard_name); auto* cond = create<ast::IdentifierExpression>(guard_name);
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
auto* const guard_stmt = auto* const guard_stmt =
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body))) AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
->AsIf(); ->AsIf();
@ -528,8 +528,8 @@ void FunctionEmitter::PushGuard(const std::string& guard_name,
void FunctionEmitter::PushTrueGuard(uint32_t end_id) { void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
assert(!statements_stack_.empty()); assert(!statements_stack_.empty());
const auto& top = statements_stack_.back(); const auto& top = statements_stack_.back();
auto cond = MakeTrue(); auto* cond = MakeTrue();
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
auto* const guard_stmt = auto* const guard_stmt =
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body))) AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
->AsIf(); ->AsIf();
@ -542,13 +542,12 @@ void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
const ast::BlockStatement* FunctionEmitter::ast_body() { const ast::BlockStatement* FunctionEmitter::ast_body() {
assert(!statements_stack_.empty()); assert(!statements_stack_.empty());
return statements_stack_[0].statements_.get(); return statements_stack_[0].statements_;
} }
ast::Statement* FunctionEmitter::AddStatement( ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
std::unique_ptr<ast::Statement> statement) {
assert(!statements_stack_.empty()); assert(!statements_stack_.empty());
auto* result = statement.get(); auto* result = statement;
if (result != nullptr) { if (result != nullptr) {
statements_stack_.back().statements_->append(std::move(statement)); statements_stack_.back().statements_->append(std::move(statement));
} }
@ -556,7 +555,7 @@ ast::Statement* FunctionEmitter::AddStatement(
} }
ast::Statement* FunctionEmitter::AddStatementForInstruction( ast::Statement* FunctionEmitter::AddStatementForInstruction(
std::unique_ptr<ast::Statement> statement, ast::Statement* statement,
const spvtools::opt::Instruction& inst) { const spvtools::opt::Instruction& inst) {
auto* node = AddStatement(std::move(statement)); auto* node = AddStatement(std::move(statement));
ApplySourceForInstruction(node, inst); ApplySourceForInstruction(node, inst);
@ -565,7 +564,7 @@ ast::Statement* FunctionEmitter::AddStatementForInstruction(
ast::Statement* FunctionEmitter::LastStatement() { ast::Statement* FunctionEmitter::LastStatement() {
assert(!statements_stack_.empty()); assert(!statements_stack_.empty());
const auto& statement_list = statements_stack_.back().statements_; auto* statement_list = statements_stack_.back().statements_;
assert(!statement_list->empty()); assert(!statement_list->empty());
return statement_list->last(); return statement_list->last();
} }
@ -593,7 +592,7 @@ bool FunctionEmitter::Emit() {
"element but has " "element but has "
<< statements_stack_.size(); << 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)); parser_impl_.get_module().functions().back()->set_body(std::move(body));
// Maintain the invariant by repopulating the one and only element. // Maintain the invariant by repopulating the one and only element.
statements_stack_.clear(); statements_stack_.clear();
@ -632,7 +631,7 @@ bool FunctionEmitter::EmitFunctionDeclaration() {
[this, &ast_params](const spvtools::opt::Instruction* param) { [this, &ast_params](const spvtools::opt::Instruction* param) {
auto* ast_type = parser_impl_.ConvertType(param->type_id()); auto* ast_type = parser_impl_.ConvertType(param->type_id());
if (ast_type != nullptr) { if (ast_type != nullptr) {
auto ast_param = parser_impl_.MakeVariable( auto* ast_param = parser_impl_.MakeVariable(
param->result_id(), ast::StorageClass::kNone, ast_type); param->result_id(), ast::StorageClass::kNone, ast_type);
// Parameters are treated as const declarations. // Parameters are treated as const declarations.
ast_param->set_is_const(true); ast_param->set_is_const(true);
@ -648,7 +647,7 @@ bool FunctionEmitter::EmitFunctionDeclaration() {
return false; return false;
} }
auto ast_fn = create<ast::Function>(name, std::move(ast_params), ret_ty, auto* ast_fn = create<ast::Function>(name, std::move(ast_params), ret_ty,
create<ast::BlockStatement>()); create<ast::BlockStatement>());
if (ep_info_ != nullptr) { if (ep_info_ != nullptr) {
@ -1695,7 +1694,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
if (failed()) { if (failed()) {
return false; return false;
} }
auto var = parser_impl_.MakeVariable( auto* var = parser_impl_.MakeVariable(
inst.result_id(), ast::StorageClass::kFunction, var_store_type); inst.result_id(), ast::StorageClass::kFunction, var_store_type);
if (inst.NumInOperands() > 1) { if (inst.NumInOperands() > 1) {
// SPIR-V initializers are always constants. // SPIR-V initializers are always constants.
@ -1705,7 +1704,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1)) parser_impl_.MakeConstantExpression(inst.GetSingleWordInOperand(1))
.expr); .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); AddStatementForInstruction(std::move(var_decl_stmt), inst);
// Save this as an already-named value. // Save this as an already-named value.
identifier_values_.insert(inst.result_id()); identifier_values_.insert(inst.result_id());
@ -1718,9 +1717,9 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
return {}; return {};
} }
if (identifier_values_.count(id) || parser_impl_.IsScalarSpecConstant(id)) { if (identifier_values_.count(id) || parser_impl_.IsScalarSpecConstant(id)) {
return TypedExpression( return TypedExpression{
parser_impl_.ConvertType(def_use_mgr_->GetDef(id)->type_id()), parser_impl_.ConvertType(def_use_mgr_->GetDef(id)->type_id()),
create<ast::IdentifierExpression>(namer_.Name(id))); create<ast::IdentifierExpression>(namer_.Name(id))};
} }
if (singly_used_values_.count(id)) { if (singly_used_values_.count(id)) {
auto expr = std::move(singly_used_values_[id]); auto expr = std::move(singly_used_values_[id]);
@ -1739,9 +1738,9 @@ TypedExpression FunctionEmitter::MakeExpression(uint32_t id) {
switch (inst->opcode()) { switch (inst->opcode()) {
case SpvOpVariable: case SpvOpVariable:
// This occurs for module-scope variables. // This occurs for module-scope variables.
return TypedExpression( return TypedExpression{
parser_impl_.ConvertType(inst->type_id()), parser_impl_.ConvertType(inst->type_id()),
create<ast::IdentifierExpression>(namer_.Name(inst->result_id()))); create<ast::IdentifierExpression>(namer_.Name(inst->result_id()))};
default: default:
break; break;
} }
@ -1970,17 +1969,17 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
const std::string guard_name = block_info.flow_guard_name; const std::string guard_name = block_info.flow_guard_name;
if (!guard_name.empty()) { if (!guard_name.empty()) {
// Declare the guard variable just before the "if", initialized to true. // Declare the guard variable just before the "if", initialized to true.
auto guard_var = create<ast::Variable>( auto* guard_var = create<ast::Variable>(
guard_name, ast::StorageClass::kFunction, parser_impl_.BoolType()); guard_name, ast::StorageClass::kFunction, parser_impl_.BoolType());
guard_var->set_constructor(MakeTrue()); guard_var->set_constructor(MakeTrue());
auto guard_decl = create<ast::VariableDeclStatement>(std::move(guard_var)); auto* guard_decl = create<ast::VariableDeclStatement>(std::move(guard_var));
AddStatement(std::move(guard_decl)); AddStatement(std::move(guard_decl));
} }
const auto condition_id = const auto condition_id =
block_info.basic_block->terminator()->GetSingleWordInOperand(0); block_info.basic_block->terminator()->GetSingleWordInOperand(0);
auto cond = MakeExpression(condition_id).expr; auto* cond = MakeExpression(condition_id).expr;
auto body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
auto* const if_stmt = auto* const if_stmt =
AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body))) AddStatement(create<ast::IfStatement>(std::move(cond), std::move(body)))
->AsIf(); ->AsIf();
@ -2108,7 +2107,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
construct, construct->end_id, [switch_stmt](StatementBlock* s) { construct, construct->end_id, [switch_stmt](StatementBlock* s) {
switch_stmt->set_body(std::move(*std::move(s->cases_))); switch_stmt->set_body(std::move(*std::move(s->cases_)));
}); });
statements_stack_.back().cases_ = 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 // Grab a pointer to the case list. It will get buried in the statement block
// stack. // stack.
auto* cases = statements_stack_.back().cases_.get(); auto* cases = statements_stack_.back().cases_.get();
@ -2156,7 +2155,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
// on the case statement list. // on the case statement list.
cases->emplace_back( cases->emplace_back(
create<ast::CaseStatement>(create<ast::BlockStatement>())); 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 // Create a list of integer literals for the selector values leading to
// this case clause. // this case clause.
@ -2192,9 +2191,9 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
if ((default_info == clause_heads[i]) && has_selectors && if ((default_info == clause_heads[i]) && has_selectors &&
construct->ContainsPos(default_info->pos)) { construct->ContainsPos(default_info->pos)) {
// Generate a default clause with a just fallthrough. // Generate a default clause with a just fallthrough.
auto stmts = create<ast::BlockStatement>(); auto* stmts = create<ast::BlockStatement>();
stmts->append(create<ast::FallthroughStatement>()); 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)); 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; const EdgeKind false_kind = block_info.succ_edge.find(false_dest)->second;
auto* const true_info = GetBlockInfo(true_dest); auto* const true_info = GetBlockInfo(true_dest);
auto* const false_info = GetBlockInfo(false_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 // We have two distinct destinations. But we only get here if this
// is a normal terminator; in particular the source block is *not* the // 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 // requiring a flow guard, then get that flow guard name too. It will
// come from at most one of these two branches. // come from at most one of these two branches.
std::string flow_guard; std::string flow_guard;
auto true_branch = auto* true_branch =
MakeBranchDetailed(block_info, *true_info, false, &flow_guard); MakeBranchDetailed(block_info, *true_info, false, &flow_guard);
auto false_branch = auto* false_branch =
MakeBranchDetailed(block_info, *false_info, false, &flow_guard); MakeBranchDetailed(block_info, *false_info, false, &flow_guard);
AddStatement(MakeSimpleIf(std::move(cond), std::move(true_branch), AddStatement(MakeSimpleIf(std::move(cond), std::move(true_branch),
@ -2334,7 +2333,7 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
return success(); return success();
} }
std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed( ast::Statement* FunctionEmitter::MakeBranchDetailed(
const BlockInfo& src_info, const BlockInfo& src_info,
const BlockInfo& dest_info, const BlockInfo& dest_info,
bool forced, bool forced,
@ -2405,25 +2404,24 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeBranchDetailed(
// Unconditional forward branch is implicit. // Unconditional forward branch is implicit.
break; break;
} }
return {nullptr}; return nullptr;
} }
std::unique_ptr<ast::Statement> FunctionEmitter::MakeSimpleIf( ast::Statement* FunctionEmitter::MakeSimpleIf(ast::Expression* condition,
std::unique_ptr<ast::Expression> condition, ast::Statement* then_stmt,
std::unique_ptr<ast::Statement> then_stmt, ast::Statement* else_stmt) const {
std::unique_ptr<ast::Statement> else_stmt) const {
if ((then_stmt == nullptr) && (else_stmt == nullptr)) { if ((then_stmt == nullptr) && (else_stmt == nullptr)) {
return nullptr; return nullptr;
} }
auto if_stmt = create<ast::IfStatement>(std::move(condition), auto* if_stmt = create<ast::IfStatement>(std::move(condition),
create<ast::BlockStatement>()); create<ast::BlockStatement>());
if (then_stmt != nullptr) { if (then_stmt != nullptr) {
auto stmts = create<ast::BlockStatement>(); auto* stmts = create<ast::BlockStatement>();
stmts->append(std::move(then_stmt)); stmts->append(std::move(then_stmt));
if_stmt->set_body(std::move(stmts)); if_stmt->set_body(std::move(stmts));
} }
if (else_stmt != nullptr) { if (else_stmt != nullptr) {
auto stmts = create<ast::BlockStatement>(); auto* stmts = create<ast::BlockStatement>();
stmts->append(std::move(else_stmt)); stmts->append(std::move(else_stmt));
ast::ElseStatementList else_stmts; ast::ElseStatementList else_stmts;
else_stmts.emplace_back( else_stmts.emplace_back(
@ -2435,7 +2433,7 @@ std::unique_ptr<ast::Statement> FunctionEmitter::MakeSimpleIf(
bool FunctionEmitter::EmitConditionalCaseFallThrough( bool FunctionEmitter::EmitConditionalCaseFallThrough(
const BlockInfo& src_info, const BlockInfo& src_info,
std::unique_ptr<ast::Expression> cond, ast::Expression* cond,
EdgeKind other_edge_kind, EdgeKind other_edge_kind,
const BlockInfo& other_dest, const BlockInfo& other_dest,
bool fall_through_is_true_branch) { bool fall_through_is_true_branch) {
@ -2462,7 +2460,7 @@ bool FunctionEmitter::EmitConditionalCaseFallThrough(
<< "internal error: normal terminator OpBranchConditional has " << "internal error: normal terminator OpBranchConditional has "
"both backedge and fallthrough edges. Violates nesting rule"; "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) { if (other_branch == nullptr) {
return Fail() << "internal error: expected a branch for edge-kind " return Fail() << "internal error: expected a branch for edge-kind "
<< int(other_edge_kind); << int(other_edge_kind);
@ -2512,7 +2510,7 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
assert(def_inst); assert(def_inst);
const auto phi_var_name = GetDefInfo(id)->phi_var; const auto phi_var_name = GetDefInfo(id)->phi_var;
assert(!phi_var_name.empty()); assert(!phi_var_name.empty());
auto var = auto* var =
create<ast::Variable>(phi_var_name, ast::StorageClass::kFunction, create<ast::Variable>(phi_var_name, ast::StorageClass::kFunction,
parser_impl_.ConvertType(def_inst->type_id())); parser_impl_.ConvertType(def_inst->type_id()));
AddStatement(create<ast::VariableDeclStatement>(std::move(var))); AddStatement(create<ast::VariableDeclStatement>(std::move(var)));
@ -2560,7 +2558,7 @@ bool FunctionEmitter::EmitConstDefinition(
if (!ast_expr.expr) { if (!ast_expr.expr) {
return false; return false;
} }
auto ast_const = parser_impl_.MakeVariable( auto* ast_const = parser_impl_.MakeVariable(
inst.result_id(), ast::StorageClass::kNone, ast_expr.type); inst.result_id(), ast::StorageClass::kNone, ast_expr.type);
if (!ast_const) { if (!ast_const) {
return false; return false;
@ -2672,9 +2670,9 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
} }
case SpvOpPhi: { case SpvOpPhi: {
// Emit a read from the associated state variable. // Emit a read from the associated state variable.
auto expr = TypedExpression expr{
TypedExpression(parser_impl_.ConvertType(inst.type_id()), parser_impl_.ConvertType(inst.type_id()),
create<ast::IdentifierExpression>(def_info->phi_var)); create<ast::IdentifierExpression>(def_info->phi_var)};
return EmitConstDefOrWriteToHoistedVar(inst, std::move(expr)); return EmitConstDefOrWriteToHoistedVar(inst, std::move(expr));
} }
case SpvOpFunctionCall: case SpvOpFunctionCall:
@ -2708,9 +2706,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
if (binary_op != ast::BinaryOp::kNone) { if (binary_op != ast::BinaryOp::kNone) {
auto arg0 = MakeOperand(inst, 0); auto arg0 = MakeOperand(inst, 0);
auto arg1 = MakeOperand(inst, 1); auto arg1 = MakeOperand(inst, 1);
auto binary_expr = create<ast::BinaryExpression>( auto* binary_expr = create<ast::BinaryExpression>(
binary_op, std::move(arg0.expr), std::move(arg1.expr)); binary_op, std::move(arg0.expr), std::move(arg1.expr));
TypedExpression result(ast_type, std::move(binary_expr)); TypedExpression result{ast_type, std::move(binary_expr)};
return parser_impl_.RectifyForcedResultType(std::move(result), opcode, return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
arg0.type); arg0.type);
} }
@ -2718,9 +2716,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
auto unary_op = ast::UnaryOp::kNegation; auto unary_op = ast::UnaryOp::kNegation;
if (GetUnaryOp(opcode, &unary_op)) { if (GetUnaryOp(opcode, &unary_op)) {
auto arg0 = MakeOperand(inst, 0); auto arg0 = MakeOperand(inst, 0);
auto unary_expr = auto* unary_expr =
create<ast::UnaryOpExpression>(unary_op, std::move(arg0.expr)); create<ast::UnaryOpExpression>(unary_op, std::move(arg0.expr));
TypedExpression result(ast_type, std::move(unary_expr)); TypedExpression result{ast_type, std::move(unary_expr)};
return parser_impl_.RectifyForcedResultType(std::move(result), opcode, return parser_impl_.RectifyForcedResultType(std::move(result), opcode,
arg0.type); arg0.type);
} }
@ -2752,9 +2750,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
if (negated_op != ast::BinaryOp::kNone) { if (negated_op != ast::BinaryOp::kNone) {
auto arg0 = MakeOperand(inst, 0); auto arg0 = MakeOperand(inst, 0);
auto arg1 = MakeOperand(inst, 1); auto arg1 = MakeOperand(inst, 1);
auto binary_expr = create<ast::BinaryExpression>( auto* binary_expr = create<ast::BinaryExpression>(
negated_op, std::move(arg0.expr), std::move(arg1.expr)); negated_op, std::move(arg0.expr), std::move(arg1.expr));
auto negated_expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, auto* negated_expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot,
std::move(binary_expr)); std::move(binary_expr));
return {ast_type, std::move(negated_expr)}; return {ast_type, std::move(negated_expr)};
} }
@ -2831,14 +2829,15 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
return {}; return {};
} }
auto func = create<ast::IdentifierExpression>(name); auto* func = create<ast::IdentifierExpression>(name);
ast::ExpressionList operands; ast::ExpressionList operands;
// All parameters to GLSL.std.450 extended instructions are IDs. // All parameters to GLSL.std.450 extended instructions are IDs.
for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) { for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) {
operands.emplace_back(MakeOperand(inst, iarg).expr); operands.emplace_back(MakeOperand(inst, iarg).expr);
} }
auto* ast_type = parser_impl_.ConvertType(inst.type_id()); auto* ast_type = parser_impl_.ConvertType(inst.type_id());
auto call = 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)}; return {ast_type, std::move(call)};
} }
@ -2928,7 +2927,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
constants[index] ? constants[index]->AsIntConstant() : nullptr; constants[index] ? constants[index]->AsIntConstant() : nullptr;
const int64_t index_const_val = const int64_t index_const_val =
index_const ? index_const->GetSignExtendedValue() : 0; 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); const auto* pointee_type_inst = def_use_mgr_->GetDef(pointee_type_id);
if (!pointee_type_inst) { if (!pointee_type_inst) {
@ -2955,7 +2954,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
<< " is too big. Max handled index is " << " is too big. Max handled index is "
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1); << ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
} }
auto letter_index = auto* letter_index =
create<ast::IdentifierExpression>(swizzles[index_const_val]); create<ast::IdentifierExpression>(swizzles[index_const_val]);
next_expr = create<ast::MemberAccessorExpression>( next_expr = create<ast::MemberAccessorExpression>(
std::move(current_expr.expr), std::move(letter_index)); std::move(current_expr.expr), std::move(letter_index));
@ -3003,7 +3002,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
<< pointee_type_id << " having " << num_members << " members"; << pointee_type_id << " having " << num_members << " members";
return {}; return {};
} }
auto member_access = create<ast::IdentifierExpression>( auto* member_access = create<ast::IdentifierExpression>(
namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val))); namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val)));
next_expr = create<ast::MemberAccessorExpression>( next_expr = create<ast::MemberAccessorExpression>(
@ -3022,7 +3021,7 @@ TypedExpression FunctionEmitter::MakeAccessChain(
auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id); auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id);
assert(ast_pointer_type); assert(ast_pointer_type);
assert(ast_pointer_type->IsPointer()); 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; return current_expr;
} }
@ -3062,7 +3061,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
<< " indices: " << inst.PrettyPrint(); << " indices: " << inst.PrettyPrint();
return {}; return {};
} }
std::unique_ptr<ast::Expression> next_expr; ast::Expression* next_expr = nullptr;
switch (current_type_inst->opcode()) { switch (current_type_inst->opcode()) {
case SpvOpTypeVector: { case SpvOpTypeVector: {
// Try generating a MemberAccessor expression. That result in something // Try generating a MemberAccessor expression. That result in something
@ -3079,7 +3078,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
<< " is too big. Max handled index is " << " is too big. Max handled index is "
<< ((sizeof(swizzles) / sizeof(swizzles[0])) - 1); << ((sizeof(swizzles) / sizeof(swizzles[0])) - 1);
} }
auto letter_index = auto* letter_index =
create<ast::IdentifierExpression>(swizzles[index_val]); create<ast::IdentifierExpression>(swizzles[index_val]);
next_expr = create<ast::MemberAccessorExpression>( next_expr = create<ast::MemberAccessorExpression>(
std::move(current_expr.expr), std::move(letter_index)); std::move(current_expr.expr), std::move(letter_index));
@ -3127,7 +3126,7 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
<< current_type_id << " having " << num_members << " members"; << current_type_id << " having " << num_members << " members";
return {}; return {};
} }
auto member_access = create<ast::IdentifierExpression>( auto* member_access = create<ast::IdentifierExpression>(
namer_.GetMemberName(current_type_id, uint32_t(index_val))); namer_.GetMemberName(current_type_id, uint32_t(index_val)));
next_expr = create<ast::MemberAccessorExpression>( next_expr = create<ast::MemberAccessorExpression>(
@ -3140,18 +3139,18 @@ TypedExpression FunctionEmitter::MakeCompositeExtract(
<< current_type_inst->PrettyPrint(); << current_type_inst->PrettyPrint();
return {}; return {};
} }
current_expr.reset(TypedExpression( current_expr = TypedExpression{parser_impl_.ConvertType(current_type_id),
parser_impl_.ConvertType(current_type_id), std::move(next_expr))); std::move(next_expr)};
} }
return current_expr; return current_expr;
} }
std::unique_ptr<ast::Expression> FunctionEmitter::MakeTrue() const { ast::Expression* FunctionEmitter::MakeTrue() const {
return create<ast::ScalarConstructorExpression>( return create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(parser_impl_.BoolType(), true)); 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; ast::type::BoolType bool_type;
return create<ast::ScalarConstructorExpression>( return create<ast::ScalarConstructorExpression>(
create<ast::BoolLiteral>(parser_impl_.BoolType(), false)); create<ast::BoolLiteral>(parser_impl_.BoolType(), false));
@ -3489,8 +3488,8 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
ast::ExpressionList params; ast::ExpressionList params;
params.push_back(std::move(arg_expr.expr)); params.push_back(std::move(arg_expr.expr));
TypedExpression result(expr_type, create<ast::TypeConstructorExpression>( TypedExpression result{expr_type, create<ast::TypeConstructorExpression>(
expr_type, std::move(params))); expr_type, std::move(params))};
if (requested_type == expr_type) { if (requested_type == expr_type) {
return result; return result;
@ -3501,14 +3500,14 @@ TypedExpression FunctionEmitter::MakeNumericConversion(
bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) { bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
// We ignore function attributes such as Inline, DontInline, Pure, Const. // We ignore function attributes such as Inline, DontInline, Pure, Const.
auto function = create<ast::IdentifierExpression>( auto* function = create<ast::IdentifierExpression>(
namer_.Name(inst.GetSingleWordInOperand(0))); namer_.Name(inst.GetSingleWordInOperand(0)));
ast::ExpressionList params; ast::ExpressionList params;
for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) { for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
params.emplace_back(MakeOperand(inst, iarg).expr); params.emplace_back(MakeOperand(inst, iarg).expr);
} }
auto call_expr = auto* call_expr =
create<ast::CallExpression>(std::move(function), std::move(params)); create<ast::CallExpression>(std::move(function), std::move(params));
auto* result_type = parser_impl_.ConvertType(inst.type_id()); auto* result_type = parser_impl_.ConvertType(inst.type_id());
if (!result_type) { if (!result_type) {
@ -3531,14 +3530,14 @@ TypedExpression FunctionEmitter::MakeIntrinsicCall(
const auto intrinsic = GetIntrinsic(inst.opcode()); const auto intrinsic = GetIntrinsic(inst.opcode());
std::ostringstream ss; std::ostringstream ss;
ss << intrinsic; ss << intrinsic;
auto ident = create<ast::IdentifierExpression>(ss.str()); auto* ident = create<ast::IdentifierExpression>(ss.str());
ident->set_intrinsic(intrinsic); ident->set_intrinsic(intrinsic);
ast::ExpressionList params; ast::ExpressionList params;
for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) { for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) {
params.emplace_back(MakeOperand(inst, iarg).expr); params.emplace_back(MakeOperand(inst, iarg).expr);
} }
auto call_expr = auto* call_expr =
create<ast::CallExpression>(std::move(ident), std::move(params)); create<ast::CallExpression>(std::move(ident), std::move(params));
auto* result_type = parser_impl_.ConvertType(inst.type_id()); auto* result_type = parser_impl_.ConvertType(inst.type_id());
if (!result_type) { if (!result_type) {

View File

@ -496,7 +496,7 @@ class FunctionEmitter {
/// @param src_info the source block /// @param src_info the source block
/// @param dest_info the destination block /// @param dest_info the destination block
/// @returns the new statement, or a null statement /// @returns the new statement, or a null statement
std::unique_ptr<ast::Statement> MakeBranch(const BlockInfo& src_info, ast::Statement* MakeBranch(const BlockInfo& src_info,
const BlockInfo& dest_info) const { const BlockInfo& dest_info) const {
return MakeBranchDetailed(src_info, dest_info, false, nullptr); return MakeBranchDetailed(src_info, dest_info, false, nullptr);
} }
@ -507,8 +507,7 @@ class FunctionEmitter {
/// @param src_info the source block /// @param src_info the source block
/// @param dest_info the destination block /// @param dest_info the destination block
/// @returns the new statement, or a null statement /// @returns the new statement, or a null statement
std::unique_ptr<ast::Statement> MakeForcedBranch( ast::Statement* MakeForcedBranch(const BlockInfo& src_info,
const BlockInfo& src_info,
const BlockInfo& dest_info) const { const BlockInfo& dest_info) const {
return MakeBranchDetailed(src_info, dest_info, true, nullptr); return MakeBranchDetailed(src_info, dest_info, true, nullptr);
} }
@ -527,8 +526,7 @@ class FunctionEmitter {
/// @param forced if true, always emit the branch (if it exists in WGSL) /// @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 /// @param flow_guard_name_ptr return parameter for control flow guard name
/// @returns the new statement, or a null statement /// @returns the new statement, or a null statement
std::unique_ptr<ast::Statement> MakeBranchDetailed( ast::Statement* MakeBranchDetailed(const BlockInfo& src_info,
const BlockInfo& src_info,
const BlockInfo& dest_info, const BlockInfo& dest_info,
bool forced, bool forced,
std::string* flow_guard_name_ptr) const; std::string* flow_guard_name_ptr) const;
@ -540,10 +538,9 @@ class FunctionEmitter {
/// @param then_stmt the statement for the then clause of the if, or nullptr /// @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 /// @param else_stmt the statement for the else clause of the if, or nullptr
/// @returns the new statement, or nullptr /// @returns the new statement, or nullptr
std::unique_ptr<ast::Statement> MakeSimpleIf( ast::Statement* MakeSimpleIf(ast::Expression* condition,
std::unique_ptr<ast::Expression> condition, ast::Statement* then_stmt,
std::unique_ptr<ast::Statement> then_stmt, ast::Statement* else_stmt) const;
std::unique_ptr<ast::Statement> else_stmt) const;
/// Emits the statements for an normal-terminator OpBranchConditional /// Emits the statements for an normal-terminator OpBranchConditional
/// where one branch is a case fall through (the true branch if and only /// where one branch is a case fall through (the true branch if and only
@ -558,7 +555,7 @@ class FunctionEmitter {
/// branch /// branch
/// @returns the false if emission fails /// @returns the false if emission fails
bool EmitConditionalCaseFallThrough(const BlockInfo& src_info, bool EmitConditionalCaseFallThrough(const BlockInfo& src_info,
std::unique_ptr<ast::Expression> cond, ast::Expression* cond,
EdgeKind other_edge_kind, EdgeKind other_edge_kind,
const BlockInfo& other_dest, const BlockInfo& other_dest,
bool fall_through_is_true_branch); bool fall_through_is_true_branch);
@ -719,7 +716,7 @@ class FunctionEmitter {
/// Does nothing if the statement is null. /// Does nothing if the statement is null.
/// @param statement the new statement /// @param statement the new statement
/// @returns a pointer to the 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 /// Appends a new statement to the top of the statement stack, and attaches
/// source location information from the given instruction. Does nothing if /// source location information from the given instruction. Does nothing if
@ -727,7 +724,7 @@ class FunctionEmitter {
/// @param statement the new statement /// @param statement the new statement
/// @returns a pointer to the statement. /// @returns a pointer to the statement.
ast::Statement* AddStatementForInstruction( ast::Statement* AddStatementForInstruction(
std::unique_ptr<ast::Statement> statement, ast::Statement* statement,
const spvtools::opt::Instruction& inst); const spvtools::opt::Instruction& inst);
/// Sets the source information for the given instruction to the given /// Sets the source information for the given instruction to the given
@ -750,8 +747,8 @@ class FunctionEmitter {
StatementBlock(const Construct* construct, StatementBlock(const Construct* construct,
uint32_t end_id, uint32_t end_id,
CompletionAction completion_action, CompletionAction completion_action,
std::unique_ptr<ast::BlockStatement> statements, ast::BlockStatement* statements,
std::unique_ptr<ast::CaseStatementList> cases); ast::CaseStatementList* cases);
StatementBlock(StatementBlock&&); StatementBlock(StatementBlock&&);
~StatementBlock(); ~StatementBlock();
@ -767,12 +764,12 @@ class FunctionEmitter {
// Only one of |statements| or |cases| is active. // Only one of |statements| or |cases| is active.
// The list of statements being built, if this construct is not a switch. // 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 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 // 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 // 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. // 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. /// Pushes an empty statement block onto the statements stack.
@ -795,16 +792,19 @@ class FunctionEmitter {
void PushTrueGuard(uint32_t end_id); void PushTrueGuard(uint32_t end_id);
/// @returns a boolean true expression. /// @returns a boolean true expression.
std::unique_ptr<ast::Expression> MakeTrue() const; ast::Expression* MakeTrue() const;
/// @returns a boolean false expression. /// @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` /// Creates a new `ast::Node` owned by the Context. When the Context is
/// @param args the arguments to forward to the constructor for `T` /// 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> template <typename T, typename... ARGS>
std::unique_ptr<T> create(ARGS&&... args) const { T* create(ARGS&&... args) const {
return std::make_unique<T>(std::forward<ARGS>(args)...); auto& ctx = parser_impl_.context();
return ctx.create<T>(std::forward<ARGS>(args)...);
} }
ParserImpl& parser_impl_; ParserImpl& parser_impl_;

View File

@ -187,22 +187,6 @@ bool AssumesResultSignednessMatchesBinaryFirstOperand(SpvOp opcode) {
} // namespace } // 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) ParserImpl::ParserImpl(Context* ctx, const std::vector<uint32_t>& spv_binary)
: Reader(ctx), : Reader(ctx),
spv_binary_(spv_binary), spv_binary_(spv_binary),
@ -375,8 +359,8 @@ std::string ParserImpl::ShowType(uint32_t type_id) {
return "SPIR-V type " + std::to_string(type_id); return "SPIR-V type " + std::to_string(type_id);
} }
std::unique_ptr<ast::StructMemberDecoration> ast::StructMemberDecoration* ParserImpl::ConvertMemberDecoration(
ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id, uint32_t struct_type_id,
uint32_t member_index, uint32_t member_index,
const Decoration& decoration) { const Decoration& decoration) {
if (decoration.empty()) { if (decoration.empty()) {
@ -861,7 +845,7 @@ ast::type::Type* ParserImpl::ConvertType(
// the members are non-writable. // the members are non-writable.
is_non_writable = true; is_non_writable = true;
} else { } else {
auto ast_member_decoration = auto* ast_member_decoration =
ConvertMemberDecoration(type_id, member_index, decoration); ConvertMemberDecoration(type_id, member_index, decoration);
if (!success_) { if (!success_) {
return nullptr; return nullptr;
@ -877,13 +861,13 @@ ast::type::Type* ParserImpl::ConvertType(
++num_non_writable_members; ++num_non_writable_members;
} }
const auto member_name = namer_.GetMemberName(type_id, member_index); const auto member_name = namer_.GetMemberName(type_id, member_index);
auto ast_struct_member = create<ast::StructMember>( auto* ast_struct_member = create<ast::StructMember>(
member_name, ast_member_ty, std::move(ast_member_decorations)); member_name, ast_member_ty, std::move(ast_member_decorations));
ast_members.push_back(std::move(ast_struct_member)); ast_members.push_back(std::move(ast_struct_member));
} }
// Now make the struct. // Now make the struct.
auto ast_struct = create<ast::Struct>(std::move(ast_struct_decorations), auto* ast_struct = create<ast::Struct>(std::move(ast_struct_decorations),
std::move(ast_members)); std::move(ast_members));
namer_.SuggestSanitizedName(type_id, "S"); namer_.SuggestSanitizedName(type_id, "S");
@ -963,7 +947,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
for (auto& inst : module_->types_values()) { for (auto& inst : module_->types_values()) {
// These will be populated for a valid scalar spec constant. // These will be populated for a valid scalar spec constant.
ast::type::Type* ast_type = nullptr; ast::type::Type* ast_type = nullptr;
std::unique_ptr<ast::ScalarConstructorExpression> ast_expr; ast::ScalarConstructorExpression* ast_expr = nullptr;
switch (inst.opcode()) { switch (inst.opcode()) {
case SpvOpSpecConstantTrue: case SpvOpSpecConstantTrue:
@ -1001,12 +985,12 @@ bool ParserImpl::EmitScalarSpecConstants() {
break; break;
} }
if (ast_type && ast_expr) { if (ast_type && ast_expr) {
auto ast_var = auto* ast_var =
MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type); MakeVariable(inst.result_id(), ast::StorageClass::kNone, ast_type);
ast::VariableDecorationList spec_id_decos; ast::VariableDecorationList spec_id_decos;
for (const auto& deco : GetDecorationsFor(inst.result_id())) { for (const auto& deco : GetDecorationsFor(inst.result_id())) {
if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) { if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
auto cid = create<ast::ConstantIdDecoration>(deco[1], Source{}); auto* cid = create<ast::ConstantIdDecoration>(deco[1], Source{});
spec_id_decos.push_back(std::move(cid)); spec_id_decos.push_back(std::move(cid));
break; break;
} }
@ -1017,7 +1001,7 @@ bool ParserImpl::EmitScalarSpecConstants() {
ast_var->set_constructor(std::move(ast_expr)); ast_var->set_constructor(std::move(ast_expr));
ast_module_.AddGlobalVariable(std::move(ast_var)); ast_module_.AddGlobalVariable(std::move(ast_var));
} else { } else {
auto ast_deco_var = 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_is_const(true);
ast_deco_var->set_constructor(std::move(ast_expr)); ast_deco_var->set_constructor(std::move(ast_expr));
ast_deco_var->set_decorations(std::move(spec_id_decos)); ast_deco_var->set_decorations(std::move(spec_id_decos));
@ -1118,7 +1102,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
} }
auto* ast_store_type = ast_type->AsPointer()->type(); auto* ast_store_type = ast_type->AsPointer()->type();
auto ast_storage_class = ast_type->AsPointer()->storage_class(); 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); MakeVariable(var.result_id(), ast_storage_class, ast_store_type);
if (var.NumInOperands() > 1) { if (var.NumInOperands() > 1) {
// SPIR-V initializers are always constants. // SPIR-V initializers are always constants.
@ -1136,7 +1120,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
// Make sure the variable has a name. // Make sure the variable has a name.
namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id, namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id,
"gl_Position"); "gl_Position");
auto var = create<ast::DecoratedVariable>(MakeVariable( auto* var = create<ast::DecoratedVariable>(MakeVariable(
builtin_position_.per_vertex_var_id, builtin_position_.per_vertex_var_id,
enum_converter_.ToStorageClass(builtin_position_.storage_class), enum_converter_.ToStorageClass(builtin_position_.storage_class),
ConvertType(builtin_position_.member_type_id))); ConvertType(builtin_position_.member_type_id)));
@ -1150,7 +1134,7 @@ bool ParserImpl::EmitModuleScopeVariables() {
return success_; return success_;
} }
std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id, ast::Variable* ParserImpl::MakeVariable(uint32_t id,
ast::StorageClass sc, ast::StorageClass sc,
ast::type::Type* type) { ast::type::Type* type) {
if (type == nullptr) { if (type == nullptr) {
@ -1167,7 +1151,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
std::make_unique<ast::type::AccessControlType>(access, type)); std::make_unique<ast::type::AccessControlType>(access, type));
} }
auto ast_var = create<ast::Variable>(namer_.Name(id), sc, type); auto* ast_var = create<ast::Variable>(namer_.Name(id), sc, type);
ast::VariableDecorationList ast_decorations; ast::VariableDecorationList ast_decorations;
for (auto& deco : GetDecorationsFor(id)) { for (auto& deco : GetDecorationsFor(id)) {
@ -1218,7 +1202,7 @@ std::unique_ptr<ast::Variable> ParserImpl::MakeVariable(uint32_t id,
} }
} }
if (!ast_decorations.empty()) { 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)); decorated_var->set_decorations(std::move(ast_decorations));
ast_var = std::move(decorated_var); ast_var = std::move(decorated_var);
} }
@ -1315,8 +1299,7 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
return {}; return {};
} }
std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue( ast::Expression* ParserImpl::MakeNullValue(ast::type::Type* type) {
ast::type::Type* type) {
// TODO(dneto): Use the no-operands constructor syntax when it becomes // TODO(dneto): Use the no-operands constructor syntax when it becomes
// available in Tint. // available in Tint.
// https://github.com/gpuweb/gpuweb/issues/685 // https://github.com/gpuweb/gpuweb/issues/685
@ -1380,7 +1363,7 @@ std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
if (type->IsStruct()) { if (type->IsStruct()) {
auto* struct_ty = type->AsStruct(); auto* struct_ty = type->AsStruct();
ast::ExpressionList ast_components; 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())); ast_components.emplace_back(MakeNullValue(member->type()));
} }
return create<ast::TypeConstructorExpression>(original_type, return create<ast::TypeConstructorExpression>(original_type,

View File

@ -56,24 +56,10 @@ using DecorationList = std::vector<Decoration>;
/// An AST expression with its type. /// An AST expression with its type.
struct TypedExpression { 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 /// The type
ast::type::Type* type; ast::type::Type* type = nullptr;
/// The expression /// The expression
std::unique_ptr<ast::Expression> expr; ast::Expression* expr = nullptr;
}; };
/// Parser implementation for SPIR-V. /// Parser implementation for SPIR-V.
@ -187,7 +173,7 @@ class ParserImpl : Reader {
/// @param member_index the index of the member /// @param member_index the index of the member
/// @param decoration an encoded SPIR-V Decoration /// @param decoration an encoded SPIR-V Decoration
/// @returns the corresponding ast::StructuMemberDecoration /// @returns the corresponding ast::StructuMemberDecoration
std::unique_ptr<ast::StructMemberDecoration> ConvertMemberDecoration( ast::StructMemberDecoration* ConvertMemberDecoration(
uint32_t struct_type_id, uint32_t struct_type_id,
uint32_t member_index, uint32_t member_index,
const Decoration& decoration); const Decoration& decoration);
@ -274,7 +260,7 @@ class ParserImpl : Reader {
/// @param sc the storage class, which cannot be ast::StorageClass::kNone /// @param sc the storage class, which cannot be ast::StorageClass::kNone
/// @param type the type /// @param type the type
/// @returns a new Variable node, or null in the error case /// @returns a new Variable node, or null in the error case
std::unique_ptr<ast::Variable> MakeVariable(uint32_t id, ast::Variable* MakeVariable(uint32_t id,
ast::StorageClass sc, ast::StorageClass sc,
ast::type::Type* type); ast::type::Type* type);
@ -286,7 +272,7 @@ class ParserImpl : Reader {
/// Creates an AST expression node for the null value for the given type. /// Creates an AST expression node for the null value for the given type.
/// @param type the AST type /// @param type the AST type
/// @returns a new expression /// @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 /// Converts a given expression to the signedness demanded for an operand
/// of the given SPIR-V opcode, if required. If the operation assumes /// 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, bool ApplyArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
ast::type::ArrayType* ast_type); ast::type::ArrayType* ast_type);
/// @return a `std::unique_ptr` to a new `T` constructed with `args`
/// @param args the arguments to forward to the constructor for `T`
template <typename T, typename... ARGS>
std::unique_ptr<T> create(ARGS&&... args) const {
return std::make_unique<T>(std::forward<ARGS>(args)...);
}
// The SPIR-V binary we're parsing // The SPIR-V binary we're parsing
std::vector<uint32_t> spv_binary_; std::vector<uint32_t> spv_binary_;

View File

@ -34,16 +34,16 @@ using ::testing::Eq;
TEST_F(SpvParserTest, ConvertMemberDecoration_Empty) { TEST_F(SpvParserTest, ConvertMemberDecoration_Empty) {
auto* p = parser(std::vector<uint32_t>{}); auto* p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(1, 1, {}); auto* result = p->ConvertMemberDecoration(1, 1, {});
EXPECT_EQ(result.get(), nullptr); EXPECT_EQ(result, nullptr);
EXPECT_THAT(p->error(), Eq("malformed SPIR-V decoration: it's empty")); EXPECT_THAT(p->error(), Eq("malformed SPIR-V decoration: it's empty"));
} }
TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) { TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
auto* p = parser(std::vector<uint32_t>{}); auto* p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset}); auto* result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset});
EXPECT_EQ(result.get(), nullptr); EXPECT_EQ(result, nullptr);
EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal " EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
"operand, has 0: member 13 of SPIR-V type 12")); "operand, has 0: member 13 of SPIR-V type 12"));
} }
@ -51,8 +51,9 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) { TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
auto* p = parser(std::vector<uint32_t>{}); auto* p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset, 3, 4}); auto* result =
EXPECT_EQ(result.get(), nullptr); p->ConvertMemberDecoration(12, 13, {SpvDecorationOffset, 3, 4});
EXPECT_EQ(result, nullptr);
EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal " EXPECT_THAT(p->error(), Eq("malformed Offset decoration: expected 1 literal "
"operand, has 2: member 13 of SPIR-V type 12")); "operand, has 2: member 13 of SPIR-V type 12"));
} }
@ -60,8 +61,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) { TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
auto* p = parser(std::vector<uint32_t>{}); auto* p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(1, 1, {SpvDecorationOffset, 8}); auto* result = p->ConvertMemberDecoration(1, 1, {SpvDecorationOffset, 8});
ASSERT_NE(result.get(), nullptr); ASSERT_NE(result, nullptr);
EXPECT_TRUE(result->IsOffset()); EXPECT_TRUE(result->IsOffset());
auto* offset_deco = result->AsOffset(); auto* offset_deco = result->AsOffset();
ASSERT_NE(offset_deco, nullptr); ASSERT_NE(offset_deco, nullptr);
@ -72,8 +73,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
TEST_F(SpvParserTest, ConvertMemberDecoration_UnhandledDecoration) { TEST_F(SpvParserTest, ConvertMemberDecoration_UnhandledDecoration) {
auto* p = parser(std::vector<uint32_t>{}); auto* p = parser(std::vector<uint32_t>{});
auto result = p->ConvertMemberDecoration(12, 13, {12345678}); auto* result = p->ConvertMemberDecoration(12, 13, {12345678});
EXPECT_EQ(result.get(), nullptr); EXPECT_EQ(result, nullptr);
EXPECT_THAT(p->error(), Eq("unhandled member decoration: 12345678 on member " EXPECT_THAT(p->error(), Eq("unhandled member decoration: 12345678 on member "
"13 of SPIR-V type 12")); "13 of SPIR-V type 12"));
} }

View File

@ -72,7 +72,7 @@ using SpvParserTest = SpvParserTestBase<::testing::Test>;
/// @returnss the string dump of a function body. /// @returnss the string dump of a function body.
inline std::string ToString(const ast::BlockStatement* body) { inline std::string ToString(const ast::BlockStatement* body) {
std::ostringstream outs; std::ostringstream outs;
for (const auto& stmt : *body) { for (const auto* stmt : *body) {
stmt->to_str(outs, 0); stmt->to_str(outs, 0);
} }
return outs.str(); return outs.str();

View File

@ -340,7 +340,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
// global_variable_decl // global_variable_decl
// : variable_decoration_list* variable_decl // : variable_decoration_list* variable_decl
// | variable_decoration_list* variable_decl EQUAL const_expr // | 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) { ast::DecorationList& decos) {
auto decl = variable_decl(); auto decl = variable_decl();
if (decl.errored) if (decl.errored)
@ -348,14 +348,14 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_variable_decl(
if (!decl.matched) if (!decl.matched)
return Failure::kNoMatch; return Failure::kNoMatch;
auto var = std::move(decl.value); auto* var = std::move(decl.value);
auto var_decos = cast_decorations<ast::VariableDecoration>(decos); auto var_decos = cast_decorations<ast::VariableDecoration>(decos);
if (var_decos.errored) if (var_decos.errored)
return Failure::kErrored; return Failure::kErrored;
if (var_decos.value.size() > 0) { 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)); dv->set_decorations(std::move(var_decos.value));
var = std::move(dv); var = std::move(dv);
} }
@ -371,7 +371,7 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_variable_decl(
// global_constant_decl // global_constant_decl
// : CONST variable_ident_decl EQUAL const_expr // : 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)) if (!match(Token::Type::kConst))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -381,7 +381,7 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_constant_decl() {
if (decl.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
auto var = create<ast::Variable>(decl->source, decl->name, auto* var = create<ast::Variable>(decl->source, decl->name,
ast::StorageClass::kNone, decl->type); ast::StorageClass::kNone, decl->type);
var->set_is_const(true); var->set_is_const(true);
@ -399,7 +399,7 @@ Maybe<std::unique_ptr<ast::Variable>> ParserImpl::global_constant_decl() {
// variable_decl // variable_decl
// : VAR variable_storage_decoration? variable_ident_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)) if (!match(Token::Type::kVar))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1100,9 +1100,8 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
ast::StructMemberList members; ast::StructMemberList members;
while (synchronized_ && !peek().IsBraceRight() && !peek().IsEof()) { while (synchronized_ && !peek().IsBraceRight() && !peek().IsEof()) {
auto member = auto member = sync(Token::Type::kSemicolon,
sync(Token::Type::kSemicolon, [&]() -> Expect<ast::StructMember*> {
[&]() -> Expect<std::unique_ptr<ast::StructMember>> {
auto decos = decoration_list(); auto decos = decoration_list();
if (decos.errored) if (decos.errored)
errored = true; errored = true;
@ -1127,7 +1126,7 @@ Expect<ast::StructMemberList> ParserImpl::expect_struct_body_decl() {
// struct_member // struct_member
// : struct_member_decoration_decl+ variable_ident_decl SEMICOLON // : 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) { ast::DecorationList& decos) {
auto decl = expect_variable_ident_decl("struct member"); auto decl = expect_variable_ident_decl("struct member");
if (decl.errored) if (decl.errored)
@ -1146,8 +1145,7 @@ Expect<std::unique_ptr<ast::StructMember>> ParserImpl::expect_struct_member(
// function_decl // function_decl
// : function_header body_stmt // : function_header body_stmt
Maybe<std::unique_ptr<ast::Function>> ParserImpl::function_decl( Maybe<ast::Function*> ParserImpl::function_decl(ast::DecorationList& decos) {
ast::DecorationList& decos) {
auto f = function_header(); auto f = function_header();
if (f.errored) { if (f.errored) {
if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) { if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
@ -1195,7 +1193,7 @@ Maybe<ast::type::Type*> ParserImpl::function_type_decl() {
// function_header // function_header
// : FN IDENT PAREN_LEFT param_list PAREN_RIGHT ARROW function_type_decl // : 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; Source source;
if (!match(Token::Type::kFn, &source)) if (!match(Token::Type::kFn, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1247,7 +1245,7 @@ Expect<ast::VariableList> ParserImpl::expect_param_list() {
ast::VariableList ret; ast::VariableList ret;
for (;;) { for (;;) {
auto var = create<ast::Variable>(decl->source, decl->name, auto* var = create<ast::Variable>(decl->source, decl->name,
ast::StorageClass::kNone, decl->type); ast::StorageClass::kNone, decl->type);
// Formal parameters are treated like a const declaration where the // Formal parameters are treated like a const declaration where the
// initializer value is provided by the call's argument. The key point is // initializer value is provided by the call's argument. The key point is
@ -1299,15 +1297,14 @@ Expect<ast::Builtin> ParserImpl::expect_builtin() {
// body_stmt // body_stmt
// : BRACKET_LEFT statements BRACKET_RIGHT // : 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(); }); return expect_brace_block("", [&] { return expect_statements(); });
} }
// paren_rhs_stmt // paren_rhs_stmt
// : PAREN_LEFT logical_or_expression PAREN_RIGHT // : PAREN_LEFT logical_or_expression PAREN_RIGHT
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_paren_rhs_stmt() { Expect<ast::Expression*> ParserImpl::expect_paren_rhs_stmt() {
return expect_paren_block( return expect_paren_block("", [&]() -> Expect<ast::Expression*> {
"", [&]() -> Expect<std::unique_ptr<ast::Expression>> {
auto expr = logical_or_expression(); auto expr = logical_or_expression();
if (expr.errored) if (expr.errored)
return Failure::kErrored; return Failure::kErrored;
@ -1320,9 +1317,9 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_paren_rhs_stmt() {
// statements // statements
// : statement* // : statement*
Expect<std::unique_ptr<ast::BlockStatement>> ParserImpl::expect_statements() { Expect<ast::BlockStatement*> ParserImpl::expect_statements() {
bool errored = false; bool errored = false;
auto ret = create<ast::BlockStatement>(); auto* ret = create<ast::BlockStatement>();
while (synchronized_) { while (synchronized_) {
auto stmt = statement(); auto stmt = statement();
@ -1356,7 +1353,7 @@ Expect<std::unique_ptr<ast::BlockStatement>> ParserImpl::expect_statements() {
// | continue_stmt SEMICOLON // | continue_stmt SEMICOLON
// | DISCARD SEMICOLON // | DISCARD SEMICOLON
// | assignment_stmt SEMICOLON // | assignment_stmt SEMICOLON
Maybe<std::unique_ptr<ast::Statement>> ParserImpl::statement() { Maybe<ast::Statement*> ParserImpl::statement() {
while (match(Token::Type::kSemicolon)) { while (match(Token::Type::kSemicolon)) {
// Skip empty statements // Skip empty statements
} }
@ -1412,8 +1409,8 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::statement() {
// | continue_stmt SEMICOLON // | continue_stmt SEMICOLON
// | DISCARD SEMICOLON // | DISCARD SEMICOLON
// | assignment_stmt SEMICOLON // | assignment_stmt SEMICOLON
Maybe<std::unique_ptr<ast::Statement>> ParserImpl::non_block_statement() { Maybe<ast::Statement*> ParserImpl::non_block_statement() {
auto stmt = [&]() -> Maybe<std::unique_ptr<ast::Statement>> { auto stmt = [&]() -> Maybe<ast::Statement*> {
auto ret_stmt = return_stmt(); auto ret_stmt = return_stmt();
if (ret_stmt.errored) if (ret_stmt.errored)
return Failure::kErrored; return Failure::kErrored;
@ -1465,7 +1462,7 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::non_block_statement() {
// return_stmt // return_stmt
// : RETURN logical_or_expression? // : RETURN logical_or_expression?
Maybe<std::unique_ptr<ast::ReturnStatement>> ParserImpl::return_stmt() { Maybe<ast::ReturnStatement*> ParserImpl::return_stmt() {
Source source; Source source;
if (!match(Token::Type::kReturn, &source)) if (!match(Token::Type::kReturn, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1485,7 +1482,7 @@ Maybe<std::unique_ptr<ast::ReturnStatement>> ParserImpl::return_stmt() {
// : variable_decl // : variable_decl
// | variable_decl EQUAL logical_or_expression // | variable_decl EQUAL logical_or_expression
// | CONST variable_ident_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)) { if (match(Token::Type::kConst)) {
auto decl = expect_variable_ident_decl("constant declaration"); auto decl = expect_variable_ident_decl("constant declaration");
if (decl.errored) if (decl.errored)
@ -1500,7 +1497,7 @@ Maybe<std::unique_ptr<ast::VariableDeclStatement>> ParserImpl::variable_stmt() {
if (!constructor.matched) if (!constructor.matched)
return add_error(peek(), "missing constructor for const declaration"); return add_error(peek(), "missing constructor for const declaration");
auto var = create<ast::Variable>(decl->source, decl->name, auto* var = create<ast::Variable>(decl->source, decl->name,
ast::StorageClass::kNone, decl->type); ast::StorageClass::kNone, decl->type);
var->set_is_const(true); var->set_is_const(true);
var->set_constructor(std::move(constructor.value)); var->set_constructor(std::move(constructor.value));
@ -1530,7 +1527,7 @@ Maybe<std::unique_ptr<ast::VariableDeclStatement>> ParserImpl::variable_stmt() {
// if_stmt // if_stmt
// : IF paren_rhs_stmt body_stmt elseif_stmt? else_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; Source source;
if (!match(Token::Type::kIf, &source)) if (!match(Token::Type::kIf, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1551,7 +1548,7 @@ Maybe<std::unique_ptr<ast::IfStatement>> ParserImpl::if_stmt() {
if (el.errored) if (el.errored)
return Failure::kErrored; return Failure::kErrored;
auto stmt = create<ast::IfStatement>(source, std::move(condition.value), auto* stmt = create<ast::IfStatement>(source, std::move(condition.value),
std::move(body.value)); std::move(body.value));
if (el.matched) { if (el.matched) {
elseif.value.push_back(std::move(el.value)); elseif.value.push_back(std::move(el.value));
@ -1590,7 +1587,7 @@ Maybe<ast::ElseStatementList> ParserImpl::elseif_stmt() {
// else_stmt // else_stmt
// : ELSE body_stmt // : ELSE body_stmt
Maybe<std::unique_ptr<ast::ElseStatement>> ParserImpl::else_stmt() { Maybe<ast::ElseStatement*> ParserImpl::else_stmt() {
Source source; Source source;
if (!match(Token::Type::kElse, &source)) if (!match(Token::Type::kElse, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1604,7 +1601,7 @@ Maybe<std::unique_ptr<ast::ElseStatement>> ParserImpl::else_stmt() {
// switch_stmt // switch_stmt
// : SWITCH paren_rhs_stmt BRACKET_LEFT switch_body+ BRACKET_RIGHT // : 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; Source source;
if (!match(Token::Type::kSwitch, &source)) if (!match(Token::Type::kSwitch, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1642,7 +1639,7 @@ Maybe<std::unique_ptr<ast::SwitchStatement>> ParserImpl::switch_stmt() {
// switch_body // switch_body
// : CASE case_selectors COLON BRACKET_LEFT case_body BRACKET_RIGHT // : CASE case_selectors COLON BRACKET_LEFT case_body BRACKET_RIGHT
// | DEFAULT 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(); auto t = peek();
if (!t.IsCase() && !t.IsDefault()) if (!t.IsCase() && !t.IsDefault())
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1650,7 +1647,7 @@ Maybe<std::unique_ptr<ast::CaseStatement>> ParserImpl::switch_body() {
auto source = t.source(); auto source = t.source();
next(); // Consume the peek next(); // Consume the peek
auto stmt = create<ast::CaseStatement>(create<ast::BlockStatement>()); auto* stmt = create<ast::CaseStatement>(create<ast::BlockStatement>());
stmt->set_source(source); stmt->set_source(source);
if (t.IsCase()) { if (t.IsCase()) {
auto selectors = expect_case_selectors(); auto selectors = expect_case_selectors();
@ -1692,8 +1689,7 @@ Expect<ast::CaseSelectorList> ParserImpl::expect_case_selectors() {
if (!cond->IsInt()) if (!cond->IsInt())
return add_error(t, "invalid case selector must be an integer value"); 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(cond.value->AsInt());
selectors.push_back(std::move(selector));
} }
if (selectors.empty()) if (selectors.empty())
@ -1706,8 +1702,8 @@ Expect<ast::CaseSelectorList> ParserImpl::expect_case_selectors() {
// : // :
// | statement case_body // | statement case_body
// | FALLTHROUGH SEMICOLON // | FALLTHROUGH SEMICOLON
Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::case_body() { Maybe<ast::BlockStatement*> ParserImpl::case_body() {
auto ret = create<ast::BlockStatement>(); auto* ret = create<ast::BlockStatement>();
for (;;) { for (;;) {
Source source; Source source;
if (match(Token::Type::kFallthrough, &source)) { if (match(Token::Type::kFallthrough, &source)) {
@ -1732,13 +1728,12 @@ Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::case_body() {
// loop_stmt // loop_stmt
// : LOOP BRACKET_LEFT statements continuing_stmt? BRACKET_RIGHT // : 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; Source source;
if (!match(Token::Type::kLoop, &source)) if (!match(Token::Type::kLoop, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
return expect_brace_block( return expect_brace_block("loop", [&]() -> Maybe<ast::LoopStatement*> {
"loop", [&]() -> Maybe<std::unique_ptr<ast::LoopStatement>> {
auto body = expect_statements(); auto body = expect_statements();
if (body.errored) if (body.errored)
return Failure::kErrored; return Failure::kErrored;
@ -1752,9 +1747,9 @@ Maybe<std::unique_ptr<ast::LoopStatement>> ParserImpl::loop_stmt() {
}); });
} }
ForHeader::ForHeader(std::unique_ptr<ast::Statement> init, ForHeader::ForHeader(ast::Statement* init,
std::unique_ptr<ast::Expression> cond, ast::Expression* cond,
std::unique_ptr<ast::Statement> cont) ast::Statement* cont)
: initializer(std::move(init)), : initializer(std::move(init)),
condition(std::move(cond)), condition(std::move(cond)),
continuing(std::move(cont)) {} continuing(std::move(cont)) {}
@ -1762,7 +1757,7 @@ ForHeader::ForHeader(std::unique_ptr<ast::Statement> init,
ForHeader::~ForHeader() = default; ForHeader::~ForHeader() = default;
// (variable_stmt | assignment_stmt | func_call_stmt)? // (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(); auto call = func_call_stmt();
if (call.errored) if (call.errored)
return Failure::kErrored; return Failure::kErrored;
@ -1785,7 +1780,7 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_header_initializer() {
} }
// (assignment_stmt | func_call_stmt)? // (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(); auto call_stmt = func_call_stmt();
if (call_stmt.errored) if (call_stmt.errored)
return Failure::kErrored; return Failure::kErrored;
@ -1825,14 +1820,14 @@ Expect<std::unique_ptr<ForHeader>> ParserImpl::expect_for_header() {
if (continuing.errored) if (continuing.errored)
return Failure::kErrored; return Failure::kErrored;
return create<ForHeader>(std::move(initializer.value), return std::make_unique<ForHeader>(std::move(initializer.value),
std::move(condition.value), std::move(condition.value),
std::move(continuing.value)); std::move(continuing.value));
} }
// for_statement // for_statement
// : FOR PAREN_LEFT for_header PAREN_RIGHT BRACE_LEFT statements BRACE_RIGHT // : 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; Source source;
if (!match(Token::Type::kFor, &source)) if (!match(Token::Type::kFor, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1852,31 +1847,31 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_stmt() {
// as we would expect from the loop statement. // as we would expect from the loop statement.
if (header->condition != nullptr) { if (header->condition != nullptr) {
// !condition // !condition
auto not_condition = create<ast::UnaryOpExpression>( auto* not_condition = create<ast::UnaryOpExpression>(
header->condition->source(), ast::UnaryOp::kNot, header->condition->source(), ast::UnaryOp::kNot,
std::move(header->condition)); std::move(header->condition));
// { break; } // { break; }
auto break_stmt = create<ast::BreakStatement>(not_condition->source()); auto* break_stmt = create<ast::BreakStatement>(not_condition->source());
auto break_body = create<ast::BlockStatement>(not_condition->source()); auto* break_body = create<ast::BlockStatement>(not_condition->source());
break_body->append(std::move(break_stmt)); break_body->append(std::move(break_stmt));
// if (!condition) { break; } // 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), not_condition->source(), std::move(not_condition),
std::move(break_body)); std::move(break_body));
body->insert(0, std::move(break_if_not_condition)); 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) { if (header->continuing != nullptr) {
continuing_body = create<ast::BlockStatement>(header->continuing->source()); continuing_body = create<ast::BlockStatement>(header->continuing->source());
continuing_body->append(std::move(header->continuing)); continuing_body->append(std::move(header->continuing));
} }
auto loop = create<ast::LoopStatement>(source, std::move(body.value), auto* loop = create<ast::LoopStatement>(source, std::move(body.value),
std::move(continuing_body)); std::move(continuing_body));
if (header->initializer != nullptr) { 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(header->initializer));
result->append(std::move(loop)); result->append(std::move(loop));
return result; return result;
@ -1887,7 +1882,7 @@ Maybe<std::unique_ptr<ast::Statement>> ParserImpl::for_stmt() {
// func_call_stmt // func_call_stmt
// : IDENT PAREN_LEFT argument_expression_list* PAREN_RIGHT // : 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 t = peek();
auto t2 = peek(1); auto t2 = peek(1);
if (!t.IsIdentifier() || !t2.IsParenLeft()) if (!t.IsIdentifier() || !t2.IsParenLeft())
@ -1919,7 +1914,7 @@ Maybe<std::unique_ptr<ast::CallStatement>> ParserImpl::func_call_stmt() {
// break_stmt // break_stmt
// : BREAK // : BREAK
Maybe<std::unique_ptr<ast::BreakStatement>> ParserImpl::break_stmt() { Maybe<ast::BreakStatement*> ParserImpl::break_stmt() {
Source source; Source source;
if (!match(Token::Type::kBreak, &source)) if (!match(Token::Type::kBreak, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1929,7 +1924,7 @@ Maybe<std::unique_ptr<ast::BreakStatement>> ParserImpl::break_stmt() {
// continue_stmt // continue_stmt
// : CONTINUE // : CONTINUE
Maybe<std::unique_ptr<ast::ContinueStatement>> ParserImpl::continue_stmt() { Maybe<ast::ContinueStatement*> ParserImpl::continue_stmt() {
Source source; Source source;
if (!match(Token::Type::kContinue, &source)) if (!match(Token::Type::kContinue, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
@ -1939,7 +1934,7 @@ Maybe<std::unique_ptr<ast::ContinueStatement>> ParserImpl::continue_stmt() {
// continuing_stmt // continuing_stmt
// : CONTINUING body_stmt // : CONTINUING body_stmt
Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::continuing_stmt() { Maybe<ast::BlockStatement*> ParserImpl::continuing_stmt() {
if (!match(Token::Type::kContinuing)) if (!match(Token::Type::kContinuing))
return create<ast::BlockStatement>(); return create<ast::BlockStatement>();
@ -1952,7 +1947,7 @@ Maybe<std::unique_ptr<ast::BlockStatement>> ParserImpl::continuing_stmt() {
// | const_literal // | const_literal
// | paren_rhs_stmt // | paren_rhs_stmt
// | BITCAST LESS_THAN type_decl GREATER_THAN 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 t = peek();
auto source = t.source(); auto source = t.source();
@ -1994,8 +1989,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::primary_expression() {
return Failure::kErrored; return Failure::kErrored;
if (type.matched) { if (type.matched) {
auto expr = expect_paren_block( auto expr = expect_paren_block(
"type constructor", "type constructor", [&]() -> Expect<ast::TypeConstructorExpression*> {
[&]() -> Expect<std::unique_ptr<ast::TypeConstructorExpression>> {
t = peek(); t = peek();
if (t.IsParenRight() || t.IsEof()) if (t.IsParenRight() || t.IsEof())
return create<ast::TypeConstructorExpression>( 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 // | BRACE_LEFT logical_or_expression BRACE_RIGHT postfix_expr
// | PAREN_LEFT argument_expression_list* PAREN_RIGHT postfix_expr // | PAREN_LEFT argument_expression_list* PAREN_RIGHT postfix_expr
// | PERIOD IDENTIFIER postfix_expr // | PERIOD IDENTIFIER postfix_expr
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expr( Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
std::unique_ptr<ast::Expression> prefix) {
Source source; Source source;
if (match(Token::Type::kBracketLeft, &source)) { if (match(Token::Type::kBracketLeft, &source)) {
auto param = logical_or_expression(); auto param = logical_or_expression();
@ -2073,7 +2066,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expr(
// postfix_expression // postfix_expression
// : primary_expression postfix_expr // : primary_expression postfix_expr
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::postfix_expression() { Maybe<ast::Expression*> ParserImpl::postfix_expression() {
auto prefix = primary_expression(); auto prefix = primary_expression();
if (prefix.errored) if (prefix.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2112,7 +2105,7 @@ Expect<ast::ExpressionList> ParserImpl::expect_argument_expression_list() {
// : postfix_expression // : postfix_expression
// | MINUS unary_expression // | MINUS unary_expression
// | BANG unary_expression // | BANG unary_expression
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::unary_expression() { Maybe<ast::Expression*> ParserImpl::unary_expression() {
auto t = peek(); auto t = peek();
auto source = t.source(); auto source = t.source();
if (t.IsMinus() || t.IsBang()) { if (t.IsMinus() || t.IsBang()) {
@ -2141,8 +2134,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::unary_expression() {
// | STAR unary_expression multiplicative_expr // | STAR unary_expression multiplicative_expr
// | FORWARD_SLASH unary_expression multiplicative_expr // | FORWARD_SLASH unary_expression multiplicative_expr
// | MODULO unary_expression multiplicative_expr // | MODULO unary_expression multiplicative_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_multiplicative_expr( Expect<ast::Expression*> ParserImpl::expect_multiplicative_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
auto t = peek(); auto t = peek();
ast::BinaryOp op = ast::BinaryOp::kNone; ast::BinaryOp op = ast::BinaryOp::kNone;
@ -2173,8 +2166,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_multiplicative_expr(
// multiplicative_expression // multiplicative_expression
// : unary_expression multiplicative_expr // : unary_expression multiplicative_expr
Maybe<std::unique_ptr<ast::Expression>> Maybe<ast::Expression*> ParserImpl::multiplicative_expression() {
ParserImpl::multiplicative_expression() {
auto lhs = unary_expression(); auto lhs = unary_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2188,8 +2180,8 @@ ParserImpl::multiplicative_expression() {
// : // :
// | PLUS multiplicative_expression additive_expr // | PLUS multiplicative_expression additive_expr
// | MINUS multiplicative_expression additive_expr // | MINUS multiplicative_expression additive_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_additive_expr( Expect<ast::Expression*> ParserImpl::expect_additive_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
auto t = peek(); auto t = peek();
ast::BinaryOp op = ast::BinaryOp::kNone; ast::BinaryOp op = ast::BinaryOp::kNone;
@ -2215,7 +2207,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_additive_expr(
// additive_expression // additive_expression
// : multiplicative_expression additive_expr // : multiplicative_expression additive_expr
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::additive_expression() { Maybe<ast::Expression*> ParserImpl::additive_expression() {
auto lhs = multiplicative_expression(); auto lhs = multiplicative_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2229,8 +2221,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::additive_expression() {
// : // :
// | LESS_THAN LESS_THAN additive_expression shift_expr // | LESS_THAN LESS_THAN additive_expression shift_expr
// | GREATER_THAN GREATER_THAN additive_expression shift_expr // | GREATER_THAN GREATER_THAN additive_expression shift_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_shift_expr( Expect<ast::Expression*> ParserImpl::expect_shift_expr(ast::Expression* lhs) {
std::unique_ptr<ast::Expression> lhs) {
auto t = peek(); auto t = peek();
auto source = t.source(); auto source = t.source();
auto t2 = peek(1); auto t2 = peek(1);
@ -2264,7 +2255,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_shift_expr(
// shift_expression // shift_expression
// : additive_expression shift_expr // : additive_expression shift_expr
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::shift_expression() { Maybe<ast::Expression*> ParserImpl::shift_expression() {
auto lhs = additive_expression(); auto lhs = additive_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2280,8 +2271,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::shift_expression() {
// | GREATER_THAN shift_expression relational_expr // | GREATER_THAN shift_expression relational_expr
// | LESS_THAN_EQUAL shift_expression relational_expr // | LESS_THAN_EQUAL shift_expression relational_expr
// | GREATER_THAN_EQUAL shift_expression relational_expr // | GREATER_THAN_EQUAL shift_expression relational_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_relational_expr( Expect<ast::Expression*> ParserImpl::expect_relational_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
auto t = peek(); auto t = peek();
ast::BinaryOp op = ast::BinaryOp::kNone; ast::BinaryOp op = ast::BinaryOp::kNone;
if (t.IsLessThan()) if (t.IsLessThan())
@ -2313,7 +2304,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_relational_expr(
// relational_expression // relational_expression
// : shift_expression relational_expr // : shift_expression relational_expr
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::relational_expression() { Maybe<ast::Expression*> ParserImpl::relational_expression() {
auto lhs = shift_expression(); auto lhs = shift_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2327,8 +2318,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::relational_expression() {
// : // :
// | EQUAL_EQUAL relational_expression equality_expr // | EQUAL_EQUAL relational_expression equality_expr
// | NOT_EQUAL relational_expression equality_expr // | NOT_EQUAL relational_expression equality_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_equality_expr( Expect<ast::Expression*> ParserImpl::expect_equality_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
auto t = peek(); auto t = peek();
ast::BinaryOp op = ast::BinaryOp::kNone; ast::BinaryOp op = ast::BinaryOp::kNone;
if (t.IsEqualEqual()) if (t.IsEqualEqual())
@ -2356,7 +2347,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_equality_expr(
// equality_expression // equality_expression
// : relational_expression equality_expr // : relational_expression equality_expr
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::equality_expression() { Maybe<ast::Expression*> ParserImpl::equality_expression() {
auto lhs = relational_expression(); auto lhs = relational_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2369,8 +2360,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::equality_expression() {
// and_expr // and_expr
// : // :
// | AND equality_expression and_expr // | AND equality_expression and_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_and_expr( Expect<ast::Expression*> ParserImpl::expect_and_expr(ast::Expression* lhs) {
std::unique_ptr<ast::Expression> lhs) {
auto t = peek(); auto t = peek();
if (!t.IsAnd()) if (!t.IsAnd())
return lhs; return lhs;
@ -2390,7 +2380,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_and_expr(
// and_expression // and_expression
// : equality_expression and_expr // : equality_expression and_expr
Maybe<std::unique_ptr<ast::Expression>> ParserImpl::and_expression() { Maybe<ast::Expression*> ParserImpl::and_expression() {
auto lhs = equality_expression(); auto lhs = equality_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2403,8 +2393,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::and_expression() {
// exclusive_or_expr // exclusive_or_expr
// : // :
// | XOR and_expression exclusive_or_expr // | XOR and_expression exclusive_or_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_exclusive_or_expr( Expect<ast::Expression*> ParserImpl::expect_exclusive_or_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
Source source; Source source;
if (!match(Token::Type::kXor, &source)) if (!match(Token::Type::kXor, &source))
return lhs; return lhs;
@ -2421,7 +2411,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_exclusive_or_expr(
// exclusive_or_expression // exclusive_or_expression
// : and_expression exclusive_or_expr // : 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(); auto lhs = and_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2434,8 +2424,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::exclusive_or_expression() {
// inclusive_or_expr // inclusive_or_expr
// : // :
// | OR exclusive_or_expression inclusive_or_expr // | OR exclusive_or_expression inclusive_or_expr
Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_inclusive_or_expr( Expect<ast::Expression*> ParserImpl::expect_inclusive_or_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
Source source; Source source;
if (!match(Token::Type::kOr)) if (!match(Token::Type::kOr))
return lhs; return lhs;
@ -2452,7 +2442,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_inclusive_or_expr(
// inclusive_or_expression // inclusive_or_expression
// : exclusive_or_expression inclusive_or_expr // : 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(); auto lhs = exclusive_or_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2465,8 +2455,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::inclusive_or_expression() {
// logical_and_expr // logical_and_expr
// : // :
// | AND_AND 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( Expect<ast::Expression*> ParserImpl::expect_logical_and_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
auto t = peek(); auto t = peek();
if (!t.IsAndAnd()) if (!t.IsAndAnd())
return lhs; return lhs;
@ -2487,7 +2477,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_and_expr(
// logical_and_expression // logical_and_expression
// : inclusive_or_expression logical_and_expr // : 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(); auto lhs = inclusive_or_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2500,8 +2490,8 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_and_expression() {
// logical_or_expr // logical_or_expr
// : // :
// | OR_OR 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( Expect<ast::Expression*> ParserImpl::expect_logical_or_expr(
std::unique_ptr<ast::Expression> lhs) { ast::Expression* lhs) {
Source source; Source source;
if (!match(Token::Type::kOrOr)) if (!match(Token::Type::kOrOr))
return lhs; return lhs;
@ -2518,7 +2508,7 @@ Expect<std::unique_ptr<ast::Expression>> ParserImpl::expect_logical_or_expr(
// logical_or_expression // logical_or_expression
// : logical_and_expression logical_or_expr // : 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(); auto lhs = logical_and_expression();
if (lhs.errored) if (lhs.errored)
return Failure::kErrored; return Failure::kErrored;
@ -2530,7 +2520,7 @@ Maybe<std::unique_ptr<ast::Expression>> ParserImpl::logical_or_expression() {
// assignment_stmt // assignment_stmt
// : unary_expression EQUAL logical_or_expression // : 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 t = peek();
auto source = t.source(); auto source = t.source();
@ -2559,7 +2549,7 @@ Maybe<std::unique_ptr<ast::AssignmentStatement>> ParserImpl::assignment_stmt() {
// | FLOAT_LITERAL // | FLOAT_LITERAL
// | TRUE // | TRUE
// | FALSE // | FALSE
Maybe<std::unique_ptr<ast::Literal>> ParserImpl::const_literal() { Maybe<ast::Literal*> ParserImpl::const_literal() {
auto t = peek(); auto t = peek();
if (match(Token::Type::kTrue)) { if (match(Token::Type::kTrue)) {
auto* type = ctx_.type_mgr().Get(std::make_unique<ast::type::BoolType>()); 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 // const_expr
// : type_decl PAREN_LEFT (const_expr COMMA)? const_expr PAREN_RIGHT // : type_decl PAREN_LEFT (const_expr COMMA)? const_expr PAREN_RIGHT
// | const_literal // | const_literal
Expect<std::unique_ptr<ast::ConstructorExpression>> Expect<ast::ConstructorExpression*> ParserImpl::expect_const_expr() {
ParserImpl::expect_const_expr() {
return expect_const_expr_internal(0); return expect_const_expr_internal(0);
} }
Expect<std::unique_ptr<ast::ConstructorExpression>> Expect<ast::ConstructorExpression*> ParserImpl::expect_const_expr_internal(
ParserImpl::expect_const_expr_internal(uint32_t depth) { uint32_t depth) {
auto t = peek(); auto t = peek();
if (depth > kMaxConstExprDepth) { 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 t = peek();
auto deco = decoration(); auto deco = decoration();
if (deco.errored) if (deco.errored)
@ -2716,8 +2705,8 @@ Expect<std::unique_ptr<ast::Decoration>> ParserImpl::expect_decoration() {
return add_error(t, "expected decoration"); return add_error(t, "expected decoration");
} }
Maybe<std::unique_ptr<ast::Decoration>> ParserImpl::decoration() { Maybe<ast::Decoration*> ParserImpl::decoration() {
using Result = Maybe<std::unique_ptr<ast::Decoration>>; using Result = Maybe<ast::Decoration*>;
auto t = next(); auto t = next();
if (t.IsLocation()) { if (t.IsLocation()) {
const char* use = "location decoration"; const char* use = "location decoration";
@ -2822,12 +2811,11 @@ Maybe<std::unique_ptr<ast::Decoration>> ParserImpl::decoration() {
} }
template <typename T> template <typename T>
Expect<std::vector<std::unique_ptr<T>>> ParserImpl::cast_decorations( Expect<std::vector<T*>> ParserImpl::cast_decorations(ast::DecorationList& in) {
ast::DecorationList& in) {
bool ok = true; bool ok = true;
std::vector<std::unique_ptr<T>> out; std::vector<T*> out;
out.reserve(in.size()); out.reserve(in.size());
for (auto& deco : in) { for (auto* deco : in) {
if (!deco->Is<T>()) { if (!deco->Is<T>()) {
std::stringstream msg; std::stringstream msg;
msg << deco->GetKind() << " decoration type cannot be used for " msg << deco->GetKind() << " decoration type cannot be used for "

View File

@ -65,18 +65,16 @@ struct ForHeader {
/// @param init the initializer statement /// @param init the initializer statement
/// @param cond the condition statement /// @param cond the condition statement
/// @param cont the continuing statement /// @param cont the continuing statement
ForHeader(std::unique_ptr<ast::Statement> init, ForHeader(ast::Statement* init, ast::Expression* cond, ast::Statement* cont);
std::unique_ptr<ast::Expression> cond,
std::unique_ptr<ast::Statement> cont);
~ForHeader(); ~ForHeader();
/// The for loop initializer /// The for loop initializer
std::unique_ptr<ast::Statement> initializer; ast::Statement* initializer = nullptr;
/// The for loop condition /// The for loop condition
std::unique_ptr<ast::Expression> condition; ast::Expression* condition = nullptr;
/// The for loop continuing statement /// The for loop continuing statement
std::unique_ptr<ast::Statement> continuing; ast::Statement* continuing = nullptr;
}; };
/// ParserImpl for WGSL source data /// ParserImpl for WGSL source data
@ -301,14 +299,13 @@ class ParserImpl {
/// `variable_decoration_list*` provided as |decos|. /// `variable_decoration_list*` provided as |decos|.
/// @returns the variable parsed or nullptr /// @returns the variable parsed or nullptr
/// @param decos the list of decorations for the variable declaration. /// @param decos the list of decorations for the variable declaration.
Maybe<std::unique_ptr<ast::Variable>> global_variable_decl( Maybe<ast::Variable*> global_variable_decl(ast::DecorationList& decos);
ast::DecorationList& decos);
/// Parses a `global_constant_decl` grammar element /// Parses a `global_constant_decl` grammar element
/// @returns the const object or nullptr /// @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 /// Parses a `variable_decl` grammar element
/// @returns the parsed variable or nullptr otherwise /// @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 /// Parses a `variable_ident_decl` grammar element, erroring on parse
/// failure. /// failure.
/// @param use a description of what was being parsed if an error was raised. /// @param use a description of what was being parsed if an error was raised.
@ -341,14 +338,12 @@ class ParserImpl {
/// failure. /// failure.
/// @param decos the list of decorations for the struct member. /// @param decos the list of decorations for the struct member.
/// @returns the struct member or nullptr /// @returns the struct member or nullptr
Expect<std::unique_ptr<ast::StructMember>> expect_struct_member( Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos);
ast::DecorationList& decos);
/// Parses a `function_decl` grammar element with the initial /// Parses a `function_decl` grammar element with the initial
/// `function_decoration_decl*` provided as |decos|. /// `function_decoration_decl*` provided as |decos|.
/// @param decos the list of decorations for the function declaration. /// @param decos the list of decorations for the function declaration.
/// @returns the parsed function, nullptr otherwise /// @returns the parsed function, nullptr otherwise
Maybe<std::unique_ptr<ast::Function>> function_decl( Maybe<ast::Function*> function_decl(ast::DecorationList& decos);
ast::DecorationList& decos);
/// Parses a `texture_sampler_types` grammar element /// Parses a `texture_sampler_types` grammar element
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
Maybe<ast::type::Type*> texture_sampler_types(); Maybe<ast::type::Type*> texture_sampler_types();
@ -380,7 +375,7 @@ class ParserImpl {
Maybe<ast::type::Type*> function_type_decl(); Maybe<ast::type::Type*> function_type_decl();
/// Parses a `function_header` grammar element /// Parses a `function_header` grammar element
/// @returns the parsed function nullptr otherwise /// @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. /// Parses a `param_list` grammar element, erroring on parse failure.
/// @returns the parsed variables /// @returns the parsed variables
Expect<ast::VariableList> expect_param_list(); Expect<ast::VariableList> expect_param_list();
@ -394,73 +389,73 @@ class ParserImpl {
Expect<ast::Builtin> expect_builtin(); Expect<ast::Builtin> expect_builtin();
/// Parses a `body_stmt` grammar element, erroring on parse failure. /// Parses a `body_stmt` grammar element, erroring on parse failure.
/// @returns the parsed statements /// @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. /// Parses a `paren_rhs_stmt` grammar element, erroring on parse failure.
/// @returns the parsed element or nullptr /// @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 /// Parses a `statements` grammar element
/// @returns the statements parsed /// @returns the statements parsed
Expect<std::unique_ptr<ast::BlockStatement>> expect_statements(); Expect<ast::BlockStatement*> expect_statements();
/// Parses a `statement` grammar element /// Parses a `statement` grammar element
/// @returns the parsed statement or nullptr /// @returns the parsed statement or nullptr
Maybe<std::unique_ptr<ast::Statement>> statement(); Maybe<ast::Statement*> statement();
/// Parses a `break_stmt` grammar element /// Parses a `break_stmt` grammar element
/// @returns the parsed statement or nullptr /// @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 /// Parses a `return_stmt` grammar element
/// @returns the parsed statement or nullptr /// @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 /// Parses a `continue_stmt` grammar element
/// @returns the parsed statement or nullptr /// @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 /// Parses a `variable_stmt` grammar element
/// @returns the parsed variable or nullptr /// @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 /// Parses a `if_stmt` grammar element
/// @returns the parsed statement or nullptr /// @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 /// Parses a `elseif_stmt` grammar element
/// @returns the parsed elements /// @returns the parsed elements
Maybe<ast::ElseStatementList> elseif_stmt(); Maybe<ast::ElseStatementList> elseif_stmt();
/// Parses a `else_stmt` grammar element /// Parses a `else_stmt` grammar element
/// @returns the parsed statement or nullptr /// @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 /// Parses a `switch_stmt` grammar element
/// @returns the parsed statement or nullptr /// @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 /// Parses a `switch_body` grammar element
/// @returns the parsed statement or nullptr /// @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 /// Parses a `case_selectors` grammar element
/// @returns the list of literals /// @returns the list of literals
Expect<ast::CaseSelectorList> expect_case_selectors(); Expect<ast::CaseSelectorList> expect_case_selectors();
/// Parses a `case_body` grammar element /// Parses a `case_body` grammar element
/// @returns the parsed statements /// @returns the parsed statements
Maybe<std::unique_ptr<ast::BlockStatement>> case_body(); Maybe<ast::BlockStatement*> case_body();
/// Parses a `func_call_stmt` grammar element /// Parses a `func_call_stmt` grammar element
/// @returns the parsed function call or nullptr /// @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 /// Parses a `loop_stmt` grammar element
/// @returns the parsed loop or nullptr /// @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. /// Parses a `for_header` grammar element, erroring on parse failure.
/// @returns the parsed for header or nullptr /// @returns the parsed for header or nullptr
Expect<std::unique_ptr<ForHeader>> expect_for_header(); Expect<std::unique_ptr<ForHeader>> expect_for_header();
/// Parses a `for_stmt` grammar element /// Parses a `for_stmt` grammar element
/// @returns the parsed for loop or nullptr /// @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 /// Parses a `continuing_stmt` grammar element
/// @returns the parsed statements /// @returns the parsed statements
Maybe<std::unique_ptr<ast::BlockStatement>> continuing_stmt(); Maybe<ast::BlockStatement*> continuing_stmt();
/// Parses a `const_literal` grammar element /// Parses a `const_literal` grammar element
/// @returns the const literal parsed or nullptr if none found /// @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. /// Parses a `const_expr` grammar element, erroring on parse failure.
/// @returns the parsed constructor expression or nullptr on error /// @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 /// Parses a `primary_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses a `argument_expression_list` grammar element, erroring on parse
/// failure. /// failure.
/// @returns the list of arguments /// @returns the list of arguments
@ -468,107 +463,96 @@ class ParserImpl {
/// Parses the recursive portion of the postfix_expression /// Parses the recursive portion of the postfix_expression
/// @param prefix the left side of the expression /// @param prefix the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Maybe<std::unique_ptr<ast::Expression>> postfix_expr( Maybe<ast::Expression*> postfix_expr(ast::Expression* prefix);
std::unique_ptr<ast::Expression> prefix);
/// Parses a `postfix_expression` grammar elment /// Parses a `postfix_expression` grammar elment
/// @returns the parsed expression or nullptr /// @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 /// Parses a `unary_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `multiplicative_expression`, erroring on
/// parse failure. /// parse failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_multiplicative_expr( Expect<ast::Expression*> expect_multiplicative_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `multiplicative_expression` grammar element /// Parses the `multiplicative_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `additive_expression`, erroring on parse
/// failure. /// failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_additive_expr( Expect<ast::Expression*> expect_additive_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `additive_expression` grammar element /// Parses the `additive_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `shift_expression`, erroring on parse
/// failure. /// failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_shift_expr( Expect<ast::Expression*> expect_shift_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `shift_expression` grammar element /// Parses the `shift_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `relational_expression`, erroring on
/// parse failure. /// parse failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_relational_expr( Expect<ast::Expression*> expect_relational_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `relational_expression` grammar element /// Parses the `relational_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `equality_expression`, erroring on parse
/// failure. /// failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_equality_expr( Expect<ast::Expression*> expect_equality_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `equality_expression` grammar element /// Parses the `equality_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `and_expression`, erroring on parse
/// failure. /// failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_and_expr( Expect<ast::Expression*> expect_and_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `and_expression` grammar element /// Parses the `and_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `exclusive_or_expression`, erroring on
/// parse failure. /// parse failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_exclusive_or_expr( Expect<ast::Expression*> expect_exclusive_or_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `exclusive_or_expression` grammar elememnt /// Parses the `exclusive_or_expression` grammar elememnt
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `inclusive_or_expression`, erroring on
/// parse failure. /// parse failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_inclusive_or_expr( Expect<ast::Expression*> expect_inclusive_or_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses the `inclusive_or_expression` grammar element /// Parses the `inclusive_or_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `logical_and_expression`, erroring on
/// parse failure. /// parse failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_logical_and_expr( Expect<ast::Expression*> expect_logical_and_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses a `logical_and_expression` grammar element /// Parses a `logical_and_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses the recursive part of the `logical_or_expression`, erroring on
/// parse failure. /// parse failure.
/// @param lhs the left side of the expression /// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr /// @returns the parsed expression or nullptr
Expect<std::unique_ptr<ast::Expression>> expect_logical_or_expr( Expect<ast::Expression*> expect_logical_or_expr(ast::Expression* lhs);
std::unique_ptr<ast::Expression> lhs);
/// Parses a `logical_or_expression` grammar element /// Parses a `logical_or_expression` grammar element
/// @returns the parsed expression or nullptr /// @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 /// Parses a `assignment_stmt` grammar element
/// @returns the parsed assignment or nullptr /// @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. /// Parses one or more bracketed decoration lists.
/// @return the parsed decoration list, or an empty list on error. /// @return the parsed decoration list, or an empty list on error.
Maybe<ast::DecorationList> decoration_list(); Maybe<ast::DecorationList> decoration_list();
@ -585,12 +569,12 @@ class ParserImpl {
/// * `global_const_decoration` /// * `global_const_decoration`
/// * `function_decoration` /// * `function_decoration`
/// @return the parsed decoration, or nullptr. /// @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 /// Parses a single decoration, reporting an error if the next token does not
/// represent a decoration. /// represent a decoration.
/// @see #decoration for the full list of decorations this method parses. /// @see #decoration for the full list of decorations this method parses.
/// @return the parsed decoration, or nullptr on error. /// @return the parsed decoration, or nullptr on error.
Expect<std::unique_ptr<ast::Decoration>> expect_decoration(); Expect<ast::Decoration*> expect_decoration();
private: private:
/// ReturnType resolves to the return type for the function or lambda F. /// 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 /// 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|. /// error if any of the decorations aren't of the type |T|.
template <typename T> template <typename T>
Expect<std::vector<std::unique_ptr<T>>> cast_decorations( Expect<std::vector<T*>> cast_decorations(ast::DecorationList& in);
ast::DecorationList& in);
/// Reports an error if the decoration list |list| is not empty. /// Reports an error if the decoration list |list| is not empty.
/// Used to ensure that all decorations are consumed. /// Used to ensure that all decorations are consumed.
bool expect_decorations_consumed(const ast::DecorationList& list); bool expect_decorations_consumed(const ast::DecorationList& list);
@ -742,20 +725,22 @@ class ParserImpl {
ast::ArrayDecorationList decos); ast::ArrayDecorationList decos);
Expect<ast::type::Type*> expect_type_decl_matrix(Token t); Expect<ast::type::Type*> expect_type_decl_matrix(Token t);
Expect<std::unique_ptr<ast::ConstructorExpression>> Expect<ast::ConstructorExpression*> expect_const_expr_internal(
expect_const_expr_internal(uint32_t depth); uint32_t depth);
Expect<ast::type::Type*> expect_type(const std::string& use); Expect<ast::type::Type*> expect_type(const std::string& use);
Maybe<std::unique_ptr<ast::Statement>> non_block_statement(); Maybe<ast::Statement*> non_block_statement();
Maybe<std::unique_ptr<ast::Statement>> for_header_initializer(); Maybe<ast::Statement*> for_header_initializer();
Maybe<std::unique_ptr<ast::Statement>> for_header_continuing(); Maybe<ast::Statement*> for_header_continuing();
/// @return a `std::unique_ptr` to a new `T` constructed with `args` /// Creates a new `ast::Node` owned by the Context. When the Context is
/// @param args the arguments to forward to the constructor for `T` /// 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> template <typename T, typename... ARGS>
std::unique_ptr<T> create(ARGS&&... args) const { T* create(ARGS&&... args) {
return std::make_unique<T>(std::forward<ARGS>(args)...); return ctx_.create<T>(std::forward<ARGS>(args)...);
} }
Context& ctx_; Context& ctx_;

View File

@ -30,8 +30,8 @@ TEST_F(ParserImplTest, FunctionDecorationList_Parses) {
EXPECT_TRUE(decos.matched); EXPECT_TRUE(decos.matched);
ASSERT_EQ(decos.value.size(), 2u); ASSERT_EQ(decos.value.size(), 2u);
auto deco_0 = ast::As<ast::FunctionDecoration>(std::move(decos.value[0])); 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_1 = ast::As<ast::FunctionDecoration>(std::move(decos.value[1]));
ASSERT_NE(deco_0, nullptr); ASSERT_NE(deco_0, nullptr);
ASSERT_NE(deco_1, nullptr); ASSERT_NE(deco_1, nullptr);

View File

@ -30,7 +30,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Workgroup) {
EXPECT_FALSE(deco.errored); EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error(); ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_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_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->IsWorkgroup()); ASSERT_TRUE(func_deco->IsWorkgroup());
@ -50,7 +50,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Workgroup_2Param) {
EXPECT_FALSE(deco.errored); EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error(); ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_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_NE(func_deco, nullptr) << p->error();
ASSERT_TRUE(func_deco->IsWorkgroup()); ASSERT_TRUE(func_deco->IsWorkgroup());
@ -70,7 +70,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Workgroup_3Param) {
EXPECT_FALSE(deco.errored); EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error(); ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_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_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->IsWorkgroup()); ASSERT_TRUE(func_deco->IsWorkgroup());
@ -257,7 +257,7 @@ TEST_F(ParserImplTest, FunctionDecoration_Stage) {
EXPECT_FALSE(deco.errored); EXPECT_FALSE(deco.errored);
ASSERT_NE(deco.value, nullptr) << p->error(); ASSERT_NE(deco.value, nullptr) << p->error();
ASSERT_FALSE(p->has_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_NE(func_deco, nullptr);
ASSERT_TRUE(func_deco->IsStage()); ASSERT_TRUE(func_deco->IsStage());
EXPECT_EQ(func_deco->AsStage()->value(), ast::PipelineStage::kCompute); EXPECT_EQ(func_deco->AsStage()->value(), ast::PipelineStage::kCompute);

Some files were not shown because too many files have changed in this diff Show More