[ir] Update `Value` parameters.
This CL updates the various instructions to allow the provided `Value`s
to be `nullptr`. These will be checked by the validator to ensure they
do not move through to the backends.
The `AddOperand` and `AddOperands` methods are updated to take the
operand position. The provided position is then validated against
the operand list to validate that it is the next appended item. This
verifies that the operands are added at the expected indices so any call
to `SetOperand` will work as expected.
Bug: tint:1718
Change-Id: I2d20f1d8a18da80a70c45e49ae8598fe477eb826
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/137360
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/ir/access.cc b/src/tint/ir/access.cc
index 8f2a793..bce9abd 100644
--- a/src/tint/ir/access.cc
+++ b/src/tint/ir/access.cc
@@ -25,12 +25,10 @@
//! @cond Doxygen_Suppress
Access::Access(const type::Type* ty, Value* object, utils::VectorRef<Value*> indices)
: result_type_(ty) {
- TINT_ASSERT(IR, object);
TINT_ASSERT(IR, result_type_);
- TINT_ASSERT(IR, !indices.IsEmpty());
- AddOperand(object);
- AddOperands(std::move(indices));
+ AddOperand(Access::kObjectOperandOffset, object);
+ AddOperands(Access::kIndicesOperandOffset, std::move(indices));
}
Access::~Access() = default;
diff --git a/src/tint/ir/access.h b/src/tint/ir/access.h
index 04467e5..f3f03c8 100644
--- a/src/tint/ir/access.h
+++ b/src/tint/ir/access.h
@@ -23,7 +23,7 @@
/// An access instruction in the IR.
class Access : public utils::Castable<Access, OperandInstruction<3>> {
public:
- /// The base offset in Operands() for the object being accessed
+ /// The offset in Operands() for the object being accessed
static constexpr size_t kObjectOperandOffset = 0;
/// The base offset in Operands() for the access indices
diff --git a/src/tint/ir/access_test.cc b/src/tint/ir/access_test.cc
index 9d461b1..ee19623 100644
--- a/src/tint/ir/access_test.cc
+++ b/src/tint/ir/access_test.cc
@@ -47,39 +47,5 @@
"");
}
-TEST_F(IR_AccessTest, Fail_NullObject) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Access(mod.Types().i32(), nullptr, u32(1));
- },
- "");
-}
-
-TEST_F(IR_AccessTest, Fail_EmptyIndices) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- auto* ty = (mod.Types().ptr<function, i32>());
- auto* var = b.Var(ty);
- b.Access(mod.Types().i32(), var, utils::Empty);
- },
- "");
-}
-
-TEST_F(IR_AccessTest, Fail_NullIndex) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- auto* ty = (mod.Types().ptr<function, i32>());
- auto* var = b.Var(ty);
- b.Access(mod.Types().i32(), var, nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/binary.cc b/src/tint/ir/binary.cc
index 6287715..0b65966 100644
--- a/src/tint/ir/binary.cc
+++ b/src/tint/ir/binary.cc
@@ -22,11 +22,9 @@
Binary::Binary(enum Kind kind, const type::Type* res_ty, Value* lhs, Value* rhs)
: kind_(kind), result_type_(res_ty) {
TINT_ASSERT(IR, result_type_);
- TINT_ASSERT(IR, lhs);
- TINT_ASSERT(IR, rhs);
- AddOperand(lhs);
- AddOperand(rhs);
+ AddOperand(Binary::kLhsOperandOffset, lhs);
+ AddOperand(Binary::kRhsOperandOffset, rhs);
}
Binary::~Binary() = default;
diff --git a/src/tint/ir/binary.h b/src/tint/ir/binary.h
index 6c8e6d4..c759c12 100644
--- a/src/tint/ir/binary.h
+++ b/src/tint/ir/binary.h
@@ -23,6 +23,12 @@
/// A binary instruction in the IR.
class Binary : public utils::Castable<Binary, OperandInstruction<2>> {
public:
+ /// The offset in Operands() for the LHS
+ static constexpr size_t kLhsOperandOffset = 0;
+
+ /// The offset in Operands() for the RHS
+ static constexpr size_t kRhsOperandOffset = 1;
+
/// The kind of instruction.
enum class Kind {
kAdd,
@@ -61,10 +67,10 @@
const type::Type* Type() override { return result_type_; }
/// @returns the left-hand-side value for the instruction
- Value* LHS() { return operands_[0]; }
+ Value* LHS() { return operands_[kLhsOperandOffset]; }
/// @returns the right-hand-side value for the instruction
- Value* RHS() { return operands_[1]; }
+ Value* RHS() { return operands_[kRhsOperandOffset]; }
private:
enum Kind kind_;
diff --git a/src/tint/ir/binary_test.cc b/src/tint/ir/binary_test.cc
index 8b3a90d..d45296c 100644
--- a/src/tint/ir/binary_test.cc
+++ b/src/tint/ir/binary_test.cc
@@ -35,26 +35,6 @@
"");
}
-TEST_F(IR_BinaryTest, Fail_NullLHS) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Add(mod.Types().u32(), nullptr, u32(2));
- },
- "");
-}
-
-TEST_F(IR_BinaryTest, Fail_NullRHS) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Add(mod.Types().u32(), u32(1), nullptr);
- },
- "");
-}
-
TEST_F(IR_BinaryTest, CreateAnd) {
auto* inst = b.And(mod.Types().i32(), 4_i, 2_i);
diff --git a/src/tint/ir/bitcast.cc b/src/tint/ir/bitcast.cc
index a219749..262d20c 100644
--- a/src/tint/ir/bitcast.cc
+++ b/src/tint/ir/bitcast.cc
@@ -20,9 +20,7 @@
namespace tint::ir {
Bitcast::Bitcast(const type::Type* ty, Value* val) : Base(ty) {
- TINT_ASSERT(IR, val);
-
- AddOperand(val);
+ AddOperand(Bitcast::kValueOperandOffset, val);
}
Bitcast::~Bitcast() = default;
diff --git a/src/tint/ir/bitcast.h b/src/tint/ir/bitcast.h
index ddf74b9..2d4403f 100644
--- a/src/tint/ir/bitcast.h
+++ b/src/tint/ir/bitcast.h
@@ -23,6 +23,9 @@
/// A bitcast instruction in the IR.
class Bitcast : public utils::Castable<Bitcast, Call> {
public:
+ /// The offset in Operands() for the value
+ static constexpr size_t kValueOperandOffset = 0;
+
/// Constructor
/// @param type the result type
/// @param val the value being bitcast
diff --git a/src/tint/ir/bitcast_test.cc b/src/tint/ir/bitcast_test.cc
index e925349..44c8d90 100644
--- a/src/tint/ir/bitcast_test.cc
+++ b/src/tint/ir/bitcast_test.cc
@@ -49,16 +49,6 @@
EXPECT_THAT(args[0]->Usages(), testing::UnorderedElementsAre(Usage{inst, 0u}));
}
-TEST_F(IR_BitcastTest, Fail_NullValue) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Bitcast(mod.Types().i32(), nullptr);
- },
- "");
-}
-
TEST_F(IR_BitcastTest, Fail_NullType) {
EXPECT_FATAL_FAILURE(
{
diff --git a/src/tint/ir/break_if.cc b/src/tint/ir/break_if.cc
index 4a18fb8..078392e 100644
--- a/src/tint/ir/break_if.cc
+++ b/src/tint/ir/break_if.cc
@@ -24,19 +24,16 @@
namespace tint::ir {
-BreakIf::BreakIf(Value* condition,
- ir::Loop* loop,
- utils::VectorRef<Value*> args /* = utils::Empty */)
- : loop_(loop) {
- TINT_ASSERT(IR, condition);
+BreakIf::BreakIf(Value* condition, ir::Loop* loop, utils::VectorRef<Value*> args) : loop_(loop) {
TINT_ASSERT(IR, loop_);
- AddOperand(condition);
+ AddOperand(BreakIf::kConditionOperandOffset, condition);
+ AddOperands(BreakIf::kArgsOperandOffset, std::move(args));
+
if (loop_) {
loop_->Body()->AddInboundSiblingBranch(this);
loop_->Merge()->AddInboundSiblingBranch(this);
}
- AddOperands(std::move(args));
}
BreakIf::~BreakIf() = default;
diff --git a/src/tint/ir/break_if.h b/src/tint/ir/break_if.h
index 1eba580..59046b2 100644
--- a/src/tint/ir/break_if.h
+++ b/src/tint/ir/break_if.h
@@ -29,6 +29,12 @@
/// A break-if iteration instruction.
class BreakIf : public utils::Castable<BreakIf, Branch> {
public:
+ /// The offset in Operands() for the condition
+ static constexpr size_t kConditionOperandOffset = 0;
+
+ /// The base offset in Operands() for the arguments
+ static constexpr size_t kArgsOperandOffset = 1;
+
/// Constructor
/// @param condition the break condition
/// @param loop the loop containing the break-if
@@ -37,10 +43,12 @@
~BreakIf() override;
/// @returns the branch arguments
- utils::Slice<Value* const> Args() override { return operands_.Slice().Offset(1); }
+ utils::Slice<Value* const> Args() override {
+ return operands_.Slice().Offset(kArgsOperandOffset);
+ }
/// @returns the break condition
- Value* Condition() { return operands_[0]; }
+ Value* Condition() { return operands_[kConditionOperandOffset]; }
/// @returns the loop containing the break-if
ir::Loop* Loop() { return loop_; }
diff --git a/src/tint/ir/break_if_test.cc b/src/tint/ir/break_if_test.cc
index 9dd095a..84c29db 100644
--- a/src/tint/ir/break_if_test.cc
+++ b/src/tint/ir/break_if_test.cc
@@ -37,16 +37,6 @@
EXPECT_THAT(arg2->Usages(), testing::UnorderedElementsAre(Usage{brk, 2u}));
}
-TEST_F(IR_BreakIfTest, Fail_NullCondition) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.BreakIf(nullptr, b.Loop());
- },
- "");
-}
-
TEST_F(IR_BreakIfTest, Fail_NullLoop) {
EXPECT_FATAL_FAILURE(
{
@@ -57,15 +47,5 @@
"");
}
-TEST_F(IR_BreakIfTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.BreakIf(true, b.Loop(), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/builtin_call.cc b/src/tint/ir/builtin_call.cc
index a230510..fb1e708 100644
--- a/src/tint/ir/builtin_call.cc
+++ b/src/tint/ir/builtin_call.cc
@@ -28,7 +28,8 @@
: Base(ty), func_(func) {
TINT_ASSERT(IR, func != builtin::Function::kNone);
TINT_ASSERT(IR, func != builtin::Function::kTintMaterialize);
- AddOperands(std::move(arguments));
+
+ AddOperands(BuiltinCall::kArgsOperandOffset, std::move(arguments));
}
BuiltinCall::~BuiltinCall() = default;
diff --git a/src/tint/ir/builtin_call.h b/src/tint/ir/builtin_call.h
index 4aef1eb..4c12f43 100644
--- a/src/tint/ir/builtin_call.h
+++ b/src/tint/ir/builtin_call.h
@@ -24,6 +24,9 @@
/// A builtin call instruction in the IR.
class BuiltinCall : public utils::Castable<BuiltinCall, Call> {
public:
+ /// The base offset in Operands() for the args
+ static constexpr size_t kArgsOperandOffset = 0;
+
/// Constructor
/// @param res_type the result type
/// @param func the builtin function
diff --git a/src/tint/ir/builtin_call_test.cc b/src/tint/ir/builtin_call_test.cc
index fb6580e..d885f88 100644
--- a/src/tint/ir/builtin_call_test.cc
+++ b/src/tint/ir/builtin_call_test.cc
@@ -62,15 +62,5 @@
"");
}
-TEST_F(IR_BuiltinCallTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Call(mod.Types().f32(), builtin::Function::kAbs, nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/construct.cc b/src/tint/ir/construct.cc
index c4a330e..06adf2d 100644
--- a/src/tint/ir/construct.cc
+++ b/src/tint/ir/construct.cc
@@ -23,7 +23,7 @@
namespace tint::ir {
Construct::Construct(const type::Type* ty, utils::VectorRef<Value*> arguments) : Base(ty) {
- AddOperands(std::move(arguments));
+ AddOperands(Construct::kArgsOperandOffset, std::move(arguments));
}
Construct::~Construct() = default;
diff --git a/src/tint/ir/construct.h b/src/tint/ir/construct.h
index 4a15849..49419be 100644
--- a/src/tint/ir/construct.h
+++ b/src/tint/ir/construct.h
@@ -23,6 +23,9 @@
/// A constructor instruction in the IR.
class Construct : public utils::Castable<Construct, Call> {
public:
+ /// The base offset in Operands() for the args
+ static constexpr size_t kArgsOperandOffset = 0;
+
/// Constructor
/// @param type the result type
/// @param args the constructor arguments
diff --git a/src/tint/ir/construct_test.cc b/src/tint/ir/construct_test.cc
index fa31ff9..13ec4c0 100644
--- a/src/tint/ir/construct_test.cc
+++ b/src/tint/ir/construct_test.cc
@@ -43,15 +43,5 @@
"");
}
-TEST_F(IR_ConstructTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Construct(mod.Types().f32(), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/continue.cc b/src/tint/ir/continue.cc
index e1e8d84..5bb29ff 100644
--- a/src/tint/ir/continue.cc
+++ b/src/tint/ir/continue.cc
@@ -24,14 +24,14 @@
namespace tint::ir {
-Continue::Continue(ir::Loop* loop, utils::VectorRef<Value*> args /* = utils::Empty */)
- : loop_(loop) {
+Continue::Continue(ir::Loop* loop, utils::VectorRef<Value*> args) : loop_(loop) {
TINT_ASSERT(IR, loop_);
+ AddOperands(Continue::kArgsOperandOffset, std::move(args));
+
if (loop_) {
loop_->Continuing()->AddInboundSiblingBranch(this);
}
- AddOperands(std::move(args));
}
Continue::~Continue() = default;
diff --git a/src/tint/ir/continue.h b/src/tint/ir/continue.h
index f9c5455..6beda97 100644
--- a/src/tint/ir/continue.h
+++ b/src/tint/ir/continue.h
@@ -28,6 +28,9 @@
/// A continue instruction.
class Continue : public utils::Castable<Continue, Branch> {
public:
+ /// The base offset in Operands() for the args
+ static constexpr size_t kArgsOperandOffset = 0;
+
/// Constructor
/// @param loop the loop owning the continue block
/// @param args the branch arguments
diff --git a/src/tint/ir/continue_test.cc b/src/tint/ir/continue_test.cc
index 29ea605..7a8df1b 100644
--- a/src/tint/ir/continue_test.cc
+++ b/src/tint/ir/continue_test.cc
@@ -45,15 +45,5 @@
"");
}
-TEST_F(IR_ContinueTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Continue(b.Loop(), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/convert.cc b/src/tint/ir/convert.cc
index ed5961b..4681668 100644
--- a/src/tint/ir/convert.cc
+++ b/src/tint/ir/convert.cc
@@ -23,9 +23,7 @@
namespace tint::ir {
Convert::Convert(const type::Type* to_type, Value* value) : Base(to_type) {
- TINT_ASSERT_OR_RETURN(IR, value);
-
- AddOperand(value);
+ AddOperand(Convert::kValueOperandOffset, value);
}
Convert::~Convert() = default;
diff --git a/src/tint/ir/convert.h b/src/tint/ir/convert.h
index 0bb07cf..8448e19 100644
--- a/src/tint/ir/convert.h
+++ b/src/tint/ir/convert.h
@@ -24,6 +24,9 @@
/// A value conversion instruction in the IR.
class Convert : public utils::Castable<Convert, Call> {
public:
+ /// The offset in Operands() for the value
+ static constexpr size_t kValueOperandOffset = 0;
+
/// Constructor
/// @param to_type the target conversion type
/// @param value the value to convert
diff --git a/src/tint/ir/convert_test.cc b/src/tint/ir/convert_test.cc
index d1affd4..d5047e5 100644
--- a/src/tint/ir/convert_test.cc
+++ b/src/tint/ir/convert_test.cc
@@ -32,15 +32,5 @@
"");
}
-TEST_F(IR_ConvertTest, Fail_NoArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Convert(mod.Types().f32(), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/exit_if.cc b/src/tint/ir/exit_if.cc
index 391c786..f843712 100644
--- a/src/tint/ir/exit_if.cc
+++ b/src/tint/ir/exit_if.cc
@@ -23,13 +23,14 @@
namespace tint::ir {
-ExitIf::ExitIf(ir::If* i, utils::VectorRef<Value*> args /* = utils::Empty */) : if_(i) {
+ExitIf::ExitIf(ir::If* i, utils::VectorRef<Value*> args) : if_(i) {
TINT_ASSERT(IR, if_);
+ AddOperands(ExitIf::kArgsOperandOffset, std::move(args));
+
if (if_) {
if_->Merge()->AddInboundSiblingBranch(this);
}
- AddOperands(std::move(args));
}
ExitIf::~ExitIf() = default;
diff --git a/src/tint/ir/exit_if.h b/src/tint/ir/exit_if.h
index 5ddaabf..f626d19 100644
--- a/src/tint/ir/exit_if.h
+++ b/src/tint/ir/exit_if.h
@@ -28,6 +28,9 @@
/// A exit if instruction.
class ExitIf : public utils::Castable<ExitIf, Branch> {
public:
+ /// The base offset in Operands() for the args
+ static constexpr size_t kArgsOperandOffset = 0;
+
/// Constructor
/// @param i the if being exited
/// @param args the branch arguments
diff --git a/src/tint/ir/exit_if_test.cc b/src/tint/ir/exit_if_test.cc
index f496d6c..68c9012 100644
--- a/src/tint/ir/exit_if_test.cc
+++ b/src/tint/ir/exit_if_test.cc
@@ -44,15 +44,5 @@
"");
}
-TEST_F(IR_ExitIfTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.ExitIf(b.If(false), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/exit_loop.cc b/src/tint/ir/exit_loop.cc
index 865b25c..2dd394f 100644
--- a/src/tint/ir/exit_loop.cc
+++ b/src/tint/ir/exit_loop.cc
@@ -28,10 +28,11 @@
: loop_(loop) {
TINT_ASSERT(IR, loop_);
+ AddOperands(ExitLoop::kArgsOperandOffset, std::move(args));
+
if (loop_) {
loop_->Merge()->AddInboundSiblingBranch(this);
}
- AddOperands(std::move(args));
}
ExitLoop::~ExitLoop() = default;
diff --git a/src/tint/ir/exit_loop.h b/src/tint/ir/exit_loop.h
index 2e7f2ea..ed501a4 100644
--- a/src/tint/ir/exit_loop.h
+++ b/src/tint/ir/exit_loop.h
@@ -28,6 +28,9 @@
/// A exit loop instruction.
class ExitLoop : public utils::Castable<ExitLoop, Branch> {
public:
+ /// The base offset in Operands() for the args
+ static constexpr size_t kArgsOperandOffset = 0;
+
/// Constructor
/// @param loop the loop being exited
/// @param args the branch arguments
diff --git a/src/tint/ir/exit_loop_test.cc b/src/tint/ir/exit_loop_test.cc
index 2b8b3de..a234793 100644
--- a/src/tint/ir/exit_loop_test.cc
+++ b/src/tint/ir/exit_loop_test.cc
@@ -44,15 +44,5 @@
"");
}
-TEST_F(IR_ExitLoopTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.ExitLoop(b.Loop(), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/exit_switch.cc b/src/tint/ir/exit_switch.cc
index 3372d6d..7710df8 100644
--- a/src/tint/ir/exit_switch.cc
+++ b/src/tint/ir/exit_switch.cc
@@ -27,10 +27,11 @@
: switch_(sw) {
TINT_ASSERT(IR, switch_);
+ AddOperands(ExitSwitch::kArgsOperandOffset, std::move(args));
+
if (switch_) {
switch_->Merge()->AddInboundSiblingBranch(this);
}
- AddOperands(std::move(args));
}
ExitSwitch::~ExitSwitch() = default;
diff --git a/src/tint/ir/exit_switch.h b/src/tint/ir/exit_switch.h
index 706ac69..9d393be 100644
--- a/src/tint/ir/exit_switch.h
+++ b/src/tint/ir/exit_switch.h
@@ -28,6 +28,9 @@
/// A exit switch instruction.
class ExitSwitch : public utils::Castable<ExitSwitch, Branch> {
public:
+ /// The base offset in Operands() for the args
+ static constexpr size_t kArgsOperandOffset = 0;
+
/// Constructor
/// @param sw the switch being exited
/// @param args the branch arguments
diff --git a/src/tint/ir/exit_switch_test.cc b/src/tint/ir/exit_switch_test.cc
index 85cb228..df2b5a1 100644
--- a/src/tint/ir/exit_switch_test.cc
+++ b/src/tint/ir/exit_switch_test.cc
@@ -44,15 +44,5 @@
"");
}
-TEST_F(IR_ExitSwitchTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.ExitSwitch(b.Switch(false), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/if.cc b/src/tint/ir/if.cc
index 7f34986..1448639 100644
--- a/src/tint/ir/if.cc
+++ b/src/tint/ir/if.cc
@@ -22,12 +22,12 @@
If::If(Value* cond, ir::Block* t, ir::Block* f, ir::MultiInBlock* m)
: true_(t), false_(f), merge_(m) {
- TINT_ASSERT(IR, cond);
TINT_ASSERT(IR, true_);
TINT_ASSERT(IR, false_);
TINT_ASSERT(IR, merge_);
- AddOperand(cond);
+ AddOperand(If::kConditionOperandOffset, cond);
+
if (true_) {
true_->SetParent(this);
}
diff --git a/src/tint/ir/if_test.cc b/src/tint/ir/if_test.cc
index 60915a6..039a398 100644
--- a/src/tint/ir/if_test.cc
+++ b/src/tint/ir/if_test.cc
@@ -37,16 +37,6 @@
EXPECT_EQ(if_->Merge()->Parent(), if_);
}
-TEST_F(IR_IfTest, Fail_NullCondition) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.If(nullptr);
- },
- "");
-}
-
TEST_F(IR_IfTest, Fail_NullTrueBlock) {
EXPECT_FATAL_FAILURE(
{
diff --git a/src/tint/ir/instruction.h b/src/tint/ir/instruction.h
index 4cf7d70..03c66b3 100644
--- a/src/tint/ir/instruction.h
+++ b/src/tint/ir/instruction.h
@@ -53,7 +53,7 @@
/// Set an operand at a given index.
/// @param index the operand index
/// @param value the value to use
- virtual void SetOperand(uint32_t index, ir::Value* value) = 0;
+ virtual void SetOperand(size_t index, ir::Value* value) = 0;
/// Pointer to the next instruction in the list
Instruction* next = nullptr;
diff --git a/src/tint/ir/load.cc b/src/tint/ir/load.cc
index 4beb11e..aa91056 100644
--- a/src/tint/ir/load.cc
+++ b/src/tint/ir/load.cc
@@ -22,11 +22,10 @@
namespace tint::ir {
Load::Load(Value* from) {
- TINT_ASSERT_OR_RETURN(IR, from);
- TINT_ASSERT_OR_RETURN(IR, tint::Is<type::Pointer>(from->Type()));
-
+ TINT_ASSERT_OR_RETURN(IR, from && tint::Is<type::Pointer>(from->Type()));
result_type_ = from->Type()->UnwrapPtr();
- AddOperand(from);
+
+ AddOperand(Load::kFromOperandOffset, from);
}
Load::~Load() = default;
diff --git a/src/tint/ir/load.h b/src/tint/ir/load.h
index 29b3b22..12efb31 100644
--- a/src/tint/ir/load.h
+++ b/src/tint/ir/load.h
@@ -23,6 +23,9 @@
/// A load instruction in the IR.
class Load : public utils::Castable<Load, OperandInstruction<1>> {
public:
+ /// The offset in Operands() for the from value
+ static constexpr size_t kFromOperandOffset = 0;
+
/// Constructor (infers type)
/// @param from the value being loaded from
explicit Load(Value* from);
@@ -33,7 +36,7 @@
const type::Type* Type() override { return result_type_; }
/// @returns the value being loaded from
- Value* From() { return operands_[0]; }
+ Value* From() { return operands_[kFromOperandOffset]; }
private:
const type::Type* result_type_ = nullptr;
diff --git a/src/tint/ir/load_test.cc b/src/tint/ir/load_test.cc
index 6f9ddb1..7ed92ed 100644
--- a/src/tint/ir/load_test.cc
+++ b/src/tint/ir/load_test.cc
@@ -58,19 +58,5 @@
"");
}
-TEST_F(IR_LoadTest, Fail_NullValue_Builder) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Load(nullptr);
- },
- "");
-}
-
-TEST_F(IR_LoadTest, Fail_NullValue) {
- EXPECT_FATAL_FAILURE({ Load l(nullptr); }, "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/multi_in_block.cc b/src/tint/ir/multi_in_block.cc
index a86db11..94e7f59 100644
--- a/src/tint/ir/multi_in_block.cc
+++ b/src/tint/ir/multi_in_block.cc
@@ -26,14 +26,10 @@
void MultiInBlock::SetParams(utils::VectorRef<BlockParam*> params) {
params_ = std::move(params);
-
- TINT_ASSERT(IR, !params_.Any(utils::IsNull));
}
void MultiInBlock::SetParams(std::initializer_list<BlockParam*> params) {
params_ = std::move(params);
-
- TINT_ASSERT(IR, !params_.Any(utils::IsNull));
}
void MultiInBlock::AddInboundSiblingBranch(ir::Branch* node) {
diff --git a/src/tint/ir/multi_in_block_test.cc b/src/tint/ir/multi_in_block_test.cc
index 2d82715..ef9438c 100644
--- a/src/tint/ir/multi_in_block_test.cc
+++ b/src/tint/ir/multi_in_block_test.cc
@@ -23,18 +23,6 @@
using namespace tint::number_suffixes; // NOLINT
using IR_MultiInBlockTest = IRTestHelper;
-TEST_F(IR_MultiInBlockTest, Fail_NullBlockParam) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
-
- auto* blk = b.MultiInBlock();
- blk->SetParams({nullptr});
- },
- "");
-}
-
TEST_F(IR_MultiInBlockTest, Fail_NullInboundBranch) {
EXPECT_FATAL_FAILURE(
{
diff --git a/src/tint/ir/next_iteration.cc b/src/tint/ir/next_iteration.cc
index dc1ccd2..c7f1e80 100644
--- a/src/tint/ir/next_iteration.cc
+++ b/src/tint/ir/next_iteration.cc
@@ -26,10 +26,12 @@
NextIteration::NextIteration(ir::Loop* loop, utils::VectorRef<Value*> args /* = utils::Empty */)
: loop_(loop) {
TINT_ASSERT(IR, loop_);
+
+ AddOperands(NextIteration::kArgsOperandOffset, std::move(args));
+
if (loop_) {
loop_->Body()->AddInboundSiblingBranch(this);
}
- AddOperands(std::move(args));
}
NextIteration::~NextIteration() = default;
diff --git a/src/tint/ir/next_iteration.h b/src/tint/ir/next_iteration.h
index e80f628..6b01634 100644
--- a/src/tint/ir/next_iteration.h
+++ b/src/tint/ir/next_iteration.h
@@ -28,6 +28,9 @@
/// A next iteration instruction.
class NextIteration : public utils::Castable<NextIteration, Branch> {
public:
+ /// The base offset in Operands() for the args
+ static constexpr size_t kArgsOperandOffset = 0;
+
/// Constructor
/// @param loop the loop being iterated
/// @param args the branch arguments
diff --git a/src/tint/ir/next_iteration_test.cc b/src/tint/ir/next_iteration_test.cc
index c0d821c..657411c 100644
--- a/src/tint/ir/next_iteration_test.cc
+++ b/src/tint/ir/next_iteration_test.cc
@@ -32,15 +32,5 @@
"");
}
-TEST_F(IR_NextIterationTest, Fail_NullValue) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.NextIteration(b.Loop(), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/operand_instruction.h b/src/tint/ir/operand_instruction.h
index 8a121f7..a607155 100644
--- a/src/tint/ir/operand_instruction.h
+++ b/src/tint/ir/operand_instruction.h
@@ -29,7 +29,7 @@
/// Set an operand at a given index.
/// @param index the operand index
/// @param value the value to use
- void SetOperand(uint32_t index, ir::Value* value) override {
+ void SetOperand(size_t index, ir::Value* value) override {
TINT_ASSERT(IR, index < operands_.Length());
if (operands_[index]) {
operands_[index]->RemoveUsage({this, index});
@@ -43,8 +43,11 @@
protected:
/// Append a new operand to the operand list for this instruction.
+ /// @param idx the index the operand should be at
/// @param value the operand value to append
- void AddOperand(ir::Value* value) {
+ void AddOperand(size_t idx, ir::Value* value) {
+ TINT_ASSERT(IR, idx == operands_.Length());
+
if (value) {
value->AddUsage({this, static_cast<uint32_t>(operands_.Length())});
}
@@ -52,11 +55,13 @@
}
/// Append a list of non-null operands to the operand list for this instruction.
+ /// @param start_idx the index from whic the values should start
/// @param values the operand values to append
- void AddOperands(utils::VectorRef<ir::Value*> values) {
+ void AddOperands(size_t start_idx, utils::VectorRef<ir::Value*> values) {
+ size_t idx = start_idx;
for (auto* val : values) {
- TINT_ASSERT(IR, val != nullptr);
- AddOperand(val);
+ AddOperand(idx, val);
+ idx += 1;
}
}
diff --git a/src/tint/ir/return.cc b/src/tint/ir/return.cc
index c22c4ea..325f283 100644
--- a/src/tint/ir/return.cc
+++ b/src/tint/ir/return.cc
@@ -23,17 +23,12 @@
namespace tint::ir {
Return::Return(Function* func) {
- TINT_ASSERT_OR_RETURN(IR, func);
-
- AddOperand(func);
+ AddOperand(Return::kFunctionOperandOffset, func);
}
Return::Return(Function* func, ir::Value* arg) {
- TINT_ASSERT_OR_RETURN(IR, func);
- TINT_ASSERT_OR_RETURN(IR, arg);
-
- AddOperand(func);
- AddOperand(arg);
+ AddOperand(Return::kFunctionOperandOffset, func);
+ AddOperand(Return::kArgOperandOffset, arg);
}
Return::~Return() = default;
diff --git a/src/tint/ir/return.h b/src/tint/ir/return.h
index 2be267f..79968bc0 100644
--- a/src/tint/ir/return.h
+++ b/src/tint/ir/return.h
@@ -28,6 +28,12 @@
/// A return instruction.
class Return : public utils::Castable<Return, Branch> {
public:
+ /// The offset in Operands() for the function being returned
+ static constexpr size_t kFunctionOperandOffset = 0;
+
+ /// The offset in Operands() for the return argument
+ static constexpr size_t kArgOperandOffset = 1;
+
/// Constructor (no return value)
/// @param func the function being returned
explicit Return(Function* func);
@@ -40,13 +46,17 @@
~Return() override;
/// @returns the function being returned
- Function* Func() { return operands_[0]->As<Function>(); }
+ Function* Func() { return operands_[kFunctionOperandOffset]->As<Function>(); }
/// @returns the return value, or nullptr
- ir::Value* Value() const { return operands_.Length() > 1 ? operands_[1] : nullptr; }
+ ir::Value* Value() const {
+ return operands_.Length() > kArgOperandOffset ? operands_[kArgOperandOffset] : nullptr;
+ }
/// @returns the branch arguments
- utils::Slice<ir::Value* const> Args() override { return operands_.Slice().Offset(1); }
+ utils::Slice<ir::Value* const> Args() override {
+ return operands_.Slice().Offset(kArgOperandOffset);
+ }
};
} // namespace tint::ir
diff --git a/src/tint/ir/return_test.cc b/src/tint/ir/return_test.cc
index 273c353..f731c6b 100644
--- a/src/tint/ir/return_test.cc
+++ b/src/tint/ir/return_test.cc
@@ -24,26 +24,6 @@
using namespace tint::number_suffixes; // NOLINT
using IR_ReturnTest = IRTestHelper;
-TEST_F(IR_ReturnTest, Fail_NullFunction) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Return(nullptr);
- },
- "");
-}
-
-TEST_F(IR_ReturnTest, Fail_NullValue) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- mod.values.Create<Return>(b.Function("myfunc", mod.Types().void_()), nullptr);
- },
- "");
-}
-
TEST_F(IR_ReturnTest, ImplicitNoValue) {
auto* func = b.Function("myfunc", ty.void_());
auto* ret = b.Return(func);
diff --git a/src/tint/ir/store.cc b/src/tint/ir/store.cc
index 958f1e4..d1ea611 100644
--- a/src/tint/ir/store.cc
+++ b/src/tint/ir/store.cc
@@ -20,11 +20,8 @@
namespace tint::ir {
Store::Store(Value* to, Value* from) {
- TINT_ASSERT(IR, to);
- TINT_ASSERT(IR, from);
-
- AddOperand(to);
- AddOperand(from);
+ AddOperand(Store::kToOperandOffset, to);
+ AddOperand(Store::kFromOperandOffset, from);
}
Store::~Store() = default;
diff --git a/src/tint/ir/store.h b/src/tint/ir/store.h
index 41289f2..7c97aee 100644
--- a/src/tint/ir/store.h
+++ b/src/tint/ir/store.h
@@ -23,6 +23,12 @@
/// A store instruction in the IR.
class Store : public utils::Castable<Store, OperandInstruction<2>> {
public:
+ /// The offset in Operands() for the `to` value
+ static constexpr size_t kToOperandOffset = 0;
+
+ /// The offset in Operands() for the `from` value
+ static constexpr size_t kFromOperandOffset = 1;
+
/// Constructor
/// @param to the value to store too
/// @param from the value being stored from
@@ -30,10 +36,10 @@
~Store() override;
/// @returns the value being stored too
- Value* To() { return operands_[0]; }
+ Value* To() { return operands_[kToOperandOffset]; }
/// @returns the value being stored
- Value* From() { return operands_[1]; }
+ Value* From() { return operands_[kFromOperandOffset]; }
};
} // namespace tint::ir
diff --git a/src/tint/ir/store_test.cc b/src/tint/ir/store_test.cc
index 5582eb4..1d543ed 100644
--- a/src/tint/ir/store_test.cc
+++ b/src/tint/ir/store_test.cc
@@ -50,26 +50,5 @@
EXPECT_THAT(inst->From()->Usages(), testing::UnorderedElementsAre(Usage{inst, 1u}));
}
-TEST_F(IR_StoreTest, Fail_NullTo) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Store(nullptr, 1_u);
- },
- "");
-}
-
-TEST_F(IR_StoreTest, Fail_NullFrom) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- auto* to = b.Var(mod.Types().ptr<private_, i32>());
- b.Store(to, nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/switch.cc b/src/tint/ir/switch.cc
index 8b70cfc..7ac98cd 100644
--- a/src/tint/ir/switch.cc
+++ b/src/tint/ir/switch.cc
@@ -21,10 +21,9 @@
namespace tint::ir {
Switch::Switch(Value* cond, ir::MultiInBlock* m) : merge_(m) {
- TINT_ASSERT(IR, cond);
TINT_ASSERT(IR, merge_);
- AddOperand(cond);
+ AddOperand(Switch::kConditionOperandOffset, cond);
if (merge_) {
merge_->SetParent(this);
diff --git a/src/tint/ir/switch.h b/src/tint/ir/switch.h
index 7791c2c..7081e47 100644
--- a/src/tint/ir/switch.h
+++ b/src/tint/ir/switch.h
@@ -46,6 +46,9 @@
/// ```
class Switch : public utils::Castable<Switch, ControlInstruction> {
public:
+ /// The offset in Operands() for the condition
+ static constexpr size_t kConditionOperandOffset = 0;
+
/// A case selector
struct CaseSelector {
/// @returns true if this is a default selector
@@ -82,7 +85,7 @@
utils::Slice<Value* const> Args() override { return {}; }
/// @returns the condition
- Value* Condition() { return operands_[0]; }
+ Value* Condition() { return operands_[kConditionOperandOffset]; }
private:
ir::MultiInBlock* merge_ = nullptr;
diff --git a/src/tint/ir/switch_test.cc b/src/tint/ir/switch_test.cc
index 72e0dda..ab88556 100644
--- a/src/tint/ir/switch_test.cc
+++ b/src/tint/ir/switch_test.cc
@@ -37,16 +37,6 @@
EXPECT_THAT(switch_->Cases().Front().Start()->Parent(), switch_);
}
-TEST_F(IR_SwitchTest, Fail_NullCondition) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Switch(nullptr);
- },
- "");
-}
-
TEST_F(IR_SwitchTest, Fail_NullMultiInBlock) {
EXPECT_FATAL_FAILURE(
{
diff --git a/src/tint/ir/swizzle.cc b/src/tint/ir/swizzle.cc
index 58cecb2..48c26cf 100644
--- a/src/tint/ir/swizzle.cc
+++ b/src/tint/ir/swizzle.cc
@@ -24,12 +24,11 @@
Swizzle::Swizzle(const type::Type* ty, Value* object, utils::VectorRef<uint32_t> indices)
: result_type_(ty), indices_(std::move(indices)) {
- TINT_ASSERT(IR, object != nullptr);
TINT_ASSERT(IR, result_type_ != nullptr);
TINT_ASSERT(IR, !indices.IsEmpty());
TINT_ASSERT(IR, indices.Length() <= 4);
- AddOperand(object);
+ AddOperand(Swizzle::kObjectOperandOffset, object);
for (auto idx : indices_) {
TINT_ASSERT(IR, idx < 4);
diff --git a/src/tint/ir/swizzle.h b/src/tint/ir/swizzle.h
index f340a01..1613bfb 100644
--- a/src/tint/ir/swizzle.h
+++ b/src/tint/ir/swizzle.h
@@ -23,6 +23,9 @@
/// A swizzle instruction in the IR.
class Swizzle : public utils::Castable<Swizzle, OperandInstruction<1>> {
public:
+ /// The offset in Operands() for the object being swizzled
+ static constexpr size_t kObjectOperandOffset = 0;
+
/// Constructor
/// @param result_type the result type
/// @param object the object being swizzled
@@ -34,7 +37,7 @@
const type::Type* Type() override { return result_type_; }
/// @returns the object used for the access
- Value* Object() { return operands_[0]; }
+ Value* Object() { return operands_[kObjectOperandOffset]; }
/// @returns the swizzle indices
utils::VectorRef<uint32_t> Indices() { return indices_; }
diff --git a/src/tint/ir/swizzle_test.cc b/src/tint/ir/swizzle_test.cc
index 58df467..43dd54b 100644
--- a/src/tint/ir/swizzle_test.cc
+++ b/src/tint/ir/swizzle_test.cc
@@ -43,16 +43,6 @@
"");
}
-TEST_F(IR_SwizzleTest, Fail_NullObject) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Swizzle(mod.Types().i32(), nullptr, {1u});
- },
- "");
-}
-
TEST_F(IR_SwizzleTest, Fail_EmptyIndices) {
EXPECT_FATAL_FAILURE(
{
diff --git a/src/tint/ir/unary.cc b/src/tint/ir/unary.cc
index 90509e0..5d448f7 100644
--- a/src/tint/ir/unary.cc
+++ b/src/tint/ir/unary.cc
@@ -20,10 +20,9 @@
namespace tint::ir {
Unary::Unary(enum Kind k, const type::Type* res_ty, Value* val) : kind_(k), result_type_(res_ty) {
- TINT_ASSERT(IR, val != nullptr);
TINT_ASSERT(IR, result_type_ != nullptr);
- AddOperand(val);
+ AddOperand(Unary::kValueOperandOffset, val);
}
Unary::~Unary() = default;
diff --git a/src/tint/ir/unary.h b/src/tint/ir/unary.h
index baf1218..f94f1bc 100644
--- a/src/tint/ir/unary.h
+++ b/src/tint/ir/unary.h
@@ -23,6 +23,9 @@
/// A unary instruction in the IR.
class Unary : public utils::Castable<Unary, OperandInstruction<1>> {
public:
+ /// The offset in Operands() for the value
+ static constexpr size_t kValueOperandOffset = 0;
+
/// The kind of instruction.
enum class Kind {
kComplement,
@@ -40,7 +43,7 @@
const type::Type* Type() override { return result_type_; }
/// @returns the value for the instruction
- Value* Val() { return operands_[0]; }
+ Value* Val() { return operands_[kValueOperandOffset]; }
/// @returns the kind of unary instruction
enum Kind Kind() { return kind_; }
diff --git a/src/tint/ir/unary_test.cc b/src/tint/ir/unary_test.cc
index 7802dd4..397a883 100644
--- a/src/tint/ir/unary_test.cc
+++ b/src/tint/ir/unary_test.cc
@@ -68,15 +68,5 @@
"");
}
-TEST_F(IR_UnaryTest, Fail_NullValue) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Negation(mod.Types().i32(), nullptr);
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/user_call.cc b/src/tint/ir/user_call.cc
index e963e14..d5bded9 100644
--- a/src/tint/ir/user_call.cc
+++ b/src/tint/ir/user_call.cc
@@ -24,10 +24,8 @@
UserCall::UserCall(const type::Type* ty, Function* func, utils::VectorRef<Value*> arguments)
: Base(ty) {
- TINT_ASSERT(IR, func);
-
- AddOperand(func);
- AddOperands(std::move(arguments));
+ AddOperand(UserCall::kFunctionOperandOffset, func);
+ AddOperands(UserCall::kArgsOperandOffset, std::move(arguments));
}
UserCall::~UserCall() = default;
diff --git a/src/tint/ir/user_call.h b/src/tint/ir/user_call.h
index 2d08482..f98b41a 100644
--- a/src/tint/ir/user_call.h
+++ b/src/tint/ir/user_call.h
@@ -24,6 +24,12 @@
/// A user call instruction in the IR.
class UserCall : public utils::Castable<UserCall, Call> {
public:
+ /// The offset in Operands() for the function being called
+ static constexpr size_t kFunctionOperandOffset = 0;
+
+ /// The base offset in Operands() for the call arguments
+ static constexpr size_t kArgsOperandOffset = 1;
+
/// Constructor
/// @param type the result type
/// @param func the function being called
@@ -32,12 +38,12 @@
~UserCall() override;
/// @returns the call arguments
- utils::Slice<Value* const> Args() override { return operands_.Slice().Offset(1); }
+ utils::Slice<Value* const> Args() override {
+ return operands_.Slice().Offset(kArgsOperandOffset);
+ }
/// @returns the called function name
- Function* Func() { return operands_.Front()->As<ir::Function>(); }
-
- private:
+ Function* Func() { return operands_[kFunctionOperandOffset]->As<ir::Function>(); }
};
} // namespace tint::ir
diff --git a/src/tint/ir/user_call_test.cc b/src/tint/ir/user_call_test.cc
index 6b73272..82746d9 100644
--- a/src/tint/ir/user_call_test.cc
+++ b/src/tint/ir/user_call_test.cc
@@ -44,26 +44,5 @@
"");
}
-TEST_F(IR_UserCallTest, Fail_NullFunction) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Call(mod.Types().f32(), nullptr);
- },
- "");
-}
-
-TEST_F(IR_UserCallTest, Fail_NullArg) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Call(mod.Types().void_(), b.Function("myfunc", mod.Types().void_()),
- utils::Vector<Value*, 1>{nullptr});
- },
- "");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/value.h b/src/tint/ir/value.h
index 1d7f88d..819e3bc 100644
--- a/src/tint/ir/value.h
+++ b/src/tint/ir/value.h
@@ -31,7 +31,7 @@
/// The instruction that is using the value;
Instruction* instruction = nullptr;
/// The index of the operand that is the value being used.
- uint32_t operand_index = 0u;
+ size_t operand_index = 0u;
/// A specialization of utils::Hasher for Usage.
struct Hasher {
diff --git a/src/tint/ir/var.cc b/src/tint/ir/var.cc
index 4dd00ce..2978f24 100644
--- a/src/tint/ir/var.cc
+++ b/src/tint/ir/var.cc
@@ -23,13 +23,13 @@
TINT_ASSERT(IR, type_ != nullptr);
// Default to no initializer.
- AddOperand(nullptr);
+ AddOperand(Var::kInitializerOperandOffset, nullptr);
}
Var::~Var() = default;
void Var::SetInitializer(Value* initializer) {
- SetOperand(0, initializer);
+ SetOperand(Var::kInitializerOperandOffset, initializer);
}
} // namespace tint::ir
diff --git a/src/tint/ir/var.h b/src/tint/ir/var.h
index 6f22c7d..435d123 100644
--- a/src/tint/ir/var.h
+++ b/src/tint/ir/var.h
@@ -28,6 +28,9 @@
/// A var instruction in the IR.
class Var : public utils::Castable<Var, OperandInstruction<1>> {
public:
+ /// The offset in Operands() for the initializer
+ static constexpr size_t kInitializerOperandOffset = 0;
+
/// Constructor
/// @param type the type of the var
explicit Var(const type::Pointer* type);
@@ -40,7 +43,7 @@
/// @param initializer the initializer
void SetInitializer(Value* initializer);
/// @returns the initializer
- Value* Initializer() { return operands_[0]; }
+ Value* Initializer() { return operands_[kInitializerOperandOffset]; }
/// Sets the binding point
/// @param group the group