Consistent formatting for Dawn/Tint.

This CL updates the clang format files to have a single shared format
between Dawn and Tint. The major changes are tabs are 4 spaces, lines
are 100 columns and namespaces are not indented.

Bug: dawn:1339
Change-Id: I4208742c95643998d9fd14e77a9cc558071ded39
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/87603
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
dan sinclair
2022-05-01 14:40:55 +00:00
committed by Dawn LUCI CQ
parent 73b1d1dafa
commit 41e4d9a34c
1827 changed files with 218382 additions and 227741 deletions

View File

@@ -1,2 +0,0 @@
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium

View File

@@ -410,8 +410,8 @@ libtint_source_set("libtint_core_all_src") {
"sem/pointer.h",
"sem/reference.h",
"sem/sampled_texture.h",
"sem/sampler_texture_pair.h",
"sem/sampler.h",
"sem/sampler_texture_pair.h",
"sem/storage_texture.h",
"sem/switch_statement.h",
"sem/texture.h",

View File

@@ -17,25 +17,25 @@
namespace tint::ast {
std::ostream& operator<<(std::ostream& out, Access access) {
switch (access) {
case ast::Access::kUndefined: {
out << "undefined";
break;
switch (access) {
case ast::Access::kUndefined: {
out << "undefined";
break;
}
case ast::Access::kRead: {
out << "read";
break;
}
case ast::Access::kReadWrite: {
out << "read_write";
break;
}
case ast::Access::kWrite: {
out << "write";
break;
}
}
case ast::Access::kRead: {
out << "read";
break;
}
case ast::Access::kReadWrite: {
out << "read_write";
break;
}
case ast::Access::kWrite: {
out << "write";
break;
}
}
return out;
return out;
}
} // namespace tint::ast

View File

@@ -22,16 +22,16 @@ namespace tint::ast {
/// The access control settings
enum Access {
/// Not declared in the source
kUndefined = 0,
/// Read only
kRead,
/// Write only
kWrite,
/// Read write
kReadWrite,
// Last valid access mode
kLastValid = kReadWrite,
/// Not declared in the source
kUndefined = 0,
/// Read only
kRead,
/// Write only
kWrite,
/// Read write
kReadWrite,
// Last valid access mode
kLastValid = kReadWrite,
};
/// @param out the std::ostream to write to

View File

@@ -20,12 +20,9 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::Alias);
namespace tint::ast {
Alias::Alias(ProgramID pid,
const Source& src,
const Symbol& n,
const Type* subtype)
Alias::Alias(ProgramID pid, const Source& src, const Symbol& n, const Type* subtype)
: Base(pid, src, n), type(subtype) {
TINT_ASSERT(AST, type);
TINT_ASSERT(AST, type);
}
Alias::Alias(Alias&&) = default;
@@ -33,11 +30,11 @@ Alias::Alias(Alias&&) = default;
Alias::~Alias() = default;
const Alias* Alias::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto sym = ctx->Clone(name);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Alias>(src, sym, ty);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto sym = ctx->Clone(name);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Alias>(src, sym, ty);
}
} // namespace tint::ast

View File

@@ -23,28 +23,25 @@ namespace tint::ast {
/// A type alias type. Holds a name and pointer to another type.
class Alias final : public Castable<Alias, TypeDecl> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param name the symbol for the alias
/// @param subtype the alias'd type
Alias(ProgramID pid,
const Source& src,
const Symbol& name,
const Type* subtype);
/// Move constructor
Alias(Alias&&);
/// Destructor
~Alias() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param name the symbol for the alias
/// @param subtype the alias'd type
Alias(ProgramID pid, const Source& src, const Symbol& name, const Type* subtype);
/// Move constructor
Alias(Alias&&);
/// Destructor
~Alias() override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Alias* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Alias* Clone(CloneContext* ctx) const override;
/// the alias type
const Type* const type;
/// the alias type
const Type* const type;
};
} // namespace tint::ast

View File

@@ -33,10 +33,10 @@ namespace {
using AstAliasTest = TestHelper;
TEST_F(AstAliasTest, Create) {
auto* u32 = create<U32>();
auto* a = Alias("a_type", u32);
EXPECT_EQ(a->name, Symbol(1, ID()));
EXPECT_EQ(a->type, u32);
auto* u32 = create<U32>();
auto* a = Alias("a_type", u32);
EXPECT_EQ(a->name, Symbol(1, ID()));
EXPECT_EQ(a->type, u32);
}
} // namespace

View File

@@ -24,17 +24,16 @@ namespace tint::ast {
namespace {
// Returns the string representation of an array size expression.
std::string SizeExprToString(const Expression* size,
const SymbolTable& symbols) {
if (auto* ident = size->As<IdentifierExpression>()) {
return symbols.NameFor(ident->symbol);
}
if (auto* literal = size->As<IntLiteralExpression>()) {
return std::to_string(literal->ValueAsU32());
}
// This will never be exposed to the user as the Resolver will reject this
// expression for array size.
return "<invalid>";
std::string SizeExprToString(const Expression* size, const SymbolTable& symbols) {
if (auto* ident = size->As<IdentifierExpression>()) {
return symbols.NameFor(ident->symbol);
}
if (auto* literal = size->As<IntLiteralExpression>()) {
return std::to_string(literal->ValueAsU32());
}
// This will never be exposed to the user as the Resolver will reject this
// expression for array size.
return "<invalid>";
}
} // namespace
@@ -50,27 +49,27 @@ Array::Array(Array&&) = default;
Array::~Array() = default;
std::string Array::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
for (auto* attr : attributes) {
if (auto* stride = attr->As<ast::StrideAttribute>()) {
out << "@stride(" << stride->stride << ") ";
std::ostringstream out;
for (auto* attr : attributes) {
if (auto* stride = attr->As<ast::StrideAttribute>()) {
out << "@stride(" << stride->stride << ") ";
}
}
}
out << "array<" << type->FriendlyName(symbols);
if (!IsRuntimeArray()) {
out << ", " << SizeExprToString(count, symbols);
}
out << ">";
return out.str();
out << "array<" << type->FriendlyName(symbols);
if (!IsRuntimeArray()) {
out << ", " << SizeExprToString(count, symbols);
}
out << ">";
return out.str();
}
const Array* Array::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
auto* cnt = ctx->Clone(count);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Array>(src, ty, cnt, attrs);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
auto* cnt = ctx->Clone(count);
auto attrs = ctx->Clone(attributes);
return ctx->dst->create<Array>(src, ty, cnt, attrs);
}
} // namespace tint::ast

View File

@@ -29,45 +29,45 @@ namespace tint::ast {
/// An array type. If size is zero then it is a runtime array.
class Array final : public Castable<Array, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param subtype the type of the array elements
/// @param count the number of elements in the array. nullptr represents a
/// runtime-sized array.
/// @param attributes the array attributes
Array(ProgramID pid,
const Source& src,
const Type* subtype,
const Expression* count,
AttributeList attributes);
/// Move constructor
Array(Array&&);
~Array() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param subtype the type of the array elements
/// @param count the number of elements in the array. nullptr represents a
/// runtime-sized array.
/// @param attributes the array attributes
Array(ProgramID pid,
const Source& src,
const Type* subtype,
const Expression* count,
AttributeList attributes);
/// Move constructor
Array(Array&&);
~Array() override;
/// @returns true if this is a runtime array.
/// i.e. the size is determined at runtime
bool IsRuntimeArray() const { return count == nullptr; }
/// @returns true if this is a runtime array.
/// i.e. the size is determined at runtime
bool IsRuntimeArray() const { return count == nullptr; }
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Array* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Array* Clone(CloneContext* ctx) const override;
/// the array element type
const Type* const type;
/// the array element type
const Type* const type;
/// the array size in elements, or nullptr for a runtime array
const Expression* const count;
/// the array size in elements, or nullptr for a runtime array
const Expression* const count;
/// the array attributes
const AttributeList attributes;
/// the array attributes
const AttributeList attributes;
};
} // namespace tint::ast

View File

@@ -22,47 +22,46 @@ namespace {
using AstArrayTest = TestHelper;
TEST_F(AstArrayTest, CreateSizedArray) {
auto* u32 = create<U32>();
auto* count = Expr(3);
auto* arr = create<Array>(u32, count, AttributeList{});
EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, count);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_FALSE(arr->IsRuntimeArray());
auto* u32 = create<U32>();
auto* count = Expr(3);
auto* arr = create<Array>(u32, count, AttributeList{});
EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, count);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_FALSE(arr->IsRuntimeArray());
}
TEST_F(AstArrayTest, CreateRuntimeArray) {
auto* u32 = create<U32>();
auto* arr = create<Array>(u32, nullptr, AttributeList{});
EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, nullptr);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_TRUE(arr->IsRuntimeArray());
auto* u32 = create<U32>();
auto* arr = create<Array>(u32, nullptr, AttributeList{});
EXPECT_EQ(arr->type, u32);
EXPECT_EQ(arr->count, nullptr);
EXPECT_TRUE(arr->Is<Array>());
EXPECT_TRUE(arr->IsRuntimeArray());
}
TEST_F(AstArrayTest, FriendlyName_RuntimeSized) {
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, nullptr, AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, nullptr, AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
}
TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, Expr(5), AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, Expr(5), AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
}
TEST_F(AstArrayTest, FriendlyName_ConstantSized) {
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, Expr("size"), AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>");
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, Expr("size"), AttributeList{});
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, size>");
}
TEST_F(AstArrayTest, FriendlyName_WithStride) {
auto* i32 = create<I32>();
auto* arr =
create<Array>(i32, Expr(5), AttributeList{create<StrideAttribute>(32)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
auto* i32 = create<I32>();
auto* arr = create<Array>(i32, Expr(5), AttributeList{create<StrideAttribute>(32)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
}
} // namespace

View File

@@ -25,10 +25,10 @@ AssignmentStatement::AssignmentStatement(ProgramID pid,
const Expression* l,
const Expression* r)
: Base(pid, src), lhs(l), rhs(r) {
TINT_ASSERT(AST, lhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
TINT_ASSERT(AST, rhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
TINT_ASSERT(AST, lhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
TINT_ASSERT(AST, rhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
}
AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;
@@ -36,11 +36,11 @@ AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;
AssignmentStatement::~AssignmentStatement() = default;
const AssignmentStatement* AssignmentStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* l = ctx->Clone(lhs);
auto* r = ctx->Clone(rhs);
return ctx->dst->create<AssignmentStatement>(src, l, r);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* l = ctx->Clone(lhs);
auto* r = ctx->Clone(rhs);
return ctx->dst->create<AssignmentStatement>(src, l, r);
}
} // namespace tint::ast

View File

@@ -21,33 +21,32 @@
namespace tint::ast {
/// An assignment statement
class AssignmentStatement final
: public Castable<AssignmentStatement, Statement> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the assignment statement source
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
AssignmentStatement(ProgramID program_id,
const Source& source,
const Expression* lhs,
const Expression* rhs);
/// Move constructor
AssignmentStatement(AssignmentStatement&&);
~AssignmentStatement() override;
class AssignmentStatement final : public Castable<AssignmentStatement, Statement> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the assignment statement source
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
AssignmentStatement(ProgramID program_id,
const Source& source,
const Expression* lhs,
const Expression* rhs);
/// Move constructor
AssignmentStatement(AssignmentStatement&&);
~AssignmentStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const AssignmentStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const AssignmentStatement* Clone(CloneContext* ctx) const override;
/// left side expression
const Expression* const lhs;
/// left side expression
const Expression* const lhs;
/// right side expression
const Expression* const rhs;
/// right side expression
const Expression* const rhs;
};
} // namespace tint::ast

View File

@@ -23,69 +23,68 @@ namespace {
using AssignmentStatementTest = TestHelper;
TEST_F(AssignmentStatementTest, Creation) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* stmt = create<AssignmentStatement>(lhs, rhs);
EXPECT_EQ(stmt->lhs, lhs);
EXPECT_EQ(stmt->rhs, rhs);
auto* stmt = create<AssignmentStatement>(lhs, rhs);
EXPECT_EQ(stmt->lhs, lhs);
EXPECT_EQ(stmt->rhs, rhs);
}
TEST_F(AssignmentStatementTest, CreationWithSource) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* stmt =
create<AssignmentStatement>(Source{Source::Location{20, 2}}, lhs, rhs);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* stmt = create<AssignmentStatement>(Source{Source::Location{20, 2}}, lhs, rhs);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(AssignmentStatementTest, IsAssign) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* stmt = create<AssignmentStatement>(lhs, rhs);
EXPECT_TRUE(stmt->Is<AssignmentStatement>());
auto* stmt = create<AssignmentStatement>(lhs, rhs);
EXPECT_TRUE(stmt->Is<AssignmentStatement>());
}
TEST_F(AssignmentStatementTest, Assert_Null_LHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<AssignmentStatement>(nullptr, b.Expr(1));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<AssignmentStatement>(nullptr, b.Expr(1));
},
"internal compiler error");
}
TEST_F(AssignmentStatementTest, Assert_Null_RHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<AssignmentStatement>(b.Expr(1), nullptr);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<AssignmentStatement>(b.Expr(1), nullptr);
},
"internal compiler error");
}
TEST_F(AssignmentStatementTest, Assert_DifferentProgramID_LHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<AssignmentStatement>(b2.Expr("lhs"), b1.Expr("rhs"));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<AssignmentStatement>(b2.Expr("lhs"), b1.Expr("rhs"));
},
"internal compiler error");
}
TEST_F(AssignmentStatementTest, Assert_DifferentProgramID_RHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<AssignmentStatement>(b1.Expr("lhs"), b2.Expr("rhs"));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<AssignmentStatement>(b1.Expr("lhs"), b2.Expr("rhs"));
},
"internal compiler error");
}
} // namespace

View File

@@ -24,9 +24,9 @@ Atomic::Atomic(ProgramID pid, const Source& src, const Type* const subtype)
: Base(pid, src), type(subtype) {}
std::string Atomic::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "atomic<" << type->FriendlyName(symbols) << ">";
return out.str();
std::ostringstream out;
out << "atomic<" << type->FriendlyName(symbols) << ">";
return out.str();
}
Atomic::Atomic(Atomic&&) = default;
@@ -34,10 +34,10 @@ Atomic::Atomic(Atomic&&) = default;
Atomic::~Atomic() = default;
const Atomic* Atomic::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Atomic>(src, ty);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* ty = ctx->Clone(type);
return ctx->dst->create<Atomic>(src, ty);
}
} // namespace tint::ast

View File

@@ -23,28 +23,28 @@ namespace tint::ast {
/// An atomic type.
class Atomic final : public Castable<Atomic, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param subtype the pointee type
Atomic(ProgramID pid, const Source& src, const Type* const subtype);
/// Move constructor
Atomic(Atomic&&);
~Atomic() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param subtype the pointee type
Atomic(ProgramID pid, const Source& src, const Type* const subtype);
/// Move constructor
Atomic(Atomic&&);
~Atomic() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Atomic* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Atomic* Clone(CloneContext* ctx) const override;
/// the pointee type
const Type* const type;
/// the pointee type
const Type* const type;
};
} // namespace tint::ast

View File

@@ -23,15 +23,15 @@ namespace {
using AstAtomicTest = TestHelper;
TEST_F(AstAtomicTest, Creation) {
auto* i32 = create<I32>();
auto* p = create<Atomic>(i32);
EXPECT_EQ(p->type, i32);
auto* i32 = create<I32>();
auto* p = create<Atomic>(i32);
EXPECT_EQ(p->type, i32);
}
TEST_F(AstAtomicTest, FriendlyName) {
auto* i32 = create<I32>();
auto* p = create<Atomic>(i32);
EXPECT_EQ(p->FriendlyName(Symbols()), "atomic<i32>");
auto* i32 = create<I32>();
auto* p = create<Atomic>(i32);
EXPECT_EQ(p->FriendlyName(Symbols()), "atomic<i32>");
}
} // namespace

View File

@@ -24,17 +24,17 @@ namespace tint::ast {
/// The base class for all attributes
class Attribute : public Castable<Attribute, Node> {
public:
~Attribute() override;
public:
~Attribute() override;
/// @returns the WGSL name for the attribute
virtual std::string Name() const = 0;
/// @returns the WGSL name for the attribute
virtual std::string Name() const = 0;
protected:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
Attribute(ProgramID pid, const Source& src) : Base(pid, src) {}
protected:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
Attribute(ProgramID pid, const Source& src) : Base(pid, src) {}
};
/// A list of attributes
@@ -44,24 +44,24 @@ using AttributeList = std::vector<const Attribute*>;
/// @returns true if `attributes` includes a attribute of type `T`
template <typename T>
bool HasAttribute(const AttributeList& attributes) {
for (auto* attr : attributes) {
if (attr->Is<T>()) {
return true;
for (auto* attr : attributes) {
if (attr->Is<T>()) {
return true;
}
}
}
return false;
return false;
}
/// @param attributes the list of attributes to search
/// @returns a pointer to `T` from `attributes` if found, otherwise nullptr.
template <typename T>
const T* GetAttribute(const AttributeList& attributes) {
for (auto* attr : attributes) {
if (attr->Is<T>()) {
return attr->As<T>();
for (auto* attr : attributes) {
if (attr->Is<T>()) {
return attr->As<T>();
}
}
}
return nullptr;
return nullptr;
}
} // namespace tint::ast

View File

@@ -26,11 +26,11 @@ BinaryExpression::BinaryExpression(ProgramID pid,
const Expression* l,
const Expression* r)
: Base(pid, src), op(o), lhs(l), rhs(r) {
TINT_ASSERT(AST, lhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
TINT_ASSERT(AST, rhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
TINT_ASSERT(AST, op != BinaryOp::kNone);
TINT_ASSERT(AST, lhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
TINT_ASSERT(AST, rhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
TINT_ASSERT(AST, op != BinaryOp::kNone);
}
BinaryExpression::BinaryExpression(BinaryExpression&&) = default;
@@ -38,11 +38,11 @@ BinaryExpression::BinaryExpression(BinaryExpression&&) = default;
BinaryExpression::~BinaryExpression() = default;
const BinaryExpression* BinaryExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* l = ctx->Clone(lhs);
auto* r = ctx->Clone(rhs);
return ctx->dst->create<BinaryExpression>(src, op, l, r);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* l = ctx->Clone(lhs);
auto* r = ctx->Clone(rhs);
return ctx->dst->create<BinaryExpression>(src, op, l, r);
}
} // namespace tint::ast

View File

@@ -21,240 +21,240 @@ namespace tint::ast {
/// The operator type
enum class BinaryOp {
kNone = 0,
kAnd, // &
kOr, // |
kXor,
kLogicalAnd, // &&
kLogicalOr, // ||
kEqual,
kNotEqual,
kLessThan,
kGreaterThan,
kLessThanEqual,
kGreaterThanEqual,
kShiftLeft,
kShiftRight,
kAdd,
kSubtract,
kMultiply,
kDivide,
kModulo,
kNone = 0,
kAnd, // &
kOr, // |
kXor,
kLogicalAnd, // &&
kLogicalOr, // ||
kEqual,
kNotEqual,
kLessThan,
kGreaterThan,
kLessThanEqual,
kGreaterThanEqual,
kShiftLeft,
kShiftRight,
kAdd,
kSubtract,
kMultiply,
kDivide,
kModulo,
};
/// An binary expression
class BinaryExpression final : public Castable<BinaryExpression, Expression> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the binary expression source
/// @param op the operation type
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
BinaryExpression(ProgramID program_id,
const Source& source,
BinaryOp op,
const Expression* lhs,
const Expression* rhs);
/// Move constructor
BinaryExpression(BinaryExpression&&);
~BinaryExpression() override;
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the binary expression source
/// @param op the operation type
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
BinaryExpression(ProgramID program_id,
const Source& source,
BinaryOp op,
const Expression* lhs,
const Expression* rhs);
/// Move constructor
BinaryExpression(BinaryExpression&&);
~BinaryExpression() override;
/// @returns true if the op is and
bool IsAnd() const { return op == BinaryOp::kAnd; }
/// @returns true if the op is or
bool IsOr() const { return op == BinaryOp::kOr; }
/// @returns true if the op is xor
bool IsXor() const { return op == BinaryOp::kXor; }
/// @returns true if the op is logical and
bool IsLogicalAnd() const { return op == BinaryOp::kLogicalAnd; }
/// @returns true if the op is logical or
bool IsLogicalOr() const { return op == BinaryOp::kLogicalOr; }
/// @returns true if the op is equal
bool IsEqual() const { return op == BinaryOp::kEqual; }
/// @returns true if the op is not equal
bool IsNotEqual() const { return op == BinaryOp::kNotEqual; }
/// @returns true if the op is less than
bool IsLessThan() const { return op == BinaryOp::kLessThan; }
/// @returns true if the op is greater than
bool IsGreaterThan() const { return op == BinaryOp::kGreaterThan; }
/// @returns true if the op is less than equal
bool IsLessThanEqual() const { return op == BinaryOp::kLessThanEqual; }
/// @returns true if the op is greater than equal
bool IsGreaterThanEqual() const { return op == BinaryOp::kGreaterThanEqual; }
/// @returns true if the op is shift left
bool IsShiftLeft() const { return op == BinaryOp::kShiftLeft; }
/// @returns true if the op is shift right
bool IsShiftRight() const { return op == BinaryOp::kShiftRight; }
/// @returns true if the op is add
bool IsAdd() const { return op == BinaryOp::kAdd; }
/// @returns true if the op is subtract
bool IsSubtract() const { return op == BinaryOp::kSubtract; }
/// @returns true if the op is multiply
bool IsMultiply() const { return op == BinaryOp::kMultiply; }
/// @returns true if the op is divide
bool IsDivide() const { return op == BinaryOp::kDivide; }
/// @returns true if the op is modulo
bool IsModulo() const { return op == BinaryOp::kModulo; }
/// @returns true if the op is an arithmetic operation
bool IsArithmetic() const;
/// @returns true if the op is a comparison operation
bool IsComparison() const;
/// @returns true if the op is a bitwise operation
bool IsBitwise() const;
/// @returns true if the op is a bit shift operation
bool IsBitshift() const;
/// @returns true if the op is a logical expression
bool IsLogical() const;
/// @returns true if the op is and
bool IsAnd() const { return op == BinaryOp::kAnd; }
/// @returns true if the op is or
bool IsOr() const { return op == BinaryOp::kOr; }
/// @returns true if the op is xor
bool IsXor() const { return op == BinaryOp::kXor; }
/// @returns true if the op is logical and
bool IsLogicalAnd() const { return op == BinaryOp::kLogicalAnd; }
/// @returns true if the op is logical or
bool IsLogicalOr() const { return op == BinaryOp::kLogicalOr; }
/// @returns true if the op is equal
bool IsEqual() const { return op == BinaryOp::kEqual; }
/// @returns true if the op is not equal
bool IsNotEqual() const { return op == BinaryOp::kNotEqual; }
/// @returns true if the op is less than
bool IsLessThan() const { return op == BinaryOp::kLessThan; }
/// @returns true if the op is greater than
bool IsGreaterThan() const { return op == BinaryOp::kGreaterThan; }
/// @returns true if the op is less than equal
bool IsLessThanEqual() const { return op == BinaryOp::kLessThanEqual; }
/// @returns true if the op is greater than equal
bool IsGreaterThanEqual() const { return op == BinaryOp::kGreaterThanEqual; }
/// @returns true if the op is shift left
bool IsShiftLeft() const { return op == BinaryOp::kShiftLeft; }
/// @returns true if the op is shift right
bool IsShiftRight() const { return op == BinaryOp::kShiftRight; }
/// @returns true if the op is add
bool IsAdd() const { return op == BinaryOp::kAdd; }
/// @returns true if the op is subtract
bool IsSubtract() const { return op == BinaryOp::kSubtract; }
/// @returns true if the op is multiply
bool IsMultiply() const { return op == BinaryOp::kMultiply; }
/// @returns true if the op is divide
bool IsDivide() const { return op == BinaryOp::kDivide; }
/// @returns true if the op is modulo
bool IsModulo() const { return op == BinaryOp::kModulo; }
/// @returns true if the op is an arithmetic operation
bool IsArithmetic() const;
/// @returns true if the op is a comparison operation
bool IsComparison() const;
/// @returns true if the op is a bitwise operation
bool IsBitwise() const;
/// @returns true if the op is a bit shift operation
bool IsBitshift() const;
/// @returns true if the op is a logical expression
bool IsLogical() const;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BinaryExpression* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BinaryExpression* Clone(CloneContext* ctx) const override;
/// the binary op type
const BinaryOp op;
/// the left side expression
const Expression* const lhs;
/// the right side expression
const Expression* const rhs;
/// the binary op type
const BinaryOp op;
/// the left side expression
const Expression* const lhs;
/// the right side expression
const Expression* const rhs;
};
/// @param op the operator
/// @returns true if the op is an arithmetic operation
inline bool IsArithmetic(BinaryOp op) {
switch (op) {
case ast::BinaryOp::kAdd:
case ast::BinaryOp::kSubtract:
case ast::BinaryOp::kMultiply:
case ast::BinaryOp::kDivide:
case ast::BinaryOp::kModulo:
return true;
default:
return false;
}
switch (op) {
case ast::BinaryOp::kAdd:
case ast::BinaryOp::kSubtract:
case ast::BinaryOp::kMultiply:
case ast::BinaryOp::kDivide:
case ast::BinaryOp::kModulo:
return true;
default:
return false;
}
}
/// @param op the operator
/// @returns true if the op is a comparison operation
inline bool IsComparison(BinaryOp op) {
switch (op) {
case ast::BinaryOp::kEqual:
case ast::BinaryOp::kNotEqual:
case ast::BinaryOp::kLessThan:
case ast::BinaryOp::kLessThanEqual:
case ast::BinaryOp::kGreaterThan:
case ast::BinaryOp::kGreaterThanEqual:
return true;
default:
return false;
}
switch (op) {
case ast::BinaryOp::kEqual:
case ast::BinaryOp::kNotEqual:
case ast::BinaryOp::kLessThan:
case ast::BinaryOp::kLessThanEqual:
case ast::BinaryOp::kGreaterThan:
case ast::BinaryOp::kGreaterThanEqual:
return true;
default:
return false;
}
}
/// @param op the operator
/// @returns true if the op is a bitwise operation
inline bool IsBitwise(BinaryOp op) {
switch (op) {
case ast::BinaryOp::kAnd:
case ast::BinaryOp::kOr:
case ast::BinaryOp::kXor:
return true;
default:
return false;
}
switch (op) {
case ast::BinaryOp::kAnd:
case ast::BinaryOp::kOr:
case ast::BinaryOp::kXor:
return true;
default:
return false;
}
}
/// @param op the operator
/// @returns true if the op is a bit shift operation
inline bool IsBitshift(BinaryOp op) {
switch (op) {
case ast::BinaryOp::kShiftLeft:
case ast::BinaryOp::kShiftRight:
return true;
default:
return false;
}
switch (op) {
case ast::BinaryOp::kShiftLeft:
case ast::BinaryOp::kShiftRight:
return true;
default:
return false;
}
}
inline bool BinaryExpression::IsLogical() const {
switch (op) {
case ast::BinaryOp::kLogicalAnd:
case ast::BinaryOp::kLogicalOr:
return true;
default:
return false;
}
switch (op) {
case ast::BinaryOp::kLogicalAnd:
case ast::BinaryOp::kLogicalOr:
return true;
default:
return false;
}
}
inline bool BinaryExpression::IsArithmetic() const {
return ast::IsArithmetic(op);
return ast::IsArithmetic(op);
}
inline bool BinaryExpression::IsComparison() const {
return ast::IsComparison(op);
return ast::IsComparison(op);
}
inline bool BinaryExpression::IsBitwise() const {
return ast::IsBitwise(op);
return ast::IsBitwise(op);
}
inline bool BinaryExpression::IsBitshift() const {
return ast::IsBitshift(op);
return ast::IsBitshift(op);
}
/// @returns the human readable name of the given BinaryOp
/// @param op the BinaryOp
constexpr const char* FriendlyName(BinaryOp op) {
switch (op) {
case BinaryOp::kNone:
return "none";
case BinaryOp::kAnd:
return "and";
case BinaryOp::kOr:
return "or";
case BinaryOp::kXor:
return "xor";
case BinaryOp::kLogicalAnd:
return "logical_and";
case BinaryOp::kLogicalOr:
return "logical_or";
case BinaryOp::kEqual:
return "equal";
case BinaryOp::kNotEqual:
return "not_equal";
case BinaryOp::kLessThan:
return "less_than";
case BinaryOp::kGreaterThan:
return "greater_than";
case BinaryOp::kLessThanEqual:
return "less_than_equal";
case BinaryOp::kGreaterThanEqual:
return "greater_than_equal";
case BinaryOp::kShiftLeft:
return "shift_left";
case BinaryOp::kShiftRight:
return "shift_right";
case BinaryOp::kAdd:
return "add";
case BinaryOp::kSubtract:
return "subtract";
case BinaryOp::kMultiply:
return "multiply";
case BinaryOp::kDivide:
return "divide";
case BinaryOp::kModulo:
return "modulo";
}
return "INVALID";
switch (op) {
case BinaryOp::kNone:
return "none";
case BinaryOp::kAnd:
return "and";
case BinaryOp::kOr:
return "or";
case BinaryOp::kXor:
return "xor";
case BinaryOp::kLogicalAnd:
return "logical_and";
case BinaryOp::kLogicalOr:
return "logical_or";
case BinaryOp::kEqual:
return "equal";
case BinaryOp::kNotEqual:
return "not_equal";
case BinaryOp::kLessThan:
return "less_than";
case BinaryOp::kGreaterThan:
return "greater_than";
case BinaryOp::kLessThanEqual:
return "less_than_equal";
case BinaryOp::kGreaterThanEqual:
return "greater_than_equal";
case BinaryOp::kShiftLeft:
return "shift_left";
case BinaryOp::kShiftRight:
return "shift_right";
case BinaryOp::kAdd:
return "add";
case BinaryOp::kSubtract:
return "subtract";
case BinaryOp::kMultiply:
return "multiply";
case BinaryOp::kDivide:
return "divide";
case BinaryOp::kModulo:
return "modulo";
}
return "INVALID";
}
/// @param out the std::ostream to write to
/// @param op the BinaryOp
/// @return the std::ostream so calls can be chained
inline std::ostream& operator<<(std::ostream& out, BinaryOp op) {
out << FriendlyName(op);
return out;
out << FriendlyName(op);
return out;
}
} // namespace tint::ast

View File

@@ -21,72 +21,69 @@ namespace {
using BinaryExpressionTest = TestHelper;
TEST_F(BinaryExpressionTest, Creation) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* r = create<BinaryExpression>(BinaryOp::kEqual, lhs, rhs);
EXPECT_EQ(r->lhs, lhs);
EXPECT_EQ(r->rhs, rhs);
EXPECT_EQ(r->op, BinaryOp::kEqual);
auto* r = create<BinaryExpression>(BinaryOp::kEqual, lhs, rhs);
EXPECT_EQ(r->lhs, lhs);
EXPECT_EQ(r->rhs, rhs);
EXPECT_EQ(r->op, BinaryOp::kEqual);
}
TEST_F(BinaryExpressionTest, Creation_WithSource) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* r = create<BinaryExpression>(Source{Source::Location{20, 2}},
BinaryOp::kEqual, lhs, rhs);
auto src = r->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* r = create<BinaryExpression>(Source{Source::Location{20, 2}}, BinaryOp::kEqual, lhs, rhs);
auto src = r->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(BinaryExpressionTest, IsBinary) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto* r = create<BinaryExpression>(BinaryOp::kEqual, lhs, rhs);
EXPECT_TRUE(r->Is<BinaryExpression>());
auto* r = create<BinaryExpression>(BinaryOp::kEqual, lhs, rhs);
EXPECT_TRUE(r->Is<BinaryExpression>());
}
TEST_F(BinaryExpressionTest, Assert_Null_LHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BinaryExpression>(BinaryOp::kEqual, nullptr, b.Expr("rhs"));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BinaryExpression>(BinaryOp::kEqual, nullptr, b.Expr("rhs"));
},
"internal compiler error");
}
TEST_F(BinaryExpressionTest, Assert_Null_RHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BinaryExpression>(BinaryOp::kEqual, b.Expr("lhs"), nullptr);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BinaryExpression>(BinaryOp::kEqual, b.Expr("lhs"), nullptr);
},
"internal compiler error");
}
TEST_F(BinaryExpressionTest, Assert_DifferentProgramID_LHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BinaryExpression>(BinaryOp::kEqual, b2.Expr("lhs"),
b1.Expr("rhs"));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BinaryExpression>(BinaryOp::kEqual, b2.Expr("lhs"), b1.Expr("rhs"));
},
"internal compiler error");
}
TEST_F(BinaryExpressionTest, Assert_DifferentProgramID_RHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BinaryExpression>(BinaryOp::kEqual, b1.Expr("lhs"),
b2.Expr("rhs"));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BinaryExpression>(BinaryOp::kEqual, b1.Expr("lhs"), b2.Expr("rhs"));
},
"internal compiler error");
}
} // namespace

View File

@@ -22,21 +22,19 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingAttribute);
namespace tint::ast {
BindingAttribute::BindingAttribute(ProgramID pid,
const Source& src,
uint32_t val)
BindingAttribute::BindingAttribute(ProgramID pid, const Source& src, uint32_t val)
: Base(pid, src), value(val) {}
BindingAttribute::~BindingAttribute() = default;
std::string BindingAttribute::Name() const {
return "binding";
return "binding";
}
const BindingAttribute* BindingAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BindingAttribute>(src, value);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BindingAttribute>(src, value);
}
} // namespace tint::ast

View File

@@ -23,25 +23,25 @@ namespace tint::ast {
/// A binding attribute
class BindingAttribute final : public Castable<BindingAttribute, Attribute> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the binding value
BindingAttribute(ProgramID pid, const Source& src, uint32_t value);
~BindingAttribute() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the binding value
BindingAttribute(ProgramID pid, const Source& src, uint32_t value);
~BindingAttribute() override;
/// @returns the WGSL name for the attribute
std::string Name() const override;
/// @returns the WGSL name for the attribute
std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BindingAttribute* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BindingAttribute* Clone(CloneContext* ctx) const override;
/// the binding value
const uint32_t value;
/// the binding value
const uint32_t value;
};
} // namespace tint::ast

View File

@@ -20,8 +20,8 @@ namespace {
using BindingAttributeTest = TestHelper;
TEST_F(BindingAttributeTest, Creation) {
auto* d = create<BindingAttribute>(2);
EXPECT_EQ(2u, d->value);
auto* d = create<BindingAttribute>(2);
EXPECT_EQ(2u, d->value);
}
} // namespace

View File

@@ -25,20 +25,20 @@ BitcastExpression::BitcastExpression(ProgramID pid,
const Type* t,
const Expression* e)
: Base(pid, src), type(t), expr(e) {
TINT_ASSERT(AST, type);
TINT_ASSERT(AST, expr);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, expr, program_id);
TINT_ASSERT(AST, type);
TINT_ASSERT(AST, expr);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, expr, program_id);
}
BitcastExpression::BitcastExpression(BitcastExpression&&) = default;
BitcastExpression::~BitcastExpression() = default;
const BitcastExpression* BitcastExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* t = ctx->Clone(type);
auto* e = ctx->Clone(expr);
return ctx->dst->create<BitcastExpression>(src, t, e);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* t = ctx->Clone(type);
auto* e = ctx->Clone(expr);
return ctx->dst->create<BitcastExpression>(src, t, e);
}
} // namespace tint::ast

View File

@@ -26,30 +26,30 @@ namespace tint::ast {
/// A bitcast expression
class BitcastExpression final : public Castable<BitcastExpression, Expression> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the bitcast expression source
/// @param type the type
/// @param expr the expr
BitcastExpression(ProgramID program_id,
const Source& source,
const Type* type,
const Expression* expr);
/// Move constructor
BitcastExpression(BitcastExpression&&);
~BitcastExpression() override;
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the bitcast expression source
/// @param type the type
/// @param expr the expr
BitcastExpression(ProgramID program_id,
const Source& source,
const Type* type,
const Expression* expr);
/// Move constructor
BitcastExpression(BitcastExpression&&);
~BitcastExpression() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BitcastExpression* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BitcastExpression* Clone(CloneContext* ctx) const override;
/// the target cast type
const Type* const type;
/// the expression
const Expression* const expr;
/// the target cast type
const Type* const type;
/// the expression
const Expression* const expr;
};
} // namespace tint::ast

View File

@@ -23,56 +23,55 @@ namespace {
using BitcastExpressionTest = TestHelper;
TEST_F(BitcastExpressionTest, Create) {
auto* expr = Expr("expr");
auto* expr = Expr("expr");
auto* exp = create<BitcastExpression>(ty.f32(), expr);
EXPECT_TRUE(exp->type->Is<ast::F32>());
ASSERT_EQ(exp->expr, expr);
auto* exp = create<BitcastExpression>(ty.f32(), expr);
EXPECT_TRUE(exp->type->Is<ast::F32>());
ASSERT_EQ(exp->expr, expr);
}
TEST_F(BitcastExpressionTest, CreateWithSource) {
auto* expr = Expr("expr");
auto* expr = Expr("expr");
auto* exp = create<BitcastExpression>(Source{Source::Location{20, 2}},
ty.f32(), expr);
auto src = exp->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* exp = create<BitcastExpression>(Source{Source::Location{20, 2}}, ty.f32(), expr);
auto src = exp->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(BitcastExpressionTest, IsBitcast) {
auto* expr = Expr("expr");
auto* expr = Expr("expr");
auto* exp = create<BitcastExpression>(ty.f32(), expr);
EXPECT_TRUE(exp->Is<BitcastExpression>());
auto* exp = create<BitcastExpression>(ty.f32(), expr);
EXPECT_TRUE(exp->Is<BitcastExpression>());
}
TEST_F(BitcastExpressionTest, Assert_Null_Type) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BitcastExpression>(nullptr, b.Expr("idx"));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BitcastExpression>(nullptr, b.Expr("idx"));
},
"internal compiler error");
}
TEST_F(BitcastExpressionTest, Assert_Null_Expr) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BitcastExpression>(b.ty.f32(), nullptr);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BitcastExpression>(b.ty.f32(), nullptr);
},
"internal compiler error");
}
TEST_F(BitcastExpressionTest, Assert_DifferentProgramID_Expr) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BitcastExpression>(b1.ty.f32(), b2.Expr("idx"));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BitcastExpression>(b1.ty.f32(), b2.Expr("idx"));
},
"internal compiler error");
}
} // namespace

View File

@@ -20,14 +20,12 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::BlockStatement);
namespace tint::ast {
BlockStatement::BlockStatement(ProgramID pid,
const Source& src,
const StatementList& stmts)
BlockStatement::BlockStatement(ProgramID pid, const Source& src, const StatementList& stmts)
: Base(pid, src), statements(std::move(stmts)) {
for (auto* stmt : statements) {
TINT_ASSERT(AST, stmt);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, stmt, program_id);
}
for (auto* stmt : statements) {
TINT_ASSERT(AST, stmt);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, stmt, program_id);
}
}
BlockStatement::BlockStatement(BlockStatement&&) = default;
@@ -35,10 +33,10 @@ BlockStatement::BlockStatement(BlockStatement&&) = default;
BlockStatement::~BlockStatement() = default;
const BlockStatement* BlockStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto stmts = ctx->Clone(statements);
return ctx->dst->create<BlockStatement>(src, stmts);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto stmts = ctx->Clone(statements);
return ctx->dst->create<BlockStatement>(src, stmts);
}
} // namespace tint::ast

View File

@@ -23,34 +23,30 @@ namespace tint::ast {
/// A block statement
class BlockStatement final : public Castable<BlockStatement, Statement> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the block statement source
/// @param statements the statements
BlockStatement(ProgramID program_id,
const Source& source,
const StatementList& statements);
/// Move constructor
BlockStatement(BlockStatement&&);
~BlockStatement() override;
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the block statement source
/// @param statements the statements
BlockStatement(ProgramID program_id, const Source& source, const StatementList& statements);
/// Move constructor
BlockStatement(BlockStatement&&);
~BlockStatement() override;
/// @returns true if the block has no statements
bool Empty() const { return statements.empty(); }
/// @returns true if the block has no statements
bool Empty() const { return statements.empty(); }
/// @returns the last statement in the block or nullptr if block empty
const Statement* Last() const {
return statements.empty() ? nullptr : statements.back();
}
/// @returns the last statement in the block or nullptr if block empty
const Statement* Last() const { return statements.empty() ? nullptr : statements.back(); }
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BlockStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BlockStatement* Clone(CloneContext* ctx) const override;
/// the statement list
const StatementList statements;
/// the statement list
const StatementList statements;
};
} // namespace tint::ast

View File

@@ -23,46 +23,44 @@ namespace {
using BlockStatementTest = TestHelper;
TEST_F(BlockStatementTest, Creation) {
auto* d = create<DiscardStatement>();
auto* ptr = d;
auto* d = create<DiscardStatement>();
auto* ptr = d;
auto* b = create<BlockStatement>(StatementList{d});
auto* b = create<BlockStatement>(StatementList{d});
ASSERT_EQ(b->statements.size(), 1u);
EXPECT_EQ(b->statements[0], ptr);
ASSERT_EQ(b->statements.size(), 1u);
EXPECT_EQ(b->statements[0], ptr);
}
TEST_F(BlockStatementTest, Creation_WithSource) {
auto* b = create<BlockStatement>(Source{Source::Location{20, 2}},
ast::StatementList{});
auto src = b->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* b = create<BlockStatement>(Source{Source::Location{20, 2}}, ast::StatementList{});
auto src = b->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(BlockStatementTest, IsBlock) {
auto* b = create<BlockStatement>(ast::StatementList{});
EXPECT_TRUE(b->Is<BlockStatement>());
auto* b = create<BlockStatement>(ast::StatementList{});
EXPECT_TRUE(b->Is<BlockStatement>());
}
TEST_F(BlockStatementTest, Assert_Null_Statement) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BlockStatement>(ast::StatementList{nullptr});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<BlockStatement>(ast::StatementList{nullptr});
},
"internal compiler error");
}
TEST_F(BlockStatementTest, Assert_DifferentProgramID_Statement) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BlockStatement>(
ast::StatementList{b2.create<DiscardStatement>()});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<BlockStatement>(ast::StatementList{b2.create<DiscardStatement>()});
},
"internal compiler error");
}
} // namespace

View File

@@ -27,12 +27,12 @@ Bool::Bool(Bool&&) = default;
Bool::~Bool() = default;
std::string Bool::FriendlyName(const SymbolTable&) const {
return "bool";
return "bool";
}
const Bool* Bool::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
return ctx->dst->create<Bool>(src);
auto src = ctx->Clone(source);
return ctx->dst->create<Bool>(src);
}
} // namespace tint::ast

View File

@@ -29,24 +29,24 @@ namespace tint::ast {
/// A boolean type
class Bool final : public Castable<Bool, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
Bool(ProgramID pid, const Source& src);
/// Move constructor
Bool(Bool&&);
~Bool() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
Bool(ProgramID pid, const Source& src);
/// Move constructor
Bool(Bool&&);
~Bool() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Bool* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const Bool* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -20,18 +20,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::BoolLiteralExpression);
namespace tint::ast {
BoolLiteralExpression::BoolLiteralExpression(ProgramID pid,
const Source& src,
bool val)
BoolLiteralExpression::BoolLiteralExpression(ProgramID pid, const Source& src, bool val)
: Base(pid, src), value(val) {}
BoolLiteralExpression::~BoolLiteralExpression() = default;
const BoolLiteralExpression* BoolLiteralExpression::Clone(
CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BoolLiteralExpression>(src, value);
const BoolLiteralExpression* BoolLiteralExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BoolLiteralExpression>(src, value);
}
} // namespace tint::ast

View File

@@ -22,24 +22,23 @@
namespace tint::ast {
/// A boolean literal
class BoolLiteralExpression final
: public Castable<BoolLiteralExpression, LiteralExpression> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the bool literals value
BoolLiteralExpression(ProgramID pid, const Source& src, bool value);
~BoolLiteralExpression() override;
class BoolLiteralExpression final : public Castable<BoolLiteralExpression, LiteralExpression> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the bool literals value
BoolLiteralExpression(ProgramID pid, const Source& src, bool value);
~BoolLiteralExpression() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BoolLiteralExpression* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BoolLiteralExpression* Clone(CloneContext* ctx) const override;
/// The boolean literal value
const bool value;
/// The boolean literal value
const bool value;
};
} // namespace tint::ast

View File

@@ -20,15 +20,15 @@ namespace {
using BoolLiteralExpressionTest = TestHelper;
TEST_F(BoolLiteralExpressionTest, True) {
auto* b = create<BoolLiteralExpression>(true);
ASSERT_TRUE(b->Is<BoolLiteralExpression>());
ASSERT_TRUE(b->value);
auto* b = create<BoolLiteralExpression>(true);
ASSERT_TRUE(b->Is<BoolLiteralExpression>());
ASSERT_TRUE(b->value);
}
TEST_F(BoolLiteralExpressionTest, False) {
auto* b = create<BoolLiteralExpression>(false);
ASSERT_TRUE(b->Is<BoolLiteralExpression>());
ASSERT_FALSE(b->value);
auto* b = create<BoolLiteralExpression>(false);
ASSERT_TRUE(b->Is<BoolLiteralExpression>());
ASSERT_FALSE(b->value);
}
} // namespace

View File

@@ -22,8 +22,8 @@ namespace {
using AstBoolTest = TestHelper;
TEST_F(AstBoolTest, FriendlyName) {
auto* b = create<Bool>();
EXPECT_EQ(b->FriendlyName(Symbols()), "bool");
auto* b = create<Bool>();
EXPECT_EQ(b->FriendlyName(Symbols()), "bool");
}
} // namespace

View File

@@ -20,17 +20,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::BreakStatement);
namespace tint::ast {
BreakStatement::BreakStatement(ProgramID pid, const Source& src)
: Base(pid, src) {}
BreakStatement::BreakStatement(ProgramID pid, const Source& src) : Base(pid, src) {}
BreakStatement::BreakStatement(BreakStatement&&) = default;
BreakStatement::~BreakStatement() = default;
const BreakStatement* BreakStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BreakStatement>(src);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BreakStatement>(src);
}
} // namespace tint::ast

View File

@@ -21,20 +21,20 @@ namespace tint::ast {
/// An break statement
class BreakStatement final : public Castable<BreakStatement, Statement> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
BreakStatement(ProgramID pid, const Source& src);
/// Move constructor
BreakStatement(BreakStatement&&);
~BreakStatement() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
BreakStatement(ProgramID pid, const Source& src);
/// Move constructor
BreakStatement(BreakStatement&&);
~BreakStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BreakStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BreakStatement* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,15 +22,15 @@ namespace {
using BreakStatementTest = TestHelper;
TEST_F(BreakStatementTest, Creation_WithSource) {
auto* stmt = create<BreakStatement>(Source{Source::Location{20, 2}});
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* stmt = create<BreakStatement>(Source{Source::Location{20, 2}});
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(BreakStatementTest, IsBreak) {
auto* stmt = create<BreakStatement>();
EXPECT_TRUE(stmt->Is<BreakStatement>());
auto* stmt = create<BreakStatement>();
EXPECT_TRUE(stmt->Is<BreakStatement>());
}
} // namespace

View File

@@ -17,64 +17,64 @@
namespace tint::ast {
std::ostream& operator<<(std::ostream& out, Builtin builtin) {
switch (builtin) {
case Builtin::kNone: {
out << "none";
break;
switch (builtin) {
case Builtin::kNone: {
out << "none";
break;
}
case Builtin::kPosition: {
out << "position";
break;
}
case Builtin::kVertexIndex: {
out << "vertex_index";
break;
}
case Builtin::kInstanceIndex: {
out << "instance_index";
break;
}
case Builtin::kFrontFacing: {
out << "front_facing";
break;
}
case Builtin::kFragDepth: {
out << "frag_depth";
break;
}
case Builtin::kLocalInvocationId: {
out << "local_invocation_id";
break;
}
case Builtin::kLocalInvocationIndex: {
out << "local_invocation_index";
break;
}
case Builtin::kGlobalInvocationId: {
out << "global_invocation_id";
break;
}
case Builtin::kWorkgroupId: {
out << "workgroup_id";
break;
}
case Builtin::kNumWorkgroups: {
out << "num_workgroups";
break;
}
case Builtin::kSampleIndex: {
out << "sample_index";
break;
}
case Builtin::kSampleMask: {
out << "sample_mask";
break;
}
case Builtin::kPointSize: {
out << "pointsize";
}
}
case Builtin::kPosition: {
out << "position";
break;
}
case Builtin::kVertexIndex: {
out << "vertex_index";
break;
}
case Builtin::kInstanceIndex: {
out << "instance_index";
break;
}
case Builtin::kFrontFacing: {
out << "front_facing";
break;
}
case Builtin::kFragDepth: {
out << "frag_depth";
break;
}
case Builtin::kLocalInvocationId: {
out << "local_invocation_id";
break;
}
case Builtin::kLocalInvocationIndex: {
out << "local_invocation_index";
break;
}
case Builtin::kGlobalInvocationId: {
out << "global_invocation_id";
break;
}
case Builtin::kWorkgroupId: {
out << "workgroup_id";
break;
}
case Builtin::kNumWorkgroups: {
out << "num_workgroups";
break;
}
case Builtin::kSampleIndex: {
out << "sample_index";
break;
}
case Builtin::kSampleMask: {
out << "sample_mask";
break;
}
case Builtin::kPointSize: {
out << "pointsize";
}
}
return out;
return out;
}
} // namespace tint::ast

View File

@@ -21,23 +21,23 @@ namespace tint::ast {
/// The builtin identifiers
enum class Builtin {
kNone = -1,
kPosition,
kVertexIndex,
kInstanceIndex,
kFrontFacing,
kFragDepth,
kLocalInvocationId,
kLocalInvocationIndex,
kGlobalInvocationId,
kWorkgroupId,
kNumWorkgroups,
kSampleIndex,
kSampleMask,
kNone = -1,
kPosition,
kVertexIndex,
kInstanceIndex,
kFrontFacing,
kFragDepth,
kLocalInvocationId,
kLocalInvocationIndex,
kGlobalInvocationId,
kWorkgroupId,
kNumWorkgroups,
kSampleIndex,
kSampleMask,
// Below are not currently WGSL builtins, but are included in this enum as
// they are used by certain backends.
kPointSize,
// Below are not currently WGSL builtins, but are included in this enum as
// they are used by certain backends.
kPointSize,
};
/// @param out the std::ostream to write to

View File

@@ -28,13 +28,13 @@ BuiltinAttribute::BuiltinAttribute(ProgramID pid, const Source& src, Builtin b)
BuiltinAttribute::~BuiltinAttribute() = default;
std::string BuiltinAttribute::Name() const {
return "builtin";
return "builtin";
}
const BuiltinAttribute* BuiltinAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BuiltinAttribute>(src, builtin);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<BuiltinAttribute>(src, builtin);
}
} // namespace tint::ast

View File

@@ -24,25 +24,25 @@ namespace tint::ast {
/// A builtin attribute
class BuiltinAttribute final : public Castable<BuiltinAttribute, Attribute> {
public:
/// constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param builtin the builtin value
BuiltinAttribute(ProgramID pid, const Source& src, Builtin builtin);
~BuiltinAttribute() override;
public:
/// constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param builtin the builtin value
BuiltinAttribute(ProgramID pid, const Source& src, Builtin builtin);
~BuiltinAttribute() override;
/// @returns the WGSL name for the attribute
std::string Name() const override;
/// @returns the WGSL name for the attribute
std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BuiltinAttribute* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const BuiltinAttribute* Clone(CloneContext* ctx) const override;
/// The builtin value
const Builtin builtin;
/// The builtin value
const Builtin builtin;
};
} // namespace tint::ast

View File

@@ -20,8 +20,8 @@ namespace {
using BuiltinAttributeTest = TestHelper;
TEST_F(BuiltinAttributeTest, Creation) {
auto* d = create<BuiltinAttribute>(Builtin::kFragDepth);
EXPECT_EQ(Builtin::kFragDepth, d->builtin);
auto* d = create<BuiltinAttribute>(Builtin::kFragDepth);
EXPECT_EQ(Builtin::kFragDepth, d->builtin);
}
} // namespace

File diff suppressed because it is too large Load Diff

View File

@@ -23,13 +23,7 @@
namespace tint::ast::builtin::test {
enum class TextureKind {
kRegular,
kDepth,
kDepthMultisampled,
kMultisampled,
kStorage
};
enum class TextureKind { kRegular, kDepth, kDepthMultisampled, kMultisampled, kStorage };
enum class TextureDataType { kF32, kU32, kI32 };
std::ostream& operator<<(std::ostream& out, const TextureKind& kind);
@@ -37,144 +31,144 @@ std::ostream& operator<<(std::ostream& out, const TextureDataType& ty);
/// Non-exhaustive list of valid texture overloads
enum class ValidTextureOverload {
kDimensions1d,
kDimensions2d,
kDimensions2dLevel,
kDimensions2dArray,
kDimensions2dArrayLevel,
kDimensions3d,
kDimensions3dLevel,
kDimensionsCube,
kDimensionsCubeLevel,
kDimensionsCubeArray,
kDimensionsCubeArrayLevel,
kDimensionsMultisampled2d,
kDimensionsDepth2d,
kDimensionsDepth2dLevel,
kDimensionsDepth2dArray,
kDimensionsDepth2dArrayLevel,
kDimensionsDepthCube,
kDimensionsDepthCubeLevel,
kDimensionsDepthCubeArray,
kDimensionsDepthCubeArrayLevel,
kDimensionsDepthMultisampled2d,
kDimensionsStorageWO1d,
kDimensionsStorageWO2d,
kDimensionsStorageWO2dArray,
kDimensionsStorageWO3d,
kGather2dF32,
kGather2dOffsetF32,
kGather2dArrayF32,
kGather2dArrayOffsetF32,
kGatherCubeF32,
kGatherCubeArrayF32,
kGatherDepth2dF32,
kGatherDepth2dOffsetF32,
kGatherDepth2dArrayF32,
kGatherDepth2dArrayOffsetF32,
kGatherDepthCubeF32,
kGatherDepthCubeArrayF32,
kGatherCompareDepth2dF32,
kGatherCompareDepth2dOffsetF32,
kGatherCompareDepth2dArrayF32,
kGatherCompareDepth2dArrayOffsetF32,
kGatherCompareDepthCubeF32,
kGatherCompareDepthCubeArrayF32,
kNumLayers2dArray,
kNumLayersCubeArray,
kNumLayersDepth2dArray,
kNumLayersDepthCubeArray,
kNumLayersStorageWO2dArray,
kNumLevels2d,
kNumLevels2dArray,
kNumLevels3d,
kNumLevelsCube,
kNumLevelsCubeArray,
kNumLevelsDepth2d,
kNumLevelsDepth2dArray,
kNumLevelsDepthCube,
kNumLevelsDepthCubeArray,
kNumSamplesMultisampled2d,
kNumSamplesDepthMultisampled2d,
kSample1dF32,
kSample2dF32,
kSample2dOffsetF32,
kSample2dArrayF32,
kSample2dArrayOffsetF32,
kSample3dF32,
kSample3dOffsetF32,
kSampleCubeF32,
kSampleCubeArrayF32,
kSampleDepth2dF32,
kSampleDepth2dOffsetF32,
kSampleDepth2dArrayF32,
kSampleDepth2dArrayOffsetF32,
kSampleDepthCubeF32,
kSampleDepthCubeArrayF32,
kSampleBias2dF32,
kSampleBias2dOffsetF32,
kSampleBias2dArrayF32,
kSampleBias2dArrayOffsetF32,
kSampleBias3dF32,
kSampleBias3dOffsetF32,
kSampleBiasCubeF32,
kSampleBiasCubeArrayF32,
kSampleLevel2dF32,
kSampleLevel2dOffsetF32,
kSampleLevel2dArrayF32,
kSampleLevel2dArrayOffsetF32,
kSampleLevel3dF32,
kSampleLevel3dOffsetF32,
kSampleLevelCubeF32,
kSampleLevelCubeArrayF32,
kSampleLevelDepth2dF32,
kSampleLevelDepth2dOffsetF32,
kSampleLevelDepth2dArrayF32,
kSampleLevelDepth2dArrayOffsetF32,
kSampleLevelDepthCubeF32,
kSampleLevelDepthCubeArrayF32,
kSampleGrad2dF32,
kSampleGrad2dOffsetF32,
kSampleGrad2dArrayF32,
kSampleGrad2dArrayOffsetF32,
kSampleGrad3dF32,
kSampleGrad3dOffsetF32,
kSampleGradCubeF32,
kSampleGradCubeArrayF32,
kSampleCompareDepth2dF32,
kSampleCompareDepth2dOffsetF32,
kSampleCompareDepth2dArrayF32,
kSampleCompareDepth2dArrayOffsetF32,
kSampleCompareDepthCubeF32,
kSampleCompareDepthCubeArrayF32,
kSampleCompareLevelDepth2dF32,
kSampleCompareLevelDepth2dOffsetF32,
kSampleCompareLevelDepth2dArrayF32,
kSampleCompareLevelDepth2dArrayOffsetF32,
kSampleCompareLevelDepthCubeF32,
kSampleCompareLevelDepthCubeArrayF32,
kLoad1dLevelF32,
kLoad1dLevelU32,
kLoad1dLevelI32,
kLoad2dLevelF32,
kLoad2dLevelU32,
kLoad2dLevelI32,
kLoad2dArrayLevelF32,
kLoad2dArrayLevelU32,
kLoad2dArrayLevelI32,
kLoad3dLevelF32,
kLoad3dLevelU32,
kLoad3dLevelI32,
kLoadMultisampled2dF32,
kLoadMultisampled2dU32,
kLoadMultisampled2dI32,
kLoadDepth2dLevelF32,
kLoadDepth2dArrayLevelF32,
kLoadDepthMultisampled2dF32,
kStoreWO1dRgba32float, // Not permutated for all texel formats
kStoreWO2dRgba32float, // Not permutated for all texel formats
kStoreWO2dArrayRgba32float, // Not permutated for all texel formats
kStoreWO3dRgba32float, // Not permutated for all texel formats
kDimensions1d,
kDimensions2d,
kDimensions2dLevel,
kDimensions2dArray,
kDimensions2dArrayLevel,
kDimensions3d,
kDimensions3dLevel,
kDimensionsCube,
kDimensionsCubeLevel,
kDimensionsCubeArray,
kDimensionsCubeArrayLevel,
kDimensionsMultisampled2d,
kDimensionsDepth2d,
kDimensionsDepth2dLevel,
kDimensionsDepth2dArray,
kDimensionsDepth2dArrayLevel,
kDimensionsDepthCube,
kDimensionsDepthCubeLevel,
kDimensionsDepthCubeArray,
kDimensionsDepthCubeArrayLevel,
kDimensionsDepthMultisampled2d,
kDimensionsStorageWO1d,
kDimensionsStorageWO2d,
kDimensionsStorageWO2dArray,
kDimensionsStorageWO3d,
kGather2dF32,
kGather2dOffsetF32,
kGather2dArrayF32,
kGather2dArrayOffsetF32,
kGatherCubeF32,
kGatherCubeArrayF32,
kGatherDepth2dF32,
kGatherDepth2dOffsetF32,
kGatherDepth2dArrayF32,
kGatherDepth2dArrayOffsetF32,
kGatherDepthCubeF32,
kGatherDepthCubeArrayF32,
kGatherCompareDepth2dF32,
kGatherCompareDepth2dOffsetF32,
kGatherCompareDepth2dArrayF32,
kGatherCompareDepth2dArrayOffsetF32,
kGatherCompareDepthCubeF32,
kGatherCompareDepthCubeArrayF32,
kNumLayers2dArray,
kNumLayersCubeArray,
kNumLayersDepth2dArray,
kNumLayersDepthCubeArray,
kNumLayersStorageWO2dArray,
kNumLevels2d,
kNumLevels2dArray,
kNumLevels3d,
kNumLevelsCube,
kNumLevelsCubeArray,
kNumLevelsDepth2d,
kNumLevelsDepth2dArray,
kNumLevelsDepthCube,
kNumLevelsDepthCubeArray,
kNumSamplesMultisampled2d,
kNumSamplesDepthMultisampled2d,
kSample1dF32,
kSample2dF32,
kSample2dOffsetF32,
kSample2dArrayF32,
kSample2dArrayOffsetF32,
kSample3dF32,
kSample3dOffsetF32,
kSampleCubeF32,
kSampleCubeArrayF32,
kSampleDepth2dF32,
kSampleDepth2dOffsetF32,
kSampleDepth2dArrayF32,
kSampleDepth2dArrayOffsetF32,
kSampleDepthCubeF32,
kSampleDepthCubeArrayF32,
kSampleBias2dF32,
kSampleBias2dOffsetF32,
kSampleBias2dArrayF32,
kSampleBias2dArrayOffsetF32,
kSampleBias3dF32,
kSampleBias3dOffsetF32,
kSampleBiasCubeF32,
kSampleBiasCubeArrayF32,
kSampleLevel2dF32,
kSampleLevel2dOffsetF32,
kSampleLevel2dArrayF32,
kSampleLevel2dArrayOffsetF32,
kSampleLevel3dF32,
kSampleLevel3dOffsetF32,
kSampleLevelCubeF32,
kSampleLevelCubeArrayF32,
kSampleLevelDepth2dF32,
kSampleLevelDepth2dOffsetF32,
kSampleLevelDepth2dArrayF32,
kSampleLevelDepth2dArrayOffsetF32,
kSampleLevelDepthCubeF32,
kSampleLevelDepthCubeArrayF32,
kSampleGrad2dF32,
kSampleGrad2dOffsetF32,
kSampleGrad2dArrayF32,
kSampleGrad2dArrayOffsetF32,
kSampleGrad3dF32,
kSampleGrad3dOffsetF32,
kSampleGradCubeF32,
kSampleGradCubeArrayF32,
kSampleCompareDepth2dF32,
kSampleCompareDepth2dOffsetF32,
kSampleCompareDepth2dArrayF32,
kSampleCompareDepth2dArrayOffsetF32,
kSampleCompareDepthCubeF32,
kSampleCompareDepthCubeArrayF32,
kSampleCompareLevelDepth2dF32,
kSampleCompareLevelDepth2dOffsetF32,
kSampleCompareLevelDepth2dArrayF32,
kSampleCompareLevelDepth2dArrayOffsetF32,
kSampleCompareLevelDepthCubeF32,
kSampleCompareLevelDepthCubeArrayF32,
kLoad1dLevelF32,
kLoad1dLevelU32,
kLoad1dLevelI32,
kLoad2dLevelF32,
kLoad2dLevelU32,
kLoad2dLevelI32,
kLoad2dArrayLevelF32,
kLoad2dArrayLevelU32,
kLoad2dArrayLevelI32,
kLoad3dLevelF32,
kLoad3dLevelU32,
kLoad3dLevelI32,
kLoadMultisampled2dF32,
kLoadMultisampled2dU32,
kLoadMultisampled2dI32,
kLoadDepth2dLevelF32,
kLoadDepth2dArrayLevelF32,
kLoadDepthMultisampled2dF32,
kStoreWO1dRgba32float, // Not permutated for all texel formats
kStoreWO2dRgba32float, // Not permutated for all texel formats
kStoreWO2dArrayRgba32float, // Not permutated for all texel formats
kStoreWO3dRgba32float, // Not permutated for all texel formats
};
/// @param texture_overload the ValidTextureOverload
@@ -183,77 +177,76 @@ bool ReturnsVoid(ValidTextureOverload texture_overload);
/// Describes a texture builtin overload
struct TextureOverloadCase {
/// Constructor for textureSample...() functions
TextureOverloadCase(ValidTextureOverload,
const char*,
TextureKind,
ast::SamplerKind,
ast::TextureDimension,
TextureDataType,
const char*,
std::function<ExpressionList(ProgramBuilder*)>);
/// Constructor for textureLoad() functions with non-storage textures
TextureOverloadCase(ValidTextureOverload,
const char*,
TextureKind,
ast::TextureDimension,
TextureDataType,
const char*,
std::function<ExpressionList(ProgramBuilder*)>);
/// Constructor for textureLoad() with storage textures
TextureOverloadCase(ValidTextureOverload,
const char*,
Access,
ast::TexelFormat,
ast::TextureDimension,
TextureDataType,
const char*,
std::function<ExpressionList(ProgramBuilder*)>);
/// Copy constructor
TextureOverloadCase(const TextureOverloadCase&);
/// Destructor
~TextureOverloadCase();
/// Constructor for textureSample...() functions
TextureOverloadCase(ValidTextureOverload,
const char*,
TextureKind,
ast::SamplerKind,
ast::TextureDimension,
TextureDataType,
const char*,
std::function<ExpressionList(ProgramBuilder*)>);
/// Constructor for textureLoad() functions with non-storage textures
TextureOverloadCase(ValidTextureOverload,
const char*,
TextureKind,
ast::TextureDimension,
TextureDataType,
const char*,
std::function<ExpressionList(ProgramBuilder*)>);
/// Constructor for textureLoad() with storage textures
TextureOverloadCase(ValidTextureOverload,
const char*,
Access,
ast::TexelFormat,
ast::TextureDimension,
TextureDataType,
const char*,
std::function<ExpressionList(ProgramBuilder*)>);
/// Copy constructor
TextureOverloadCase(const TextureOverloadCase&);
/// Destructor
~TextureOverloadCase();
/// @return a vector containing a large number (non-exhaustive) of valid
/// texture overloads.
static std::vector<TextureOverloadCase> ValidCases();
/// @return a vector containing a large number (non-exhaustive) of valid
/// texture overloads.
static std::vector<TextureOverloadCase> ValidCases();
/// @param builder the AST builder used for the test
/// @returns the vector component type of the texture function return value
const ast::Type* BuildResultVectorComponentType(
ProgramBuilder* builder) const;
/// @param builder the AST builder used for the test
/// @returns a variable holding the test texture, automatically registered as
/// a global variable.
const ast::Variable* BuildTextureVariable(ProgramBuilder* builder) const;
/// @param builder the AST builder used for the test
/// @returns a Variable holding the test sampler, automatically registered as
/// a global variable.
const ast::Variable* BuildSamplerVariable(ProgramBuilder* builder) const;
/// @param builder the AST builder used for the test
/// @returns the vector component type of the texture function return value
const ast::Type* BuildResultVectorComponentType(ProgramBuilder* builder) const;
/// @param builder the AST builder used for the test
/// @returns a variable holding the test texture, automatically registered as
/// a global variable.
const ast::Variable* BuildTextureVariable(ProgramBuilder* builder) const;
/// @param builder the AST builder used for the test
/// @returns a Variable holding the test sampler, automatically registered as
/// a global variable.
const ast::Variable* BuildSamplerVariable(ProgramBuilder* builder) const;
/// The enumerator for this overload
const ValidTextureOverload overload;
/// A human readable description of the overload
const char* const description;
/// The texture kind for the texture parameter
const TextureKind texture_kind;
/// The sampler kind for the sampler parameter
/// Used only when texture_kind is not kStorage
ast::SamplerKind const sampler_kind = ast::SamplerKind::kSampler;
/// The access control for the storage texture
/// Used only when texture_kind is kStorage
Access const access = Access::kReadWrite;
/// The image format for the storage texture
/// Used only when texture_kind is kStorage
ast::TexelFormat const texel_format = ast::TexelFormat::kNone;
/// The dimensions of the texture parameter
ast::TextureDimension const texture_dimension;
/// The data type of the texture parameter
const TextureDataType texture_data_type;
/// Name of the function. e.g. `textureSample`, `textureSampleGrad`, etc
const char* const function;
/// A function that builds the AST arguments for the overload
std::function<ExpressionList(ProgramBuilder*)> const args;
/// The enumerator for this overload
const ValidTextureOverload overload;
/// A human readable description of the overload
const char* const description;
/// The texture kind for the texture parameter
const TextureKind texture_kind;
/// The sampler kind for the sampler parameter
/// Used only when texture_kind is not kStorage
ast::SamplerKind const sampler_kind = ast::SamplerKind::kSampler;
/// The access control for the storage texture
/// Used only when texture_kind is kStorage
Access const access = Access::kReadWrite;
/// The image format for the storage texture
/// Used only when texture_kind is kStorage
ast::TexelFormat const texel_format = ast::TexelFormat::kNone;
/// The dimensions of the texture parameter
ast::TextureDimension const texture_dimension;
/// The data type of the texture parameter
const TextureDataType texture_data_type;
/// Name of the function. e.g. `textureSample`, `textureSampleGrad`, etc
const char* const function;
/// A function that builds the AST arguments for the overload
std::function<ExpressionList(ProgramBuilder*)> const args;
};
std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data);

View File

@@ -22,14 +22,14 @@ namespace tint::ast {
namespace {
CallExpression::Target ToTarget(const IdentifierExpression* name) {
CallExpression::Target target;
target.name = name;
return target;
CallExpression::Target target;
target.name = name;
return target;
}
CallExpression::Target ToTarget(const Type* type) {
CallExpression::Target target;
target.type = type;
return target;
CallExpression::Target target;
target.type = type;
return target;
}
} // namespace
@@ -38,25 +38,22 @@ CallExpression::CallExpression(ProgramID pid,
const IdentifierExpression* name,
ExpressionList a)
: Base(pid, src), target(ToTarget(name)), args(a) {
TINT_ASSERT(AST, name);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id);
for (auto* arg : args) {
TINT_ASSERT(AST, arg);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
}
TINT_ASSERT(AST, name);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id);
for (auto* arg : args) {
TINT_ASSERT(AST, arg);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
}
}
CallExpression::CallExpression(ProgramID pid,
const Source& src,
const Type* type,
ExpressionList a)
CallExpression::CallExpression(ProgramID pid, const Source& src, const Type* type, ExpressionList a)
: Base(pid, src), target(ToTarget(type)), args(a) {
TINT_ASSERT(AST, type);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
for (auto* arg : args) {
TINT_ASSERT(AST, arg);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
}
TINT_ASSERT(AST, type);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
for (auto* arg : args) {
TINT_ASSERT(AST, arg);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
}
}
CallExpression::CallExpression(CallExpression&&) = default;
@@ -64,13 +61,11 @@ CallExpression::CallExpression(CallExpression&&) = default;
CallExpression::~CallExpression() = default;
const CallExpression* CallExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto p = ctx->Clone(args);
return target.name
? ctx->dst->create<CallExpression>(src, ctx->Clone(target.name), p)
: ctx->dst->create<CallExpression>(src, ctx->Clone(target.type),
p);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto p = ctx->Clone(args);
return target.name ? ctx->dst->create<CallExpression>(src, ctx->Clone(target.name), p)
: ctx->dst->create<CallExpression>(src, ctx->Clone(target.type), p);
}
} // namespace tint::ast

View File

@@ -31,52 +31,52 @@ namespace tint::ast {
/// * sem::TypeConstructor
/// * sem::TypeConversion
class CallExpression final : public Castable<CallExpression, Expression> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the call expression source
/// @param name the function or type name
/// @param args the arguments
CallExpression(ProgramID program_id,
const Source& source,
const IdentifierExpression* name,
ExpressionList args);
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the call expression source
/// @param name the function or type name
/// @param args the arguments
CallExpression(ProgramID program_id,
const Source& source,
const IdentifierExpression* name,
ExpressionList args);
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the call expression source
/// @param type the type
/// @param args the arguments
CallExpression(ProgramID program_id,
const Source& source,
const Type* type,
ExpressionList args);
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the call expression source
/// @param type the type
/// @param args the arguments
CallExpression(ProgramID program_id,
const Source& source,
const Type* type,
ExpressionList args);
/// Move constructor
CallExpression(CallExpression&&);
~CallExpression() override;
/// Move constructor
CallExpression(CallExpression&&);
~CallExpression() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CallExpression* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CallExpression* Clone(CloneContext* ctx) const override;
/// Target is either an identifier, or a Type.
/// One of these must be nullptr and the other a non-nullptr.
struct Target {
/// name is a function or builtin to call, or type name to construct or
/// cast-to
const IdentifierExpression* name = nullptr;
/// type to construct or cast-to
const Type* type = nullptr;
};
/// Target is either an identifier, or a Type.
/// One of these must be nullptr and the other a non-nullptr.
struct Target {
/// name is a function or builtin to call, or type name to construct or
/// cast-to
const IdentifierExpression* name = nullptr;
/// type to construct or cast-to
const Type* type = nullptr;
};
/// The target function
const Target target;
/// The target function
const Target target;
/// The arguments
const ExpressionList args;
/// The arguments
const ExpressionList args;
};
} // namespace tint::ast

View File

@@ -21,126 +21,124 @@ namespace {
using CallExpressionTest = TestHelper;
TEST_F(CallExpressionTest, CreationIdentifier) {
auto* func = Expr("func");
ExpressionList params;
params.push_back(Expr("param1"));
params.push_back(Expr("param2"));
auto* func = Expr("func");
ExpressionList params;
params.push_back(Expr("param1"));
params.push_back(Expr("param2"));
auto* stmt = create<CallExpression>(func, params);
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
auto* stmt = create<CallExpression>(func, params);
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
const auto& vec = stmt->args;
ASSERT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0], params[0]);
EXPECT_EQ(vec[1], params[1]);
const auto& vec = stmt->args;
ASSERT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0], params[0]);
EXPECT_EQ(vec[1], params[1]);
}
TEST_F(CallExpressionTest, CreationIdentifier_WithSource) {
auto* func = Expr("func");
auto* stmt = create<CallExpression>(Source{{20, 2}}, func, ExpressionList{});
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
auto* func = Expr("func");
auto* stmt = create<CallExpression>(Source{{20, 2}}, func, ExpressionList{});
EXPECT_EQ(stmt->target.name, func);
EXPECT_EQ(stmt->target.type, nullptr);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(CallExpressionTest, CreationType) {
auto* type = ty.f32();
ExpressionList params;
params.push_back(Expr("param1"));
params.push_back(Expr("param2"));
auto* type = ty.f32();
ExpressionList params;
params.push_back(Expr("param1"));
params.push_back(Expr("param2"));
auto* stmt = create<CallExpression>(type, params);
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
auto* stmt = create<CallExpression>(type, params);
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
const auto& vec = stmt->args;
ASSERT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0], params[0]);
EXPECT_EQ(vec[1], params[1]);
const auto& vec = stmt->args;
ASSERT_EQ(vec.size(), 2u);
EXPECT_EQ(vec[0], params[0]);
EXPECT_EQ(vec[1], params[1]);
}
TEST_F(CallExpressionTest, CreationType_WithSource) {
auto* type = ty.f32();
auto* stmt = create<CallExpression>(Source{{20, 2}}, type, ExpressionList{});
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
auto* type = ty.f32();
auto* stmt = create<CallExpression>(Source{{20, 2}}, type, ExpressionList{});
EXPECT_EQ(stmt->target.name, nullptr);
EXPECT_EQ(stmt->target.type, type);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(CallExpressionTest, IsCall) {
auto* func = Expr("func");
auto* stmt = create<CallExpression>(func, ExpressionList{});
EXPECT_TRUE(stmt->Is<CallExpression>());
auto* func = Expr("func");
auto* stmt = create<CallExpression>(func, ExpressionList{});
EXPECT_TRUE(stmt->Is<CallExpression>());
}
TEST_F(CallExpressionTest, Assert_Null_Identifier) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CallExpression>(static_cast<IdentifierExpression*>(nullptr),
ExpressionList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CallExpression>(static_cast<IdentifierExpression*>(nullptr), ExpressionList{});
},
"internal compiler error");
}
TEST_F(CallExpressionTest, Assert_Null_Type) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CallExpression>(static_cast<Type*>(nullptr), ExpressionList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CallExpression>(static_cast<Type*>(nullptr), ExpressionList{});
},
"internal compiler error");
}
TEST_F(CallExpressionTest, Assert_Null_Param) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
ExpressionList params;
params.push_back(b.Expr("param1"));
params.push_back(nullptr);
params.push_back(b.Expr("param2"));
b.create<CallExpression>(b.Expr("func"), params);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
ExpressionList params;
params.push_back(b.Expr("param1"));
params.push_back(nullptr);
params.push_back(b.Expr("param2"));
b.create<CallExpression>(b.Expr("func"), params);
},
"internal compiler error");
}
TEST_F(CallExpressionTest, Assert_DifferentProgramID_Identifier) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallExpression>(b2.Expr("func"), ExpressionList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallExpression>(b2.Expr("func"), ExpressionList{});
},
"internal compiler error");
}
TEST_F(CallExpressionTest, Assert_DifferentProgramID_Type) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallExpression>(b2.ty.f32(), ExpressionList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallExpression>(b2.ty.f32(), ExpressionList{});
},
"internal compiler error");
}
TEST_F(CallExpressionTest, Assert_DifferentProgramID_Param) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallExpression>(b1.Expr("func"),
ExpressionList{b2.Expr("param1")});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallExpression>(b1.Expr("func"), ExpressionList{b2.Expr("param1")});
},
"internal compiler error");
}
} // namespace

View File

@@ -20,12 +20,10 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::CallStatement);
namespace tint::ast {
CallStatement::CallStatement(ProgramID pid,
const Source& src,
const CallExpression* call)
CallStatement::CallStatement(ProgramID pid, const Source& src, const CallExpression* call)
: Base(pid, src), expr(call) {
TINT_ASSERT(AST, expr);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, expr, program_id);
TINT_ASSERT(AST, expr);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, expr, program_id);
}
CallStatement::CallStatement(CallStatement&&) = default;
@@ -33,10 +31,10 @@ CallStatement::CallStatement(CallStatement&&) = default;
CallStatement::~CallStatement() = default;
const CallStatement* CallStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* call = ctx->Clone(expr);
return ctx->dst->create<CallStatement>(src, call);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* call = ctx->Clone(expr);
return ctx->dst->create<CallStatement>(src, call);
}
} // namespace tint::ast

View File

@@ -22,24 +22,24 @@ namespace tint::ast {
/// A call expression
class CallStatement final : public Castable<CallStatement, Statement> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node for the statement
/// @param call the function
CallStatement(ProgramID pid, const Source& src, const CallExpression* call);
/// Move constructor
CallStatement(CallStatement&&);
~CallStatement() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node for the statement
/// @param call the function
CallStatement(ProgramID pid, const Source& src, const CallExpression* call);
/// Move constructor
CallStatement(CallStatement&&);
~CallStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CallStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CallStatement* Clone(CloneContext* ctx) const override;
/// The call expression
const CallExpression* const expr;
/// The call expression
const CallExpression* const expr;
};
} // namespace tint::ast

View File

@@ -23,35 +23,34 @@ namespace {
using CallStatementTest = TestHelper;
TEST_F(CallStatementTest, Creation) {
auto* expr = create<CallExpression>(Expr("func"), ExpressionList{});
auto* expr = create<CallExpression>(Expr("func"), ExpressionList{});
auto* c = create<CallStatement>(expr);
EXPECT_EQ(c->expr, expr);
auto* c = create<CallStatement>(expr);
EXPECT_EQ(c->expr, expr);
}
TEST_F(CallStatementTest, IsCall) {
auto* c = create<CallStatement>(Call("f"));
EXPECT_TRUE(c->Is<CallStatement>());
auto* c = create<CallStatement>(Call("f"));
EXPECT_TRUE(c->Is<CallStatement>());
}
TEST_F(CallStatementTest, Assert_Null_Call) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CallStatement>(nullptr);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CallStatement>(nullptr);
},
"internal compiler error");
}
TEST_F(CallStatementTest, Assert_DifferentProgramID_Call) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallStatement>(
b2.create<CallExpression>(b2.Expr("func"), ExpressionList{}));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CallStatement>(b2.create<CallExpression>(b2.Expr("func"), ExpressionList{}));
},
"internal compiler error");
}
} // namespace

View File

@@ -25,12 +25,12 @@ CaseStatement::CaseStatement(ProgramID pid,
CaseSelectorList s,
const BlockStatement* b)
: Base(pid, src), selectors(s), body(b) {
TINT_ASSERT(AST, body);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
for (auto* selector : selectors) {
TINT_ASSERT(AST, selector);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, selector, program_id);
}
TINT_ASSERT(AST, body);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
for (auto* selector : selectors) {
TINT_ASSERT(AST, selector);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, selector, program_id);
}
}
CaseStatement::CaseStatement(CaseStatement&&) = default;
@@ -38,11 +38,11 @@ CaseStatement::CaseStatement(CaseStatement&&) = default;
CaseStatement::~CaseStatement() = default;
const CaseStatement* CaseStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto sel = ctx->Clone(selectors);
auto* b = ctx->Clone(body);
return ctx->dst->create<CaseStatement>(src, sel, b);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto sel = ctx->Clone(selectors);
auto* b = ctx->Clone(body);
return ctx->dst->create<CaseStatement>(src, sel, b);
}
} // namespace tint::ast

View File

@@ -27,34 +27,34 @@ using CaseSelectorList = std::vector<const IntLiteralExpression*>;
/// A case statement
class CaseStatement final : public Castable<CaseStatement, Statement> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param selectors the case selectors
/// @param body the case body
CaseStatement(ProgramID pid,
const Source& src,
CaseSelectorList selectors,
const BlockStatement* body);
/// Move constructor
CaseStatement(CaseStatement&&);
~CaseStatement() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param selectors the case selectors
/// @param body the case body
CaseStatement(ProgramID pid,
const Source& src,
CaseSelectorList selectors,
const BlockStatement* body);
/// Move constructor
CaseStatement(CaseStatement&&);
~CaseStatement() override;
/// @returns true if this is a default statement
bool IsDefault() const { return selectors.empty(); }
/// @returns true if this is a default statement
bool IsDefault() const { return selectors.empty(); }
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CaseStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CaseStatement* Clone(CloneContext* ctx) const override;
/// The case selectors, empty if none set
const CaseSelectorList selectors;
/// The case selectors, empty if none set
const CaseSelectorList selectors;
/// The case body
const BlockStatement* const body;
/// The case body
const BlockStatement* const body;
};
/// A list of case statements

View File

@@ -25,110 +25,108 @@ namespace {
using CaseStatementTest = TestHelper;
TEST_F(CaseStatementTest, Creation_i32) {
CaseSelectorList b;
auto* selector = create<SintLiteralExpression>(2);
b.push_back(selector);
CaseSelectorList b;
auto* selector = create<SintLiteralExpression>(2);
b.push_back(selector);
auto* discard = create<DiscardStatement>();
auto* body = create<BlockStatement>(StatementList{discard});
auto* discard = create<DiscardStatement>();
auto* body = create<BlockStatement>(StatementList{discard});
auto* c = create<CaseStatement>(b, body);
ASSERT_EQ(c->selectors.size(), 1u);
EXPECT_EQ(c->selectors[0], selector);
ASSERT_EQ(c->body->statements.size(), 1u);
EXPECT_EQ(c->body->statements[0], discard);
auto* c = create<CaseStatement>(b, body);
ASSERT_EQ(c->selectors.size(), 1u);
EXPECT_EQ(c->selectors[0], selector);
ASSERT_EQ(c->body->statements.size(), 1u);
EXPECT_EQ(c->body->statements[0], discard);
}
TEST_F(CaseStatementTest, Creation_u32) {
CaseSelectorList b;
auto* selector = create<UintLiteralExpression>(2u);
b.push_back(selector);
CaseSelectorList b;
auto* selector = create<UintLiteralExpression>(2u);
b.push_back(selector);
auto* discard = create<DiscardStatement>();
auto* body = create<BlockStatement>(StatementList{discard});
auto* discard = create<DiscardStatement>();
auto* body = create<BlockStatement>(StatementList{discard});
auto* c = create<CaseStatement>(b, body);
ASSERT_EQ(c->selectors.size(), 1u);
EXPECT_EQ(c->selectors[0], selector);
ASSERT_EQ(c->body->statements.size(), 1u);
EXPECT_EQ(c->body->statements[0], discard);
auto* c = create<CaseStatement>(b, body);
ASSERT_EQ(c->selectors.size(), 1u);
EXPECT_EQ(c->selectors[0], selector);
ASSERT_EQ(c->body->statements.size(), 1u);
EXPECT_EQ(c->body->statements[0], discard);
}
TEST_F(CaseStatementTest, Creation_WithSource) {
CaseSelectorList b;
b.push_back(create<SintLiteralExpression>(2));
CaseSelectorList b;
b.push_back(create<SintLiteralExpression>(2));
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),
});
auto* c = create<CaseStatement>(Source{Source::Location{20, 2}}, b, body);
auto src = c->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),
});
auto* c = create<CaseStatement>(Source{Source::Location{20, 2}}, b, body);
auto src = c->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),
});
auto* c = create<CaseStatement>(CaseSelectorList{}, body);
EXPECT_TRUE(c->IsDefault());
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(),
});
auto* c = create<CaseStatement>(CaseSelectorList{}, body);
EXPECT_TRUE(c->IsDefault());
}
TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
CaseSelectorList b;
b.push_back(create<SintLiteralExpression>(2));
CaseSelectorList b;
b.push_back(create<SintLiteralExpression>(2));
auto* c = create<CaseStatement>(b, create<BlockStatement>(StatementList{}));
EXPECT_FALSE(c->IsDefault());
auto* c = create<CaseStatement>(b, create<BlockStatement>(StatementList{}));
EXPECT_FALSE(c->IsDefault());
}
TEST_F(CaseStatementTest, IsCase) {
auto* c = create<CaseStatement>(CaseSelectorList{},
create<BlockStatement>(StatementList{}));
EXPECT_TRUE(c->Is<CaseStatement>());
auto* c = create<CaseStatement>(CaseSelectorList{}, create<BlockStatement>(StatementList{}));
EXPECT_TRUE(c->Is<CaseStatement>());
}
TEST_F(CaseStatementTest, Assert_Null_Body) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CaseStatement>(CaseSelectorList{}, nullptr);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CaseStatement>(CaseSelectorList{}, nullptr);
},
"internal compiler error");
}
TEST_F(CaseStatementTest, Assert_Null_Selector) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CaseStatement>(CaseSelectorList{nullptr},
b.create<BlockStatement>(StatementList{}));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CaseStatement>(CaseSelectorList{nullptr},
b.create<BlockStatement>(StatementList{}));
},
"internal compiler error");
}
TEST_F(CaseStatementTest, Assert_DifferentProgramID_Call) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CaseStatement>(CaseSelectorList{},
b2.create<BlockStatement>(StatementList{}));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CaseStatement>(CaseSelectorList{},
b2.create<BlockStatement>(StatementList{}));
},
"internal compiler error");
}
TEST_F(CaseStatementTest, Assert_DifferentProgramID_Selector) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CaseStatement>(
CaseSelectorList{b2.create<SintLiteralExpression>(2)},
b1.create<BlockStatement>(StatementList{}));
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CaseStatement>(CaseSelectorList{b2.create<SintLiteralExpression>(2)},
b1.create<BlockStatement>(StatementList{}));
},
"internal compiler error");
}
} // namespace

View File

@@ -26,24 +26,22 @@ CompoundAssignmentStatement::CompoundAssignmentStatement(ProgramID pid,
const Expression* r,
BinaryOp o)
: Base(pid, src), lhs(l), rhs(r), op(o) {
TINT_ASSERT(AST, lhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
TINT_ASSERT(AST, rhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
TINT_ASSERT(AST, lhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
TINT_ASSERT(AST, rhs);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
}
CompoundAssignmentStatement::CompoundAssignmentStatement(
CompoundAssignmentStatement&&) = default;
CompoundAssignmentStatement::CompoundAssignmentStatement(CompoundAssignmentStatement&&) = default;
CompoundAssignmentStatement::~CompoundAssignmentStatement() = default;
const CompoundAssignmentStatement* CompoundAssignmentStatement::Clone(
CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* l = ctx->Clone(lhs);
auto* r = ctx->Clone(rhs);
return ctx->dst->create<CompoundAssignmentStatement>(src, l, r, op);
const CompoundAssignmentStatement* CompoundAssignmentStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* l = ctx->Clone(lhs);
auto* r = ctx->Clone(rhs);
return ctx->dst->create<CompoundAssignmentStatement>(src, l, r, op);
}
} // namespace tint::ast

View File

@@ -22,38 +22,37 @@
namespace tint::ast {
/// A compound assignment statement
class CompoundAssignmentStatement final
: public Castable<CompoundAssignmentStatement, Statement> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the compound assignment statement source
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
/// @param op the binary operator
CompoundAssignmentStatement(ProgramID program_id,
const Source& source,
const Expression* lhs,
const Expression* rhs,
BinaryOp op);
/// Move constructor
CompoundAssignmentStatement(CompoundAssignmentStatement&&);
~CompoundAssignmentStatement() override;
class CompoundAssignmentStatement final : public Castable<CompoundAssignmentStatement, Statement> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the compound assignment statement source
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
/// @param op the binary operator
CompoundAssignmentStatement(ProgramID program_id,
const Source& source,
const Expression* lhs,
const Expression* rhs,
BinaryOp op);
/// Move constructor
CompoundAssignmentStatement(CompoundAssignmentStatement&&);
~CompoundAssignmentStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CompoundAssignmentStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const CompoundAssignmentStatement* Clone(CloneContext* ctx) const override;
/// left side expression
const Expression* const lhs;
/// left side expression
const Expression* const lhs;
/// right side expression
const Expression* const rhs;
/// right side expression
const Expression* const rhs;
/// the binary operator
const BinaryOp op;
/// the binary operator
const BinaryOp op;
};
} // namespace tint::ast

View File

@@ -23,77 +23,72 @@ namespace {
using CompoundAssignmentStatementTest = TestHelper;
TEST_F(CompoundAssignmentStatementTest, Creation) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto op = BinaryOp::kAdd;
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto op = BinaryOp::kAdd;
auto* stmt = create<CompoundAssignmentStatement>(lhs, rhs, op);
EXPECT_EQ(stmt->lhs, lhs);
EXPECT_EQ(stmt->rhs, rhs);
EXPECT_EQ(stmt->op, op);
auto* stmt = create<CompoundAssignmentStatement>(lhs, rhs, op);
EXPECT_EQ(stmt->lhs, lhs);
EXPECT_EQ(stmt->rhs, rhs);
EXPECT_EQ(stmt->op, op);
}
TEST_F(CompoundAssignmentStatementTest, CreationWithSource) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto op = BinaryOp::kMultiply;
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto op = BinaryOp::kMultiply;
auto* stmt = create<CompoundAssignmentStatement>(
Source{Source::Location{20, 2}}, lhs, rhs, op);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* stmt = create<CompoundAssignmentStatement>(Source{Source::Location{20, 2}}, lhs, rhs, op);
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(CompoundAssignmentStatementTest, IsCompoundAssign) {
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto op = BinaryOp::kSubtract;
auto* lhs = Expr("lhs");
auto* rhs = Expr("rhs");
auto op = BinaryOp::kSubtract;
auto* stmt = create<CompoundAssignmentStatement>(lhs, rhs, op);
EXPECT_TRUE(stmt->Is<CompoundAssignmentStatement>());
auto* stmt = create<CompoundAssignmentStatement>(lhs, rhs, op);
EXPECT_TRUE(stmt->Is<CompoundAssignmentStatement>());
}
TEST_F(CompoundAssignmentStatementTest, Assert_Null_LHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CompoundAssignmentStatement>(nullptr, b.Expr(1),
BinaryOp::kAdd);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CompoundAssignmentStatement>(nullptr, b.Expr(1), BinaryOp::kAdd);
},
"internal compiler error");
}
TEST_F(CompoundAssignmentStatementTest, Assert_Null_RHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CompoundAssignmentStatement>(b.Expr(1), nullptr,
BinaryOp::kAdd);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.create<CompoundAssignmentStatement>(b.Expr(1), nullptr, BinaryOp::kAdd);
},
"internal compiler error");
}
TEST_F(CompoundAssignmentStatementTest, Assert_DifferentProgramID_LHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CompoundAssignmentStatement>(b2.Expr("lhs"), b1.Expr("rhs"),
BinaryOp::kAdd);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CompoundAssignmentStatement>(b2.Expr("lhs"), b1.Expr("rhs"), BinaryOp::kAdd);
},
"internal compiler error");
}
TEST_F(CompoundAssignmentStatementTest, Assert_DifferentProgramID_RHS) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CompoundAssignmentStatement>(b1.Expr("lhs"), b2.Expr("rhs"),
BinaryOp::kAdd);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.create<CompoundAssignmentStatement>(b1.Expr("lhs"), b2.Expr("rhs"), BinaryOp::kAdd);
},
"internal compiler error");
}
} // namespace

View File

@@ -20,17 +20,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::ContinueStatement);
namespace tint::ast {
ContinueStatement::ContinueStatement(ProgramID pid, const Source& src)
: Base(pid, src) {}
ContinueStatement::ContinueStatement(ProgramID pid, const Source& src) : Base(pid, src) {}
ContinueStatement::ContinueStatement(ContinueStatement&&) = default;
ContinueStatement::~ContinueStatement() = default;
const ContinueStatement* ContinueStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<ContinueStatement>(src);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<ContinueStatement>(src);
}
} // namespace tint::ast

View File

@@ -21,20 +21,20 @@ namespace tint::ast {
/// An continue statement
class ContinueStatement final : public Castable<ContinueStatement, Statement> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
ContinueStatement(ProgramID pid, const Source& src);
/// Move constructor
ContinueStatement(ContinueStatement&&);
~ContinueStatement() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
ContinueStatement(ProgramID pid, const Source& src);
/// Move constructor
ContinueStatement(ContinueStatement&&);
~ContinueStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const ContinueStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const ContinueStatement* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,15 +22,15 @@ namespace {
using ContinueStatementTest = TestHelper;
TEST_F(ContinueStatementTest, Creation_WithSource) {
auto* stmt = create<ContinueStatement>(Source{Source::Location{20, 2}});
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* stmt = create<ContinueStatement>(Source{Source::Location{20, 2}});
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(ContinueStatementTest, IsContinue) {
auto* stmt = create<ContinueStatement>();
EXPECT_TRUE(stmt->Is<ContinueStatement>());
auto* stmt = create<ContinueStatement>();
EXPECT_TRUE(stmt->Is<ContinueStatement>());
}
} // namespace

View File

@@ -22,7 +22,7 @@ namespace tint::ast {
namespace {
bool IsValidDepthDimension(TextureDimension dim) {
return dim == TextureDimension::k2d;
return dim == TextureDimension::k2d;
}
} // namespace
@@ -31,24 +31,22 @@ DepthMultisampledTexture::DepthMultisampledTexture(ProgramID pid,
const Source& src,
TextureDimension d)
: Base(pid, src, d) {
TINT_ASSERT(AST, IsValidDepthDimension(dim));
TINT_ASSERT(AST, IsValidDepthDimension(dim));
}
DepthMultisampledTexture::DepthMultisampledTexture(DepthMultisampledTexture&&) =
default;
DepthMultisampledTexture::DepthMultisampledTexture(DepthMultisampledTexture&&) = default;
DepthMultisampledTexture::~DepthMultisampledTexture() = default;
std::string DepthMultisampledTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out;
out << "texture_depth_multisampled_" << dim;
return out.str();
std::ostringstream out;
out << "texture_depth_multisampled_" << dim;
return out.str();
}
const DepthMultisampledTexture* DepthMultisampledTexture::Clone(
CloneContext* ctx) const {
auto src = ctx->Clone(source);
return ctx->dst->create<DepthMultisampledTexture>(src, dim);
const DepthMultisampledTexture* DepthMultisampledTexture::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
return ctx->dst->create<DepthMultisampledTexture>(src, dim);
}
} // namespace tint::ast

View File

@@ -22,29 +22,26 @@
namespace tint::ast {
/// A multisampled depth texture type.
class DepthMultisampledTexture final
: public Castable<DepthMultisampledTexture, Texture> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param dim the dimensionality of the texture
DepthMultisampledTexture(ProgramID pid,
const Source& src,
TextureDimension dim);
/// Move constructor
DepthMultisampledTexture(DepthMultisampledTexture&&);
~DepthMultisampledTexture() override;
class DepthMultisampledTexture final : public Castable<DepthMultisampledTexture, Texture> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param dim the dimensionality of the texture
DepthMultisampledTexture(ProgramID pid, const Source& src, TextureDimension dim);
/// Move constructor
DepthMultisampledTexture(DepthMultisampledTexture&&);
~DepthMultisampledTexture() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const DepthMultisampledTexture* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const DepthMultisampledTexture* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,13 +22,13 @@ namespace {
using AstDepthMultisampledTextureTest = TestHelper;
TEST_F(AstDepthMultisampledTextureTest, Dim) {
auto* d = create<DepthMultisampledTexture>(TextureDimension::k2d);
EXPECT_EQ(d->dim, TextureDimension::k2d);
auto* d = create<DepthMultisampledTexture>(TextureDimension::k2d);
EXPECT_EQ(d->dim, TextureDimension::k2d);
}
TEST_F(AstDepthMultisampledTextureTest, FriendlyName) {
auto* d = create<DepthMultisampledTexture>(TextureDimension::k2d);
EXPECT_EQ(d->FriendlyName(Symbols()), "texture_depth_multisampled_2d");
auto* d = create<DepthMultisampledTexture>(TextureDimension::k2d);
EXPECT_EQ(d->FriendlyName(Symbols()), "texture_depth_multisampled_2d");
}
} // namespace

View File

@@ -22,15 +22,15 @@ namespace tint::ast {
namespace {
bool IsValidDepthDimension(TextureDimension dim) {
return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
}
} // namespace
DepthTexture::DepthTexture(ProgramID pid, const Source& src, TextureDimension d)
: Base(pid, src, d) {
TINT_ASSERT(AST, IsValidDepthDimension(dim));
TINT_ASSERT(AST, IsValidDepthDimension(dim));
}
DepthTexture::DepthTexture(DepthTexture&&) = default;
@@ -38,14 +38,14 @@ DepthTexture::DepthTexture(DepthTexture&&) = default;
DepthTexture::~DepthTexture() = default;
std::string DepthTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out;
out << "texture_depth_" << dim;
return out.str();
std::ostringstream out;
out << "texture_depth_" << dim;
return out.str();
}
const DepthTexture* DepthTexture::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
return ctx->dst->create<DepthTexture>(src, dim);
auto src = ctx->Clone(source);
return ctx->dst->create<DepthTexture>(src, dim);
}
} // namespace tint::ast

View File

@@ -23,25 +23,25 @@ namespace tint::ast {
/// A depth texture type.
class DepthTexture final : public Castable<DepthTexture, Texture> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param dim the dimensionality of the texture
DepthTexture(ProgramID pid, const Source& src, TextureDimension dim);
/// Move constructor
DepthTexture(DepthTexture&&);
~DepthTexture() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param dim the dimensionality of the texture
DepthTexture(ProgramID pid, const Source& src, TextureDimension dim);
/// Move constructor
DepthTexture(DepthTexture&&);
~DepthTexture() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const DepthTexture* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const DepthTexture* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,20 +22,20 @@ namespace {
using AstDepthTextureTest = TestHelper;
TEST_F(AstDepthTextureTest, IsTexture) {
Texture* ty = create<DepthTexture>(TextureDimension::kCube);
EXPECT_TRUE(ty->Is<DepthTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_FALSE(ty->Is<StorageTexture>());
Texture* ty = create<DepthTexture>(TextureDimension::kCube);
EXPECT_TRUE(ty->Is<DepthTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_FALSE(ty->Is<StorageTexture>());
}
TEST_F(AstDepthTextureTest, Dim) {
auto* d = create<DepthTexture>(TextureDimension::kCube);
EXPECT_EQ(d->dim, TextureDimension::kCube);
auto* d = create<DepthTexture>(TextureDimension::kCube);
EXPECT_EQ(d->dim, TextureDimension::kCube);
}
TEST_F(AstDepthTextureTest, FriendlyName) {
auto* d = create<DepthTexture>(TextureDimension::kCube);
EXPECT_EQ(d->FriendlyName(Symbols()), "texture_depth_cube");
auto* d = create<DepthTexture>(TextureDimension::kCube);
EXPECT_EQ(d->FriendlyName(Symbols()), "texture_depth_cube");
}
} // namespace

View File

@@ -20,36 +20,33 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::DisableValidationAttribute);
namespace tint::ast {
DisableValidationAttribute::DisableValidationAttribute(ProgramID pid,
DisabledValidation val)
DisableValidationAttribute::DisableValidationAttribute(ProgramID pid, DisabledValidation val)
: Base(pid), validation(val) {}
DisableValidationAttribute::~DisableValidationAttribute() = default;
std::string DisableValidationAttribute::InternalName() const {
switch (validation) {
case DisabledValidation::kFunctionHasNoBody:
return "disable_validation__function_has_no_body";
case DisabledValidation::kBindingPointCollision:
return "disable_validation__binding_point_collision";
case DisabledValidation::kIgnoreStorageClass:
return "disable_validation__ignore_storage_class";
case DisabledValidation::kEntryPointParameter:
return "disable_validation__entry_point_parameter";
case DisabledValidation::kIgnoreConstructibleFunctionParameter:
return "disable_validation__ignore_constructible_function_parameter";
case DisabledValidation::kIgnoreStrideAttribute:
return "disable_validation__ignore_stride";
case DisabledValidation::kIgnoreInvalidPointerArgument:
return "disable_validation__ignore_invalid_pointer_argument";
}
return "<invalid>";
switch (validation) {
case DisabledValidation::kFunctionHasNoBody:
return "disable_validation__function_has_no_body";
case DisabledValidation::kBindingPointCollision:
return "disable_validation__binding_point_collision";
case DisabledValidation::kIgnoreStorageClass:
return "disable_validation__ignore_storage_class";
case DisabledValidation::kEntryPointParameter:
return "disable_validation__entry_point_parameter";
case DisabledValidation::kIgnoreConstructibleFunctionParameter:
return "disable_validation__ignore_constructible_function_parameter";
case DisabledValidation::kIgnoreStrideAttribute:
return "disable_validation__ignore_stride";
case DisabledValidation::kIgnoreInvalidPointerArgument:
return "disable_validation__ignore_invalid_pointer_argument";
}
return "<invalid>";
}
const DisableValidationAttribute* DisableValidationAttribute::Clone(
CloneContext* ctx) const {
return ctx->dst->ASTNodes().Create<DisableValidationAttribute>(ctx->dst->ID(),
validation);
const DisableValidationAttribute* DisableValidationAttribute::Clone(CloneContext* ctx) const {
return ctx->dst->ASTNodes().Create<DisableValidationAttribute>(ctx->dst->ID(), validation);
}
} // namespace tint::ast

View File

@@ -24,28 +24,28 @@ namespace tint::ast {
/// Enumerator of validation features that can be disabled with a
/// DisableValidationAttribute attribute.
enum class DisabledValidation {
/// When applied to a function, the validator will not complain there is no
/// body to a function.
kFunctionHasNoBody,
/// When applied to a module-scoped variable, the validator will not complain
/// if two resource variables have the same binding points.
kBindingPointCollision,
/// When applied to a variable, the validator will not complain about the
/// declared storage class.
kIgnoreStorageClass,
/// When applied to an entry-point function parameter, the validator will not
/// check for entry IO attributes.
kEntryPointParameter,
/// When applied to a function parameter, the validator will not
/// check if parameter type is constructible
kIgnoreConstructibleFunctionParameter,
/// When applied to a member attribute, a stride attribute may be applied to
/// non-array types.
kIgnoreStrideAttribute,
/// When applied to a pointer function parameter, the validator will not
/// require a function call argument passed for that parameter to have a
/// certain form.
kIgnoreInvalidPointerArgument,
/// When applied to a function, the validator will not complain there is no
/// body to a function.
kFunctionHasNoBody,
/// When applied to a module-scoped variable, the validator will not complain
/// if two resource variables have the same binding points.
kBindingPointCollision,
/// When applied to a variable, the validator will not complain about the
/// declared storage class.
kIgnoreStorageClass,
/// When applied to an entry-point function parameter, the validator will not
/// check for entry IO attributes.
kEntryPointParameter,
/// When applied to a function parameter, the validator will not
/// check if parameter type is constructible
kIgnoreConstructibleFunctionParameter,
/// When applied to a member attribute, a stride attribute may be applied to
/// non-array types.
kIgnoreStrideAttribute,
/// When applied to a pointer function parameter, the validator will not
/// require a function call argument passed for that parameter to have a
/// certain form.
kIgnoreInvalidPointerArgument,
};
/// An internal attribute used to tell the validator to ignore specific
@@ -53,27 +53,26 @@ enum class DisabledValidation {
/// would otherwise cause validation errors.
class DisableValidationAttribute final
: public Castable<DisableValidationAttribute, InternalAttribute> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param validation the validation to disable
explicit DisableValidationAttribute(ProgramID program_id,
DisabledValidation validation);
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param validation the validation to disable
explicit DisableValidationAttribute(ProgramID program_id, DisabledValidation validation);
/// Destructor
~DisableValidationAttribute() override;
/// Destructor
~DisableValidationAttribute() override;
/// @return a short description of the internal attribute which will be
/// displayed in WGSL as `@internal(<name>)` (but is not parsable).
std::string InternalName() const override;
/// @return a short description of the internal attribute which will be
/// displayed in WGSL as `@internal(<name>)` (but is not parsable).
std::string InternalName() const override;
/// Performs a deep clone of this object using the CloneContext `ctx`.
/// @param ctx the clone context
/// @return the newly cloned object
const DisableValidationAttribute* Clone(CloneContext* ctx) const override;
/// Performs a deep clone of this object using the CloneContext `ctx`.
/// @param ctx the clone context
/// @return the newly cloned object
const DisableValidationAttribute* Clone(CloneContext* ctx) const override;
/// The validation that this attribute disables
const DisabledValidation validation;
/// The validation that this attribute disables
const DisabledValidation validation;
};
} // namespace tint::ast

View File

@@ -20,17 +20,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::DiscardStatement);
namespace tint::ast {
DiscardStatement::DiscardStatement(ProgramID pid, const Source& src)
: Base(pid, src) {}
DiscardStatement::DiscardStatement(ProgramID pid, const Source& src) : Base(pid, src) {}
DiscardStatement::DiscardStatement(DiscardStatement&&) = default;
DiscardStatement::~DiscardStatement() = default;
const DiscardStatement* DiscardStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<DiscardStatement>(src);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<DiscardStatement>(src);
}
} // namespace tint::ast

View File

@@ -21,20 +21,20 @@ namespace tint::ast {
/// A discard statement
class DiscardStatement final : public Castable<DiscardStatement, Statement> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
DiscardStatement(ProgramID pid, const Source& src);
/// Move constructor
DiscardStatement(DiscardStatement&&);
~DiscardStatement() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
DiscardStatement(ProgramID pid, const Source& src);
/// Move constructor
DiscardStatement(DiscardStatement&&);
~DiscardStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const DiscardStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const DiscardStatement* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,25 +22,25 @@ namespace {
using DiscardStatementTest = TestHelper;
TEST_F(DiscardStatementTest, Creation) {
auto* stmt = create<DiscardStatement>();
EXPECT_EQ(stmt->source.range.begin.line, 0u);
EXPECT_EQ(stmt->source.range.begin.column, 0u);
EXPECT_EQ(stmt->source.range.end.line, 0u);
EXPECT_EQ(stmt->source.range.end.column, 0u);
auto* stmt = create<DiscardStatement>();
EXPECT_EQ(stmt->source.range.begin.line, 0u);
EXPECT_EQ(stmt->source.range.begin.column, 0u);
EXPECT_EQ(stmt->source.range.end.line, 0u);
EXPECT_EQ(stmt->source.range.end.column, 0u);
}
TEST_F(DiscardStatementTest, Creation_WithSource) {
auto* stmt = create<DiscardStatement>(
Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}});
EXPECT_EQ(stmt->source.range.begin.line, 20u);
EXPECT_EQ(stmt->source.range.begin.column, 2u);
EXPECT_EQ(stmt->source.range.end.line, 20u);
EXPECT_EQ(stmt->source.range.end.column, 5u);
auto* stmt = create<DiscardStatement>(
Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}});
EXPECT_EQ(stmt->source.range.begin.line, 20u);
EXPECT_EQ(stmt->source.range.begin.column, 2u);
EXPECT_EQ(stmt->source.range.end.line, 20u);
EXPECT_EQ(stmt->source.range.end.column, 5u);
}
TEST_F(DiscardStatementTest, IsDiscard) {
auto* stmt = create<DiscardStatement>();
EXPECT_TRUE(stmt->Is<DiscardStatement>());
auto* stmt = create<DiscardStatement>();
EXPECT_TRUE(stmt->Is<DiscardStatement>());
}
} // namespace

View File

@@ -22,26 +22,26 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::Enable);
namespace tint::ast {
Enable::ExtensionKind Enable::NameToKind(const std::string& name) {
// The reserved internal extension name for testing
if (name == "InternalExtensionForTesting") {
return Enable::ExtensionKind::kInternalExtensionForTesting;
}
// The reserved internal extension name for testing
if (name == "InternalExtensionForTesting") {
return Enable::ExtensionKind::kInternalExtensionForTesting;
}
return Enable::ExtensionKind::kNotAnExtension;
return Enable::ExtensionKind::kNotAnExtension;
}
std::string Enable::KindToName(ExtensionKind kind) {
switch (kind) {
// The reserved internal extension for testing
case ExtensionKind::kInternalExtensionForTesting:
return "InternalExtensionForTesting";
case ExtensionKind::kNotAnExtension:
// Return an empty string for kNotAnExtension
return {};
// No default case, as this switch must cover all ExtensionKind values.
}
// This return shall never get hit.
return {};
switch (kind) {
// The reserved internal extension for testing
case ExtensionKind::kInternalExtensionForTesting:
return "InternalExtensionForTesting";
case ExtensionKind::kNotAnExtension:
// Return an empty string for kNotAnExtension
return {};
// No default case, as this switch must cover all ExtensionKind values.
}
// This return shall never get hit.
return {};
}
Enable::Enable(ProgramID pid, const Source& src, const std::string& ext_name)
@@ -52,7 +52,7 @@ Enable::Enable(Enable&&) = default;
Enable::~Enable() = default;
const Enable* Enable::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
return ctx->dst->create<Enable>(src, name);
auto src = ctx->Clone(source);
return ctx->dst->create<Enable>(src, name);
}
} // namespace tint::ast

View File

@@ -29,55 +29,55 @@ namespace tint::ast {
/// // Enable an extension named "f16"
/// enable f16;
class Enable : public Castable<Enable, Node> {
public:
/// The enum class identifing each supported WGSL extension
enum class ExtensionKind {
/// An internal reserved extension for test, named
/// "InternalExtensionForTesting"
kInternalExtensionForTesting = -2,
kNotAnExtension = -1,
};
public:
/// The enum class identifing each supported WGSL extension
enum class ExtensionKind {
/// An internal reserved extension for test, named
/// "InternalExtensionForTesting"
kInternalExtensionForTesting = -2,
kNotAnExtension = -1,
};
/// Convert a string of extension name into one of ExtensionKind enum value,
/// the result will be ExtensionKind::kNotAnExtension if the name is not a
/// known extension name. A extension node of kind kNotAnExtension must not
/// exist in the AST tree, and using a unknown extension name in WGSL code
/// should result in a shader-creation error.
/// @param name string of the extension name
/// @return the ExtensionKind enum value for the extension of given name, or
/// kNotAnExtension if no known extension has the given name
static ExtensionKind NameToKind(const std::string& name);
/// Convert a string of extension name into one of ExtensionKind enum value,
/// the result will be ExtensionKind::kNotAnExtension if the name is not a
/// known extension name. A extension node of kind kNotAnExtension must not
/// exist in the AST tree, and using a unknown extension name in WGSL code
/// should result in a shader-creation error.
/// @param name string of the extension name
/// @return the ExtensionKind enum value for the extension of given name, or
/// kNotAnExtension if no known extension has the given name
static ExtensionKind NameToKind(const std::string& name);
/// Convert the ExtensionKind enum value to corresponding extension name
/// string. If the given enum value is kNotAnExtension or don't have a known
/// name, return an empty string instead.
/// @param kind the ExtensionKind enum value
/// @return string of the extension name corresponding to the given kind, or
/// an empty string if the given enum value is kNotAnExtension or don't have a
/// known corresponding name
static std::string KindToName(ExtensionKind kind);
/// Convert the ExtensionKind enum value to corresponding extension name
/// string. If the given enum value is kNotAnExtension or don't have a known
/// name, return an empty string instead.
/// @param kind the ExtensionKind enum value
/// @return string of the extension name corresponding to the given kind, or
/// an empty string if the given enum value is kNotAnExtension or don't have a
/// known corresponding name
static std::string KindToName(ExtensionKind kind);
/// Create a extension
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param name the name of extension
Enable(ProgramID pid, const Source& src, const std::string& name);
/// Move constructor
Enable(Enable&&);
/// Create a extension
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param name the name of extension
Enable(ProgramID pid, const Source& src, const std::string& name);
/// Move constructor
Enable(Enable&&);
~Enable() override;
~Enable() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const Enable* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const Enable* Clone(CloneContext* ctx) const override;
/// The extension name
const std::string name;
/// The extension name
const std::string name;
/// The extension kind
const ExtensionKind kind;
/// The extension kind
const ExtensionKind kind;
};
/// A set of extension kinds

View File

@@ -22,44 +22,37 @@ namespace {
using AstExtensionTest = TestHelper;
TEST_F(AstExtensionTest, Creation) {
auto* ext = create<Enable>(
Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}},
"InternalExtensionForTesting");
EXPECT_EQ(ext->source.range.begin.line, 20u);
EXPECT_EQ(ext->source.range.begin.column, 2u);
EXPECT_EQ(ext->source.range.end.line, 20u);
EXPECT_EQ(ext->source.range.end.column, 5u);
EXPECT_EQ(ext->kind,
ast::Enable::ExtensionKind::kInternalExtensionForTesting);
auto* ext =
create<Enable>(Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}},
"InternalExtensionForTesting");
EXPECT_EQ(ext->source.range.begin.line, 20u);
EXPECT_EQ(ext->source.range.begin.column, 2u);
EXPECT_EQ(ext->source.range.end.line, 20u);
EXPECT_EQ(ext->source.range.end.column, 5u);
EXPECT_EQ(ext->kind, ast::Enable::ExtensionKind::kInternalExtensionForTesting);
}
TEST_F(AstExtensionTest, Creation_InvalidName) {
auto* ext = create<Enable>(
Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}},
std::string());
EXPECT_EQ(ext->source.range.begin.line, 20u);
EXPECT_EQ(ext->source.range.begin.column, 2u);
EXPECT_EQ(ext->source.range.end.line, 20u);
EXPECT_EQ(ext->source.range.end.column, 5u);
EXPECT_EQ(ext->kind, ast::Enable::ExtensionKind::kNotAnExtension);
auto* ext = create<Enable>(
Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}}, std::string());
EXPECT_EQ(ext->source.range.begin.line, 20u);
EXPECT_EQ(ext->source.range.begin.column, 2u);
EXPECT_EQ(ext->source.range.end.line, 20u);
EXPECT_EQ(ext->source.range.end.column, 5u);
EXPECT_EQ(ext->kind, ast::Enable::ExtensionKind::kNotAnExtension);
}
TEST_F(AstExtensionTest, NameToKind_InvalidName) {
EXPECT_EQ(ast::Enable::NameToKind(std::string()),
ast::Enable::ExtensionKind::kNotAnExtension);
EXPECT_EQ(ast::Enable::NameToKind("__ImpossibleExtensionName"),
ast::Enable::ExtensionKind::kNotAnExtension);
EXPECT_EQ(ast::Enable::NameToKind("123"),
ast::Enable::ExtensionKind::kNotAnExtension);
EXPECT_EQ(ast::Enable::NameToKind(std::string()), ast::Enable::ExtensionKind::kNotAnExtension);
EXPECT_EQ(ast::Enable::NameToKind("__ImpossibleExtensionName"),
ast::Enable::ExtensionKind::kNotAnExtension);
EXPECT_EQ(ast::Enable::NameToKind("123"), ast::Enable::ExtensionKind::kNotAnExtension);
}
TEST_F(AstExtensionTest, KindToName) {
EXPECT_EQ(ast::Enable::KindToName(
ast::Enable::ExtensionKind::kInternalExtensionForTesting),
"InternalExtensionForTesting");
EXPECT_EQ(
ast::Enable::KindToName(ast::Enable::ExtensionKind::kNotAnExtension),
std::string());
EXPECT_EQ(ast::Enable::KindToName(ast::Enable::ExtensionKind::kInternalExtensionForTesting),
"InternalExtensionForTesting");
EXPECT_EQ(ast::Enable::KindToName(ast::Enable::ExtensionKind::kNotAnExtension), std::string());
}
} // namespace

View File

@@ -25,16 +25,16 @@ namespace tint::ast {
/// Base expression class
class Expression : public Castable<Expression, Node> {
public:
~Expression() override;
public:
~Expression() override;
protected:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
Expression(ProgramID pid, const Source& src);
/// Move constructor
Expression(Expression&&);
protected:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
Expression(ProgramID pid, const Source& src);
/// Move constructor
Expression(Expression&&);
};
/// A list of expressions

View File

@@ -29,11 +29,11 @@ ExternalTexture::ExternalTexture(ExternalTexture&&) = default;
ExternalTexture::~ExternalTexture() = default;
std::string ExternalTexture::FriendlyName(const SymbolTable&) const {
return "texture_external";
return "texture_external";
}
const ExternalTexture* ExternalTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<ExternalTexture>();
return ctx->dst->create<ExternalTexture>();
}
} // namespace tint::ast

View File

@@ -23,25 +23,25 @@ namespace tint::ast {
/// An external texture type
class ExternalTexture final : public Castable<ExternalTexture, Texture> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
ExternalTexture(ProgramID pid, const Source& src);
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
ExternalTexture(ProgramID pid, const Source& src);
/// Move constructor
ExternalTexture(ExternalTexture&&);
~ExternalTexture() override;
/// Move constructor
ExternalTexture(ExternalTexture&&);
~ExternalTexture() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const ExternalTexture* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const ExternalTexture* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,22 +22,22 @@ namespace {
using AstExternalTextureTest = TestHelper;
TEST_F(AstExternalTextureTest, IsTexture) {
Texture* ty = create<ExternalTexture>();
EXPECT_FALSE(ty->Is<DepthTexture>());
EXPECT_TRUE(ty->Is<ExternalTexture>());
EXPECT_FALSE(ty->Is<MultisampledTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_FALSE(ty->Is<StorageTexture>());
Texture* ty = create<ExternalTexture>();
EXPECT_FALSE(ty->Is<DepthTexture>());
EXPECT_TRUE(ty->Is<ExternalTexture>());
EXPECT_FALSE(ty->Is<MultisampledTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_FALSE(ty->Is<StorageTexture>());
}
TEST_F(AstExternalTextureTest, Dim) {
auto* ty = create<ExternalTexture>();
EXPECT_EQ(ty->dim, ast::TextureDimension::k2d);
auto* ty = create<ExternalTexture>();
EXPECT_EQ(ty->dim, ast::TextureDimension::k2d);
}
TEST_F(AstExternalTextureTest, FriendlyName) {
auto* ty = create<ExternalTexture>();
EXPECT_EQ(ty->FriendlyName(Symbols()), "texture_external");
auto* ty = create<ExternalTexture>();
EXPECT_EQ(ty->FriendlyName(Symbols()), "texture_external");
}
} // namespace

View File

@@ -27,12 +27,12 @@ F32::F32(F32&&) = default;
F32::~F32() = default;
std::string F32::FriendlyName(const SymbolTable&) const {
return "f32";
return "f32";
}
const F32* F32::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
return ctx->dst->create<F32>(src);
auto src = ctx->Clone(source);
return ctx->dst->create<F32>(src);
}
} // namespace tint::ast

View File

@@ -23,24 +23,24 @@ namespace tint::ast {
/// A float 32 type
class F32 final : public Castable<F32, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
F32(ProgramID pid, const Source& src);
/// Move constructor
F32(F32&&);
~F32() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
F32(ProgramID pid, const Source& src);
/// Move constructor
F32(F32&&);
~F32() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const F32* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const F32* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,8 +22,8 @@ namespace {
using AstF32Test = TestHelper;
TEST_F(AstF32Test, FriendlyName) {
auto* f = create<F32>();
EXPECT_EQ(f->FriendlyName(Symbols()), "f32");
auto* f = create<F32>();
EXPECT_EQ(f->FriendlyName(Symbols()), "f32");
}
} // namespace

View File

@@ -20,18 +20,16 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::FallthroughStatement);
namespace tint::ast {
FallthroughStatement::FallthroughStatement(ProgramID pid, const Source& src)
: Base(pid, src) {}
FallthroughStatement::FallthroughStatement(ProgramID pid, const Source& src) : Base(pid, src) {}
FallthroughStatement::FallthroughStatement(FallthroughStatement&&) = default;
FallthroughStatement::~FallthroughStatement() = default;
const FallthroughStatement* FallthroughStatement::Clone(
CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<FallthroughStatement>(src);
const FallthroughStatement* FallthroughStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<FallthroughStatement>(src);
}
} // namespace tint::ast

View File

@@ -20,22 +20,21 @@
namespace tint::ast {
/// An fallthrough statement
class FallthroughStatement final
: public Castable<FallthroughStatement, Statement> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
FallthroughStatement(ProgramID pid, const Source& src);
/// Move constructor
FallthroughStatement(FallthroughStatement&&);
~FallthroughStatement() override;
class FallthroughStatement final : public Castable<FallthroughStatement, Statement> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
FallthroughStatement(ProgramID pid, const Source& src);
/// Move constructor
FallthroughStatement(FallthroughStatement&&);
~FallthroughStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const FallthroughStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const FallthroughStatement* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,23 +22,23 @@ namespace {
using FallthroughStatementTest = TestHelper;
TEST_F(FallthroughStatementTest, Creation) {
auto* stmt = create<FallthroughStatement>();
EXPECT_EQ(stmt->source.range.begin.line, 0u);
EXPECT_EQ(stmt->source.range.begin.column, 0u);
EXPECT_EQ(stmt->source.range.end.line, 0u);
EXPECT_EQ(stmt->source.range.end.column, 0u);
auto* stmt = create<FallthroughStatement>();
EXPECT_EQ(stmt->source.range.begin.line, 0u);
EXPECT_EQ(stmt->source.range.begin.column, 0u);
EXPECT_EQ(stmt->source.range.end.line, 0u);
EXPECT_EQ(stmt->source.range.end.column, 0u);
}
TEST_F(FallthroughStatementTest, Creation_WithSource) {
auto* stmt = create<FallthroughStatement>(Source{Source::Location{20, 2}});
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* stmt = create<FallthroughStatement>(Source{Source::Location{20, 2}});
auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(FallthroughStatementTest, IsFallthrough) {
auto* stmt = create<FallthroughStatement>();
EXPECT_TRUE(stmt->Is<FallthroughStatement>());
auto* stmt = create<FallthroughStatement>();
EXPECT_TRUE(stmt->Is<FallthroughStatement>());
}
} // namespace

View File

@@ -22,18 +22,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::FloatLiteralExpression);
namespace tint::ast {
FloatLiteralExpression::FloatLiteralExpression(ProgramID pid,
const Source& src,
float val)
FloatLiteralExpression::FloatLiteralExpression(ProgramID pid, const Source& src, float val)
: Base(pid, src), value(val) {}
FloatLiteralExpression::~FloatLiteralExpression() = default;
const FloatLiteralExpression* FloatLiteralExpression::Clone(
CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<FloatLiteralExpression>(src, value);
const FloatLiteralExpression* FloatLiteralExpression::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<FloatLiteralExpression>(src, value);
}
} // namespace tint::ast

View File

@@ -22,24 +22,23 @@
namespace tint::ast {
/// A float literal
class FloatLiteralExpression final
: public Castable<FloatLiteralExpression, LiteralExpression> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the float literals value
FloatLiteralExpression(ProgramID pid, const Source& src, float value);
~FloatLiteralExpression() override;
class FloatLiteralExpression final : public Castable<FloatLiteralExpression, LiteralExpression> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the float literals value
FloatLiteralExpression(ProgramID pid, const Source& src, float value);
~FloatLiteralExpression() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const FloatLiteralExpression* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const FloatLiteralExpression* Clone(CloneContext* ctx) const override;
/// The float literal value
const float value;
/// The float literal value
const float value;
};
} // namespace tint::ast

View File

@@ -20,9 +20,9 @@ namespace {
using FloatLiteralExpressionTest = TestHelper;
TEST_F(FloatLiteralExpressionTest, Value) {
auto* f = create<FloatLiteralExpression>(47.2f);
ASSERT_TRUE(f->Is<FloatLiteralExpression>());
EXPECT_EQ(f->value, 47.2f);
auto* f = create<FloatLiteralExpression>(47.2f);
ASSERT_TRUE(f->Is<FloatLiteralExpression>());
EXPECT_EQ(f->value, 47.2f);
}
} // namespace

View File

@@ -26,17 +26,13 @@ ForLoopStatement::ForLoopStatement(ProgramID pid,
const Expression* cond,
const Statement* cont,
const BlockStatement* b)
: Base(pid, src),
initializer(init),
condition(cond),
continuing(cont),
body(b) {
TINT_ASSERT(AST, body);
: Base(pid, src), initializer(init), condition(cond), continuing(cont), body(b) {
TINT_ASSERT(AST, body);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, initializer, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, continuing, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, initializer, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, continuing, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
}
ForLoopStatement::ForLoopStatement(ForLoopStatement&&) = default;
@@ -44,14 +40,14 @@ ForLoopStatement::ForLoopStatement(ForLoopStatement&&) = default;
ForLoopStatement::~ForLoopStatement() = default;
const ForLoopStatement* ForLoopStatement::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto* init = ctx->Clone(initializer);
auto* cond = ctx->Clone(condition);
auto* cont = ctx->Clone(continuing);
auto* b = ctx->Clone(body);
return ctx->dst->create<ForLoopStatement>(src, init, cond, cont, b);
auto* init = ctx->Clone(initializer);
auto* cond = ctx->Clone(condition);
auto* cont = ctx->Clone(continuing);
auto* b = ctx->Clone(body);
return ctx->dst->create<ForLoopStatement>(src, init, cond, cont, b);
}
} // namespace tint::ast

View File

@@ -23,41 +23,41 @@ class Expression;
/// A for loop statement
class ForLoopStatement final : public Castable<ForLoopStatement, Statement> {
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the for loop statement source
/// @param initializer the optional loop initializer statement
/// @param condition the optional loop condition expression
/// @param continuing the optional continuing statement
/// @param body the loop body
ForLoopStatement(ProgramID program_id,
Source const& source,
const Statement* initializer,
const Expression* condition,
const Statement* continuing,
const BlockStatement* body);
/// Move constructor
ForLoopStatement(ForLoopStatement&&);
~ForLoopStatement() override;
public:
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the for loop statement source
/// @param initializer the optional loop initializer statement
/// @param condition the optional loop condition expression
/// @param continuing the optional continuing statement
/// @param body the loop body
ForLoopStatement(ProgramID program_id,
Source const& source,
const Statement* initializer,
const Expression* condition,
const Statement* continuing,
const BlockStatement* body);
/// Move constructor
ForLoopStatement(ForLoopStatement&&);
~ForLoopStatement() override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const ForLoopStatement* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const ForLoopStatement* Clone(CloneContext* ctx) const override;
/// The initializer statement
const Statement* const initializer;
/// The initializer statement
const Statement* const initializer;
/// The condition expression
const Expression* const condition;
/// The condition expression
const Expression* const condition;
/// The continuing statement
const Statement* const continuing;
/// The continuing statement
const Statement* const continuing;
/// The loop body block
const BlockStatement* const body;
/// The loop body block
const BlockStatement* const body;
};
} // namespace tint::ast

View File

@@ -22,80 +22,79 @@ namespace {
using ForLoopStatementTest = TestHelper;
TEST_F(ForLoopStatementTest, Creation) {
auto* init = Decl(Var("i", ty.u32()));
auto* cond =
create<BinaryExpression>(BinaryOp::kLessThan, Expr("i"), Expr(5u));
auto* cont = Assign("i", Add("i", 1));
auto* body = Block(Return());
auto* l = For(init, cond, cont, body);
auto* init = Decl(Var("i", ty.u32()));
auto* cond = create<BinaryExpression>(BinaryOp::kLessThan, Expr("i"), Expr(5u));
auto* cont = Assign("i", Add("i", 1));
auto* body = Block(Return());
auto* l = For(init, cond, cont, body);
EXPECT_EQ(l->initializer, init);
EXPECT_EQ(l->condition, cond);
EXPECT_EQ(l->continuing, cont);
EXPECT_EQ(l->body, body);
EXPECT_EQ(l->initializer, init);
EXPECT_EQ(l->condition, cond);
EXPECT_EQ(l->continuing, cont);
EXPECT_EQ(l->body, body);
}
TEST_F(ForLoopStatementTest, Creation_WithSource) {
auto* body = Block(Return());
auto* l = For(Source{{20u, 2u}}, nullptr, nullptr, nullptr, body);
auto src = l->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* body = Block(Return());
auto* l = For(Source{{20u, 2u}}, nullptr, nullptr, nullptr, body);
auto src = l->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(ForLoopStatementTest, Creation_Null_InitCondCont) {
auto* body = Block(Return());
auto* l = For(nullptr, nullptr, nullptr, body);
EXPECT_EQ(l->body, body);
auto* body = Block(Return());
auto* l = For(nullptr, nullptr, nullptr, body);
EXPECT_EQ(l->body, body);
}
TEST_F(ForLoopStatementTest, Assert_Null_Body) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.For(nullptr, nullptr, nullptr, nullptr);
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.For(nullptr, nullptr, nullptr, nullptr);
},
"internal compiler error");
}
TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Initializer) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(b2.Block(), nullptr, nullptr, b1.Block());
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(b2.Block(), nullptr, nullptr, b1.Block());
},
"internal compiler error");
}
TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Condition) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(nullptr, b2.Expr(true), nullptr, b1.Block());
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(nullptr, b2.Expr(true), nullptr, b1.Block());
},
"internal compiler error");
}
TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Continuing) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(nullptr, nullptr, b2.Block(), b1.Block());
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(nullptr, nullptr, b2.Block(), b1.Block());
},
"internal compiler error");
}
TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Body) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(nullptr, nullptr, nullptr, b2.Block());
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.For(nullptr, nullptr, nullptr, b2.Block());
},
"internal compiler error");
}
} // namespace

View File

@@ -37,20 +37,20 @@ Function::Function(ProgramID pid,
body(b),
attributes(std::move(attrs)),
return_type_attributes(std::move(return_type_attrs)) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
for (auto* param : params) {
TINT_ASSERT(AST, param && param->is_const);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, param, program_id);
}
TINT_ASSERT(AST, symbol.IsValid());
TINT_ASSERT(AST, return_type);
for (auto* attr : attributes) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
}
for (auto* attr : return_type_attributes) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
}
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
for (auto* param : params) {
TINT_ASSERT(AST, param && param->is_const);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, param, program_id);
}
TINT_ASSERT(AST, symbol.IsValid());
TINT_ASSERT(AST, return_type);
for (auto* attr : attributes) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
}
for (auto* attr : return_type_attributes) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
}
}
Function::Function(Function&&) = default;
@@ -58,49 +58,49 @@ Function::Function(Function&&) = default;
Function::~Function() = default;
PipelineStage Function::PipelineStage() const {
if (auto* stage = GetAttribute<StageAttribute>(attributes)) {
return stage->stage;
}
return PipelineStage::kNone;
if (auto* stage = GetAttribute<StageAttribute>(attributes)) {
return stage->stage;
}
return PipelineStage::kNone;
}
const Function* Function::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol);
auto p = ctx->Clone(params);
auto* ret = ctx->Clone(return_type);
auto* b = ctx->Clone(body);
auto attrs = ctx->Clone(attributes);
auto ret_attrs = ctx->Clone(return_type_attributes);
return ctx->dst->create<Function>(src, sym, p, ret, b, attrs, ret_attrs);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol);
auto p = ctx->Clone(params);
auto* ret = ctx->Clone(return_type);
auto* b = ctx->Clone(body);
auto attrs = ctx->Clone(attributes);
auto ret_attrs = ctx->Clone(return_type_attributes);
return ctx->dst->create<Function>(src, sym, p, ret, b, attrs, ret_attrs);
}
const Function* FunctionList::Find(Symbol sym) const {
for (auto* func : *this) {
if (func->symbol == sym) {
return func;
for (auto* func : *this) {
if (func->symbol == sym) {
return func;
}
}
}
return nullptr;
return nullptr;
}
const Function* FunctionList::Find(Symbol sym, PipelineStage stage) const {
for (auto* func : *this) {
if (func->symbol == sym && func->PipelineStage() == stage) {
return func;
for (auto* func : *this) {
if (func->symbol == sym && func->PipelineStage() == stage) {
return func;
}
}
}
return nullptr;
return nullptr;
}
bool FunctionList::HasStage(ast::PipelineStage stage) const {
for (auto* func : *this) {
if (func->PipelineStage() == stage) {
return true;
for (auto* func : *this) {
if (func->PipelineStage() == stage) {
return true;
}
}
}
return false;
return false;
}
} // namespace tint::ast

View File

@@ -33,82 +33,82 @@ namespace tint::ast {
/// A Function statement.
class Function final : public Castable<Function, Node> {
public:
/// Create a function
/// @param program_id the identifier of the program that owns this node
/// @param source the variable source
/// @param symbol the function symbol
/// @param params the function parameters
/// @param return_type the return type
/// @param body the function body
/// @param attributes the function attributes
/// @param return_type_attributes the return type attributes
Function(ProgramID program_id,
const Source& source,
Symbol symbol,
VariableList params,
const Type* return_type,
const BlockStatement* body,
AttributeList attributes,
AttributeList return_type_attributes);
/// Move constructor
Function(Function&&);
public:
/// Create a function
/// @param program_id the identifier of the program that owns this node
/// @param source the variable source
/// @param symbol the function symbol
/// @param params the function parameters
/// @param return_type the return type
/// @param body the function body
/// @param attributes the function attributes
/// @param return_type_attributes the return type attributes
Function(ProgramID program_id,
const Source& source,
Symbol symbol,
VariableList params,
const Type* return_type,
const BlockStatement* body,
AttributeList attributes,
AttributeList return_type_attributes);
/// Move constructor
Function(Function&&);
~Function() override;
~Function() override;
/// @returns the functions pipeline stage or None if not set
ast::PipelineStage PipelineStage() const;
/// @returns the functions pipeline stage or None if not set
ast::PipelineStage PipelineStage() const;
/// @returns true if this function is an entry point
bool IsEntryPoint() const { return PipelineStage() != PipelineStage::kNone; }
/// @returns true if this function is an entry point
bool IsEntryPoint() const { return PipelineStage() != PipelineStage::kNone; }
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const Function* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const Function* Clone(CloneContext* ctx) const override;
/// The function symbol
const Symbol symbol;
/// The function symbol
const Symbol symbol;
/// The function params
const VariableList params;
/// The function params
const VariableList params;
/// The function return type
const Type* const return_type;
/// The function return type
const Type* const return_type;
/// The function body
const BlockStatement* const body;
/// The function body
const BlockStatement* const body;
/// The attributes attached to this function
const AttributeList attributes;
/// The attributes attached to this function
const AttributeList attributes;
/// The attributes attached to the function return type.
const AttributeList return_type_attributes;
/// The attributes attached to the function return type.
const AttributeList return_type_attributes;
};
/// A list of functions
class FunctionList : public std::vector<const Function*> {
public:
/// Appends f to the end of the list
/// @param f the function to append to this list
void Add(const Function* f) { this->emplace_back(f); }
public:
/// Appends f to the end of the list
/// @param f the function to append to this list
void Add(const Function* f) { this->emplace_back(f); }
/// Returns the function with the given name
/// @param sym the function symbol to search for
/// @returns the associated function or nullptr if none exists
const Function* Find(Symbol sym) const;
/// Returns the function with the given name
/// @param sym the function symbol to search for
/// @returns the associated function or nullptr if none exists
const Function* Find(Symbol sym) const;
/// Returns the function with the given name
/// @param sym the function symbol to search for
/// @param stage the pipeline stage
/// @returns the associated function or nullptr if none exists
const Function* Find(Symbol sym, PipelineStage stage) const;
/// Returns the function with the given name
/// @param sym the function symbol to search for
/// @param stage the pipeline stage
/// @returns the associated function or nullptr if none exists
const Function* Find(Symbol sym, PipelineStage stage) const;
/// @param stage the pipeline stage
/// @returns true if the Builder contains an entrypoint function with
/// the given stage
bool HasStage(PipelineStage stage) const;
/// @param stage the pipeline stage
/// @returns true if the Builder contains an entrypoint function with
/// the given stage
bool HasStage(PipelineStage stage) const;
};
} // namespace tint::ast

View File

@@ -24,170 +24,165 @@ namespace {
using FunctionTest = TestHelper;
TEST_F(FunctionTest, Creation) {
VariableList params;
params.push_back(Param("var", ty.i32()));
auto* var = params[0];
VariableList params;
params.push_back(Param("var", ty.i32()));
auto* var = params[0];
auto* f = Func("func", params, ty.void_(), StatementList{}, AttributeList{});
EXPECT_EQ(f->symbol, Symbols().Get("func"));
ASSERT_EQ(f->params.size(), 1u);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
EXPECT_EQ(f->params[0], var);
auto* f = Func("func", params, ty.void_(), StatementList{}, AttributeList{});
EXPECT_EQ(f->symbol, Symbols().Get("func"));
ASSERT_EQ(f->params.size(), 1u);
EXPECT_TRUE(f->return_type->Is<ast::Void>());
EXPECT_EQ(f->params[0], var);
}
TEST_F(FunctionTest, Creation_WithSource) {
VariableList params;
params.push_back(Param("var", ty.i32()));
VariableList params;
params.push_back(Param("var", ty.i32()));
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(),
StatementList{}, AttributeList{});
auto src = f->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(), StatementList{},
AttributeList{});
auto src = f->source;
EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u);
}
TEST_F(FunctionTest, Assert_InvalidName) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Func("", VariableList{}, b.ty.void_(), StatementList{},
AttributeList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Func("", VariableList{}, b.ty.void_(), StatementList{}, AttributeList{});
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_Null_ReturnType) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Func("f", VariableList{}, nullptr, StatementList{}, AttributeList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Func("f", VariableList{}, nullptr, StatementList{}, AttributeList{});
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_Null_Param) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
VariableList params;
params.push_back(b.Param("var", b.ty.i32()));
params.push_back(nullptr);
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
VariableList params;
params.push_back(b.Param("var", b.ty.i32()));
params.push_back(nullptr);
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
},
"internal compiler error");
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_DifferentProgramID_Symbol) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func(b2.Sym("func"), VariableList{}, b1.ty.void_(), StatementList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func(b2.Sym("func"), VariableList{}, b1.ty.void_(), StatementList{});
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_DifferentProgramID_Param) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func("func", VariableList{b2.Param("var", b2.ty.i32())},
b1.ty.void_(), StatementList{});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func("func", VariableList{b2.Param("var", b2.ty.i32())}, b1.ty.void_(),
StatementList{});
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_DifferentProgramID_Attr) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
AttributeList{
b2.WorkgroupSize(2, 4, 6),
});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
AttributeList{
b2.WorkgroupSize(2, 4, 6),
});
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnAttr) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
AttributeList{},
AttributeList{
b2.WorkgroupSize(2, 4, 6),
});
},
"internal compiler error");
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b1;
ProgramBuilder b2;
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{}, AttributeList{},
AttributeList{
b2.WorkgroupSize(2, 4, 6),
});
},
"internal compiler error");
}
TEST_F(FunctionTest, Assert_NonConstParam) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
VariableList params;
params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone));
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
VariableList params;
params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone));
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
},
"internal compiler error");
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
},
"internal compiler error");
}
using FunctionListTest = TestHelper;
TEST_F(FunctionListTest, FindSymbol) {
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{});
FunctionList list;
list.Add(func);
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{}, ast::AttributeList{});
FunctionList list;
list.Add(func);
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
}
TEST_F(FunctionListTest, FindSymbolMissing) {
FunctionList list;
EXPECT_EQ(nullptr, list.Find(Symbols().Register("Missing")));
FunctionList list;
EXPECT_EQ(nullptr, list.Find(Symbols().Register("Missing")));
}
TEST_F(FunctionListTest, FindSymbolStage) {
auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kFragment),
});
auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kVertex),
});
FunctionList list;
list.Add(fs);
list.Add(vs);
EXPECT_EQ(fs,
list.Find(Symbols().Register("main"), PipelineStage::kFragment));
EXPECT_EQ(vs, list.Find(Symbols().Register("main"), PipelineStage::kVertex));
auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kFragment),
});
auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kVertex),
});
FunctionList list;
list.Add(fs);
list.Add(vs);
EXPECT_EQ(fs, list.Find(Symbols().Register("main"), PipelineStage::kFragment));
EXPECT_EQ(vs, list.Find(Symbols().Register("main"), PipelineStage::kVertex));
}
TEST_F(FunctionListTest, FindSymbolStageMissing) {
FunctionList list;
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kFragment),
}));
EXPECT_EQ(nullptr,
list.Find(Symbols().Register("main"), PipelineStage::kVertex));
FunctionList list;
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kFragment),
}));
EXPECT_EQ(nullptr, list.Find(Symbols().Register("main"), PipelineStage::kVertex));
}
TEST_F(FunctionListTest, HasStage) {
FunctionList list;
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kFragment),
}));
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
EXPECT_FALSE(list.HasStage(PipelineStage::kVertex));
FunctionList list;
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
ast::AttributeList{
Stage(PipelineStage::kFragment),
}));
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
EXPECT_FALSE(list.HasStage(PipelineStage::kVertex));
}
} // namespace

View File

@@ -28,13 +28,13 @@ GroupAttribute::GroupAttribute(ProgramID pid, const Source& src, uint32_t val)
GroupAttribute::~GroupAttribute() = default;
std::string GroupAttribute::Name() const {
return "group";
return "group";
}
const GroupAttribute* GroupAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<GroupAttribute>(src, value);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<GroupAttribute>(src, value);
}
} // namespace tint::ast

View File

@@ -23,25 +23,25 @@ namespace tint::ast {
/// A group attribute
class GroupAttribute final : public Castable<GroupAttribute, Attribute> {
public:
/// constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the group value
GroupAttribute(ProgramID pid, const Source& src, uint32_t value);
~GroupAttribute() override;
public:
/// constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
/// @param value the group value
GroupAttribute(ProgramID pid, const Source& src, uint32_t value);
~GroupAttribute() override;
/// @returns the WGSL name for the attribute
std::string Name() const override;
/// @returns the WGSL name for the attribute
std::string Name() const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const GroupAttribute* Clone(CloneContext* ctx) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
const GroupAttribute* Clone(CloneContext* ctx) const override;
/// The group value
const uint32_t value;
/// The group value
const uint32_t value;
};
} // namespace tint::ast

View File

@@ -20,8 +20,8 @@ namespace {
using GroupAttributeTest = TestHelper;
TEST_F(GroupAttributeTest, Creation) {
auto* d = create<GroupAttribute>(2);
EXPECT_EQ(2u, d->value);
auto* d = create<GroupAttribute>(2);
EXPECT_EQ(2u, d->value);
}
} // namespace

View File

@@ -27,12 +27,12 @@ I32::I32(I32&&) = default;
I32::~I32() = default;
std::string I32::FriendlyName(const SymbolTable&) const {
return "i32";
return "i32";
}
const I32* I32::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
return ctx->dst->create<I32>(src);
auto src = ctx->Clone(source);
return ctx->dst->create<I32>(src);
}
} // namespace tint::ast

View File

@@ -23,24 +23,24 @@ namespace tint::ast {
/// A signed int 32 type.
class I32 final : public Castable<I32, Type> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
I32(ProgramID pid, const Source& src);
/// Move constructor
I32(I32&&);
~I32() override;
public:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
I32(ProgramID pid, const Source& src);
/// Move constructor
I32(I32&&);
~I32() override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const I32* Clone(CloneContext* ctx) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
const I32* Clone(CloneContext* ctx) const override;
};
} // namespace tint::ast

View File

@@ -22,8 +22,8 @@ namespace {
using AstI32Test = TestHelper;
TEST_F(AstI32Test, FriendlyName) {
auto* i = create<I32>();
EXPECT_EQ(i->FriendlyName(Symbols()), "i32");
auto* i = create<I32>();
EXPECT_EQ(i->FriendlyName(Symbols()), "i32");
}
} // namespace

View File

@@ -28,13 +28,13 @@ IdAttribute::IdAttribute(ProgramID pid, const Source& src, uint32_t val)
IdAttribute::~IdAttribute() = default;
std::string IdAttribute::Name() const {
return "id";
return "id";
}
const IdAttribute* IdAttribute::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<IdAttribute>(src, value);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source);
return ctx->dst->create<IdAttribute>(src, value);
}
} // namespace tint::ast

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