Reland "Revert "moved BinaryExpression's data into IRNode""
This reverts commit 1d3e0e0054b243b7a62029c29090e7e76a19a805.
Reason for revert: possibly causing https://task-scheduler.skia.org/task/F1DoniJAddPuEkH9ETTE
Original change's description:
> Revert "Revert "moved BinaryExpression's data into IRNode""
>
> This reverts commit b61c3a9a01c44840eaa35b28cae0a4b358727f3c.
>
> Change-Id: I4689e1f4977fab3233ff492cee06fbc301b5c689
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317386
> Reviewed-by: John Stiles <johnstiles@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com
# Not skipping CQ checks because this is a reland.
Change-Id: Id0f3f211f09fbf31b626c648ed141fc6154a450c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317395
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLASTNode.h b/src/sksl/SkSLASTNode.h
index e493895..c65429c 100644
--- a/src/sksl/SkSLASTNode.h
+++ b/src/sksl/SkSLASTNode.h
@@ -12,11 +12,15 @@
#include "src/sksl/SkSLString.h"
#include "src/sksl/ir/SkSLModifiers.h"
-#include <algorithm>
#include <vector>
namespace SkSL {
+// std::max isn't constexpr in some compilers
+static constexpr size_t Max(size_t a, size_t b) {
+ return a > b ? a : b;
+}
+
/**
* Represents a node in the abstract syntax tree (AST). The AST is based directly on the parse tree;
* it is a parsed-but-not-yet-analyzed version of the program.
@@ -263,18 +267,18 @@
};
struct NodeData {
- char fBytes[std::max(sizeof(Token),
- std::max(sizeof(StringFragment),
- std::max(sizeof(bool),
- std::max(sizeof(SKSL_INT),
- std::max(sizeof(SKSL_FLOAT),
- std::max(sizeof(Modifiers),
- std::max(sizeof(TypeData),
- std::max(sizeof(FunctionData),
- std::max(sizeof(ParameterData),
- std::max(sizeof(VarData),
- std::max(sizeof(InterfaceBlockData),
- sizeof(SectionData))))))))))))];
+ char fBytes[Max(sizeof(Token),
+ Max(sizeof(StringFragment),
+ Max(sizeof(bool),
+ Max(sizeof(SKSL_INT),
+ Max(sizeof(SKSL_FLOAT),
+ Max(sizeof(Modifiers),
+ Max(sizeof(TypeData),
+ Max(sizeof(FunctionData),
+ Max(sizeof(ParameterData),
+ Max(sizeof(VarData),
+ Max(sizeof(InterfaceBlockData),
+ sizeof(SectionData))))))))))))];
enum class Kind {
kToken,
diff --git a/src/sksl/SkSLAnalysis.cpp b/src/sksl/SkSLAnalysis.cpp
index 82ac423..6496965 100644
--- a/src/sksl/SkSLAnalysis.cpp
+++ b/src/sksl/SkSLAnalysis.cpp
@@ -266,7 +266,7 @@
return false;
case Expression::Kind::kBinary: {
const BinaryExpression& b = e.as<BinaryExpression>();
- return this->visitExpression(b.left()) || this->visitExpression(b.right()); }
+ return this->visitExpression(*b.fLeft) || this->visitExpression(*b.fRight); }
case Expression::Kind::kConstructor: {
const Constructor& c = e.as<Constructor>();
for (const auto& arg : c.fArguments) {
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 1e9dab0..a213ca4 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -681,29 +681,28 @@
}
bool ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b, bool discard) {
- const Expression& left = b.left();
- const Expression& right = b.right();
- Token::Kind op = b.getOperator();
- if (op == Token::Kind::TK_EQ) {
- std::unique_ptr<LValue> lvalue = this->getLValue(left);
- this->writeExpression(right);
+ if (b.fOperator == Token::Kind::TK_EQ) {
+ std::unique_ptr<LValue> lvalue = this->getLValue(*b.fLeft);
+ this->writeExpression(*b.fRight);
lvalue->store(discard);
discard = false;
return discard;
}
- const Type& lType = left.type();
- const Type& rType = right.type();
+ const Type& lType = b.fLeft->type();
+ const Type& rType = b.fRight->type();
bool lVecOrMtx = (lType.typeKind() == Type::TypeKind::kVector ||
lType.typeKind() == Type::TypeKind::kMatrix);
bool rVecOrMtx = (rType.typeKind() == Type::TypeKind::kVector ||
rType.typeKind() == Type::TypeKind::kMatrix);
+ Token::Kind op;
std::unique_ptr<LValue> lvalue;
- if (Compiler::IsAssignment(op)) {
- lvalue = this->getLValue(left);
+ if (Compiler::IsAssignment(b.fOperator)) {
+ lvalue = this->getLValue(*b.fLeft);
lvalue->load();
- op = Compiler::RemoveAssignment(op);
+ op = Compiler::RemoveAssignment(b.fOperator);
} else {
- this->writeExpression(left);
+ this->writeExpression(*b.fLeft);
+ op = b.fOperator;
if (!lVecOrMtx && rVecOrMtx) {
for (int i = SlotCount(rType); i > 1; --i) {
this->write(ByteCodeInstruction::kDup, 1);
@@ -719,7 +718,7 @@
this->write(ByteCodeInstruction::kMaskPush);
this->write(ByteCodeInstruction::kBranchIfAllFalse);
DeferredLocation falseLocation(this);
- this->writeExpression(right);
+ this->writeExpression(*b.fRight);
this->write(ByteCodeInstruction::kAndB, 1);
falseLocation.set();
this->write(ByteCodeInstruction::kMaskPop);
@@ -732,7 +731,7 @@
this->write(ByteCodeInstruction::kMaskPush);
this->write(ByteCodeInstruction::kBranchIfAllFalse);
DeferredLocation falseLocation(this);
- this->writeExpression(right);
+ this->writeExpression(*b.fRight);
this->write(ByteCodeInstruction::kOrB, 1);
falseLocation.set();
this->write(ByteCodeInstruction::kMaskPop);
@@ -742,13 +741,13 @@
case Token::Kind::TK_SHR: {
SkASSERT(count == 1 && (tc == SkSL::TypeCategory::kSigned ||
tc == SkSL::TypeCategory::kUnsigned));
- if (!right.isCompileTimeConstant()) {
- fErrors.error(right.fOffset, "Shift amounts must be constant");
+ if (!b.fRight->isCompileTimeConstant()) {
+ fErrors.error(b.fRight->fOffset, "Shift amounts must be constant");
return false;
}
- int64_t shift = right.getConstantInt();
+ int64_t shift = b.fRight->getConstantInt();
if (shift < 0 || shift > 31) {
- fErrors.error(right.fOffset, "Shift amount out of range");
+ fErrors.error(b.fRight->fOffset, "Shift amount out of range");
return false;
}
@@ -766,7 +765,7 @@
default:
break;
}
- this->writeExpression(right);
+ this->writeExpression(*b.fRight);
if (lVecOrMtx && !rVecOrMtx) {
for (int i = SlotCount(lType); i > 1; --i) {
this->write(ByteCodeInstruction::kDup, 1);
diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp
index 281e380..d9a9ab1 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -166,14 +166,14 @@
switch (expr->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression& b = expr->as<BinaryExpression>();
- if (b.getOperator() == Token::Kind::TK_EQ) {
- if (!this->tryRemoveLValueBefore(iter, &b.left())) {
+ if (b.fOperator == Token::Kind::TK_EQ) {
+ if (!this->tryRemoveLValueBefore(iter, b.fLeft.get())) {
return false;
}
- } else if (!this->tryRemoveExpressionBefore(iter, &b.left())) {
+ } else if (!this->tryRemoveExpressionBefore(iter, b.fLeft.get())) {
return false;
}
- if (!this->tryRemoveExpressionBefore(iter, &b.right())) {
+ if (!this->tryRemoveExpressionBefore(iter, b.fRight.get())) {
return false;
}
SkASSERT((*iter)->expression()->get() == expr);
@@ -267,12 +267,11 @@
switch ((*expr)->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression& b = expr->get()->as<BinaryExpression>();
- if (!this->tryInsertExpression(iter, &b.rightPointer())) {
+ if (!this->tryInsertExpression(iter, &b.fRight)) {
return false;
}
-
++(*iter);
- if (!this->tryInsertExpression(iter, &b.leftPointer())) {
+ if (!this->tryInsertExpression(iter, &b.fLeft)) {
return false;
}
++(*iter);
@@ -320,17 +319,16 @@
switch ((*e)->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression& b = e->get()->as<BinaryExpression>();
- Token::Kind op = b.getOperator();
- switch (op) {
+ switch (b.fOperator) {
case Token::Kind::TK_LOGICALAND: // fall through
case Token::Kind::TK_LOGICALOR: {
// this isn't as precise as it could be -- we don't bother to track that if we
// early exit from a logical and/or, we know which branch of an 'if' we're going
// to hit -- but it won't make much difference in practice.
- this->addExpression(cfg, &b.leftPointer(), constantPropagate);
+ this->addExpression(cfg, &b.fLeft, constantPropagate);
BlockId start = cfg.fCurrent;
cfg.newBlock();
- this->addExpression(cfg, &b.rightPointer(), constantPropagate);
+ this->addExpression(cfg, &b.fRight, constantPropagate);
cfg.newBlock();
cfg.addExit(start, cfg.fCurrent);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
@@ -342,8 +340,8 @@
break;
}
case Token::Kind::TK_EQ: {
- this->addExpression(cfg, &b.rightPointer(), constantPropagate);
- this->addLValue(cfg, &b.leftPointer());
+ this->addExpression(cfg, &b.fRight, constantPropagate);
+ this->addLValue(cfg, &b.fLeft);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
BasicBlock::Node::kExpression_Kind,
constantPropagate,
@@ -353,8 +351,8 @@
break;
}
default:
- this->addExpression(cfg, &b.leftPointer(), !Compiler::IsAssignment(op));
- this->addExpression(cfg, &b.rightPointer(), constantPropagate);
+ this->addExpression(cfg, &b.fLeft, !Compiler::IsAssignment(b.fOperator));
+ this->addExpression(cfg, &b.fRight, constantPropagate);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
BasicBlock::Node::kExpression_Kind,
constantPropagate,
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index a62374e..3eacb80 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -70,45 +70,42 @@
void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
Precedence parentPrecedence) {
- const Expression& left = b.left();
- const Expression& right = b.right();
- Token::Kind op = b.getOperator();
- if (op == Token::Kind::TK_PERCENT) {
+ if (b.fOperator == Token::Kind::TK_PERCENT) {
// need to use "%%" instead of "%" b/c the code will be inside of a printf
- Precedence precedence = GetBinaryPrecedence(op);
+ Precedence precedence = GetBinaryPrecedence(b.fOperator);
if (precedence >= parentPrecedence) {
this->write("(");
}
- this->writeExpression(left, precedence);
+ this->writeExpression(*b.fLeft, precedence);
this->write(" %% ");
- this->writeExpression(right, precedence);
+ this->writeExpression(*b.fRight, precedence);
if (precedence >= parentPrecedence) {
this->write(")");
}
- } else if (left.kind() == Expression::Kind::kNullLiteral ||
- right.kind() == Expression::Kind::kNullLiteral) {
+ } else if (b.fLeft->kind() == Expression::Kind::kNullLiteral ||
+ b.fRight->kind() == Expression::Kind::kNullLiteral) {
const Variable* var;
- if (left.kind() != Expression::Kind::kNullLiteral) {
- var = &left.as<VariableReference>().fVariable;
+ if (b.fLeft->kind() != Expression::Kind::kNullLiteral) {
+ var = &b.fLeft->as<VariableReference>().fVariable;
} else {
- var = &right.as<VariableReference>().fVariable;
+ var = &b.fRight->as<VariableReference>().fVariable;
}
SkASSERT(var->type().typeKind() == Type::TypeKind::kNullable &&
var->type().componentType() == *fContext.fFragmentProcessor_Type);
this->write("%s");
- const char* prefix = "";
- switch (op) {
+ const char* op = "";
+ switch (b.fOperator) {
case Token::Kind::TK_EQEQ:
- prefix = "!";
+ op = "!";
break;
case Token::Kind::TK_NEQ:
- prefix = "";
+ op = "";
break;
default:
SkASSERT(false);
}
int childIndex = this->getChildFPIndex(*var);
- fFormatArgs.push_back(String(prefix) + "_outer.childProcessor(" + to_string(childIndex) +
+ fFormatArgs.push_back(String(op) + "_outer.childProcessor(" + to_string(childIndex) +
") ? \"true\" : \"false\"");
} else {
INHERITED::writeBinaryExpression(b, parentPrecedence);
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 6bd8f74..0558688 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -436,11 +436,11 @@
switch (expr->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression* b = &expr->as<BinaryExpression>();
- if (b->getOperator() == Token::Kind::TK_EQ) {
- this->addDefinition(&b->left(), &b->rightPointer(), definitions);
- } else if (Compiler::IsAssignment(b->getOperator())) {
+ if (b->fOperator == Token::Kind::TK_EQ) {
+ this->addDefinition(b->fLeft.get(), &b->fRight, definitions);
+ } else if (Compiler::IsAssignment(b->fOperator)) {
this->addDefinition(
- &b->left(),
+ b->fLeft.get(),
(std::unique_ptr<Expression>*) &fContext->fDefined_Expression,
definitions);
@@ -607,10 +607,10 @@
* to a dead target and lack of side effects on the left hand side.
*/
static bool dead_assignment(const BinaryExpression& b) {
- if (!Compiler::IsAssignment(b.getOperator())) {
+ if (!Compiler::IsAssignment(b.fOperator)) {
return false;
}
- return is_dead(b.left());
+ return is_dead(*b.fLeft);
}
void Compiler::computeDataFlow(CFG* cfg) {
@@ -705,16 +705,14 @@
*outUpdated = true;
std::unique_ptr<Expression>* target = (*iter)->expression();
BinaryExpression& bin = (*target)->as<BinaryExpression>();
- Expression& left = bin.left();
- std::unique_ptr<Expression>& rightPointer = bin.rightPointer();
- SkASSERT(!left.hasSideEffects());
+ SkASSERT(!bin.fLeft->hasSideEffects());
bool result;
- if (bin.getOperator() == Token::Kind::TK_EQ) {
- result = b->tryRemoveLValueBefore(iter, &left);
+ if (bin.fOperator == Token::Kind::TK_EQ) {
+ result = b->tryRemoveLValueBefore(iter, bin.fLeft.get());
} else {
- result = b->tryRemoveExpressionBefore(iter, &left);
+ result = b->tryRemoveExpressionBefore(iter, bin.fLeft.get());
}
- *target = std::move(rightPointer);
+ *target = std::move(bin.fRight);
if (!result) {
*outNeedsRescan = true;
return;
@@ -725,7 +723,7 @@
}
--(*iter);
if ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
- (*iter)->expression() != &rightPointer) {
+ (*iter)->expression() != &bin.fRight) {
*outNeedsRescan = true;
return;
}
@@ -744,22 +742,20 @@
*outUpdated = true;
std::unique_ptr<Expression>* target = (*iter)->expression();
BinaryExpression& bin = (*target)->as<BinaryExpression>();
- std::unique_ptr<Expression>& leftPointer = bin.leftPointer();
- Expression& right = bin.right();
- SkASSERT(!right.hasSideEffects());
- if (!b->tryRemoveExpressionBefore(iter, &right)) {
- *target = std::move(leftPointer);
+ SkASSERT(!bin.fRight->hasSideEffects());
+ if (!b->tryRemoveExpressionBefore(iter, bin.fRight.get())) {
+ *target = std::move(bin.fLeft);
*outNeedsRescan = true;
return;
}
- *target = std::move(leftPointer);
+ *target = std::move(bin.fLeft);
if (*iter == b->fNodes.begin()) {
*outNeedsRescan = true;
return;
}
--(*iter);
if (((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
- (*iter)->expression() != &leftPointer)) {
+ (*iter)->expression() != &bin.fLeft)) {
*outNeedsRescan = true;
return;
}
@@ -812,7 +808,7 @@
bool* outUpdated,
bool* outNeedsRescan) {
BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
- vectorize(b, iter, bin.right().type(), &bin.leftPointer(), outUpdated, outNeedsRescan);
+ vectorize(b, iter, bin.fRight->type(), &bin.fLeft, outUpdated, outNeedsRescan);
}
/**
@@ -824,7 +820,7 @@
bool* outUpdated,
bool* outNeedsRescan) {
BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
- vectorize(b, iter, bin.left().type(), &bin.rightPointer(), outUpdated, outNeedsRescan);
+ vectorize(b, iter, bin.fLeft->type(), &bin.fRight, outUpdated, outNeedsRescan);
}
// Mark that an expression which we were writing to is no longer being written to
@@ -906,10 +902,8 @@
delete_left(&b, iter, outUpdated, outNeedsRescan);
break;
}
- Expression& left = bin->left();
- Expression& right = bin->right();
- const Type& leftType = left.type();
- const Type& rightType = right.type();
+ const Type& leftType = bin->fLeft->type();
+ const Type& rightType = bin->fRight->type();
// collapse useless expressions like x * 1 or x + 0
if (((leftType.typeKind() != Type::TypeKind::kScalar) &&
(leftType.typeKind() != Type::TypeKind::kVector)) ||
@@ -917,9 +911,9 @@
(rightType.typeKind() != Type::TypeKind::kVector))) {
break;
}
- switch (bin->getOperator()) {
+ switch (bin->fOperator) {
case Token::Kind::TK_STAR:
- if (is_constant(left, 1)) {
+ if (is_constant(*bin->fLeft, 1)) {
if (leftType.typeKind() == Type::TypeKind::kVector &&
rightType.typeKind() == Type::TypeKind::kScalar) {
// float4(1) * x -> float4(x)
@@ -931,22 +925,22 @@
delete_left(&b, iter, outUpdated, outNeedsRescan);
}
}
- else if (is_constant(left, 0)) {
+ else if (is_constant(*bin->fLeft, 0)) {
if (leftType.typeKind() == Type::TypeKind::kScalar &&
rightType.typeKind() == Type::TypeKind::kVector &&
- !right.hasSideEffects()) {
+ !bin->fRight->hasSideEffects()) {
// 0 * float4(x) -> float4(0)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
// 0 * x -> 0
// float4(0) * x -> float4(0)
// float4(0) * float4(x) -> float4(0)
- if (!right.hasSideEffects()) {
+ if (!bin->fRight->hasSideEffects()) {
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
}
}
- else if (is_constant(right, 1)) {
+ else if (is_constant(*bin->fRight, 1)) {
if (leftType.typeKind() == Type::TypeKind::kScalar &&
rightType.typeKind() == Type::TypeKind::kVector) {
// x * float4(1) -> float4(x)
@@ -958,24 +952,24 @@
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
}
- else if (is_constant(right, 0)) {
+ else if (is_constant(*bin->fRight, 0)) {
if (leftType.typeKind() == Type::TypeKind::kVector &&
rightType.typeKind() == Type::TypeKind::kScalar &&
- !left.hasSideEffects()) {
+ !bin->fLeft->hasSideEffects()) {
// float4(x) * 0 -> float4(0)
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
} else {
// x * 0 -> 0
// x * float4(0) -> float4(0)
// float4(x) * float4(0) -> float4(0)
- if (!left.hasSideEffects()) {
+ if (!bin->fLeft->hasSideEffects()) {
delete_left(&b, iter, outUpdated, outNeedsRescan);
}
}
}
break;
case Token::Kind::TK_PLUS:
- if (is_constant(left, 0)) {
+ if (is_constant(*bin->fLeft, 0)) {
if (leftType.typeKind() == Type::TypeKind::kVector &&
rightType.typeKind() == Type::TypeKind::kScalar) {
// float4(0) + x -> float4(x)
@@ -986,7 +980,7 @@
// float4(0) + float4(x) -> float4(x)
delete_left(&b, iter, outUpdated, outNeedsRescan);
}
- } else if (is_constant(right, 0)) {
+ } else if (is_constant(*bin->fRight, 0)) {
if (leftType.typeKind() == Type::TypeKind::kScalar &&
rightType.typeKind() == Type::TypeKind::kVector) {
// x + float4(0) -> float4(x)
@@ -1000,7 +994,7 @@
}
break;
case Token::Kind::TK_MINUS:
- if (is_constant(right, 0)) {
+ if (is_constant(*bin->fRight, 0)) {
if (leftType.typeKind() == Type::TypeKind::kScalar &&
rightType.typeKind() == Type::TypeKind::kVector) {
// x - float4(0) -> float4(x)
@@ -1014,7 +1008,7 @@
}
break;
case Token::Kind::TK_SLASH:
- if (is_constant(right, 1)) {
+ if (is_constant(*bin->fRight, 1)) {
if (leftType.typeKind() == Type::TypeKind::kScalar &&
rightType.typeKind() == Type::TypeKind::kVector) {
// x / float4(1) -> float4(x)
@@ -1025,43 +1019,43 @@
// float4(x) / float4(1) -> float4(x)
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
- } else if (is_constant(left, 0)) {
+ } else if (is_constant(*bin->fLeft, 0)) {
if (leftType.typeKind() == Type::TypeKind::kScalar &&
rightType.typeKind() == Type::TypeKind::kVector &&
- !right.hasSideEffects()) {
+ !bin->fRight->hasSideEffects()) {
// 0 / float4(x) -> float4(0)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
// 0 / x -> 0
// float4(0) / x -> float4(0)
// float4(0) / float4(x) -> float4(0)
- if (!right.hasSideEffects()) {
+ if (!bin->fRight->hasSideEffects()) {
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
}
}
break;
case Token::Kind::TK_PLUSEQ:
- if (is_constant(right, 0)) {
- clear_write(left);
+ if (is_constant(*bin->fRight, 0)) {
+ clear_write(*bin->fLeft);
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
break;
case Token::Kind::TK_MINUSEQ:
- if (is_constant(right, 0)) {
- clear_write(left);
+ if (is_constant(*bin->fRight, 0)) {
+ clear_write(*bin->fLeft);
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
break;
case Token::Kind::TK_STAREQ:
- if (is_constant(right, 1)) {
- clear_write(left);
+ if (is_constant(*bin->fRight, 1)) {
+ clear_write(*bin->fLeft);
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
break;
case Token::Kind::TK_SLASHEQ:
- if (is_constant(right, 1)) {
- clear_write(left);
+ if (is_constant(*bin->fRight, 1)) {
+ clear_write(*bin->fLeft);
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
break;
diff --git a/src/sksl/SkSLDehydrator.cpp b/src/sksl/SkSLDehydrator.cpp
index b320343..4f93647 100644
--- a/src/sksl/SkSLDehydrator.cpp
+++ b/src/sksl/SkSLDehydrator.cpp
@@ -258,9 +258,9 @@
case Expression::Kind::kBinary: {
const BinaryExpression& b = e->as<BinaryExpression>();
this->writeU8(Rehydrator::kBinary_Command);
- this->write(&b.left());
- this->writeU8((int) b.getOperator());
- this->write(&b.right());
+ this->write(b.fLeft.get());
+ this->writeU8((int) b.fOperator);
+ this->write(b.fRight.get());
this->write(b.type());
break;
}
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 6ef3b9b..433b11b 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -913,33 +913,31 @@
void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
Precedence parentPrecedence) {
- const Expression& left = b.left();
- const Expression& right = b.right();
- Token::Kind op = b.getOperator();
if (fProgram.fSettings.fCaps->unfoldShortCircuitAsTernary() &&
- (op == Token::Kind::TK_LOGICALAND || op == Token::Kind::TK_LOGICALOR)) {
+ (b.fOperator == Token::Kind::TK_LOGICALAND ||
+ b.fOperator == Token::Kind::TK_LOGICALOR)) {
this->writeShortCircuitWorkaroundExpression(b, parentPrecedence);
return;
}
- Precedence precedence = GetBinaryPrecedence(op);
+ Precedence precedence = GetBinaryPrecedence(b.fOperator);
if (precedence >= parentPrecedence) {
this->write("(");
}
bool positionWorkaround = fProgramKind == Program::Kind::kVertex_Kind &&
- Compiler::IsAssignment(op) &&
- left.kind() == Expression::Kind::kFieldAccess &&
- is_sk_position((FieldAccess&) left) &&
- !right.containsRTAdjust() &&
+ Compiler::IsAssignment(b.fOperator) &&
+ b.fLeft->kind() == Expression::Kind::kFieldAccess &&
+ is_sk_position((FieldAccess&) *b.fLeft) &&
+ !b.fRight->containsRTAdjust() &&
!fProgram.fSettings.fCaps->canUseFragCoord();
if (positionWorkaround) {
this->write("sk_FragCoord_Workaround = (");
}
- this->writeExpression(left, precedence);
+ this->writeExpression(*b.fLeft, precedence);
this->write(" ");
- this->write(Compiler::OperatorName(op));
+ this->write(Compiler::OperatorName(b.fOperator));
this->write(" ");
- this->writeExpression(right, precedence);
+ this->writeExpression(*b.fRight, precedence);
if (positionWorkaround) {
this->write(")");
}
@@ -957,20 +955,20 @@
// Transform:
// a && b => a ? b : false
// a || b => a ? true : b
- this->writeExpression(b.left(), kTernary_Precedence);
+ this->writeExpression(*b.fLeft, kTernary_Precedence);
this->write(" ? ");
- if (b.getOperator() == Token::Kind::TK_LOGICALAND) {
- this->writeExpression(b.right(), kTernary_Precedence);
+ if (b.fOperator == Token::Kind::TK_LOGICALAND) {
+ this->writeExpression(*b.fRight, kTernary_Precedence);
} else {
BoolLiteral boolTrue(fContext, -1, true);
this->writeBoolLiteral(boolTrue);
}
this->write(" : ");
- if (b.getOperator() == Token::Kind::TK_LOGICALAND) {
+ if (b.fOperator == Token::Kind::TK_LOGICALAND) {
BoolLiteral boolFalse(fContext, -1, false);
this->writeBoolLiteral(boolFalse);
} else {
- this->writeExpression(b.right(), kTernary_Precedence);
+ this->writeExpression(*b.fRight, kTernary_Precedence);
}
if (kTernary_Precedence >= parentPrecedence) {
this->write(")");
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 4761329..5ede14d 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -308,9 +308,9 @@
case Expression::Kind::kBinary: {
const BinaryExpression& b = expression.as<BinaryExpression>();
return std::make_unique<BinaryExpression>(offset,
- expr(b.leftPointer()),
- b.getOperator(),
- expr(b.rightPointer()),
+ expr(b.fLeft),
+ b.fOperator,
+ expr(b.fRight),
&b.type());
}
case Expression::Kind::kBoolLiteral:
@@ -938,7 +938,7 @@
case Expression::Kind::kBinary: {
BinaryExpression& binaryExpr = (*expr)->as<BinaryExpression>();
- this->visitExpression(&binaryExpr.leftPointer());
+ this->visitExpression(&binaryExpr.fLeft);
// Logical-and and logical-or binary expressions do not inline the right side,
// because that would invalidate short-circuiting. That is, when evaluating
@@ -948,11 +948,10 @@
// It is illegal for side-effects from x() or y() to occur. The simplest way to
// enforce that rule is to avoid inlining the right side entirely. However, it
// is safe for other types of binary expression to inline both sides.
- Token::Kind op = binaryExpr.getOperator();
- bool shortCircuitable = (op == Token::Kind::TK_LOGICALAND ||
- op == Token::Kind::TK_LOGICALOR);
+ bool shortCircuitable = (binaryExpr.fOperator == Token::Kind::TK_LOGICALAND ||
+ binaryExpr.fOperator == Token::Kind::TK_LOGICALOR);
if (!shortCircuitable) {
- this->visitExpression(&binaryExpr.rightPointer());
+ this->visitExpression(&binaryExpr.fRight);
}
break;
}
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 1ee05a4..d573c38 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -808,14 +808,11 @@
void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
Precedence parentPrecedence) {
- const Expression& left = b.left();
- const Expression& right = b.right();
- const Type& leftType = left.type();
- const Type& rightType = right.type();
- Token::Kind op = b.getOperator();
- Precedence precedence = GetBinaryPrecedence(b.getOperator());
+ const Type& leftType = b.fLeft->type();
+ const Type& rightType = b.fRight->type();
+ Precedence precedence = GetBinaryPrecedence(b.fOperator);
bool needParens = precedence >= parentPrecedence;
- switch (op) {
+ switch (b.fOperator) {
case Token::Kind::TK_EQEQ:
if (leftType.typeKind() == Type::TypeKind::kVector) {
this->write("all");
@@ -834,21 +831,22 @@
if (needParens) {
this->write("(");
}
- if (Compiler::IsAssignment(op) &&
- Expression::Kind::kVariableReference == left.kind() &&
- Variable::kParameter_Storage == left.as<VariableReference>().fVariable.fStorage &&
- left.as<VariableReference>().fVariable.fModifiers.fFlags & Modifiers::kOut_Flag) {
+ if (Compiler::IsAssignment(b.fOperator) &&
+ Expression::Kind::kVariableReference == b.fLeft->kind() &&
+ Variable::kParameter_Storage == ((VariableReference&) *b.fLeft).fVariable.fStorage &&
+ (((VariableReference&) *b.fLeft).fVariable.fModifiers.fFlags & Modifiers::kOut_Flag)) {
// writing to an out parameter. Since we have to turn those into pointers, we have to
// dereference it here.
this->write("*");
}
- if (op == Token::Kind::TK_STAREQ && leftType.typeKind() == Type::TypeKind::kMatrix &&
+ if (b.fOperator == Token::Kind::TK_STAREQ &&
+ leftType.typeKind() == Type::TypeKind::kMatrix &&
rightType.typeKind() == Type::TypeKind::kMatrix) {
this->writeMatrixTimesEqualHelper(leftType, rightType, b.type());
}
- this->writeExpression(left, precedence);
- if (op != Token::Kind::TK_EQ && Compiler::IsAssignment(op) &&
- left.kind() == Expression::Kind::kSwizzle && !left.hasSideEffects()) {
+ this->writeExpression(*b.fLeft, precedence);
+ if (b.fOperator != Token::Kind::TK_EQ && Compiler::IsAssignment(b.fOperator) &&
+ b.fLeft->kind() == Expression::Kind::kSwizzle && !b.fLeft->hasSideEffects()) {
// This doesn't compile in Metal:
// float4 x = float4(1);
// x.xy *= float2x2(...);
@@ -856,16 +854,16 @@
// but switching it to x.xy = x.xy * float2x2(...) fixes it. We perform this tranformation
// as long as the LHS has no side effects, and hope for the best otherwise.
this->write(" = ");
- this->writeExpression(left, kAssignment_Precedence);
+ this->writeExpression(*b.fLeft, kAssignment_Precedence);
this->write(" ");
- String opName = Compiler::OperatorName(op);
- SkASSERT(opName.endsWith("="));
- this->write(opName.substr(0, opName.size() - 1).c_str());
+ String op = Compiler::OperatorName(b.fOperator);
+ SkASSERT(op.endsWith("="));
+ this->write(op.substr(0, op.size() - 1).c_str());
this->write(" ");
} else {
- this->write(String(" ") + Compiler::OperatorName(op) + " ");
+ this->write(String(" ") + Compiler::OperatorName(b.fOperator) + " ");
}
- this->writeExpression(right, precedence);
+ this->writeExpression(*b.fRight, precedence);
if (needParens) {
this->write(")");
}
@@ -1732,8 +1730,8 @@
return this->requirements(e->as<Swizzle>().fBase.get());
case Expression::Kind::kBinary: {
const BinaryExpression& bin = e->as<BinaryExpression>();
- return this->requirements(&bin.left()) |
- this->requirements(&bin.right());
+ return this->requirements(bin.fLeft.get()) |
+ this->requirements(bin.fRight.get());
}
case Expression::Kind::kIndex: {
const IndexExpression& idx = e->as<IndexExpression>();
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 6e07dfb..ab3d709 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -2302,14 +2302,11 @@
}
SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, OutputStream& out) {
- const Expression& left = b.left();
- const Expression& right = b.right();
- Token::Kind op = b.getOperator();
// handle cases where we don't necessarily evaluate both LHS and RHS
- switch (op) {
+ switch (b.fOperator) {
case Token::Kind::TK_EQ: {
- SpvId rhs = this->writeExpression(right, out);
- this->getLValue(left, out)->store(rhs, out);
+ SpvId rhs = this->writeExpression(*b.fRight, out);
+ this->getLValue(*b.fLeft, out)->store(rhs, out);
return rhs;
}
case Token::Kind::TK_LOGICALAND:
@@ -2322,16 +2319,17 @@
std::unique_ptr<LValue> lvalue;
SpvId lhs;
- if (Compiler::IsAssignment(op)) {
- lvalue = this->getLValue(left, out);
+ if (Compiler::IsAssignment(b.fOperator)) {
+ lvalue = this->getLValue(*b.fLeft, out);
lhs = lvalue->load(out);
} else {
lvalue = nullptr;
- lhs = this->writeExpression(left, out);
+ lhs = this->writeExpression(*b.fLeft, out);
}
- SpvId rhs = this->writeExpression(right, out);
- SpvId result = this->writeBinaryExpression(left.type(), lhs, Compiler::RemoveAssignment(op),
- right.type(), rhs, b.type(), out);
+ SpvId rhs = this->writeExpression(*b.fRight, out);
+ SpvId result = this->writeBinaryExpression(b.fLeft->type(), lhs,
+ Compiler::RemoveAssignment(b.fOperator),
+ b.fRight->type(), rhs, b.type(), out);
if (lvalue) {
lvalue->store(result, out);
}
@@ -2339,17 +2337,17 @@
}
SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStream& out) {
- SkASSERT(a.getOperator() == Token::Kind::TK_LOGICALAND);
+ SkASSERT(a.fOperator == Token::Kind::TK_LOGICALAND);
BoolLiteral falseLiteral(fContext, -1, false);
SpvId falseConstant = this->writeBoolLiteral(falseLiteral);
- SpvId lhs = this->writeExpression(a.left(), out);
+ SpvId lhs = this->writeExpression(*a.fLeft, out);
SpvId rhsLabel = this->nextId();
SpvId end = this->nextId();
SpvId lhsBlock = fCurrentBlock;
this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone, out);
this->writeInstruction(SpvOpBranchConditional, lhs, rhsLabel, end, out);
this->writeLabel(rhsLabel, out);
- SpvId rhs = this->writeExpression(a.right(), out);
+ SpvId rhs = this->writeExpression(*a.fRight, out);
SpvId rhsBlock = fCurrentBlock;
this->writeInstruction(SpvOpBranch, end, out);
this->writeLabel(end, out);
@@ -2360,17 +2358,17 @@
}
SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, OutputStream& out) {
- SkASSERT(o.getOperator() == Token::Kind::TK_LOGICALOR);
+ SkASSERT(o.fOperator == Token::Kind::TK_LOGICALOR);
BoolLiteral trueLiteral(fContext, -1, true);
SpvId trueConstant = this->writeBoolLiteral(trueLiteral);
- SpvId lhs = this->writeExpression(o.left(), out);
+ SpvId lhs = this->writeExpression(*o.fLeft, out);
SpvId rhsLabel = this->nextId();
SpvId end = this->nextId();
SpvId lhsBlock = fCurrentBlock;
this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone, out);
this->writeInstruction(SpvOpBranchConditional, lhs, end, rhsLabel, out);
this->writeLabel(rhsLabel, out);
- SpvId rhs = this->writeExpression(o.right(), out);
+ SpvId rhs = this->writeExpression(*o.fRight, out);
SpvId rhsBlock = fCurrentBlock;
this->writeInstruction(SpvOpBranch, end, out);
this->writeLabel(end, out);
diff --git a/src/sksl/ir/SkSLBinaryExpression.h b/src/sksl/ir/SkSLBinaryExpression.h
index 47ccd7a..18ce2b7 100644
--- a/src/sksl/ir/SkSLBinaryExpression.h
+++ b/src/sksl/ir/SkSLBinaryExpression.h
@@ -19,24 +19,24 @@
namespace SkSL {
-static inline bool check_ref(const Expression& expr) {
- switch (expr.kind()) {
+static inline bool check_ref(Expression* expr) {
+ switch (expr->kind()) {
case Expression::Kind::kExternalValue:
return true;
case Expression::Kind::kFieldAccess:
- return check_ref(*expr.as<FieldAccess>().fBase);
+ return check_ref(((FieldAccess*) expr)->fBase.get());
case Expression::Kind::kIndex:
- return check_ref(*expr.as<IndexExpression>().fBase);
+ return check_ref(((IndexExpression*) expr)->fBase.get());
case Expression::Kind::kSwizzle:
- return check_ref(*expr.as<Swizzle>().fBase);
+ return check_ref(((Swizzle*) expr)->fBase.get());
case Expression::Kind::kTernary: {
- const TernaryExpression& t = expr.as<TernaryExpression>();
- return check_ref(*t.fIfTrue) && check_ref(*t.fIfFalse);
+ TernaryExpression* t = (TernaryExpression*) expr;
+ return check_ref(t->fIfTrue.get()) && check_ref(t->fIfFalse.get());
}
case Expression::Kind::kVariableReference: {
- const VariableReference& ref = expr.as<VariableReference>();
- return ref.fRefKind == VariableReference::kWrite_RefKind ||
- ref.fRefKind == VariableReference::kReadWrite_RefKind;
+ VariableReference* ref = (VariableReference*) expr;
+ return ref->fRefKind == VariableReference::kWrite_RefKind ||
+ ref->fRefKind == VariableReference::kReadWrite_RefKind;
}
default:
return false;
@@ -51,75 +51,46 @@
BinaryExpression(int offset, std::unique_ptr<Expression> left, Token::Kind op,
std::unique_ptr<Expression> right, const Type* type)
- : INHERITED(offset, kExpressionKind, { type, op }) {
- fExpressionChildren.reserve(2);
- fExpressionChildren.push_back(std::move(left));
- fExpressionChildren.push_back(std::move(right));
+ : INHERITED(offset, kExpressionKind, type)
+ , fLeft(std::move(left))
+ , fOperator(op)
+ , fRight(std::move(right)) {
// If we are assigning to a VariableReference, ensure that it is set to Write or ReadWrite
- SkASSERT(!Compiler::IsAssignment(op) || check_ref(this->left()));
- }
-
- Expression& left() const {
- return this->expressionChild(0);
- }
-
- std::unique_ptr<Expression>& leftPointer() {
- return this->expressionPointer(0);
- }
-
- const std::unique_ptr<Expression>& leftPointer() const {
- return this->expressionPointer(0);
- }
-
- Expression& right() const {
- return this->expressionChild(1);
- }
-
- std::unique_ptr<Expression>& rightPointer() {
- return this->expressionPointer(1);
- }
-
- const std::unique_ptr<Expression>& rightPointer() const {
- return this->expressionPointer(1);
- }
-
- Token::Kind getOperator() const {
- return this->typeTokenData().fToken;
+ SkASSERT(!Compiler::IsAssignment(op) || check_ref(fLeft.get()));
}
bool isConstantOrUniform() const override {
- return this->left().isConstantOrUniform() && this->right().isConstantOrUniform();
+ return fLeft->isConstantOrUniform() && fRight->isConstantOrUniform();
}
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override {
- return irGenerator.constantFold(this->left(),
- this->getOperator(),
- this->right());
+ return irGenerator.constantFold(*fLeft,
+ fOperator,
+ *fRight);
}
bool hasProperty(Property property) const override {
- if (property == Property::kSideEffects && Compiler::IsAssignment(this->getOperator())) {
+ if (property == Property::kSideEffects && Compiler::IsAssignment(fOperator)) {
return true;
}
- return this->left().hasProperty(property) || this->right().hasProperty(property);
+ return fLeft->hasProperty(property) || fRight->hasProperty(property);
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new BinaryExpression(fOffset,
- this->left().clone(),
- this->getOperator(),
- this->right().clone(),
- &this->type()));
+ return std::unique_ptr<Expression>(new BinaryExpression(fOffset, fLeft->clone(), fOperator,
+ fRight->clone(), &this->type()));
}
String description() const override {
- return "(" + this->left().description() + " " +
- Compiler::OperatorName(this->getOperator()) + " " + this->right().description() +
- ")";
+ return "(" + fLeft->description() + " " + Compiler::OperatorName(fOperator) + " " +
+ fRight->description() + ")";
}
-private:
+ std::unique_ptr<Expression> fLeft;
+ const Token::Kind fOperator;
+ std::unique_ptr<Expression> fRight;
+
using INHERITED = Expression;
};
diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h
index 14c9708..7beb341 100644
--- a/src/sksl/ir/SkSLExpression.h
+++ b/src/sksl/ir/SkSLExpression.h
@@ -57,12 +57,7 @@
};
Expression(int offset, Kind kind, const Type* type)
- : INHERITED(offset, (int) kind, type) {
- SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
- }
-
- Expression(int offset, Kind kind, TypeTokenData data)
- : INHERITED(offset, (int) kind, data) {
+ : INHERITED(offset, (int) kind, type) {
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
diff --git a/src/sksl/ir/SkSLIRNode.cpp b/src/sksl/ir/SkSLIRNode.cpp
deleted file mode 100644
index 19eaf8b..0000000
--- a/src/sksl/ir/SkSLIRNode.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2020 Google LLC.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/sksl/ir/SkSLIRNode.h"
-
-#include "src/sksl/ir/SkSLExpression.h"
-
-namespace SkSL {
-
-IRNode::IRNode(int offset, int kind, const Type* data)
-: fOffset(offset)
-, fKind(kind)
-, fData(data) {}
-
-IRNode::IRNode(int offset, int kind, TypeTokenData data)
-: fOffset(offset)
-, fKind(kind)
-, fData(data) {}
-
-IRNode::IRNode(const IRNode& other)
- : fOffset(other.fOffset)
- , fKind(other.fKind)
- , fData(other.fData) {
- // For now, we can't use a default copy constructor because of the std::unique_ptr children.
- // Since we never copy nodes containing children, it's easiest just to assert we don't have any
- // than bother with cloning them.
- SkASSERT(other.fExpressionChildren.empty());
-}
-
-IRNode::~IRNode() {}
-
-} // namespace SkSL
diff --git a/src/sksl/ir/SkSLIRNode.h b/src/sksl/ir/SkSLIRNode.h
index b43ee06..4a6aa90 100644
--- a/src/sksl/ir/SkSLIRNode.h
+++ b/src/sksl/ir/SkSLIRNode.h
@@ -8,16 +8,11 @@
#ifndef SKSL_IRNODE
#define SKSL_IRNODE
-#include "src/sksl/SkSLASTNode.h"
#include "src/sksl/SkSLLexer.h"
#include "src/sksl/SkSLString.h"
-#include <algorithm>
-#include <vector>
-
namespace SkSL {
-struct Expression;
class Type;
/**
@@ -26,19 +21,12 @@
*/
class IRNode {
public:
- virtual ~IRNode();
+ IRNode(int offset, int kind, const Type* type = nullptr)
+ : fOffset(offset)
+ , fKind(kind)
+ , fType(type) {}
- IRNode& operator=(const IRNode& other) {
- // Need to have a copy assignment operator because Type requires it, but can't use the
- // default version until we finish migrating away from std::unique_ptr children. For now,
- // just assert that there are no children (we could theoretically clone them, but we never
- // actually copy nodes containing children).
- SkASSERT(other.fExpressionChildren.empty());
- fKind = other.fKind;
- fOffset = other.fOffset;
- fData = other.fData;
- return *this;
- }
+ virtual ~IRNode() {}
virtual String description() const = 0;
@@ -47,81 +35,15 @@
int fOffset;
const Type& type() const {
- switch (fData.fKind) {
- case NodeData::Kind::kType:
- return *this->typeData();
- case NodeData::Kind::kTypeToken:
- return *this->typeTokenData().fType;
- default:
- SkUNREACHABLE;
- }
+ SkASSERT(fType);
+ return *fType;
}
protected:
- struct TypeTokenData {
- const Type* fType;
- Token::Kind fToken;
- };
-
- struct NodeData {
- char fBytes[std::max(sizeof(Type*),
- sizeof(TypeTokenData))];
-
- enum class Kind {
- kType,
- kTypeToken,
- } fKind;
-
- NodeData() = default;
-
- NodeData(const Type* data)
- : fKind(Kind::kType) {
- memcpy(fBytes, &data, sizeof(data));
- }
-
- NodeData(TypeTokenData data)
- : fKind(Kind::kTypeToken) {
- memcpy(fBytes, &data, sizeof(data));
- }
- };
-
- IRNode(int offset, int kind, const Type* data = nullptr);
-
- IRNode(int offset, int kind, TypeTokenData data);
-
- IRNode(const IRNode& other);
-
- Expression& expressionChild(int index) const {
- return *fExpressionChildren[index];
- }
-
- std::unique_ptr<Expression>& expressionPointer(int index) {
- return fExpressionChildren[index];
- }
-
- const std::unique_ptr<Expression>& expressionPointer(int index) const {
- return fExpressionChildren[index];
- }
-
- Type* typeData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kType);
- Type* result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
-
- TypeTokenData typeTokenData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kTypeToken);
- TypeTokenData result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
-
int fKind;
- std::vector<std::unique_ptr<Expression>> fExpressionChildren;
private:
- NodeData fData;
+ const Type* fType;
};
} // namespace SkSL