Revamped handling of SkSL node kinds

Moved the actual field into the base class, changed all of the enums
into non-overlapping enum classes, and finally renamed Type::Kind to
fix the ambiguity there.

Change-Id: I4e6c24d2dbbc7b1d12b7b7bf12e77c651eea7ed9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315318
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
Ethan Nicholas 2020-09-08 10:22:09 -04:00 committed by Skia Commit-Bot
parent a9b45b6a7c
commit e659214bc6
75 changed files with 1256 additions and 1183 deletions

View File

@ -155,7 +155,7 @@ SkRuntimeEffect::EffectResult SkRuntimeEffect::Make(SkString sksl) {
// Go through program elements, pulling out information that we need
for (const auto& elem : *program) {
// Variables (uniform, varying, etc.)
if (elem.fKind == SkSL::ProgramElement::kVar_Kind) {
if (elem.kind() == SkSL::ProgramElement::Kind::kVar) {
const auto& varDecls = static_cast<const SkSL::VarDeclarations&>(elem);
for (const auto& varDecl : varDecls.fVars) {
const SkSL::Variable& var =
@ -163,9 +163,10 @@ SkRuntimeEffect::EffectResult SkRuntimeEffect::Make(SkString sksl) {
// Varyings (only used in conjunction with drawVertices)
if (var.fModifiers.fFlags & SkSL::Modifiers::kVarying_Flag) {
varyings.push_back({var.fName, var.fType.kind() == SkSL::Type::kVector_Kind
? var.fType.columns()
: 1});
varyings.push_back({var.fName,
var.fType.typeKind() == SkSL::Type::TypeKind::kVector
? var.fType.columns()
: 1});
}
// Fragment Processors (aka 'shader'): These are child effects
else if (&var.fType == ctx.fFragmentProcessor_Type.get()) {
@ -180,7 +181,7 @@ SkRuntimeEffect::EffectResult SkRuntimeEffect::Make(SkString sksl) {
uni.fCount = 1;
const SkSL::Type* type = &var.fType;
if (type->kind() == SkSL::Type::kArray_Kind) {
if (type->typeKind() == SkSL::Type::TypeKind::kArray) {
uni.fFlags |= Uniform::kArray_Flag;
uni.fCount = type->columns();
type = &type->componentType();
@ -213,7 +214,7 @@ SkRuntimeEffect::EffectResult SkRuntimeEffect::Make(SkString sksl) {
}
}
// Functions
else if (elem.fKind == SkSL::ProgramElement::kFunction_Kind) {
else if (elem.kind() == SkSL::ProgramElement::Kind::kFunction) {
const auto& func = static_cast<const SkSL::FunctionDefinition&>(elem);
const SkSL::FunctionDeclaration& decl = func.fDeclaration;
if (decl.fName == "main") {

View File

@ -65,7 +65,7 @@ namespace {
static bool is_sample_call_to_fp(const FunctionCall& fc, const Variable& fp) {
const FunctionDeclaration& f = fc.fFunction;
return f.fBuiltin && f.fName == "sample" && fc.fArguments.size() >= 1 &&
fc.fArguments[0]->fKind == Expression::kVariableReference_Kind &&
fc.fArguments[0]->kind() == Expression::Kind::kVariableReference &&
&((VariableReference&) *fc.fArguments[0]).fVariable == &fp;
}
@ -88,7 +88,7 @@ protected:
bool visitExpression(const Expression& e) override {
// Looking for sample(fp, inColor?, ...)
if (e.fKind == Expression::kFunctionCall_Kind) {
if (e.kind() == Expression::Kind::kFunctionCall) {
const FunctionCall& fc = e.as<FunctionCall>();
if (is_sample_call_to_fp(fc, fFP)) {
// Determine the type of call at this site, and merge it with the accumulated state
@ -99,8 +99,8 @@ protected:
} else if (lastArg->fType == *fContext.fFloat3x3_Type) {
// Determine the type of matrix for this call site
if (lastArg->isConstantOrUniform()) {
if (lastArg->fKind == Expression::Kind::kVariableReference_Kind ||
lastArg->fKind == Expression::Kind::kConstructor_Kind) {
if (lastArg->kind() == Expression::Kind::kVariableReference ||
lastArg->kind() == Expression::Kind::kConstructor) {
// FIXME if this is a constant, we should parse the float3x3 constructor
// and determine if the resulting matrix introduces perspective.
fUsage.merge(SampleUsage::UniformMatrix(lastArg->description()));
@ -136,7 +136,7 @@ public:
BuiltinVariableVisitor(int builtin) : fBuiltin(builtin) {}
bool visitExpression(const Expression& e) override {
if (e.fKind == Expression::kVariableReference_Kind) {
if (e.kind() == Expression::Kind::kVariableReference) {
const VariableReference& var = e.as<VariableReference>();
return var.fVariable.fModifiers.fLayout.fBuiltin == fBuiltin;
}
@ -188,7 +188,7 @@ public:
}
bool visitExpression(const Expression& e) override {
if (e.fKind == Expression::kVariableReference_Kind) {
if (e.kind() == Expression::Kind::kVariableReference) {
const VariableReference& ref = e.as<VariableReference>();
if (&ref.fVariable == fVar && (ref.fRefKind == VariableReference::kWrite_RefKind ||
ref.fRefKind == VariableReference::kReadWrite_RefKind ||
@ -249,51 +249,51 @@ bool ProgramVisitor::visit(const Program& program) {
}
bool ProgramVisitor::visitExpression(const Expression& e) {
switch(e.fKind) {
case Expression::kBoolLiteral_Kind:
case Expression::kDefined_Kind:
case Expression::kExternalValue_Kind:
case Expression::kFieldAccess_Kind:
case Expression::kFloatLiteral_Kind:
case Expression::kFunctionReference_Kind:
case Expression::kIntLiteral_Kind:
case Expression::kNullLiteral_Kind:
case Expression::kSetting_Kind:
case Expression::kTypeReference_Kind:
case Expression::kVariableReference_Kind:
switch(e.kind()) {
case Expression::Kind::kBoolLiteral:
case Expression::Kind::kDefined:
case Expression::Kind::kExternalValue:
case Expression::Kind::kFieldAccess:
case Expression::Kind::kFloatLiteral:
case Expression::Kind::kFunctionReference:
case Expression::Kind::kIntLiteral:
case Expression::Kind::kNullLiteral:
case Expression::Kind::kSetting:
case Expression::Kind::kTypeReference:
case Expression::Kind::kVariableReference:
// Leaf expressions return false
return false;
case Expression::kBinary_Kind: {
case Expression::Kind::kBinary: {
const BinaryExpression& b = e.as<BinaryExpression>();
return this->visitExpression(*b.fLeft) || this->visitExpression(*b.fRight); }
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
const Constructor& c = e.as<Constructor>();
for (const auto& arg : c.fArguments) {
if (this->visitExpression(*arg)) { return true; }
}
return false; }
case Expression::kExternalFunctionCall_Kind: {
case Expression::Kind::kExternalFunctionCall: {
const ExternalFunctionCall& c = e.as<ExternalFunctionCall>();
for (const auto& arg : c.fArguments) {
if (this->visitExpression(*arg)) { return true; }
}
return false; }
case Expression::kFunctionCall_Kind: {
case Expression::Kind::kFunctionCall: {
const FunctionCall& c = e.as<FunctionCall>();
for (const auto& arg : c.fArguments) {
if (this->visitExpression(*arg)) { return true; }
}
return false; }
case Expression::kIndex_Kind:{
case Expression::Kind::kIndex: {
const IndexExpression& i = e.as<IndexExpression>();
return this->visitExpression(*i.fBase) || this->visitExpression(*i.fIndex); }
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
return this->visitExpression(*e.as<PostfixExpression>().fOperand);
case Expression::kPrefix_Kind:
case Expression::Kind::kPrefix:
return this->visitExpression(*e.as<PrefixExpression>().fOperand);
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
return this->visitExpression(*e.as<Swizzle>().fBase);
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
const TernaryExpression& t = e.as<TernaryExpression>();
return this->visitExpression(*t.fTest) ||
this->visitExpression(*t.fIfTrue) ||
@ -304,38 +304,38 @@ bool ProgramVisitor::visitExpression(const Expression& e) {
}
bool ProgramVisitor::visitStatement(const Statement& s) {
switch(s.fKind) {
case Statement::kBreak_Kind:
case Statement::kContinue_Kind:
case Statement::kDiscard_Kind:
case Statement::kNop_Kind:
switch(s.kind()) {
case Statement::Kind::kBreak:
case Statement::Kind::kContinue:
case Statement::Kind::kDiscard:
case Statement::Kind::kNop:
// Leaf statements just return false
return false;
case Statement::kBlock_Kind:
case Statement::Kind::kBlock:
for (const std::unique_ptr<Statement>& blockStmt : s.as<Block>().fStatements) {
if (this->visitStatement(*blockStmt)) { return true; }
}
return false;
case Statement::kDo_Kind: {
case Statement::Kind::kDo: {
const DoStatement& d = s.as<DoStatement>();
return this->visitExpression(*d.fTest) || this->visitStatement(*d.fStatement); }
case Statement::kExpression_Kind:
case Statement::Kind::kExpression:
return this->visitExpression(*s.as<ExpressionStatement>().fExpression);
case Statement::kFor_Kind: {
case Statement::Kind::kFor: {
const ForStatement& f = s.as<ForStatement>();
return (f.fInitializer && this->visitStatement(*f.fInitializer)) ||
(f.fTest && this->visitExpression(*f.fTest)) ||
(f.fNext && this->visitExpression(*f.fNext)) ||
this->visitStatement(*f.fStatement); }
case Statement::kIf_Kind: {
case Statement::Kind::kIf: {
const IfStatement& i = s.as<IfStatement>();
return this->visitExpression(*i.fTest) ||
this->visitStatement(*i.fIfTrue) ||
(i.fIfFalse && this->visitStatement(*i.fIfFalse)); }
case Statement::kReturn_Kind: {
case Statement::Kind::kReturn: {
const ReturnStatement& r = s.as<ReturnStatement>();
return r.fExpression && this->visitExpression(*r.fExpression); }
case Statement::kSwitch_Kind: {
case Statement::Kind::kSwitch: {
const SwitchStatement& sw = s.as<SwitchStatement>();
if (this->visitExpression(*sw.fValue)) { return true; }
for (const auto& c : sw.fCases) {
@ -345,15 +345,15 @@ bool ProgramVisitor::visitStatement(const Statement& s) {
}
}
return false; }
case Statement::kVarDeclaration_Kind: {
case Statement::Kind::kVarDeclaration: {
const VarDeclaration& v = s.as<VarDeclaration>();
for (const std::unique_ptr<Expression>& sizeExpr : v.fSizes) {
if (sizeExpr && this->visitExpression(*sizeExpr)) { return true; }
}
return v.fValue && this->visitExpression(*v.fValue); }
case Statement::kVarDeclarations_Kind:
case Statement::Kind::kVarDeclarations:
return this->visitProgramElement(*s.as<VarDeclarationsStatement>().fDeclaration);
case Statement::kWhile_Kind: {
case Statement::Kind::kWhile: {
const WhileStatement& w = s.as<WhileStatement>();
return this->visitExpression(*w.fTest) || this->visitStatement(*w.fStatement); }
default:
@ -362,21 +362,21 @@ bool ProgramVisitor::visitStatement(const Statement& s) {
}
bool ProgramVisitor::visitProgramElement(const ProgramElement& pe) {
switch(pe.fKind) {
case ProgramElement::kEnum_Kind:
case ProgramElement::kExtension_Kind:
case ProgramElement::kModifiers_Kind:
case ProgramElement::kSection_Kind:
switch(pe.kind()) {
case ProgramElement::Kind::kEnum:
case ProgramElement::Kind::kExtension:
case ProgramElement::Kind::kModifiers:
case ProgramElement::Kind::kSection:
// Leaf program elements just return false by default
return false;
case ProgramElement::kFunction_Kind:
case ProgramElement::Kind::kFunction:
return this->visitStatement(*pe.as<FunctionDefinition>().fBody);
case ProgramElement::kInterfaceBlock_Kind:
case ProgramElement::Kind::kInterfaceBlock:
for (const auto& e : pe.as<InterfaceBlock>().fSizes) {
if (this->visitExpression(*e)) { return true; }
}
return false;
case ProgramElement::kVar_Kind:
case ProgramElement::Kind::kVar:
for (const auto& v : pe.as<VarDeclarations>().fVars) {
if (this->visitStatement(*v)) { return true; }
}

View File

@ -12,9 +12,9 @@
namespace SkSL {
static TypeCategory type_category(const Type& type) {
switch (type.kind()) {
case Type::Kind::kVector_Kind:
case Type::Kind::kMatrix_Kind:
switch (type.typeKind()) {
case Type::TypeKind::kVector:
case Type::TypeKind::kMatrix:
return type_category(type.componentType());
default:
if (type.fName == "bool") {
@ -92,23 +92,26 @@ ByteCodeGenerator::ByteCodeGenerator(const Context* context, const Program* prog
int ByteCodeGenerator::SlotCount(const Type& type) {
if (type.kind() == Type::kOther_Kind) {
return 0;
} else if (type.kind() == Type::kStruct_Kind) {
int slots = 0;
for (const auto& f : type.fields()) {
slots += SlotCount(*f.fType);
switch (type.typeKind()) {
case Type::TypeKind::kOther:
return 0;
case Type::TypeKind::kStruct: {
int slots = 0;
for (const auto& f : type.fields()) {
slots += SlotCount(*f.fType);
}
SkASSERT(slots <= 255);
return slots;
}
SkASSERT(slots <= 255);
return slots;
} else if (type.kind() == Type::kArray_Kind) {
int columns = type.columns();
SkASSERT(columns >= 0);
int slots = columns * SlotCount(type.componentType());
SkASSERT(slots <= 255);
return slots;
} else {
return type.columns() * type.rows();
case Type::TypeKind::kArray: {
int columns = type.columns();
SkASSERT(columns >= 0);
int slots = columns * SlotCount(type.componentType());
SkASSERT(slots <= 255);
return slots;
}
default:
return type.columns() * type.rows();
}
}
@ -121,27 +124,31 @@ static inline bool is_in(const SkSL::Variable& var) {
}
void ByteCodeGenerator::gatherUniforms(const Type& type, const String& name) {
if (type.kind() == Type::kOther_Kind) {
return;
} else if (type.kind() == Type::kStruct_Kind) {
for (const auto& f : type.fields()) {
this->gatherUniforms(*f.fType, name + "." + f.fName);
}
} else if (type.kind() == Type::kArray_Kind) {
for (int i = 0; i < type.columns(); ++i) {
this->gatherUniforms(type.componentType(), String::printf("%s[%d]", name.c_str(), i));
}
} else {
fOutput->fUniforms.push_back({ name, type_category(type), type.rows(), type.columns(),
fOutput->fUniformSlotCount });
fOutput->fUniformSlotCount += type.columns() * type.rows();
switch (type.typeKind()) {
case Type::TypeKind::kOther:
break;
case Type::TypeKind::kStruct:
for (const auto& f : type.fields()) {
this->gatherUniforms(*f.fType, name + "." + f.fName);
}
break;
case Type::TypeKind::kArray:
for (int i = 0; i < type.columns(); ++i) {
this->gatherUniforms(type.componentType(), String::printf("%s[%d]", name.c_str(),
i));
}
break;
default:
fOutput->fUniforms.push_back({ name, type_category(type), type.rows(), type.columns(),
fOutput->fUniformSlotCount });
fOutput->fUniformSlotCount += type.columns() * type.rows();
}
}
bool ByteCodeGenerator::generateCode() {
for (const auto& e : fProgram) {
switch (e.fKind) {
case ProgramElement::kFunction_Kind: {
switch (e.kind()) {
case ProgramElement::Kind::kFunction: {
std::unique_ptr<ByteCodeFunction> f =
this->writeFunction(e.as<FunctionDefinition>());
if (!f) {
@ -151,7 +158,7 @@ bool ByteCodeGenerator::generateCode() {
fFunctions.push_back(&e.as<FunctionDefinition>());
break;
}
case ProgramElement::kVar_Kind: {
case ProgramElement::Kind::kVar: {
const VarDeclarations& decl = e.as<VarDeclarations>();
for (const auto& v : decl.fVars) {
const Variable* declVar = v->as<VarDeclaration>().fVar;
@ -210,7 +217,7 @@ std::unique_ptr<ByteCodeFunction> ByteCodeGenerator::writeFunction(const Functio
// If the expression is a reference to a builtin global variable, return the builtin ID.
// Otherwise, return -1.
static int expression_as_builtin(const Expression& e) {
if (e.fKind == Expression::kVariableReference_Kind) {
if (e.kind() == Expression::Kind::kVariableReference) {
const Variable& var(e.as<VariableReference>().fVariable);
if (var.fStorage == Variable::kGlobal_Storage) {
return var.fModifiers.fLayout.fBuiltin;
@ -228,10 +235,10 @@ static bool swizzle_is_simple(const Swizzle& s) {
return false;
}
switch (s.fBase->fKind) {
case Expression::kFieldAccess_Kind:
case Expression::kIndex_Kind:
case Expression::kVariableReference_Kind:
switch (s.fBase->kind()) {
case Expression::Kind::kFieldAccess:
case Expression::Kind::kIndex:
case Expression::Kind::kVariableReference:
break;
default:
return false;
@ -449,7 +456,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
if (var.fType == *fContext.fFragmentProcessor_Type) {
int offset = 0;
for (const auto& e : fProgram) {
if (e.fKind == ProgramElement::kVar_Kind) {
if (e.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decl = e.as<VarDeclarations>();
for (const auto& v : decl.fVars) {
const Variable* declVar = v->as<VarDeclaration>().fVar;
@ -479,7 +486,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
int offset = 0;
bool isUniform = is_uniform(var);
for (const auto& e : fProgram) {
if (e.fKind == ProgramElement::kVar_Kind) {
if (e.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decl = e.as<VarDeclarations>();
for (const auto& v : decl.fVars) {
const Variable* declVar = v->as<VarDeclaration>().fVar;
@ -507,8 +514,8 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
}
ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& expr) {
switch (expr.fKind) {
case Expression::kFieldAccess_Kind: {
switch (expr.kind()) {
case Expression::Kind::kFieldAccess: {
const FieldAccess& f = expr.as<FieldAccess>();
Location baseLoc = this->getLocation(*f.fBase);
int offset = 0;
@ -526,7 +533,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& exp
return baseLoc + offset;
}
}
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
const IndexExpression& i = expr.as<IndexExpression>();
int stride = SlotCount(i.fType);
int length = i.fBase->fType.columns();
@ -582,7 +589,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& exp
this->write(ByteCodeInstruction::kAddI, 1);
return baseLoc.makeOnStack();
}
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
const Swizzle& s = expr.as<Swizzle>();
SkASSERT(swizzle_is_simple(s));
Location baseLoc = this->getLocation(*s.fBase);
@ -598,7 +605,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& exp
return baseLoc + offset;
}
}
case Expression::kVariableReference_Kind: {
case Expression::Kind::kVariableReference: {
const Variable& var = expr.as<VariableReference>().fVariable;
return this->getLocation(var);
}
@ -683,8 +690,10 @@ bool ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b, bool di
}
const Type& lType = b.fLeft->fType;
const Type& rType = b.fRight->fType;
bool lVecOrMtx = (lType.kind() == Type::kVector_Kind || lType.kind() == Type::kMatrix_Kind);
bool rVecOrMtx = (rType.kind() == Type::kVector_Kind || rType.kind() == Type::kMatrix_Kind);
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 (is_assignment(b.fOperator)) {
@ -764,7 +773,8 @@ bool ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b, bool di
}
// Special case for M*V, V*M, M*M (but not V*V!)
if (op == Token::Kind::TK_STAR && lVecOrMtx && rVecOrMtx &&
!(lType.kind() == Type::kVector_Kind && rType.kind() == Type::kVector_Kind)) {
!(lType.typeKind() == Type::TypeKind::kVector &&
rType.typeKind() == Type::TypeKind::kVector)) {
this->write(ByteCodeInstruction::kMatrixMultiply,
SlotCount(b.fType) - (SlotCount(lType) + SlotCount(rType)));
int rCols = rType.columns(),
@ -772,7 +782,7 @@ bool ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b, bool di
lCols = lType.columns(),
lRows = lType.rows();
// M*V treats the vector as a column
if (rType.kind() == Type::kVector_Kind) {
if (rType.typeKind() == Type::TypeKind::kVector) {
std::swap(rCols, rRows);
}
SkASSERT(lCols == rRows);
@ -921,7 +931,8 @@ void ByteCodeGenerator::writeConstructor(const Constructor& c) {
SkASSERT(false);
}
}
if (inType.kind() == Type::kMatrix_Kind && outType.kind() == Type::kMatrix_Kind) {
if (inType.typeKind() == Type::TypeKind::kMatrix &&
outType.typeKind() == Type::TypeKind::kMatrix) {
this->write(ByteCodeInstruction::kMatrixToMatrix,
SlotCount(outType) - SlotCount(inType));
this->write8(inType.columns());
@ -930,12 +941,12 @@ void ByteCodeGenerator::writeConstructor(const Constructor& c) {
this->write8(outType.rows());
} else if (inCount != outCount) {
SkASSERT(inCount == 1);
if (outType.kind() == Type::kMatrix_Kind) {
if (outType.typeKind() == Type::TypeKind::kMatrix) {
this->write(ByteCodeInstruction::kScalarToMatrix, SlotCount(outType) - 1);
this->write8(outType.columns());
this->write8(outType.rows());
} else {
SkASSERT(outType.kind() == Type::kVector_Kind);
SkASSERT(outType.typeKind() == Type::TypeKind::kVector);
for (; inCount != outCount; ++inCount) {
this->write(ByteCodeInstruction::kDup, 1);
}
@ -1430,49 +1441,49 @@ void ByteCodeGenerator::writeTernaryExpression(const TernaryExpression& t) {
}
void ByteCodeGenerator::writeExpression(const Expression& e, bool discard) {
switch (e.fKind) {
case Expression::kBinary_Kind:
switch (e.kind()) {
case Expression::Kind::kBinary:
discard = this->writeBinaryExpression(e.as<BinaryExpression>(), discard);
break;
case Expression::kBoolLiteral_Kind:
case Expression::Kind::kBoolLiteral:
this->writeBoolLiteral(e.as<BoolLiteral>());
break;
case Expression::kConstructor_Kind:
case Expression::Kind::kConstructor:
this->writeConstructor(e.as<Constructor>());
break;
case Expression::kExternalFunctionCall_Kind:
case Expression::Kind::kExternalFunctionCall:
this->writeExternalFunctionCall(e.as<ExternalFunctionCall>());
break;
case Expression::kExternalValue_Kind:
case Expression::Kind::kExternalValue:
this->writeExternalValue(e.as<ExternalValueReference>());
break;
case Expression::kFieldAccess_Kind:
case Expression::kIndex_Kind:
case Expression::kVariableReference_Kind:
case Expression::Kind::kFieldAccess:
case Expression::Kind::kIndex:
case Expression::Kind::kVariableReference:
this->writeVariableExpression(e);
break;
case Expression::kFloatLiteral_Kind:
case Expression::Kind::kFloatLiteral:
this->writeFloatLiteral(e.as<FloatLiteral>());
break;
case Expression::kFunctionCall_Kind:
case Expression::Kind::kFunctionCall:
this->writeFunctionCall(e.as<FunctionCall>());
break;
case Expression::kIntLiteral_Kind:
case Expression::Kind::kIntLiteral:
this->writeIntLiteral(e.as<IntLiteral>());
break;
case Expression::kNullLiteral_Kind:
case Expression::Kind::kNullLiteral:
this->writeNullLiteral(e.as<NullLiteral>());
break;
case Expression::kPrefix_Kind:
case Expression::Kind::kPrefix:
discard = this->writePrefixExpression(e.as<PrefixExpression>(), discard);
break;
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
discard = this->writePostfixExpression(e.as<PostfixExpression>(), discard);
break;
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
this->writeSwizzle(e.as<Swizzle>());
break;
case Expression::kTernary_Kind:
case Expression::Kind::kTernary:
this->writeTernaryExpression(e.as<TernaryExpression>());
break;
default:
@ -1601,25 +1612,25 @@ private:
};
std::unique_ptr<ByteCodeGenerator::LValue> ByteCodeGenerator::getLValue(const Expression& e) {
switch (e.fKind) {
case Expression::kExternalValue_Kind: {
switch (e.kind()) {
case Expression::Kind::kExternalValue: {
const ExternalValue* value = e.as<ExternalValueReference>().fValue;
int index = fOutput->fExternalValues.size();
fOutput->fExternalValues.push_back(value);
SkASSERT(index <= 255);
return std::unique_ptr<LValue>(new ByteCodeExternalValueLValue(this, *value, index));
}
case Expression::kFieldAccess_Kind:
case Expression::kIndex_Kind:
case Expression::kVariableReference_Kind:
case Expression::Kind::kFieldAccess:
case Expression::Kind::kIndex:
case Expression::Kind::kVariableReference:
return std::unique_ptr<LValue>(new ByteCodeExpressionLValue(this, e));
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
const Swizzle& s = e.as<Swizzle>();
return swizzle_is_simple(s)
? std::unique_ptr<LValue>(new ByteCodeExpressionLValue(this, e))
: std::unique_ptr<LValue>(new ByteCodeSwizzleLValue(this, s));
}
case Expression::kTernary_Kind:
case Expression::Kind::kTernary:
default:
#ifdef SK_DEBUG
ABORT("unsupported lvalue %s\n", e.description().c_str());
@ -1769,43 +1780,43 @@ void ByteCodeGenerator::writeWhileStatement(const WhileStatement& w) {
}
void ByteCodeGenerator::writeStatement(const Statement& s) {
switch (s.fKind) {
case Statement::kBlock_Kind:
switch (s.kind()) {
case Statement::Kind::kBlock:
this->writeBlock(s.as<Block>());
break;
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
this->writeBreakStatement(s.as<BreakStatement>());
break;
case Statement::kContinue_Kind:
case Statement::Kind::kContinue:
this->writeContinueStatement(s.as<ContinueStatement>());
break;
case Statement::kDiscard_Kind:
case Statement::Kind::kDiscard:
// not yet implemented
abort();
case Statement::kDo_Kind:
case Statement::Kind::kDo:
this->writeDoStatement(s.as<DoStatement>());
break;
case Statement::kExpression_Kind:
case Statement::Kind::kExpression:
this->writeExpression(*s.as<ExpressionStatement>().fExpression, true);
break;
case Statement::kFor_Kind:
case Statement::Kind::kFor:
this->writeForStatement(s.as<ForStatement>());
break;
case Statement::kIf_Kind:
case Statement::Kind::kIf:
this->writeIfStatement(s.as<IfStatement>());
break;
case Statement::kNop_Kind:
case Statement::Kind::kNop:
break;
case Statement::kReturn_Kind:
case Statement::Kind::kReturn:
this->writeReturnStatement(s.as<ReturnStatement>());
break;
case Statement::kSwitch_Kind:
case Statement::Kind::kSwitch:
this->writeSwitchStatement(s.as<SwitchStatement>());
break;
case Statement::kVarDeclarations_Kind:
case Statement::Kind::kVarDeclarations:
this->writeVarDeclarations(*s.as<VarDeclarationsStatement>().fDeclaration);
break;
case Statement::kWhile_Kind:
case Statement::Kind::kWhile:
this->writeWhileStatement(s.as<WhileStatement>());
break;
default:

View File

@ -87,7 +87,7 @@ void CFG::dump() {
bool BasicBlock::tryRemoveExpressionBefore(std::vector<BasicBlock::Node>::iterator* iter,
Expression* e) {
if (e->fKind == Expression::kTernary_Kind) {
if (e->kind() == Expression::Kind::kTernary) {
return false;
}
bool result;
@ -128,22 +128,22 @@ bool BasicBlock::tryRemoveExpressionBefore(std::vector<BasicBlock::Node>::iterat
bool BasicBlock::tryRemoveLValueBefore(std::vector<BasicBlock::Node>::iterator* iter,
Expression* lvalue) {
switch (lvalue->fKind) {
case Expression::kExternalValue_Kind: // fall through
case Expression::kVariableReference_Kind:
switch (lvalue->kind()) {
case Expression::Kind::kExternalValue: // fall through
case Expression::Kind::kVariableReference:
return true;
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
return this->tryRemoveLValueBefore(iter, lvalue->as<Swizzle>().fBase.get());
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
return this->tryRemoveLValueBefore(iter, lvalue->as<FieldAccess>().fBase.get());
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
IndexExpression& indexExpr = lvalue->as<IndexExpression>();
if (!this->tryRemoveLValueBefore(iter, indexExpr.fBase.get())) {
return false;
}
return this->tryRemoveExpressionBefore(iter, indexExpr.fIndex.get());
}
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
TernaryExpression& ternary = lvalue->as<TernaryExpression>();
if (!this->tryRemoveExpressionBefore(iter, ternary.fTest.get())) {
return false;
@ -163,8 +163,8 @@ bool BasicBlock::tryRemoveLValueBefore(std::vector<BasicBlock::Node>::iterator*
bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* iter) {
Expression* expr = (*iter)->expression()->get();
switch (expr->fKind) {
case Expression::kBinary_Kind: {
switch (expr->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression& b = expr->as<BinaryExpression>();
if (b.fOperator == Token::Kind::TK_EQ) {
if (!this->tryRemoveLValueBefore(iter, b.fLeft.get())) {
@ -180,11 +180,11 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.erase(*iter);
return true;
}
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
// ternaries cross basic block boundaries, must regenerate the CFG to remove it
return false;
}
case Expression::kFieldAccess_Kind: {
case Expression::Kind::kFieldAccess: {
FieldAccess& f = expr->as<FieldAccess>();
if (!this->tryRemoveExpressionBefore(iter, f.fBase.get())) {
return false;
@ -192,7 +192,7 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.erase(*iter);
return true;
}
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
Swizzle& s = expr->as<Swizzle>();
if (s.fBase && !this->tryRemoveExpressionBefore(iter, s.fBase.get())) {
return false;
@ -200,7 +200,7 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.erase(*iter);
return true;
}
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
IndexExpression& idx = expr->as<IndexExpression>();
if (!this->tryRemoveExpressionBefore(iter, idx.fBase.get())) {
return false;
@ -211,7 +211,7 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.erase(*iter);
return true;
}
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
Constructor& c = expr->as<Constructor>();
for (auto& arg : c.fArguments) {
if (!this->tryRemoveExpressionBefore(iter, arg.get())) {
@ -222,7 +222,7 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.erase(*iter);
return true;
}
case Expression::kFunctionCall_Kind: {
case Expression::Kind::kFunctionCall: {
FunctionCall& f = expr->as<FunctionCall>();
for (auto& arg : f.fArguments) {
if (!this->tryRemoveExpressionBefore(iter, arg.get())) {
@ -233,25 +233,25 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.erase(*iter);
return true;
}
case Expression::kPrefix_Kind:
case Expression::Kind::kPrefix:
if (!this->tryRemoveExpressionBefore(iter,
expr->as<PrefixExpression>().fOperand.get())) {
return false;
}
*iter = fNodes.erase(*iter);
return true;
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
if (!this->tryRemoveExpressionBefore(iter,
expr->as<PrefixExpression>().fOperand.get())) {
return false;
}
*iter = fNodes.erase(*iter);
return true;
case Expression::kBoolLiteral_Kind: // fall through
case Expression::kFloatLiteral_Kind: // fall through
case Expression::kIntLiteral_Kind: // fall through
case Expression::kSetting_Kind: // fall through
case Expression::kVariableReference_Kind:
case Expression::Kind::kBoolLiteral: // fall through
case Expression::Kind::kFloatLiteral: // fall through
case Expression::Kind::kIntLiteral: // fall through
case Expression::Kind::kSetting: // fall through
case Expression::Kind::kVariableReference:
*iter = fNodes.erase(*iter);
return true;
default:
@ -264,8 +264,8 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it
bool BasicBlock::tryInsertExpression(std::vector<BasicBlock::Node>::iterator* iter,
std::unique_ptr<Expression>* expr) {
switch ((*expr)->fKind) {
case Expression::kBinary_Kind: {
switch ((*expr)->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression& b = expr->get()->as<BinaryExpression>();
if (!this->tryInsertExpression(iter, &b.fRight)) {
return false;
@ -279,15 +279,15 @@ bool BasicBlock::tryInsertExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.insert(*iter, node);
return true;
}
case Expression::kBoolLiteral_Kind: // fall through
case Expression::kFloatLiteral_Kind: // fall through
case Expression::kIntLiteral_Kind: // fall through
case Expression::kVariableReference_Kind: {
case Expression::Kind::kBoolLiteral: // fall through
case Expression::Kind::kFloatLiteral: // fall through
case Expression::Kind::kIntLiteral: // fall through
case Expression::Kind::kVariableReference: {
BasicBlock::Node node = { BasicBlock::Node::kExpression_Kind, true, expr, nullptr };
*iter = fNodes.insert(*iter, node);
return true;
}
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
Constructor& c = expr->get()->as<Constructor>();
for (auto& arg : c.fArguments) {
if (!this->tryInsertExpression(iter, &arg)) {
@ -299,7 +299,7 @@ bool BasicBlock::tryInsertExpression(std::vector<BasicBlock::Node>::iterator* it
*iter = fNodes.insert(*iter, node);
return true;
}
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
Swizzle& s = expr->get()->as<Swizzle>();
if (!this->tryInsertExpression(iter, &s.fBase)) {
return false;
@ -316,8 +316,8 @@ bool BasicBlock::tryInsertExpression(std::vector<BasicBlock::Node>::iterator* it
void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool constantPropagate) {
SkASSERT(e);
switch ((*e)->fKind) {
case Expression::kBinary_Kind: {
switch ((*e)->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression& b = e->get()->as<BinaryExpression>();
switch (b.fOperator) {
case Token::Kind::TK_LOGICALAND: // fall through
@ -362,7 +362,7 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
}
break;
}
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
Constructor& c = e->get()->as<Constructor>();
for (auto& arg : c.fArguments) {
this->addExpression(cfg, &arg, constantPropagate);
@ -371,7 +371,7 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
constantPropagate, e, nullptr });
break;
}
case Expression::kExternalFunctionCall_Kind: {
case Expression::Kind::kExternalFunctionCall: {
ExternalFunctionCall& c = e->get()->as<ExternalFunctionCall>();
for (auto& arg : c.fArguments) {
this->addExpression(cfg, &arg, constantPropagate);
@ -380,7 +380,7 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
constantPropagate, e, nullptr });
break;
}
case Expression::kFunctionCall_Kind: {
case Expression::Kind::kFunctionCall: {
FunctionCall& c = e->get()->as<FunctionCall>();
for (auto& arg : c.fArguments) {
this->addExpression(cfg, &arg, constantPropagate);
@ -389,12 +389,13 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
constantPropagate, e, nullptr });
break;
}
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess: {
this->addExpression(cfg, &e->get()->as<FieldAccess>().fBase, constantPropagate);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kExpression_Kind,
constantPropagate, e, nullptr });
break;
case Expression::kIndex_Kind: {
}
case Expression::Kind::kIndex: {
IndexExpression& indexExpr = e->get()->as<IndexExpression>();
this->addExpression(cfg, &indexExpr.fBase, constantPropagate);
@ -403,7 +404,7 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
constantPropagate, e, nullptr });
break;
}
case Expression::kPrefix_Kind: {
case Expression::Kind::kPrefix: {
PrefixExpression& p = e->get()->as<PrefixExpression>();
this->addExpression(cfg, &p.fOperand, constantPropagate &&
p.fOperator != Token::Kind::TK_PLUSPLUS &&
@ -412,27 +413,27 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
constantPropagate, e, nullptr });
break;
}
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
this->addExpression(cfg, &e->get()->as<PostfixExpression>().fOperand, false);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kExpression_Kind,
constantPropagate, e, nullptr });
break;
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
this->addExpression(cfg, &e->get()->as<Swizzle>().fBase, constantPropagate);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kExpression_Kind,
constantPropagate, e, nullptr });
break;
case Expression::kBoolLiteral_Kind: // fall through
case Expression::kExternalValue_Kind: // fall through
case Expression::kFloatLiteral_Kind: // fall through
case Expression::kIntLiteral_Kind: // fall through
case Expression::kNullLiteral_Kind: // fall through
case Expression::kSetting_Kind: // fall through
case Expression::kVariableReference_Kind:
case Expression::Kind::kBoolLiteral: // fall through
case Expression::Kind::kExternalValue: // fall through
case Expression::Kind::kFloatLiteral: // fall through
case Expression::Kind::kIntLiteral: // fall through
case Expression::Kind::kNullLiteral: // fall through
case Expression::Kind::kSetting: // fall through
case Expression::Kind::kVariableReference:
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kExpression_Kind,
constantPropagate, e, nullptr });
break;
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
TernaryExpression& t = e->get()->as<TernaryExpression>();
this->addExpression(cfg, &t.fTest, constantPropagate);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kExpression_Kind,
@ -448,9 +449,9 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
cfg.fCurrent = next;
break;
}
case Expression::kFunctionReference_Kind: // fall through
case Expression::kTypeReference_Kind: // fall through
case Expression::kDefined_Kind:
case Expression::Kind::kFunctionReference: // fall through
case Expression::Kind::kTypeReference: // fall through
case Expression::Kind::kDefined:
SkASSERT(false);
break;
}
@ -458,23 +459,23 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
// adds expressions that are evaluated as part of resolving an lvalue
void CFGGenerator::addLValue(CFG& cfg, std::unique_ptr<Expression>* e) {
switch ((*e)->fKind) {
case Expression::kFieldAccess_Kind:
switch ((*e)->kind()) {
case Expression::Kind::kFieldAccess:
this->addLValue(cfg, &e->get()->as<FieldAccess>().fBase);
break;
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
IndexExpression& indexExpr = e->get()->as<IndexExpression>();
this->addLValue(cfg, &indexExpr.fBase);
this->addExpression(cfg, &indexExpr.fIndex, /*constantPropagate=*/true);
break;
}
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
this->addLValue(cfg, &e->get()->as<Swizzle>().fBase);
break;
case Expression::kExternalValue_Kind: // fall through
case Expression::kVariableReference_Kind:
case Expression::Kind::kExternalValue: // fall through
case Expression::Kind::kVariableReference:
break;
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
TernaryExpression& ternary = e->get()->as<TernaryExpression>();
this->addExpression(cfg, &ternary.fTest, /*constantPropagate=*/true);
// Technically we will of course only evaluate one or the other, but if the test turns
@ -492,17 +493,17 @@ void CFGGenerator::addLValue(CFG& cfg, std::unique_ptr<Expression>* e) {
}
static bool is_true(Expression& expr) {
return expr.fKind == Expression::kBoolLiteral_Kind && expr.as<BoolLiteral>().fValue;
return expr.kind() == Expression::Kind::kBoolLiteral && expr.as<BoolLiteral>().fValue;
}
void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
switch ((*s)->fKind) {
case Statement::kBlock_Kind:
switch ((*s)->kind()) {
case Statement::Kind::kBlock:
for (auto& child : (*s)->as<Block>().fStatements) {
addStatement(cfg, &child);
}
break;
case Statement::kIf_Kind: {
case Statement::Kind::kIf: {
IfStatement& ifs = (*s)->as<IfStatement>();
this->addExpression(cfg, &ifs.fTest, /*constantPropagate=*/true);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
@ -522,17 +523,17 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
}
break;
}
case Statement::kExpression_Kind: {
case Statement::Kind::kExpression: {
this->addExpression(cfg, &(*s)->as<ExpressionStatement>().fExpression,
/*constantPropagate=*/true);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
nullptr, s });
break;
}
case Statement::kVarDeclarations_Kind: {
case Statement::Kind::kVarDeclarations: {
VarDeclarationsStatement& decls = (*s)->as<VarDeclarationsStatement>();
for (auto& stmt : decls.fDeclaration->fVars) {
if (stmt->fKind == Statement::kNop_Kind) {
if (stmt->kind() == Statement::Kind::kNop) {
continue;
}
VarDeclaration& vd = stmt->as<VarDeclaration>();
@ -546,12 +547,12 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
nullptr, s });
break;
}
case Statement::kDiscard_Kind:
case Statement::Kind::kDiscard:
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
nullptr, s });
cfg.fCurrent = cfg.newIsolatedBlock();
break;
case Statement::kReturn_Kind: {
case Statement::Kind::kReturn: {
ReturnStatement& r = (*s)->as<ReturnStatement>();
if (r.fExpression) {
this->addExpression(cfg, &r.fExpression, /*constantPropagate=*/true);
@ -561,19 +562,19 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
cfg.fCurrent = cfg.newIsolatedBlock();
break;
}
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
nullptr, s });
cfg.addExit(cfg.fCurrent, fLoopExits.top());
cfg.fCurrent = cfg.newIsolatedBlock();
break;
case Statement::kContinue_Kind:
case Statement::Kind::kContinue:
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
nullptr, s });
cfg.addExit(cfg.fCurrent, fLoopContinues.top());
cfg.fCurrent = cfg.newIsolatedBlock();
break;
case Statement::kWhile_Kind: {
case Statement::Kind::kWhile: {
WhileStatement& w = (*s)->as<WhileStatement>();
BlockId loopStart = cfg.newBlock();
fLoopContinues.push(loopStart);
@ -592,7 +593,7 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
cfg.fCurrent = loopExit;
break;
}
case Statement::kDo_Kind: {
case Statement::Kind::kDo: {
DoStatement& d = (*s)->as<DoStatement>();
BlockId loopStart = cfg.newBlock();
fLoopContinues.push(loopStart);
@ -607,7 +608,7 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
cfg.fCurrent = loopExit;
break;
}
case Statement::kFor_Kind: {
case Statement::Kind::kFor: {
ForStatement& f = (*s)->as<ForStatement>();
if (f.fInitializer) {
this->addStatement(cfg, &f.fInitializer);
@ -641,7 +642,7 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
cfg.fCurrent = loopExit;
break;
}
case Statement::kSwitch_Kind: {
case Statement::Kind::kSwitch: {
SwitchStatement& ss = (*s)->as<SwitchStatement>();
this->addExpression(cfg, &ss.fValue, /*constantPropagate=*/true);
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
@ -671,7 +672,7 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
cfg.fCurrent = switchExit;
break;
}
case Statement::kNop_Kind:
case Statement::Kind::kNop:
break;
default:
#ifdef SK_DEBUG

View File

@ -21,7 +21,7 @@ namespace SkSL {
static bool needs_uniform_var(const Variable& var) {
return (var.fModifiers.fFlags & Modifiers::kUniform_Flag) &&
var.fType.kind() != Type::kSampler_Kind;
var.fType.typeKind() != Type::TypeKind::kSampler;
}
CPPCodeGenerator::CPPCodeGenerator(const Context* context, const Program* program,
@ -82,15 +82,15 @@ void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
if (precedence >= parentPrecedence) {
this->write(")");
}
} else if (b.fLeft->fKind == Expression::kNullLiteral_Kind ||
b.fRight->fKind == Expression::kNullLiteral_Kind) {
} else if (b.fLeft->kind() == Expression::Kind::kNullLiteral ||
b.fRight->kind() == Expression::Kind::kNullLiteral) {
const Variable* var;
if (b.fLeft->fKind != Expression::kNullLiteral_Kind) {
if (b.fLeft->kind() != Expression::Kind::kNullLiteral) {
var = &b.fLeft->as<VariableReference>().fVariable;
} else {
var = &b.fRight->as<VariableReference>().fVariable;
}
SkASSERT(var->fType.kind() == Type::kNullable_Kind &&
SkASSERT(var->fType.typeKind() == Type::TypeKind::kNullable &&
var->fType.componentType() == *fContext.fFragmentProcessor_Type);
this->write("%s");
const char* op = "";
@ -116,10 +116,10 @@ static String default_value(const Type& type) {
if (type.fName == "bool") {
return "false";
}
switch (type.kind()) {
case Type::kScalar_Kind: return "0";
case Type::kVector_Kind: return type.name() + "(0)";
case Type::kMatrix_Kind: return type.name() + "(1)";
switch (type.typeKind()) {
case Type::TypeKind::kScalar: return "0";
case Type::TypeKind::kVector: return type.name() + "(0)";
case Type::TypeKind::kMatrix: return type.name() + "(1)";
default: ABORT("unsupported default_value type\n");
}
}
@ -141,14 +141,14 @@ static bool is_private(const Variable& var) {
static bool is_uniform_in(const Variable& var) {
return (var.fModifiers.fFlags & Modifiers::kUniform_Flag) &&
(var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
var.fType.kind() != Type::kSampler_Kind;
var.fType.typeKind() != Type::TypeKind::kSampler;
}
String CPPCodeGenerator::formatRuntimeValue(const Type& type,
const Layout& layout,
const String& cppCode,
std::vector<String>* formatArgs) {
if (type.kind() == Type::kArray_Kind) {
if (type.typeKind() == Type::TypeKind::kArray) {
String result("[");
const char* separator = "";
for (int i = 0; i < type.columns(); i++) {
@ -215,7 +215,7 @@ String CPPCodeGenerator::formatRuntimeValue(const Type& type,
}
return type.name() + "(%f, %f, %f, %f)";
}
if (type.kind() == Type::kMatrix_Kind) {
if (type.typeKind() == Type::TypeKind::kMatrix) {
SkASSERT(type.componentType() == *fContext.fFloat_Type ||
type.componentType() == *fContext.fHalf_Type);
@ -232,7 +232,7 @@ String CPPCodeGenerator::formatRuntimeValue(const Type& type,
format.back() = ')';
return format;
}
if (type.kind() == Type::kEnum_Kind) {
if (type.typeKind() == Type::TypeKind::kEnum) {
formatArgs->push_back("(int) " + cppCode);
return "%d";
}
@ -269,7 +269,7 @@ String CPPCodeGenerator::getSamplerHandle(const Variable& var) {
if (&var == param) {
return "args.fTexSamplers[" + to_string(samplerCount) + "]";
}
if (param->fType.kind() == Type::kSampler_Kind) {
if (param->fType.typeKind() == Type::TypeKind::kSampler) {
++samplerCount;
}
}
@ -327,7 +327,7 @@ void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
this->write("sk_Height");
break;
default:
if (ref.fVariable.fType.kind() == Type::kSampler_Kind) {
if (ref.fVariable.fType.typeKind() == Type::TypeKind::kSampler) {
this->write("%s");
fFormatArgs.push_back("fragBuilder->getProgramBuilder()->samplerVariable(" +
this->getSamplerHandle(ref.fVariable) + ")");
@ -383,7 +383,7 @@ void CPPCodeGenerator::writeFieldAccess(const FieldAccess& access) {
if (access.fBase->fType.name() == "fragmentProcessor") {
// Special field access on fragment processors are converted into function calls on
// GrFragmentProcessor's getters.
if (access.fBase->fKind != Expression::kVariableReference_Kind) {
if (access.fBase->kind() != Expression::Kind::kVariableReference) {
fErrors.error(access.fBase->fOffset, "fragmentProcessor must be a reference\n");
return;
}
@ -408,7 +408,7 @@ int CPPCodeGenerator::getChildFPIndex(const Variable& var) const {
int index = 0;
bool found = false;
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const auto& raw : decls.fVars) {
const VarDeclaration& decl = raw->as<VarDeclaration>();
@ -429,7 +429,7 @@ int CPPCodeGenerator::getChildFPIndex(const Variable& var) const {
void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
if (c.fFunction.fBuiltin && c.fFunction.fName == "sample" &&
c.fArguments[0]->fType.kind() != Type::Kind::kSampler_Kind) {
c.fArguments[0]->fType.typeKind() != Type::TypeKind::kSampler) {
// Validity checks that are detected by function definition in sksl_fp.inc
SkASSERT(c.fArguments.size() >= 1 && c.fArguments.size() <= 3);
SkASSERT("fragmentProcessor" == c.fArguments[0]->fType.name() ||
@ -438,7 +438,7 @@ void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
// Actually fail during compilation if arguments with valid types are
// provided that are not variable references, since sample() is a
// special function that impacts code emission.
if (c.fArguments[0]->fKind != Expression::kVariableReference_Kind) {
if (c.fArguments[0]->kind() != Expression::Kind::kVariableReference) {
fErrors.error(c.fArguments[0]->fOffset,
"sample()'s fragmentProcessor argument must be a variable reference\n");
return;
@ -511,7 +511,7 @@ void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
if (c.fFunction.fBuiltin && c.fFunction.fName == "sample") {
this->write(".%s");
SkASSERT(c.fArguments.size() >= 1);
SkASSERT(c.fArguments[0]->fKind == Expression::kVariableReference_Kind);
SkASSERT(c.fArguments[0]->kind() == Expression::Kind::kVariableReference);
String sampler = this->getSamplerHandle(c.fArguments[0]->as<VariableReference>().fVariable);
fFormatArgs.push_back("fragBuilder->getProgramBuilder()->samplerSwizzle(" + sampler +
").asString().c_str()");
@ -583,7 +583,7 @@ static const char* glsltype_string(const Context& context, const Type& type) {
return "kVoid_GrSLType";
} else if (type == *context.fBool_Type) {
return "kBool_GrSLType";
} else if (type.kind() == Type::kEnum_Kind) {
} else if (type.typeKind() == Type::TypeKind::kEnum) {
return "int";
}
SkASSERT(false);
@ -652,19 +652,23 @@ bool CPPCodeGenerator::writeSection(const char* name, const char* prefix) {
}
void CPPCodeGenerator::writeProgramElement(const ProgramElement& p) {
if (p.fKind == ProgramElement::kSection_Kind) {
return;
}
if (p.fKind == ProgramElement::kVar_Kind) {
const VarDeclarations& decls = p.as<VarDeclarations>();
if (!decls.fVars.size()) {
return;
}
const Variable& var = *decls.fVars[0]->as<VarDeclaration>().fVar;
if (var.fModifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
-1 != var.fModifiers.fLayout.fBuiltin) {
switch (p.kind()) {
case ProgramElement::Kind::kSection:
return;
case ProgramElement::Kind::kVar: {
const VarDeclarations& decls = p.as<VarDeclarations>();
if (!decls.fVars.size()) {
return;
}
const Variable& var = *decls.fVars[0]->as<VarDeclaration>().fVar;
if (var.fModifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
-1 != var.fModifiers.fLayout.fBuiltin) {
return;
}
break;
}
default:
break;
}
INHERITED::writeProgramElement(p);
}
@ -677,7 +681,7 @@ void CPPCodeGenerator::addUniform(const Variable& var) {
this->writef(" if (%s) {\n ", String(var.fModifiers.fLayout.fWhen).c_str());
}
String name(var.fName);
if (var.fType.kind() != Type::kArray_Kind) {
if (var.fType.typeKind() != Type::TypeKind::kArray) {
this->writef(" %sVar = args.fUniformHandler->addUniform(&_outer, "
"kFragment_GrShaderFlag, %s, \"%s\");\n",
HCodeGenerator::FieldName(name.c_str()).c_str(),
@ -701,7 +705,7 @@ void CPPCodeGenerator::writeInputVars() {
void CPPCodeGenerator::writePrivateVars() {
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const auto& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
@ -741,7 +745,7 @@ void CPPCodeGenerator::writePrivateVars() {
void CPPCodeGenerator::writePrivateVarValues() {
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const auto& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
@ -759,8 +763,8 @@ void CPPCodeGenerator::writePrivateVarValues() {
static bool is_accessible(const Variable& var) {
const Type& type = var.fType.nonnullable();
return Type::kSampler_Kind != type.kind() &&
Type::kOther_Kind != type.kind();
return Type::TypeKind::kSampler != type.typeKind() &&
Type::TypeKind::kOther != type.typeKind();
}
void CPPCodeGenerator::newExtraEmitCodeBlock() {
@ -958,7 +962,7 @@ bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
" (void) _outer;\n",
fFullName.c_str(), fFullName.c_str());
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const auto& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
@ -1074,14 +1078,14 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
if (section) {
int samplerIndex = 0;
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const std::unique_ptr<Statement>& raw : decls.fVars) {
const VarDeclaration& decl = raw->as<VarDeclaration>();
const Variable& variable = *decl.fVar;
String nameString(variable.fName);
const char* name = nameString.c_str();
if (variable.fType.kind() == Type::kSampler_Kind) {
if (variable.fType.typeKind() == Type::TypeKind::kSampler) {
this->writef(" const GrSurfaceProxyView& %sView = "
"_outer.textureSampler(%d).view();\n",
name, samplerIndex);
@ -1118,7 +1122,7 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
void CPPCodeGenerator::writeOnTextureSampler() {
bool foundSampler = false;
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
if (param->fType.kind() == Type::kSampler_Kind) {
if (param->fType.typeKind() == Type::TypeKind::kSampler) {
if (!foundSampler) {
this->writef(
"const GrFragmentProcessor::TextureSampler& %s::onTextureSampler(int "
@ -1159,7 +1163,7 @@ void CPPCodeGenerator::writeClone() {
this->writef(" this->cloneAndRegisterAllChildProcessors(src);\n");
int samplerCount = 0;
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
if (param->fType.kind() == Type::kSampler_Kind) {
if (param->fType.typeKind() == Type::TypeKind::kSampler) {
++samplerCount;
}
}
@ -1248,7 +1252,7 @@ void CPPCodeGenerator::writeGetKey() {
"GrProcessorKeyBuilder* b) const {\n",
fFullName.c_str());
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const auto& raw : decls.fVars) {
const VarDeclaration& decl = raw->as<VarDeclaration>();
@ -1295,7 +1299,7 @@ void CPPCodeGenerator::writeGetKey() {
this->writef(" b->add32(sk_bit_cast<uint32_t>(%s));\n",
HCodeGenerator::FieldName(name).c_str());
} else if (var.fType.isInteger() || var.fType == *fContext.fBool_Type ||
var.fType.kind() == Type::kEnum_Kind) {
var.fType.typeKind() == Type::TypeKind::kEnum) {
this->writef(" b->add32((uint32_t) %s);\n",
HCodeGenerator::FieldName(name).c_str());
} else {
@ -1307,7 +1311,7 @@ void CPPCodeGenerator::writeGetKey() {
}
break;
case Layout::kIdentity_Key:
if (var.fType.kind() != Type::kMatrix_Kind) {
if (var.fType.typeKind() != Type::TypeKind::kMatrix) {
fErrors.error(var.fOffset,
"layout(key=identity) requires matrix type");
}
@ -1326,12 +1330,12 @@ void CPPCodeGenerator::writeGetKey() {
bool CPPCodeGenerator::generateCode() {
std::vector<const Variable*> uniforms;
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const auto& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
if ((decl.fVar->fModifiers.fFlags & Modifiers::kUniform_Flag) &&
decl.fVar->fType.kind() != Type::kSampler_Kind) {
decl.fVar->fType.typeKind() != Type::TypeKind::kSampler) {
uniforms.push_back(decl.fVar);
}

View File

@ -253,7 +253,7 @@ static const std::vector<UniformCTypeMapper>& get_mappers() {
// ctype and supports the sksl type of the variable.
const UniformCTypeMapper* UniformCTypeMapper::Get(const Context& context, const Type& type,
const Layout& layout) {
if (type.kind() == Type::kArray_Kind) {
if (type.typeKind() == Type::TypeKind::kArray) {
const UniformCTypeMapper* base = Get(context, type.componentType(), layout);
return base ? base->arrayMapper(type.columns()) : nullptr;
}

View File

@ -74,8 +74,8 @@ static void grab_intrinsics(std::vector<std::unique_ptr<ProgramElement>>* src,
IRIntrinsicMap* target) {
for (auto iter = src->begin(); iter != src->end(); ) {
std::unique_ptr<ProgramElement>& element = *iter;
switch (element->fKind) {
case ProgramElement::kFunction_Kind: {
switch (element->kind()) {
case ProgramElement::Kind::kFunction: {
FunctionDefinition& f = element->as<FunctionDefinition>();
SkASSERT(f.fDeclaration.fBuiltin);
String key = f.fDeclaration.description();
@ -84,7 +84,7 @@ static void grab_intrinsics(std::vector<std::unique_ptr<ProgramElement>>* src,
iter = src->erase(iter);
break;
}
case ProgramElement::kEnum_Kind: {
case ProgramElement::Kind::kEnum: {
Enum& e = element->as<Enum>();
StringFragment name = e.fTypeName;
SkASSERT(target->find(name) == target->end());
@ -376,15 +376,15 @@ void Compiler::processIncludeFile(Program::Kind kind, const char* path,
// add the definition created by assigning to the lvalue to the definition set
void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
DefinitionMap* definitions) {
switch (lvalue->fKind) {
case Expression::kVariableReference_Kind: {
switch (lvalue->kind()) {
case Expression::Kind::kVariableReference: {
const Variable& var = lvalue->as<VariableReference>().fVariable;
if (var.fStorage == Variable::kLocal_Storage) {
(*definitions)[&var] = expr;
}
break;
}
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
// We consider the variable written to as long as at least some of its components have
// been written to. This will lead to some false negatives (we won't catch it if you
// write to foo.x and then read foo.y), but being stricter could lead to false positives
@ -395,19 +395,19 @@ void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expressio
(std::unique_ptr<Expression>*) &fContext->fDefined_Expression,
definitions);
break;
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
// see comments in Swizzle
this->addDefinition(lvalue->as<IndexExpression>().fBase.get(),
(std::unique_ptr<Expression>*) &fContext->fDefined_Expression,
definitions);
break;
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
// see comments in Swizzle
this->addDefinition(lvalue->as<FieldAccess>().fBase.get(),
(std::unique_ptr<Expression>*) &fContext->fDefined_Expression,
definitions);
break;
case Expression::kTernary_Kind:
case Expression::Kind::kTernary:
// To simplify analysis, we just pretend that we write to both sides of the ternary.
// This allows for false positives (meaning we fail to detect that a variable might not
// have been assigned), but is preferable to false negatives.
@ -418,7 +418,7 @@ void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expressio
(std::unique_ptr<Expression>*) &fContext->fDefined_Expression,
definitions);
break;
case Expression::kExternalValue_Kind:
case Expression::Kind::kExternalValue:
break;
default:
// not an lvalue, can't happen
@ -433,8 +433,8 @@ void Compiler::addDefinitions(const BasicBlock::Node& node,
case BasicBlock::Node::kExpression_Kind: {
SkASSERT(node.expression());
Expression* expr = node.expression()->get();
switch (expr->fKind) {
case Expression::kBinary_Kind: {
switch (expr->kind()) {
case Expression::Kind::kBinary: {
BinaryExpression* b = &expr->as<BinaryExpression>();
if (b->fOperator == Token::Kind::TK_EQ) {
this->addDefinition(b->fLeft.get(), &b->fRight, definitions);
@ -447,7 +447,7 @@ void Compiler::addDefinitions(const BasicBlock::Node& node,
}
break;
}
case Expression::kFunctionCall_Kind: {
case Expression::Kind::kFunctionCall: {
const FunctionCall& c = expr->as<FunctionCall>();
for (size_t i = 0; i < c.fFunction.fParameters.size(); ++i) {
if (c.fFunction.fParameters[i]->fModifiers.fFlags & Modifiers::kOut_Flag) {
@ -459,7 +459,7 @@ void Compiler::addDefinitions(const BasicBlock::Node& node,
}
break;
}
case Expression::kPrefix_Kind: {
case Expression::Kind::kPrefix: {
const PrefixExpression* p = &expr->as<PrefixExpression>();
if (p->fOperator == Token::Kind::TK_MINUSMINUS ||
p->fOperator == Token::Kind::TK_PLUSPLUS) {
@ -470,7 +470,7 @@ void Compiler::addDefinitions(const BasicBlock::Node& node,
}
break;
}
case Expression::kPostfix_Kind: {
case Expression::Kind::kPostfix: {
const PostfixExpression* p = &expr->as<PostfixExpression>();
if (p->fOperator == Token::Kind::TK_MINUSMINUS ||
p->fOperator == Token::Kind::TK_PLUSPLUS) {
@ -481,7 +481,7 @@ void Compiler::addDefinitions(const BasicBlock::Node& node,
}
break;
}
case Expression::kVariableReference_Kind: {
case Expression::Kind::kVariableReference: {
const VariableReference* v = &expr->as<VariableReference>();
if (v->fRefKind != VariableReference::kRead_RefKind) {
this->addDefinition(
@ -498,7 +498,7 @@ void Compiler::addDefinitions(const BasicBlock::Node& node,
}
case BasicBlock::Node::kStatement_Kind: {
Statement* stmt = node.statement()->get();
if (stmt->fKind == Statement::kVarDeclaration_Kind) {
if (stmt->kind() == Statement::Kind::kVarDeclaration) {
VarDeclaration& vd = stmt->as<VarDeclaration>();
if (vd.fValue) {
(*definitions)[vd.fVar] = &vd.fValue;
@ -558,10 +558,10 @@ static DefinitionMap compute_start_state(const CFG& cfg) {
if (node.fKind == BasicBlock::Node::kStatement_Kind) {
SkASSERT(node.statement());
const Statement* s = node.statement()->get();
if (s->fKind == Statement::kVarDeclarations_Kind) {
if (s->kind() == Statement::Kind::kVarDeclarations) {
const VarDeclarationsStatement* vd = &s->as<VarDeclarationsStatement>();
for (const auto& decl : vd->fDeclaration->fVars) {
if (decl->fKind == Statement::kVarDeclaration_Kind) {
if (decl->kind() == Statement::Kind::kVarDeclaration) {
result[decl->as<VarDeclaration>().fVar] = nullptr;
}
}
@ -576,23 +576,23 @@ static DefinitionMap compute_start_state(const CFG& cfg) {
* Returns true if assigning to this lvalue has no effect.
*/
static bool is_dead(const Expression& lvalue) {
switch (lvalue.fKind) {
case Expression::kVariableReference_Kind:
switch (lvalue.kind()) {
case Expression::Kind::kVariableReference:
return lvalue.as<VariableReference>().fVariable.dead();
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
return is_dead(*lvalue.as<Swizzle>().fBase);
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
return is_dead(*lvalue.as<FieldAccess>().fBase);
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
const IndexExpression& idx = lvalue.as<IndexExpression>();
return is_dead(*idx.fBase) &&
!idx.fIndex->hasProperty(Expression::Property::kSideEffects);
}
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
const TernaryExpression& t = lvalue.as<TernaryExpression>();
return !t.fTest->hasSideEffects() && is_dead(*t.fIfTrue) && is_dead(*t.fIfFalse);
}
case Expression::kExternalValue_Kind:
case Expression::Kind::kExternalValue:
return false;
default:
#ifdef SK_DEBUG
@ -650,21 +650,21 @@ static bool try_replace_expression(BasicBlock* b,
*/
template <typename T = double>
static bool is_constant(const Expression& expr, T value) {
switch (expr.fKind) {
case Expression::kIntLiteral_Kind:
switch (expr.kind()) {
case Expression::Kind::kIntLiteral:
return expr.as<IntLiteral>().fValue == value;
case Expression::kFloatLiteral_Kind:
case Expression::Kind::kFloatLiteral:
return expr.as<FloatLiteral>().fValue == value;
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
const Constructor& constructor = expr.as<Constructor>();
if (constructor.isCompileTimeConstant()) {
bool isFloat = constructor.fType.columns() > 1
? constructor.fType.componentType().isFloat()
: constructor.fType.isFloat();
switch (constructor.fType.kind()) {
case Type::kVector_Kind:
switch (constructor.fType.typeKind()) {
case Type::TypeKind::kVector:
for (int i = 0; i < constructor.fType.columns(); ++i) {
if (isFloat) {
if (constructor.getFVecComponent(i) != value) {
@ -678,7 +678,7 @@ static bool is_constant(const Expression& expr, T value) {
}
return true;
case Type::kScalar_Kind:
case Type::TypeKind::kScalar:
SkASSERT(constructor.fArguments.size() == 1);
return is_constant<T>(*constructor.fArguments[0], value);
@ -768,7 +768,7 @@ static void delete_right(BasicBlock* b,
static std::unique_ptr<Expression> construct(const Type& type, std::unique_ptr<Expression> v) {
std::vector<std::unique_ptr<Expression>> args;
args.push_back(std::move(v));
auto result = std::unique_ptr<Expression>(new Constructor(-1, type, std::move(args)));
std::unique_ptr<Expression> result = std::make_unique<Constructor>(-1, type, std::move(args));
return result;
}
@ -782,9 +782,9 @@ static void vectorize(BasicBlock* b,
std::unique_ptr<Expression>* otherExpression,
bool* outUpdated,
bool* outNeedsRescan) {
SkASSERT((*(*iter)->expression())->fKind == Expression::kBinary_Kind);
SkASSERT(type.kind() == Type::kVector_Kind);
SkASSERT((*otherExpression)->fType.kind() == Type::kScalar_Kind);
SkASSERT((*(*iter)->expression())->kind() == Expression::Kind::kBinary);
SkASSERT(type.typeKind() == Type::TypeKind::kVector);
SkASSERT((*otherExpression)->fType.typeKind() == Type::TypeKind::kScalar);
*outUpdated = true;
std::unique_ptr<Expression>* target = (*iter)->expression();
if (!b->tryRemoveExpression(iter)) {
@ -824,18 +824,18 @@ static void vectorize_right(BasicBlock* b,
// Mark that an expression which we were writing to is no longer being written to
static void clear_write(Expression& expr) {
switch (expr.fKind) {
case Expression::kVariableReference_Kind: {
switch (expr.kind()) {
case Expression::Kind::kVariableReference: {
expr.as<VariableReference>().setRefKind(VariableReference::kRead_RefKind);
break;
}
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
clear_write(*expr.as<FieldAccess>().fBase);
break;
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
clear_write(*expr.as<Swizzle>().fBase);
break;
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
clear_write(*expr.as<IndexExpression>().fBase);
break;
default:
@ -864,8 +864,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
expr = (*iter)->expression()->get();
}
}
switch (expr->fKind) {
case Expression::kVariableReference_Kind: {
switch (expr->kind()) {
case Expression::Kind::kVariableReference: {
const VariableReference& ref = expr->as<VariableReference>();
const Variable& var = ref.fVariable;
if (ref.refKind() != VariableReference::kWrite_RefKind &&
@ -878,9 +878,9 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
}
break;
}
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
TernaryExpression* t = &expr->as<TernaryExpression>();
if (t->fTest->fKind == Expression::kBoolLiteral_Kind) {
if (t->fTest->kind() == Expression::Kind::kBoolLiteral) {
// ternary has a constant test, replace it with either the true or
// false branch
if (t->fTest->as<BoolLiteral>().fValue) {
@ -893,24 +893,24 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
}
break;
}
case Expression::kBinary_Kind: {
case Expression::Kind::kBinary: {
BinaryExpression* bin = &expr->as<BinaryExpression>();
if (dead_assignment(*bin)) {
delete_left(&b, iter, outUpdated, outNeedsRescan);
break;
}
// collapse useless expressions like x * 1 or x + 0
if (((bin->fLeft->fType.kind() != Type::kScalar_Kind) &&
(bin->fLeft->fType.kind() != Type::kVector_Kind)) ||
((bin->fRight->fType.kind() != Type::kScalar_Kind) &&
(bin->fRight->fType.kind() != Type::kVector_Kind))) {
if (((bin->fLeft->fType.typeKind() != Type::TypeKind::kScalar) &&
(bin->fLeft->fType.typeKind() != Type::TypeKind::kVector)) ||
((bin->fRight->fType.typeKind() != Type::TypeKind::kScalar) &&
(bin->fRight->fType.typeKind() != Type::TypeKind::kVector))) {
break;
}
switch (bin->fOperator) {
case Token::Kind::TK_STAR:
if (is_constant(*bin->fLeft, 1)) {
if (bin->fLeft->fType.kind() == Type::kVector_Kind &&
bin->fRight->fType.kind() == Type::kScalar_Kind) {
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kVector &&
bin->fRight->fType.typeKind() == Type::TypeKind::kScalar) {
// float4(1) * x -> float4(x)
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
} else {
@ -921,8 +921,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
}
}
else if (is_constant(*bin->fLeft, 0)) {
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
bin->fRight->fType.kind() == Type::kVector_Kind &&
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
bin->fRight->fType.typeKind() == Type::TypeKind::kVector &&
!bin->fRight->hasSideEffects()) {
// 0 * float4(x) -> float4(0)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
@ -936,8 +936,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
}
}
else if (is_constant(*bin->fRight, 1)) {
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
bin->fRight->fType.kind() == Type::kVector_Kind) {
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
// x * float4(1) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@ -948,8 +948,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
}
}
else if (is_constant(*bin->fRight, 0)) {
if (bin->fLeft->fType.kind() == Type::kVector_Kind &&
bin->fRight->fType.kind() == Type::kScalar_Kind &&
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kVector &&
bin->fRight->fType.typeKind() == Type::TypeKind::kScalar &&
!bin->fLeft->hasSideEffects()) {
// float4(x) * 0 -> float4(0)
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
@ -965,8 +965,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
break;
case Token::Kind::TK_PLUS:
if (is_constant(*bin->fLeft, 0)) {
if (bin->fLeft->fType.kind() == Type::kVector_Kind &&
bin->fRight->fType.kind() == Type::kScalar_Kind) {
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kVector &&
bin->fRight->fType.typeKind() == Type::TypeKind::kScalar) {
// float4(0) + x -> float4(x)
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
} else {
@ -976,8 +976,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
delete_left(&b, iter, outUpdated, outNeedsRescan);
}
} else if (is_constant(*bin->fRight, 0)) {
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
bin->fRight->fType.kind() == Type::kVector_Kind) {
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
// x + float4(0) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@ -990,8 +990,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
break;
case Token::Kind::TK_MINUS:
if (is_constant(*bin->fRight, 0)) {
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
bin->fRight->fType.kind() == Type::kVector_Kind) {
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
// x - float4(0) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@ -1004,8 +1004,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
break;
case Token::Kind::TK_SLASH:
if (is_constant(*bin->fRight, 1)) {
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
bin->fRight->fType.kind() == Type::kVector_Kind) {
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
// x / float4(1) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@ -1015,8 +1015,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
} else if (is_constant(*bin->fLeft, 0)) {
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
bin->fRight->fType.kind() == Type::kVector_Kind &&
if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
bin->fRight->fType.typeKind() == Type::TypeKind::kVector &&
!bin->fRight->hasSideEffects()) {
// 0 / float4(x) -> float4(0)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
@ -1059,7 +1059,7 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
}
break;
}
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
Swizzle& s = expr->as<Swizzle>();
// detect identity swizzles like foo.rgba
if ((int) s.fComponents.size() == s.fBase->fType.columns()) {
@ -1081,7 +1081,7 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
}
}
// detect swizzles of swizzles, e.g. replace foo.argb.r000 with foo.a000
if (s.fBase->fKind == Expression::kSwizzle_Kind) {
if (s.fBase->kind() == Expression::Kind::kSwizzle) {
Swizzle& base = s.fBase->as<Swizzle>();
std::vector<int> final;
for (int c : s.fComponents) {
@ -1113,14 +1113,14 @@ static bool contains_conditional_break(Statement& stmt) {
class ContainsConditionalBreak : public ProgramVisitor {
public:
bool visitStatement(const Statement& stmt) override {
switch (stmt.fKind) {
case Statement::kBlock_Kind:
switch (stmt.kind()) {
case Statement::Kind::kBlock:
return this->INHERITED::visitStatement(stmt);
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
return fInConditional > 0;
case Statement::kIf_Kind: {
case Statement::Kind::kIf: {
++fInConditional;
bool result = this->INHERITED::visitStatement(stmt);
--fInConditional;
@ -1145,11 +1145,11 @@ static bool contains_unconditional_break(Statement& stmt) {
class ContainsUnconditionalBreak : public ProgramVisitor {
public:
bool visitStatement(const Statement& stmt) override {
switch (stmt.fKind) {
case Statement::kBlock_Kind:
switch (stmt.kind()) {
case Statement::Kind::kBlock:
return this->INHERITED::visitStatement(stmt);
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
return true;
default:
@ -1165,8 +1165,8 @@ static bool contains_unconditional_break(Statement& stmt) {
static void move_all_but_break(std::unique_ptr<Statement>& stmt,
std::vector<std::unique_ptr<Statement>>* target) {
switch (stmt->fKind) {
case Statement::kBlock_Kind: {
switch (stmt->kind()) {
case Statement::Kind::kBlock: {
// Recurse into the block.
Block& block = static_cast<Block&>(*stmt);
@ -1181,7 +1181,7 @@ static void move_all_but_break(std::unique_ptr<Statement>& stmt,
break;
}
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
// Do not append a break to the target.
break;
@ -1273,8 +1273,8 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
bool* outUpdated,
bool* outNeedsRescan) {
Statement* stmt = (*iter)->statement()->get();
switch (stmt->fKind) {
case Statement::kVarDeclaration_Kind: {
switch (stmt->kind()) {
case Statement::Kind::kVarDeclaration: {
const auto& varDecl = stmt->as<VarDeclaration>();
if (varDecl.fVar->dead() &&
(!varDecl.fValue ||
@ -1290,9 +1290,9 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
}
break;
}
case Statement::kIf_Kind: {
case Statement::Kind::kIf: {
IfStatement& i = stmt->as<IfStatement>();
if (i.fTest->fKind == Expression::kBoolLiteral_Kind) {
if (i.fTest->kind() == Expression::Kind::kBoolLiteral) {
// constant if, collapse down to a single branch
if (i.fTest->as<BoolLiteral>().fValue) {
SkASSERT(i.fIfTrue);
@ -1330,7 +1330,7 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
}
break;
}
case Statement::kSwitch_Kind: {
case Statement::Kind::kSwitch: {
SwitchStatement& s = stmt->as<SwitchStatement>();
if (s.fValue->isCompileTimeConstant()) {
// switch is constant, replace it with the case that matches
@ -1380,7 +1380,7 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
}
break;
}
case Statement::kExpression_Kind: {
case Statement::Kind::kExpression: {
ExpressionStatement& e = stmt->as<ExpressionStatement>();
SkASSERT((*iter)->statement()->get() == &e);
if (!e.fExpression->hasSideEffects()) {
@ -1414,8 +1414,8 @@ void Compiler::scanCFG(FunctionDefinition& f) {
break;
case BasicBlock::Node::kExpression_Kind:
offset = (*cfg.fBlocks[i].fNodes[0].expression())->fOffset;
if ((*cfg.fBlocks[i].fNodes[0].expression())->fKind ==
Expression::kBoolLiteral_Kind) {
if ((*cfg.fBlocks[i].fNodes[0].expression())->kind() ==
Expression::Kind::kBoolLiteral) {
// Function inlining can generate do { ... } while(false) loops which always
// break, so the boolean condition is considered unreachable. Since not
// being able to reach a literal is a non-issue in the first place, we
@ -1452,7 +1452,7 @@ void Compiler::scanCFG(FunctionDefinition& f) {
// have not been properly assigned. Kill it.
for (BasicBlock::Node& node : b.fNodes) {
if (node.fKind == BasicBlock::Node::kStatement_Kind &&
(*node.statement())->fKind != Statement::kNop_Kind) {
(*node.statement())->kind() != Statement::Kind::kNop) {
node.setStatement(std::unique_ptr<Statement>(new Nop()));
}
}
@ -1485,25 +1485,25 @@ void Compiler::scanCFG(FunctionDefinition& f) {
for (auto iter = b.fNodes.begin(); iter != b.fNodes.end() && !needsRescan;) {
if (iter->fKind == BasicBlock::Node::kStatement_Kind) {
const Statement& s = **iter->statement();
switch (s.fKind) {
case Statement::kIf_Kind:
switch (s.kind()) {
case Statement::Kind::kIf:
if (s.as<IfStatement>().fIsStatic &&
!(fFlags & kPermitInvalidStaticTests_Flag)) {
this->error(s.fOffset, "static if has non-static test");
}
++iter;
break;
case Statement::kSwitch_Kind:
case Statement::Kind::kSwitch:
if (s.as<SwitchStatement>().fIsStatic &&
!(fFlags & kPermitInvalidStaticTests_Flag)) {
this->error(s.fOffset, "static switch has non-static test");
}
++iter;
break;
case Statement::kVarDeclarations_Kind: {
case Statement::Kind::kVarDeclarations: {
VarDeclarations& decls = *s.as<VarDeclarationsStatement>().fDeclaration;
for (auto varIter = decls.fVars.begin(); varIter != decls.fVars.end();) {
if ((*varIter)->fKind == Statement::kNop_Kind) {
if ((*varIter)->kind() == Statement::Kind::kNop) {
varIter = decls.fVars.erase(varIter);
} else {
++varIter;
@ -1644,7 +1644,7 @@ bool Compiler::optimize(Program& program) {
// Scan and optimize based on the control-flow graph for each function.
for (ProgramElement& element : program) {
if (element.fKind == ProgramElement::kFunction_Kind) {
if (element.kind() == ProgramElement::Kind::kFunction) {
this->scanCFG(element.as<FunctionDefinition>());
}
}
@ -1656,7 +1656,7 @@ bool Compiler::optimize(Program& program) {
std::remove_if(program.fElements.begin(),
program.fElements.end(),
[](const std::unique_ptr<ProgramElement>& pe) {
if (pe->fKind != ProgramElement::kFunction_Kind) {
if (pe->kind() != ProgramElement::Kind::kFunction) {
return false;
}
const FunctionDefinition& fn = pe->as<FunctionDefinition>();
@ -1669,7 +1669,7 @@ bool Compiler::optimize(Program& program) {
if (program.fKind != Program::kFragmentProcessor_Kind) {
// Remove dead variables.
for (ProgramElement& element : program) {
if (element.fKind == ProgramElement::kVar_Kind) {
if (element.kind() == ProgramElement::Kind::kVar) {
VarDeclarations& vars = element.as<VarDeclarations>();
vars.fVars.erase(
std::remove_if(vars.fVars.begin(), vars.fVars.end(),
@ -1684,7 +1684,7 @@ bool Compiler::optimize(Program& program) {
program.fElements.erase(
std::remove_if(program.fElements.begin(), program.fElements.end(),
[](const std::unique_ptr<ProgramElement>& element) {
return element->fKind == ProgramElement::kVar_Kind &&
return element->kind() == ProgramElement::Kind::kVar &&
element->as<VarDeclarations>().fVars.empty();
}),
program.fElements.end());

View File

@ -24,41 +24,41 @@ public:
: fInvalid_Type(new Type("<INVALID>"))
, fVoid_Type(new Type("void"))
, fNull_Type(new Type("null"))
, fFloatLiteral_Type(new Type("$floatLiteral", Type::kFloat_NumberKind, 3))
, fIntLiteral_Type(new Type("$intLiteral", Type::kSigned_NumberKind, 1))
, fFloat_Type(new Type("float", Type::kFloat_NumberKind, 5, true))
, fFloatLiteral_Type(new Type("$floatLiteral", Type::NumberKind::kFloat, 3))
, fIntLiteral_Type(new Type("$intLiteral", Type::NumberKind::kSigned, 1))
, fFloat_Type(new Type("float", Type::NumberKind::kFloat, 5, true))
, fFloat2_Type(new Type("float2", *fFloat_Type, 2))
, fFloat3_Type(new Type("float3", *fFloat_Type, 3))
, fFloat4_Type(new Type("float4", *fFloat_Type, 4))
, fHalf_Type(new Type("half", Type::kFloat_NumberKind, 4))
, fHalf_Type(new Type("half", Type::NumberKind::kFloat, 4))
, fHalf2_Type(new Type("half2", *fHalf_Type, 2))
, fHalf3_Type(new Type("half3", *fHalf_Type, 3))
, fHalf4_Type(new Type("half4", *fHalf_Type, 4))
, fUInt_Type(new Type("uint", Type::kUnsigned_NumberKind, 2, true))
, fUInt_Type(new Type("uint", Type::NumberKind::kUnsigned, 2, true))
, fUInt2_Type(new Type("uint2", *fUInt_Type, 2))
, fUInt3_Type(new Type("uint3", *fUInt_Type, 3))
, fUInt4_Type(new Type("uint4", *fUInt_Type, 4))
, fInt_Type(new Type("int", Type::kSigned_NumberKind, 2, true))
, fInt_Type(new Type("int", Type::NumberKind::kSigned, 2, true))
, fInt2_Type(new Type("int2", *fInt_Type, 2))
, fInt3_Type(new Type("int3", *fInt_Type, 3))
, fInt4_Type(new Type("int4", *fInt_Type, 4))
, fUShort_Type(new Type("ushort", Type::kUnsigned_NumberKind, 0))
, fUShort_Type(new Type("ushort", Type::NumberKind::kUnsigned, 0))
, fUShort2_Type(new Type("ushort2", *fUShort_Type, 2))
, fUShort3_Type(new Type("ushort3", *fUShort_Type, 3))
, fUShort4_Type(new Type("ushort4", *fUShort_Type, 4))
, fShort_Type(new Type("short", Type::kSigned_NumberKind, 0))
, fShort_Type(new Type("short", Type::NumberKind::kSigned, 0))
, fShort2_Type(new Type("short2", *fShort_Type, 2))
, fShort3_Type(new Type("short3", *fShort_Type, 3))
, fShort4_Type(new Type("short4", *fShort_Type, 4))
, fUByte_Type(new Type("ubyte", Type::kUnsigned_NumberKind, 0))
, fUByte_Type(new Type("ubyte", Type::NumberKind::kUnsigned, 0))
, fUByte2_Type(new Type("ubyte2", *fUByte_Type, 2))
, fUByte3_Type(new Type("ubyte3", *fUByte_Type, 3))
, fUByte4_Type(new Type("ubyte4", *fUByte_Type, 4))
, fByte_Type(new Type("byte", Type::kSigned_NumberKind, 0))
, fByte_Type(new Type("byte", Type::NumberKind::kSigned, 0))
, fByte2_Type(new Type("byte2", *fByte_Type, 2))
, fByte3_Type(new Type("byte3", *fByte_Type, 3))
, fByte4_Type(new Type("byte4", *fByte_Type, 4))
, fBool_Type(new Type("bool", Type::kNonnumeric_NumberKind, -1))
, fBool_Type(new Type("bool", Type::NumberKind::kNonnumeric, -1))
, fBool2_Type(new Type("bool2", *fBool_Type, 2))
, fBool3_Type(new Type("bool3", *fBool_Type, 3))
, fBool4_Type(new Type("bool4", *fBool_Type, 4))
@ -111,7 +111,7 @@ public:
// Related to below FIXME, gsampler*s don't currently expand to cover integer case.
, fISampler2D_Type(new Type("isampler2D", *fITexture2D_Type))
, fSampler_Type(new Type("sampler", Type::kSeparateSampler_Kind))
, fSampler_Type(new Type("sampler", Type::TypeKind::kSeparateSampler))
// FIXME express these as "gimage2D" that expand to image2D, iimage2D, and uimage2D.
, fImage2D_Type(new Type("image2D", SpvDim2D, false, false, false, true))
, fIImage2D_Type(new Type("iimage2D", SpvDim2D, false, false, false, true))
@ -351,7 +351,7 @@ public:
private:
class Defined : public Expression {
public:
static constexpr Kind kExpressionKind = kDefined_Kind;
static constexpr Kind kExpressionKind = Kind::kDefined;
Defined(const Type& type)
: INHERITED(-1, kExpressionKind, type) {}

View File

@ -142,8 +142,8 @@ void Dehydrator::write(const Symbol& s) {
this->writeU16(id);
return;
}
switch (s.fKind) {
case Symbol::kFunctionDeclaration_Kind: {
switch (s.kind()) {
case Symbol::Kind::kFunctionDeclaration: {
const FunctionDeclaration& f = s.as<FunctionDeclaration>();
this->writeU8(Rehydrator::kFunctionDeclaration_Command);
this->writeId(&f);
@ -156,7 +156,7 @@ void Dehydrator::write(const Symbol& s) {
this->write(f.fReturnType);
break;
}
case Symbol::kUnresolvedFunction_Kind: {
case Symbol::Kind::kUnresolvedFunction: {
const UnresolvedFunction& f = s.as<UnresolvedFunction>();
this->writeU8(Rehydrator::kUnresolvedFunction_Command);
this->writeId(&f);
@ -166,26 +166,26 @@ void Dehydrator::write(const Symbol& s) {
}
break;
}
case Symbol::kType_Kind: {
case Symbol::Kind::kType: {
const Type& t = s.as<Type>();
switch (t.kind()) {
case Type::kArray_Kind:
switch (t.typeKind()) {
case Type::TypeKind::kArray:
this->writeU8(Rehydrator::kArrayType_Command);
this->writeId(&t);
this->write(t.componentType());
this->writeU8(t.columns());
break;
case Type::kEnum_Kind:
case Type::TypeKind::kEnum:
this->writeU8(Rehydrator::kEnumType_Command);
this->writeId(&t);
this->write(t.fName);
break;
case Type::kNullable_Kind:
case Type::TypeKind::kNullable:
this->writeU8(Rehydrator::kNullableType_Command);
this->writeId(&t);
this->write(t.componentType());
break;
case Type::kStruct_Kind:
case Type::TypeKind::kStruct:
this->writeU8(Rehydrator::kStructType_Command);
this->writeId(&t);
this->write(t.fName);
@ -203,7 +203,7 @@ void Dehydrator::write(const Symbol& s) {
}
break;
}
case Symbol::kVariable_Kind: {
case Symbol::Kind::kVariable: {
const Variable& v = s.as<Variable>();
this->writeU8(Rehydrator::kVariable_Command);
this->writeId(&v);
@ -213,14 +213,14 @@ void Dehydrator::write(const Symbol& s) {
this->writeU8(v.fStorage);
break;
}
case Symbol::kField_Kind: {
case Symbol::Kind::kField: {
const Field& f = s.as<Field>();
this->writeU8(Rehydrator::kField_Command);
this->writeU16(this->symbolId(&f.fOwner));
this->writeU8(f.fFieldIndex);
break;
}
case Symbol::kExternal_Kind:
case Symbol::Kind::kExternal:
SkASSERT(false);
break;
}
@ -253,8 +253,8 @@ void Dehydrator::write(const SymbolTable& symbols) {
void Dehydrator::write(const Expression* e) {
if (e) {
switch (e->fKind) {
case Expression::kBinary_Kind: {
switch (e->kind()) {
case Expression::Kind::kBinary: {
const BinaryExpression& b = e->as<BinaryExpression>();
this->writeU8(Rehydrator::kBinary_Command);
this->write(b.fLeft.get());
@ -263,13 +263,13 @@ void Dehydrator::write(const Expression* e) {
this->write(b.fType);
break;
}
case Expression::kBoolLiteral_Kind: {
case Expression::Kind::kBoolLiteral: {
const BoolLiteral& b = e->as<BoolLiteral>();
this->writeU8(Rehydrator::kBoolLiteral_Command);
this->writeU8(b.fValue);
break;
}
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
const Constructor& c = e->as<Constructor>();
this->writeU8(Rehydrator::kConstructor_Command);
this->write(c.fType);
@ -279,13 +279,13 @@ void Dehydrator::write(const Expression* e) {
}
break;
}
case Expression::kExternalFunctionCall_Kind:
case Expression::kExternalValue_Kind:
case Expression::Kind::kExternalFunctionCall:
case Expression::Kind::kExternalValue:
// not implemented; doesn't seem like we'll ever need them from within an include
// file
SkASSERT(false);
break;
case Expression::kFieldAccess_Kind: {
case Expression::Kind::kFieldAccess: {
const FieldAccess& f = e->as<FieldAccess>();
this->writeU8(Rehydrator::kFieldAccess_Command);
this->write(f.fBase.get());
@ -293,7 +293,7 @@ void Dehydrator::write(const Expression* e) {
this->writeU8(f.fOwnerKind);
break;
}
case Expression::kFloatLiteral_Kind: {
case Expression::Kind::kFloatLiteral: {
const FloatLiteral& f = e->as<FloatLiteral>();
this->writeU8(Rehydrator::kFloatLiteral_Command);
FloatIntUnion u;
@ -301,7 +301,7 @@ void Dehydrator::write(const Expression* e) {
this->writeS32(u.fInt);
break;
}
case Expression::kFunctionCall_Kind: {
case Expression::Kind::kFunctionCall: {
const FunctionCall& f = e->as<FunctionCall>();
this->writeU8(Rehydrator::kFunctionCall_Command);
this->write(f.fType);
@ -312,44 +312,44 @@ void Dehydrator::write(const Expression* e) {
}
break;
}
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
const IndexExpression& i = e->as<IndexExpression>();
this->writeU8(Rehydrator::kIndex_Command);
this->write(i.fBase.get());
this->write(i.fIndex.get());
break;
}
case Expression::kIntLiteral_Kind: {
case Expression::Kind::kIntLiteral: {
const IntLiteral& i = e->as<IntLiteral>();
this->writeU8(Rehydrator::kIntLiteral_Command);
this->writeS32(i.fValue);
break;
}
case Expression::kNullLiteral_Kind:
case Expression::Kind::kNullLiteral:
this->writeU8(Rehydrator::kNullLiteral_Command);
break;
case Expression::kPostfix_Kind: {
case Expression::Kind::kPostfix: {
const PostfixExpression& p = e->as<PostfixExpression>();
this->writeU8(Rehydrator::kPostfix_Command);
this->writeU8((int) p.fOperator);
this->write(p.fOperand.get());
break;
}
case Expression::kPrefix_Kind: {
case Expression::Kind::kPrefix: {
const PrefixExpression& p = e->as<PrefixExpression>();
this->writeU8(Rehydrator::kPrefix_Command);
this->writeU8((int) p.fOperator);
this->write(p.fOperand.get());
break;
}
case Expression::kSetting_Kind: {
case Expression::Kind::kSetting: {
const Setting& s = e->as<Setting>();
this->writeU8(Rehydrator::kSetting_Command);
this->write(s.fName);
this->write(s.fValue.get());
break;
}
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
const Swizzle& s = e->as<Swizzle>();
this->writeU8(Rehydrator::kSwizzle_Command);
this->write(s.fBase.get());
@ -359,7 +359,7 @@ void Dehydrator::write(const Expression* e) {
}
break;
}
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
const TernaryExpression& t = e->as<TernaryExpression>();
this->writeU8(Rehydrator::kTernary_Command);
this->write(t.fTest.get());
@ -367,16 +367,16 @@ void Dehydrator::write(const Expression* e) {
this->write(t.fIfFalse.get());
break;
}
case Expression::kVariableReference_Kind: {
case Expression::Kind::kVariableReference: {
const VariableReference& v = e->as<VariableReference>();
this->writeU8(Rehydrator::kVariableReference_Command);
this->writeId(&v.fVariable);
this->writeU8(v.fRefKind);
break;
}
case Expression::kFunctionReference_Kind:
case Expression::kTypeReference_Kind:
case Expression::kDefined_Kind:
case Expression::Kind::kFunctionReference:
case Expression::Kind::kTypeReference:
case Expression::Kind::kDefined:
// shouldn't appear in finished code
SkASSERT(false);
break;
@ -388,8 +388,8 @@ void Dehydrator::write(const Expression* e) {
void Dehydrator::write(const Statement* s) {
if (s) {
switch (s->fKind) {
case Statement::kBlock_Kind: {
switch (s->kind()) {
case Statement::Kind::kBlock: {
const Block& b = s->as<Block>();
this->writeU8(Rehydrator::kBlock_Command);
AutoDehydratorSymbolTable symbols(this, b.fSymbols);
@ -400,29 +400,29 @@ void Dehydrator::write(const Statement* s) {
this->writeU8(b.fIsScope);
break;
}
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
this->writeU8(Rehydrator::kBreak_Command);
break;
case Statement::kContinue_Kind:
case Statement::Kind::kContinue:
this->writeU8(Rehydrator::kContinue_Command);
break;
case Statement::kDiscard_Kind:
case Statement::Kind::kDiscard:
this->writeU8(Rehydrator::kDiscard_Command);
break;
case Statement::kDo_Kind: {
case Statement::Kind::kDo: {
const DoStatement& d = s->as<DoStatement>();
this->writeU8(Rehydrator::kDo_Command);
this->write(d.fStatement.get());
this->write(d.fTest.get());
break;
}
case Statement::kExpression_Kind: {
case Statement::Kind::kExpression: {
const ExpressionStatement& e = s->as<ExpressionStatement>();
this->writeU8(Rehydrator::kExpressionStatement_Command);
this->write(e.fExpression.get());
break;
}
case Statement::kFor_Kind: {
case Statement::Kind::kFor: {
const ForStatement& f = s->as<ForStatement>();
this->writeU8(Rehydrator::kFor_Command);
this->write(f.fInitializer.get());
@ -432,7 +432,7 @@ void Dehydrator::write(const Statement* s) {
this->write(f.fSymbols);
break;
}
case Statement::kIf_Kind: {
case Statement::Kind::kIf: {
const IfStatement& i = s->as<IfStatement>();
this->writeU8(Rehydrator::kIf_Command);
this->writeU8(i.fIsStatic);
@ -441,16 +441,16 @@ void Dehydrator::write(const Statement* s) {
this->write(i.fIfFalse.get());
break;
}
case Statement::kNop_Kind:
case Statement::Kind::kNop:
SkASSERT(false);
break;
case Statement::kReturn_Kind: {
case Statement::Kind::kReturn: {
const ReturnStatement& r = s->as<ReturnStatement>();
this->writeU8(Rehydrator::kReturn_Command);
this->write(r.fExpression.get());
break;
}
case Statement::kSwitch_Kind: {
case Statement::Kind::kSwitch: {
const SwitchStatement& ss = s->as<SwitchStatement>();
this->writeU8(Rehydrator::kSwitch_Command);
this->writeU8(ss.fIsStatic);
@ -466,7 +466,7 @@ void Dehydrator::write(const Statement* s) {
}
break;
}
case Statement::kVarDeclaration_Kind: {
case Statement::Kind::kVarDeclaration: {
const VarDeclaration& v = s->as<VarDeclaration>();
this->writeU8(Rehydrator::kVarDeclaration_Command);
this->writeU16(this->symbolId(v.fVar));
@ -477,12 +477,12 @@ void Dehydrator::write(const Statement* s) {
this->write(v.fValue.get());
break;
}
case Statement::kVarDeclarations_Kind: {
case Statement::Kind::kVarDeclarations: {
const VarDeclarationsStatement& v = s->as<VarDeclarationsStatement>();
this->write(*v.fDeclaration);
break;
}
case Statement::kWhile_Kind: {
case Statement::Kind::kWhile: {
const WhileStatement& w = s->as<WhileStatement>();
this->writeU8(Rehydrator::kWhile_Command);
this->write(w.fTest.get());
@ -496,14 +496,14 @@ void Dehydrator::write(const Statement* s) {
}
void Dehydrator::write(const ProgramElement& e) {
switch (e.fKind) {
case ProgramElement::kEnum_Kind: {
switch (e.kind()) {
case ProgramElement::Kind::kEnum: {
const Enum& en = e.as<Enum>();
this->writeU8(Rehydrator::kEnum_Command);
this->write(en.fTypeName);
AutoDehydratorSymbolTable symbols(this, en.fSymbols);
for (const std::unique_ptr<const Symbol>& s : en.fSymbols->fOwnedSymbols) {
SkASSERT(s->fKind == Symbol::kVariable_Kind);
SkASSERT(s->kind() == Symbol::Kind::kVariable);
Variable& v = (Variable&) *s;
SkASSERT(v.fInitialValue);
const IntLiteral& i = v.fInitialValue->as<IntLiteral>();
@ -511,10 +511,10 @@ void Dehydrator::write(const ProgramElement& e) {
}
break;
}
case ProgramElement::kExtension_Kind:
case ProgramElement::Kind::kExtension:
SkASSERT(false);
break;
case ProgramElement::kFunction_Kind: {
case ProgramElement::Kind::kFunction: {
const FunctionDefinition& f = e.as<FunctionDefinition>();
this->writeU8(Rehydrator::kFunctionDefinition_Command);
this->writeU16(this->symbolId(&f.fDeclaration));
@ -529,7 +529,7 @@ void Dehydrator::write(const ProgramElement& e) {
}
break;
}
case ProgramElement::kInterfaceBlock_Kind: {
case ProgramElement::Kind::kInterfaceBlock: {
const InterfaceBlock& i = e.as<InterfaceBlock>();
this->writeU8(Rehydrator::kInterfaceBlock_Command);
this->write(i.fVariable);
@ -541,13 +541,13 @@ void Dehydrator::write(const ProgramElement& e) {
}
break;
}
case ProgramElement::kModifiers_Kind:
case ProgramElement::Kind::kModifiers:
SkASSERT(false);
break;
case ProgramElement::kSection_Kind:
case ProgramElement::Kind::kSection:
SkASSERT(false);
break;
case ProgramElement::kVar_Kind: {
case ProgramElement::Kind::kVar: {
const VarDeclarations& v = e.as<VarDeclarations>();
this->writeU8(Rehydrator::kVarDeclarations_Command);
this->write(v.fBaseType);

View File

@ -17,7 +17,7 @@ class Type;
class ExternalValue : public Symbol {
public:
static constexpr Kind kSymbolKind = kExternal_Kind;
static constexpr Kind kSymbolKind = Kind::kExternal;
ExternalValue(const char* name, const Type& type)
: INHERITED(-1, kSymbolKind, name)

View File

@ -82,8 +82,8 @@ bool GLSLCodeGenerator::usesPrecisionModifiers() const {
}
String GLSLCodeGenerator::getTypeName(const Type& type) {
switch (type.kind()) {
case Type::kVector_Kind: {
switch (type.typeKind()) {
case Type::TypeKind::kVector: {
const Type& component = type.componentType();
String result;
if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) {
@ -104,7 +104,7 @@ String GLSLCodeGenerator::getTypeName(const Type& type) {
result += to_string(type.columns());
return result;
}
case Type::kMatrix_Kind: {
case Type::TypeKind::kMatrix: {
String result;
const Type& component = type.componentType();
if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) {
@ -120,7 +120,7 @@ String GLSLCodeGenerator::getTypeName(const Type& type) {
}
return result;
}
case Type::kArray_Kind: {
case Type::TypeKind::kArray: {
String result = this->getTypeName(type.componentType()) + "[";
if (type.columns() != -1) {
result += to_string(type.columns());
@ -128,7 +128,7 @@ String GLSLCodeGenerator::getTypeName(const Type& type) {
result += "]";
return result;
}
case Type::kScalar_Kind: {
case Type::TypeKind::kScalar: {
if (type == *fContext.fHalf_Type) {
return "float";
}
@ -149,7 +149,7 @@ String GLSLCodeGenerator::getTypeName(const Type& type) {
}
break;
}
case Type::kEnum_Kind:
case Type::TypeKind::kEnum:
return "int";
default:
return type.name();
@ -157,7 +157,7 @@ String GLSLCodeGenerator::getTypeName(const Type& type) {
}
void GLSLCodeGenerator::writeType(const Type& type) {
if (type.kind() == Type::kStruct_Kind) {
if (type.typeKind() == Type::TypeKind::kStruct) {
for (const Type* search : fWrittenStructs) {
if (*search == type) {
// already written
@ -187,47 +187,47 @@ void GLSLCodeGenerator::writeType(const Type& type) {
}
void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) {
switch (expr.fKind) {
case Expression::kBinary_Kind:
switch (expr.kind()) {
case Expression::Kind::kBinary:
this->writeBinaryExpression(expr.as<BinaryExpression>(), parentPrecedence);
break;
case Expression::kBoolLiteral_Kind:
case Expression::Kind::kBoolLiteral:
this->writeBoolLiteral(expr.as<BoolLiteral>());
break;
case Expression::kConstructor_Kind:
case Expression::Kind::kConstructor:
this->writeConstructor(expr.as<Constructor>(), parentPrecedence);
break;
case Expression::kIntLiteral_Kind:
case Expression::Kind::kIntLiteral:
this->writeIntLiteral(expr.as<IntLiteral>());
break;
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
this->writeFieldAccess(expr.as<FieldAccess>());
break;
case Expression::kFloatLiteral_Kind:
case Expression::Kind::kFloatLiteral:
this->writeFloatLiteral(expr.as<FloatLiteral>());
break;
case Expression::kFunctionCall_Kind:
case Expression::Kind::kFunctionCall:
this->writeFunctionCall(expr.as<FunctionCall>());
break;
case Expression::kPrefix_Kind:
case Expression::Kind::kPrefix:
this->writePrefixExpression(expr.as<PrefixExpression>(), parentPrecedence);
break;
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
this->writePostfixExpression(expr.as<PostfixExpression>(), parentPrecedence);
break;
case Expression::kSetting_Kind:
case Expression::Kind::kSetting:
this->writeSetting(expr.as<Setting>());
break;
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
this->writeSwizzle(expr.as<Swizzle>());
break;
case Expression::kVariableReference_Kind:
case Expression::Kind::kVariableReference:
this->writeVariableReference(expr.as<VariableReference>());
break;
case Expression::kTernary_Kind:
case Expression::Kind::kTernary:
this->writeTernaryExpression(expr.as<TernaryExpression>(), parentPrecedence);
break;
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
this->writeIndexExpression(expr.as<IndexExpression>());
break;
default:
@ -239,7 +239,7 @@ void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence paren
}
static bool is_abs(Expression& expr) {
if (expr.fKind != Expression::kFunctionCall_Kind) {
if (expr.kind() != Expression::Kind::kFunctionCall) {
return false;
}
return expr.as<FunctionCall>().fFunction.fName == "abs";
@ -506,7 +506,7 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
case FunctionClass::kAtan:
if (fProgram.fSettings.fCaps->mustForceNegatedAtanParamToFloat() &&
c.fArguments.size() == 2 &&
c.fArguments[1]->fKind == Expression::kPrefix_Kind) {
c.fArguments[1]->kind() == Expression::Kind::kPrefix) {
const PrefixExpression& p = (PrefixExpression&) *c.fArguments[1];
if (p.fOperator == Token::Kind::TK_MINUS) {
this->write("atan(");
@ -713,7 +713,7 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
void GLSLCodeGenerator::writeConstructor(const Constructor& c, Precedence parentPrecedence) {
if (c.fArguments.size() == 1 &&
(this->getTypeName(c.fType) == this->getTypeName(c.fArguments[0]->fType) ||
(c.fType.kind() == Type::kScalar_Kind &&
(c.fType.typeKind() == Type::TypeKind::kScalar &&
c.fArguments[0]->fType == *fContext.fFloatLiteral_Type))) {
// in cases like half(float), they're different types as far as SkSL is concerned but the
// same type as far as GLSL is concerned. We avoid a redundant float(float) by just writing
@ -1097,7 +1097,7 @@ void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
}
bool positionWorkaround = fProgramKind == Program::Kind::kVertex_Kind &&
Compiler::IsAssignment(b.fOperator) &&
Expression::kFieldAccess_Kind == b.fLeft->fKind &&
b.fLeft->kind() == Expression::Kind::kFieldAccess &&
is_sk_position((FieldAccess&) *b.fLeft) &&
!b.fRight->containsRTAdjust() &&
!fProgram.fSettings.fCaps->canUseFragCoord();
@ -1227,7 +1227,7 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
this->writeModifiers(param->fModifiers, false);
std::vector<int> sizes;
const Type* type = &param->fType;
while (type->kind() == Type::kArray_Kind) {
while (type->typeKind() == Type::TypeKind::kArray) {
sizes.push_back(type->columns());
type = &type->componentType();
}
@ -1350,7 +1350,7 @@ void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
this->writeLine(intf.fTypeName + " {");
fIndentation++;
const Type* structType = &intf.fVariable.fType;
while (structType->kind() == Type::kArray_Kind) {
while (structType->typeKind() == Type::TypeKind::kArray) {
structType = &structType->componentType();
}
for (const auto& f : structType->fields()) {
@ -1381,8 +1381,8 @@ void GLSLCodeGenerator::writeVarInitializer(const Variable& var, const Expressio
const char* GLSLCodeGenerator::getTypePrecision(const Type& type) {
if (usesPrecisionModifiers()) {
switch (type.kind()) {
case Type::kScalar_Kind:
switch (type.typeKind()) {
case Type::TypeKind::kScalar:
if (type == *fContext.fShort_Type || type == *fContext.fUShort_Type ||
type == *fContext.fByte_Type || type == *fContext.fUByte_Type) {
if (fProgram.fSettings.fForceHighPrecision ||
@ -1399,8 +1399,8 @@ const char* GLSLCodeGenerator::getTypePrecision(const Type& type) {
return "highp ";
}
return "";
case Type::kVector_Kind: // fall through
case Type::kMatrix_Kind:
case Type::TypeKind::kVector: // fall through
case Type::TypeKind::kMatrix:
return this->getTypePrecision(type.componentType());
default:
break;
@ -1461,45 +1461,45 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g
}
void GLSLCodeGenerator::writeStatement(const Statement& s) {
switch (s.fKind) {
case Statement::kBlock_Kind:
switch (s.kind()) {
case Statement::Kind::kBlock:
this->writeBlock(s.as<Block>());
break;
case Statement::kExpression_Kind:
case Statement::Kind::kExpression:
this->writeExpression(*s.as<ExpressionStatement>().fExpression, kTopLevel_Precedence);
this->write(";");
break;
case Statement::kReturn_Kind:
case Statement::Kind::kReturn:
this->writeReturnStatement(s.as<ReturnStatement>());
break;
case Statement::kVarDeclarations_Kind:
case Statement::Kind::kVarDeclarations:
this->writeVarDeclarations(*s.as<VarDeclarationsStatement>().fDeclaration, false);
break;
case Statement::kIf_Kind:
case Statement::Kind::kIf:
this->writeIfStatement(s.as<IfStatement>());
break;
case Statement::kFor_Kind:
case Statement::Kind::kFor:
this->writeForStatement(s.as<ForStatement>());
break;
case Statement::kWhile_Kind:
case Statement::Kind::kWhile:
this->writeWhileStatement(s.as<WhileStatement>());
break;
case Statement::kDo_Kind:
case Statement::Kind::kDo:
this->writeDoStatement(s.as<DoStatement>());
break;
case Statement::kSwitch_Kind:
case Statement::Kind::kSwitch:
this->writeSwitchStatement(s.as<SwitchStatement>());
break;
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
this->write("break;");
break;
case Statement::kContinue_Kind:
case Statement::Kind::kContinue:
this->write("continue;");
break;
case Statement::kDiscard_Kind:
case Statement::Kind::kDiscard:
this->write("discard;");
break;
case Statement::kNop_Kind:
case Statement::Kind::kNop:
this->write(";");
break;
default:
@ -1667,11 +1667,11 @@ void GLSLCodeGenerator::writeHeader() {
}
void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
switch (e.fKind) {
case ProgramElement::kExtension_Kind:
switch (e.kind()) {
case ProgramElement::Kind::kExtension:
this->writeExtension(e.as<Extension>().fName);
break;
case ProgramElement::kVar_Kind: {
case ProgramElement::Kind::kVar: {
const VarDeclarations& decl = e.as<VarDeclarations>();
if (decl.fVars.size() > 0) {
int builtin = decl.fVars[0]->as<VarDeclaration>().fVar->fModifiers.fLayout.fBuiltin;
@ -1695,13 +1695,13 @@ void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
}
break;
}
case ProgramElement::kInterfaceBlock_Kind:
case ProgramElement::Kind::kInterfaceBlock:
this->writeInterfaceBlock(e.as<InterfaceBlock>());
break;
case ProgramElement::kFunction_Kind:
case ProgramElement::Kind::kFunction:
this->writeFunction(e.as<FunctionDefinition>());
break;
case ProgramElement::kModifiers_Kind: {
case ProgramElement::Kind::kModifiers: {
const Modifiers& modifiers = e.as<ModifiersDeclaration>().fModifiers;
if (!fFoundGSInvocations && modifiers.fLayout.fInvocations >= 0) {
if (fProgram.fSettings.fCaps->gsInvocationsExtensionString()) {
@ -1713,7 +1713,7 @@ void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
this->writeLine(";");
break;
}
case ProgramElement::kEnum_Kind:
case ProgramElement::Kind::kEnum:
break;
default:
#ifdef SK_DEBUG

View File

@ -33,7 +33,7 @@ HCodeGenerator::HCodeGenerator(const Context* context, const Program* program,
String HCodeGenerator::ParameterType(const Context& context, const Type& type,
const Layout& layout) {
if (type.kind() == Type::kArray_Kind) {
if (type.typeKind() == Type::TypeKind::kArray) {
return String::printf("std::array<%s>", ParameterType(context, type.componentType(),
layout).c_str());
}
@ -46,11 +46,11 @@ String HCodeGenerator::ParameterType(const Context& context, const Type& type,
Layout::CType HCodeGenerator::ParameterCType(const Context& context, const Type& type,
const Layout& layout) {
SkASSERT(type.kind() != Type::kArray_Kind);
SkASSERT(type.typeKind() != Type::TypeKind::kArray);
if (layout.fCType != Layout::CType::kDefault) {
return layout.fCType;
}
if (type.kind() == Type::kNullable_Kind) {
if (type.typeKind() == Type::TypeKind::kNullable) {
return ParameterCType(context, type.componentType(), layout);
} else if (type == *context.fFloat_Type || type == *context.fHalf_Type) {
return Layout::CType::kFloat;
@ -74,7 +74,7 @@ Layout::CType HCodeGenerator::ParameterCType(const Context& context, const Type&
return Layout::CType::kSkMatrix;
} else if (type == *context.fFloat4x4_Type || type == *context.fHalf4x4_Type) {
return Layout::CType::kSkM44;
} else if (type.kind() == Type::kSampler_Kind) {
} else if (type.typeKind() == Type::TypeKind::kSampler) {
return Layout::CType::kGrSurfaceProxyView;
} else if (type == *context.fFragmentProcessor_Type) {
return Layout::CType::kGrFragmentProcessor;
@ -84,7 +84,7 @@ Layout::CType HCodeGenerator::ParameterCType(const Context& context, const Type&
String HCodeGenerator::FieldType(const Context& context, const Type& type,
const Layout& layout) {
if (type.kind() == Type::kSampler_Kind) {
if (type.typeKind() == Type::TypeKind::kSampler) {
return "TextureSampler";
} else if (type == *context.fFragmentProcessor_Type) {
// we don't store fragment processors in fields, they get registered via
@ -201,7 +201,7 @@ void HCodeGenerator::writeMake() {
separator = "";
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type ||
param->fType.nonnullable().kind() == Type::kSampler_Kind) {
param->fType.nonnullable().typeKind() == Type::TypeKind::kSampler) {
this->writef("%sstd::move(%s)", separator, String(param->fName).c_str());
} else {
this->writef("%s%s", separator, String(param->fName).c_str());
@ -250,7 +250,7 @@ void HCodeGenerator::writeConstructor() {
String nameString(param->fName);
const char* name = nameString.c_str();
const Type& type = param->fType.nonnullable();
if (type.kind() == Type::kSampler_Kind) {
if (type.typeKind() == Type::TypeKind::kSampler) {
this->writef("\n , %s(std::move(%s)", FieldName(name).c_str(), name);
for (const Section* s : fSectionAndParameterHelper.getSections(
kSamplerParamsSection)) {
@ -274,10 +274,10 @@ void HCodeGenerator::writeConstructor() {
int samplerCount = 0;
for (const Variable* param : fSectionAndParameterHelper.getParameters()) {
if (param->fType.kind() == Type::kSampler_Kind) {
if (param->fType.typeKind() == Type::TypeKind::kSampler) {
++samplerCount;
} else if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
if (param->fType.kind() != Type::kNullable_Kind) {
if (param->fType.typeKind() != Type::TypeKind::kNullable) {
this->writef(" SkASSERT(%s);", String(param->fName).c_str());
}
@ -355,7 +355,7 @@ bool HCodeGenerator::generateCode() {
"public:\n",
fFullName.c_str());
for (const auto& p : fProgram) {
if (ProgramElement::kEnum_Kind == p.fKind && !((Enum&) p).fBuiltin) {
if (p.kind() == ProgramElement::Kind::kEnum && !((Enum&) p).fBuiltin) {
this->writef("%s\n", ((Enum&) p).code().c_str());
}
}
@ -374,7 +374,7 @@ bool HCodeGenerator::generateCode() {
"GrProcessorKeyBuilder*) const override;\n"
" bool onIsEqual(const GrFragmentProcessor&) const override;\n");
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
if (param->fType.kind() == Type::kSampler_Kind) {
if (param->fType.typeKind() == Type::TypeKind::kSampler) {
this->writef(" const TextureSampler& onTextureSampler(int) const override;");
break;
}

View File

@ -185,7 +185,7 @@ void IRGenerator::start(const Program::Settings* settings,
fTmpSwizzleCounter = 0;
if (inherited) {
for (const auto& e : *inherited) {
if (e->fKind == ProgramElement::kInterfaceBlock_Kind) {
if (e->kind() == ProgramElement::Kind::kInterfaceBlock) {
InterfaceBlock& intf = e->as<InterfaceBlock>();
if (intf.fVariable.fName == Compiler::PERVERTEX_NAME) {
SkASSERT(!fSkPerVertex);
@ -243,10 +243,10 @@ std::unique_ptr<Statement> IRGenerator::convertSingleStatement(const ASTNode& st
default:
// it's an expression
std::unique_ptr<Statement> result = this->convertExpressionStatement(statement);
if (fRTAdjust && Program::kGeometry_Kind == fKind) {
SkASSERT(result->fKind == Statement::kExpression_Kind);
if (fRTAdjust && fKind == Program::kGeometry_Kind) {
SkASSERT(result->kind() == Statement::Kind::kExpression);
Expression& expr = *result->as<ExpressionStatement>().fExpression;
if (expr.fKind == Expression::kFunctionCall_Kind) {
if (expr.kind() == Expression::Kind::kFunctionCall) {
FunctionCall& fc = expr.as<FunctionCall>();
if (fc.fFunction.fBuiltin && fc.fFunction.fName == "EmitVertex") {
std::vector<std::unique_ptr<Statement>> statements;
@ -320,7 +320,7 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTNo
}
if (fKind != Program::kFragmentProcessor_Kind) {
if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
baseType->kind() == Type::Kind::kMatrix_Kind) {
baseType->typeKind() == Type::TypeKind::kMatrix) {
fErrors.error(decls.fOffset, "'in' variables may not have matrix type");
}
if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
@ -370,10 +370,10 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTNo
"'srgb_unpremul' is only permitted on 'uniform' variables");
}
auto validColorXformType = [](const Type& t) {
return t.kind() == Type::kVector_Kind && t.componentType().isFloat() &&
return t.typeKind() == Type::TypeKind::kVector && t.componentType().isFloat() &&
(t.columns() == 3 || t.columns() == 4);
};
if (!validColorXformType(*baseType) && !(baseType->kind() == Type::kArray_Kind &&
if (!validColorXformType(*baseType) && !(baseType->typeKind() == Type::TypeKind::kArray &&
validColorXformType(baseType->componentType()))) {
fErrors.error(decls.fOffset,
"'srgb_unpremul' is only permitted on half3, half4, float3, or float4 "
@ -385,7 +385,8 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTNo
fErrors.error(decls.fOffset, "'varying' is only permitted in runtime effects");
}
if (!baseType->isFloat() &&
!(baseType->kind() == Type::kVector_Kind && baseType->componentType().isFloat())) {
!(baseType->typeKind() == Type::TypeKind::kVector &&
baseType->componentType().isFloat())) {
fErrors.error(decls.fOffset, "'varying' must be float scalar or vector");
}
}
@ -421,7 +422,7 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTNo
}
String name(type->fName);
int64_t count;
if (size->fKind == Expression::kIntLiteral_Kind) {
if (size->kind() == Expression::Kind::kIntLiteral) {
count = size->as<IntLiteral>().fValue;
if (count <= 0) {
fErrors.error(size->fOffset, "array size must be positive");
@ -433,11 +434,11 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTNo
return nullptr;
}
type = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Type>(name, Type::kArray_Kind, *type, (int)count));
std::make_unique<Type>(name, Type::TypeKind::kArray, *type, (int)count));
sizes.push_back(std::move(size));
} else {
type = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Type>(
type->name() + "[]", Type::kArray_Kind, *type, /*columns=*/-1));
type->name() + "[]", Type::TypeKind::kArray, *type, /*columns=*/-1));
sizes.push_back(nullptr);
}
}
@ -465,7 +466,7 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTNo
if (symbol && storage == Variable::kGlobal_Storage && var->fName == "sk_FragColor") {
// Already defined, ignore.
} else if (symbol && storage == Variable::kGlobal_Storage &&
symbol->fKind == Symbol::kVariable_Kind &&
symbol->kind() == Symbol::Kind::kVariable &&
symbol->as<Variable>().fModifiers.fLayout.fBuiltin >= 0) {
// Already defined, just update the modifiers.
symbol->as<Variable>().fModifiers = var->fModifiers;
@ -514,7 +515,7 @@ std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration(c
static void ensure_scoped_blocks(Statement* stmt) {
// No changes necessary if this statement isn't actually a block.
if (stmt->fKind != Statement::kBlock_Kind) {
if (stmt->kind() != Statement::Kind::kBlock) {
return;
}
@ -538,7 +539,7 @@ static void ensure_scoped_blocks(Statement* stmt) {
block.fIsScope = true;
return;
}
if (nestedBlock->fStatements[0]->fKind != Statement::kBlock_Kind) {
if (nestedBlock->fStatements[0]->kind() != Statement::Kind::kBlock) {
// This block has exactly one thing inside, and it's not another block. No need to scope
// it.
return;
@ -569,7 +570,7 @@ std::unique_ptr<Statement> IRGenerator::convertIf(const ASTNode& n) {
}
ensure_scoped_blocks(ifFalse.get());
}
if (test->fKind == Expression::kBoolLiteral_Kind) {
if (test->kind() == Expression::Kind::kBoolLiteral) {
// static boolean value, fold down to a single branch
if (test->as<BoolLiteral>().fValue) {
return ifTrue;
@ -674,7 +675,8 @@ std::unique_ptr<Statement> IRGenerator::convertSwitch(const ASTNode& s) {
if (!value) {
return nullptr;
}
if (value->fType != *fContext.fUInt_Type && value->fType.kind() != Type::kEnum_Kind) {
if (value->fType != *fContext.fUInt_Type &&
value->fType.typeKind() != Type::TypeKind::kEnum) {
value = this->coerce(std::move(value), *fContext.fInt_Type);
if (!value) {
return nullptr;
@ -972,7 +974,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
int size = (param.begin() + j)->getInt();
String name = type->name() + "[" + to_string(size) + "]";
type = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Type>(std::move(name), Type::kArray_Kind, *type, size));
std::make_unique<Type>(std::move(name), Type::TypeKind::kArray, *type, size));
}
// Only the (builtin) declarations of 'sample' are allowed to have FP parameters
if ((type->nonnullable() == *fContext.fFragmentProcessor_Type && !fIsBuiltinCode) ||
@ -1029,11 +1031,11 @@ void IRGenerator::convertFunction(const ASTNode& f) {
const Symbol* entry = (*fSymbolTable)[funcData.fName];
if (entry) {
std::vector<const FunctionDeclaration*> functions;
switch (entry->fKind) {
case Symbol::kUnresolvedFunction_Kind:
switch (entry->kind()) {
case Symbol::Kind::kUnresolvedFunction:
functions = entry->as<UnresolvedFunction>().fFunctions;
break;
case Symbol::kFunctionDeclaration_Kind:
case Symbol::Kind::kFunctionDeclaration:
functions.push_back(&entry->as<FunctionDeclaration>());
break;
default:
@ -1172,7 +1174,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
fErrors.error(decl->fOffset,
"initializers are not permitted on interface block fields");
}
if (vd.fVar->fType.kind() == Type::kArray_Kind &&
if (vd.fVar->fType.typeKind() == Type::TypeKind::kArray &&
vd.fVar->fType.columns() == -1) {
haveRuntimeArray = true;
}
@ -1191,7 +1193,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
}
String name = type->fName;
int64_t count;
if (converted->fKind == Expression::kIntLiteral_Kind) {
if (converted->kind() == Expression::Kind::kIntLiteral) {
count = converted->as<IntLiteral>().fValue;
if (count <= 0) {
fErrors.error(converted->fOffset, "array size must be positive");
@ -1203,7 +1205,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
return nullptr;
}
type = symbols->takeOwnershipOfSymbol(
std::make_unique<Type>(name, Type::kArray_Kind, *type, (int)count));
std::make_unique<Type>(name, Type::TypeKind::kArray, *type, (int)count));
sizes.push_back(std::move(converted));
} else {
fErrors.error(intf.fOffset, "array size must be specified");
@ -1235,11 +1237,11 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
}
bool IRGenerator::getConstantInt(const Expression& value, int64_t* out) {
switch (value.fKind) {
case Expression::kIntLiteral_Kind:
switch (value.kind()) {
case Expression::Kind::kIntLiteral:
*out = static_cast<const IntLiteral&>(value).fValue;
return true;
case Expression::kVariableReference_Kind: {
case Expression::Kind::kVariableReference: {
const Variable& var = static_cast<const VariableReference&>(value).fVariable;
return (var.fModifiers.fFlags & Modifiers::kConst_Flag) &&
var.fInitialValue &&
@ -1292,7 +1294,7 @@ void IRGenerator::convertEnum(const ASTNode& e) {
const Type* IRGenerator::convertType(const ASTNode& type) {
ASTNode::TypeData td = type.getTypeData();
const Symbol* result = (*fSymbolTable)[td.fName];
if (result && result->fKind == Symbol::kType_Kind) {
if (result && result->kind() == Symbol::Kind::kType) {
if (td.fIsNullable) {
if (result->as<Type>() == *fContext.fFragmentProcessor_Type) {
if (type.begin() != type.end()) {
@ -1300,7 +1302,7 @@ const Type* IRGenerator::convertType(const ASTNode& type) {
"an array");
}
result = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Type>(
String(result->fName) + "?", Type::kNullable_Kind, result->as<Type>()));
String(result->fName) + "?", Type::TypeKind::kNullable, result->as<Type>()));
} else {
fErrors.error(type.fOffset, "type '" + td.fName + "' may not be nullable");
}
@ -1313,7 +1315,7 @@ const Type* IRGenerator::convertType(const ASTNode& type) {
}
name += "]";
result = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Type>(
name, Type::kArray_Kind, result->as<Type>(), size ? size.getInt() : 0));
name, Type::TypeKind::kArray, result->as<Type>(), size ? size.getInt() : 0));
}
return &result->as<Type>();
}
@ -1365,18 +1367,18 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identi
fErrors.error(identifier.fOffset, "unknown identifier '" + identifier.getString() + "'");
return nullptr;
}
switch (result->fKind) {
case Symbol::kFunctionDeclaration_Kind: {
switch (result->kind()) {
case Symbol::Kind::kFunctionDeclaration: {
std::vector<const FunctionDeclaration*> f = {
&result->as<FunctionDeclaration>()
};
return std::make_unique<FunctionReference>(fContext, identifier.fOffset, f);
}
case Symbol::kUnresolvedFunction_Kind: {
case Symbol::Kind::kUnresolvedFunction: {
const UnresolvedFunction* f = &result->as<UnresolvedFunction>();
return std::make_unique<FunctionReference>(fContext, identifier.fOffset, f->fFunctions);
}
case Symbol::kVariable_Kind: {
case Symbol::Kind::kVariable: {
const Variable* var = &result->as<Variable>();
switch (var->fModifiers.fLayout.fBuiltin) {
case SK_WIDTH_BUILTIN:
@ -1401,7 +1403,7 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identi
!var->fModifiers.fLayout.fKey &&
var->fModifiers.fLayout.fBuiltin == -1 &&
var->fType.nonnullable() != *fContext.fFragmentProcessor_Type &&
var->fType.kind() != Type::kSampler_Kind) {
var->fType.typeKind() != Type::TypeKind::kSampler) {
bool valid = false;
for (const auto& decl : fFile->root()) {
if (decl.fKind == ASTNode::Kind::kSection) {
@ -1423,7 +1425,7 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identi
*var,
VariableReference::kRead_RefKind);
}
case Symbol::kField_Kind: {
case Symbol::Kind::kField: {
const Field* field = &result->as<Field>();
VariableReference* base = new VariableReference(identifier.fOffset, field->fOwner,
VariableReference::kRead_RefKind);
@ -1432,16 +1434,16 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identi
field->fFieldIndex,
FieldAccess::kAnonymousInterfaceBlock_OwnerKind));
}
case Symbol::kType_Kind: {
case Symbol::Kind::kType: {
const Type* t = &result->as<Type>();
return std::make_unique<TypeReference>(fContext, identifier.fOffset, *t);
return std::make_unique<TypeReference>(fContext, identifier.fOffset, t);
}
case Symbol::kExternal_Kind: {
case Symbol::Kind::kExternal: {
const ExternalValue* r = &result->as<ExternalValue>();
return std::make_unique<ExternalValueReference>(identifier.fOffset, r);
}
default:
ABORT("unsupported symbol type %d\n", result->fKind);
ABORT("unsupported symbol type %d\n", (int) result->kind());
}
}
@ -1474,7 +1476,7 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr
expr->fType.displayName() + "'");
return nullptr;
}
if (type.kind() == Type::kScalar_Kind) {
if (type.typeKind() == Type::TypeKind::kScalar) {
std::vector<std::unique_ptr<Expression>> args;
args.push_back(std::move(expr));
std::unique_ptr<Expression> ctor;
@ -1494,8 +1496,8 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr
SkASSERT(ctor);
return this->call(-1, std::move(ctor), std::move(args));
}
if (expr->fKind == Expression::kNullLiteral_Kind) {
SkASSERT(type.kind() == Type::kNullable_Kind);
if (expr->kind() == Expression::Kind::kNullLiteral) {
SkASSERT(type.typeKind() == Type::TypeKind::kNullable);
return std::unique_ptr<Expression>(new NullLiteral(expr->fOffset, type));
}
std::vector<std::unique_ptr<Expression>> args;
@ -1504,10 +1506,12 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr
}
static bool is_matrix_multiply(const Type& left, const Type& right) {
if (left.kind() == Type::kMatrix_Kind) {
return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVector_Kind;
if (left.typeKind() == Type::TypeKind::kMatrix) {
return right.typeKind() == Type::TypeKind::kMatrix ||
right.typeKind() == Type::TypeKind::kVector;
}
return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Kind;
return left.typeKind() == Type::TypeKind::kVector &&
right.typeKind() == Type::TypeKind::kMatrix;
}
/**
@ -1563,7 +1567,7 @@ static bool determine_binary_type(const Context& context,
return left.canCoerceTo(*context.fBool_Type) &&
right.canCoerceTo(*context.fBool_Type);
case Token::Kind::TK_STAREQ:
if (left.kind() == Type::kScalar_Kind) {
if (left.typeKind() == Type::TypeKind::kScalar) {
*outLeftType = &left;
*outRightType = &left;
*outResultType = &left;
@ -1584,7 +1588,7 @@ static bool determine_binary_type(const Context& context,
int leftRows = left.rows();
int rightColumns;
int rightRows;
if (right.kind() == Type::kVector_Kind) {
if (right.typeKind() == Type::TypeKind::kVector) {
// matrix * vector treats the vector as a column vector, so we need to
// transpose it
rightColumns = right.rows();
@ -1616,7 +1620,7 @@ static bool determine_binary_type(const Context& context,
case Token::Kind::TK_PERCENTEQ:
case Token::Kind::TK_SHLEQ:
case Token::Kind::TK_SHREQ:
if (left.kind() == Type::kScalar_Kind) {
if (left.typeKind() == Type::TypeKind::kScalar) {
*outLeftType = &left;
*outRightType = &left;
*outResultType = &left;
@ -1638,8 +1642,9 @@ static bool determine_binary_type(const Context& context,
isLogical = false;
validMatrixOrVectorOp = false;
}
bool isVectorOrMatrix = left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind;
if (left.kind() == Type::kScalar_Kind && right.kind() == Type::kScalar_Kind &&
bool isVectorOrMatrix = left.typeKind() == Type::TypeKind::kVector ||
left.typeKind() == Type::TypeKind::kMatrix;
if (left.typeKind() == Type::TypeKind::kScalar && right.typeKind() == Type::TypeKind::kScalar &&
right.canCoerceTo(left)) {
if (left.priority() > right.priority()) {
*outLeftType = &left;
@ -1665,8 +1670,9 @@ static bool determine_binary_type(const Context& context,
}
return true;
}
if ((left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind) &&
(right.kind() == Type::kScalar_Kind)) {
if ((left.typeKind() == Type::TypeKind::kVector ||
left.typeKind() == Type::TypeKind::kMatrix) &&
(right.typeKind() == Type::TypeKind::kScalar)) {
if (determine_binary_type(context, op, left.componentType(), right, outLeftType,
outRightType, outResultType, false)) {
*outLeftType = &(*outLeftType)->toCompound(context, left.columns(), left.rows());
@ -1689,7 +1695,7 @@ static std::unique_ptr<Expression> short_circuit_boolean(const Context& context,
const Expression& left,
Token::Kind op,
const Expression& right) {
SkASSERT(left.fKind == Expression::kBoolLiteral_Kind);
SkASSERT(left.kind() == Expression::Kind::kBoolLiteral);
bool leftVal = left.as<BoolLiteral>().fValue;
if (op == Token::Kind::TK_LOGICALAND) {
// (true && expr) -> (expr) and (false && expr) -> (false)
@ -1715,9 +1721,9 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
const Expression& right) const {
// If the left side is a constant boolean literal, the right side does not need to be constant
// for short circuit optimizations to allow the constant to be folded.
if (left.fKind == Expression::kBoolLiteral_Kind && !right.isCompileTimeConstant()) {
if (left.kind() == Expression::Kind::kBoolLiteral && !right.isCompileTimeConstant()) {
return short_circuit_boolean(fContext, left, op, right);
} else if (right.fKind == Expression::kBoolLiteral_Kind && !left.isCompileTimeConstant()) {
} else if (right.kind() == Expression::Kind::kBoolLiteral && !left.isCompileTimeConstant()) {
// There aren't side effects in SKSL within expressions, so (left OP right) is equivalent to
// (right OP left) for short-circuit optimizations
return short_circuit_boolean(fContext, right, op, left);
@ -1731,8 +1737,8 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
// precision to calculate the results and hope the result makes sense. The plan is to move the
// Skia caps into SkSL, so we have access to all of them including the precisions of the various
// types, which will let us be more intelligent about this.
if (left.fKind == Expression::kBoolLiteral_Kind &&
right.fKind == Expression::kBoolLiteral_Kind) {
if (left.kind() == Expression::Kind::kBoolLiteral &&
right.kind() == Expression::Kind::kBoolLiteral) {
bool leftVal = left.as<BoolLiteral>().fValue;
bool rightVal = right.as<BoolLiteral>().fValue;
bool result;
@ -1749,7 +1755,8 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
#define URESULT(t, op) std::make_unique<t ## Literal>(fContext, left.fOffset, \
(uint32_t) leftVal op \
(uint32_t) rightVal)
if (left.fKind == Expression::kIntLiteral_Kind && right.fKind == Expression::kIntLiteral_Kind) {
if (left.kind() == Expression::Kind::kIntLiteral &&
right.kind() == Expression::Kind::kIntLiteral) {
int64_t leftVal = left.as<IntLiteral>().fValue;
int64_t rightVal = right.as<IntLiteral>().fValue;
switch (op) {
@ -1802,8 +1809,8 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
return nullptr;
}
}
if (left.fKind == Expression::kFloatLiteral_Kind &&
right.fKind == Expression::kFloatLiteral_Kind) {
if (left.kind() == Expression::Kind::kFloatLiteral &&
right.kind() == Expression::Kind::kFloatLiteral) {
double leftVal = left.as<FloatLiteral>().fValue;
double rightVal = right.as<FloatLiteral>().fValue;
switch (op) {
@ -1825,7 +1832,7 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
default: return nullptr;
}
}
if (left.fType.kind() == Type::kVector_Kind && left.fType.componentType().isFloat() &&
if (left.fType.typeKind() == Type::TypeKind::kVector && left.fType.componentType().isFloat() &&
left.fType == right.fType) {
std::vector<std::unique_ptr<Expression>> args;
#define RETURN_VEC_COMPONENTWISE_RESULT(op) \
@ -1858,12 +1865,13 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
}
return std::unique_ptr<Expression>(new Constructor(-1, left.fType,
std::move(args)));
default: return nullptr;
default:
return nullptr;
}
}
if (left.fType.kind() == Type::kMatrix_Kind &&
right.fType.kind() == Type::kMatrix_Kind &&
left.fKind == right.fKind) {
if (left.fType.typeKind() == Type::TypeKind::kMatrix &&
right.fType.typeKind() == Type::TypeKind::kMatrix &&
left.kind() == right.kind()) {
switch (op) {
case Token::Kind::TK_EQEQ:
return std::unique_ptr<Expression>(new BoolLiteral(fContext, -1,
@ -1902,13 +1910,13 @@ std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(const ASTNode&
const Type* rightType;
const Type* resultType;
const Type* rawLeftType;
if (left->fKind == Expression::kIntLiteral_Kind && right->fType.isInteger()) {
if (left->kind() == Expression::Kind::kIntLiteral && right->fType.isInteger()) {
rawLeftType = &right->fType;
} else {
rawLeftType = &left->fType;
}
const Type* rawRightType;
if (right->fKind == Expression::kIntLiteral_Kind && left->fType.isInteger()) {
if (right->kind() == Expression::Kind::kIntLiteral && left->fType.isInteger()) {
rawRightType = &left->fType;
} else {
rawRightType = &right->fType;
@ -1985,7 +1993,7 @@ std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(const ASTNode&
if (!ifFalse) {
return nullptr;
}
if (test->fKind == Expression::kBoolLiteral_Kind) {
if (test->kind() == Expression::Kind::kBoolLiteral) {
// static boolean test, just return one of the branches
if (test->as<BoolLiteral>().fValue) {
return ifTrue;
@ -2108,12 +2116,12 @@ int IRGenerator::callCost(const FunctionDeclaration& function,
std::unique_ptr<Expression> IRGenerator::call(int offset,
std::unique_ptr<Expression> functionValue,
std::vector<std::unique_ptr<Expression>> arguments) {
switch (functionValue->fKind) {
case Expression::kTypeReference_Kind:
switch (functionValue->kind()) {
case Expression::Kind::kTypeReference:
return this->convertConstructor(offset,
functionValue->as<TypeReference>().fValue,
std::move(arguments));
case Expression::kExternalValue_Kind: {
case Expression::Kind::kExternalValue: {
const ExternalValue* v = functionValue->as<ExternalValueReference>().fValue;
if (!v->canCall()) {
fErrors.error(offset, "this external value is not a function");
@ -2135,10 +2143,10 @@ std::unique_ptr<Expression> IRGenerator::call(int offset,
return nullptr;
}
}
return std::unique_ptr<Expression>(new ExternalFunctionCall(offset, v->callReturnType(),
v, std::move(arguments)));
return std::make_unique<ExternalFunctionCall>(offset, v->callReturnType(), v,
std::move(arguments));
}
case Expression::kFunctionReference_Kind: {
case Expression::Kind::kFunctionReference: {
const FunctionReference& ref = functionValue->as<FunctionReference>();
int bestCost = INT_MAX;
const FunctionDeclaration* best = nullptr;
@ -2186,15 +2194,15 @@ std::unique_ptr<Expression> IRGenerator::convertNumberConstructor(
if (type == args[0]->fType) {
return std::move(args[0]);
}
if (type.isFloat() && args.size() == 1 && args[0]->fKind == Expression::kFloatLiteral_Kind) {
if (type.isFloat() && args.size() == 1 && args[0]->kind() == Expression::Kind::kFloatLiteral) {
double value = args[0]->as<FloatLiteral>().fValue;
return std::unique_ptr<Expression>(new FloatLiteral(offset, value, &type));
}
if (type.isFloat() && args.size() == 1 && args[0]->fKind == Expression::kIntLiteral_Kind) {
if (type.isFloat() && args.size() == 1 && args[0]->kind() == Expression::Kind::kIntLiteral) {
int64_t value = args[0]->as<IntLiteral>().fValue;
return std::unique_ptr<Expression>(new FloatLiteral(offset, (double) value, &type));
}
if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext.fInt_Type ||
if (args[0]->kind() == Expression::Kind::kIntLiteral && (type == *fContext.fInt_Type ||
type == *fContext.fUInt_Type)) {
return std::unique_ptr<Expression>(new IntLiteral(offset,
args[0]->as<IntLiteral>().fValue,
@ -2219,10 +2227,10 @@ std::unique_ptr<Expression> IRGenerator::convertNumberConstructor(
}
static int component_count(const Type& type) {
switch (type.kind()) {
case Type::kVector_Kind:
switch (type.typeKind()) {
case Type::TypeKind::kVector:
return type.columns();
case Type::kMatrix_Kind:
case Type::TypeKind::kMatrix:
return type.columns() * type.rows();
default:
return 1;
@ -2233,9 +2241,10 @@ std::unique_ptr<Expression> IRGenerator::convertCompoundConstructor(
int offset,
const Type& type,
std::vector<std::unique_ptr<Expression>> args) {
SkASSERT(type.kind() == Type::kVector_Kind || type.kind() == Type::kMatrix_Kind);
if (type.kind() == Type::kMatrix_Kind && args.size() == 1 &&
args[0]->fType.kind() == Type::kMatrix_Kind) {
SkASSERT(type.typeKind() == Type::TypeKind::kVector ||
type.typeKind() == Type::TypeKind::kMatrix);
if (type.typeKind() == Type::TypeKind::kMatrix && args.size() == 1 &&
args[0]->fType.typeKind() == Type::TypeKind::kMatrix) {
// matrix from matrix is always legal
return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
}
@ -2244,7 +2253,7 @@ std::unique_ptr<Expression> IRGenerator::convertCompoundConstructor(
if (args.size() != 1 || expected != component_count(args[0]->fType) ||
type.componentType().isNumber() != args[0]->fType.componentType().isNumber()) {
for (size_t i = 0; i < args.size(); i++) {
if (args[i]->fType.kind() == Type::kVector_Kind) {
if (args[i]->fType.typeKind() == Type::TypeKind::kVector) {
if (type.componentType().isNumber() !=
args[i]->fType.componentType().isNumber()) {
fErrors.error(offset, "'" + args[i]->fType.displayName() + "' is not a valid "
@ -2253,9 +2262,9 @@ std::unique_ptr<Expression> IRGenerator::convertCompoundConstructor(
return nullptr;
}
actual += args[i]->fType.columns();
} else if (args[i]->fType.kind() == Type::kScalar_Kind) {
} else if (args[i]->fType.typeKind() == Type::TypeKind::kScalar) {
actual += 1;
if (type.kind() != Type::kScalar_Kind) {
if (type.typeKind() != Type::TypeKind::kScalar) {
args[i] = this->coerce(std::move(args[i]), type.componentType());
if (!args[i]) {
return nullptr;
@ -2287,10 +2296,10 @@ std::unique_ptr<Expression> IRGenerator::convertConstructor(
// argument is already the right type, just return it
return std::move(args[0]);
}
Type::Kind kind = type.kind();
Type::TypeKind kind = type.typeKind();
if (type.isNumber()) {
return this->convertNumberConstructor(offset, type, std::move(args));
} else if (kind == Type::kArray_Kind) {
} else if (kind == Type::TypeKind::kArray) {
const Type& base = type.componentType();
for (size_t i = 0; i < args.size(); i++) {
args[i] = this->coerce(std::move(args[i]), base);
@ -2298,8 +2307,8 @@ std::unique_ptr<Expression> IRGenerator::convertConstructor(
return nullptr;
}
}
return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
} else if (kind == Type::kVector_Kind || kind == Type::kMatrix_Kind) {
return std::make_unique<Constructor>(offset, type, std::move(args));
} else if (kind == Type::TypeKind::kVector || kind == Type::TypeKind::kMatrix) {
return this->convertCompoundConstructor(offset, type, std::move(args));
} else {
fErrors.error(offset, "cannot construct '" + type.displayName() + "'");
@ -2315,7 +2324,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
}
switch (expression.getToken().fKind) {
case Token::Kind::TK_PLUS:
if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind &&
if (!base->fType.isNumber() && base->fType.typeKind() != Type::TypeKind::kVector &&
base->fType != *fContext.fFloatLiteral_Type) {
fErrors.error(expression.fOffset,
"'+' cannot operate on '" + base->fType.displayName() + "'");
@ -2323,16 +2332,16 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
}
return base;
case Token::Kind::TK_MINUS:
if (base->fKind == Expression::kIntLiteral_Kind) {
if (base->kind() == Expression::Kind::kIntLiteral) {
return std::unique_ptr<Expression>(new IntLiteral(fContext, base->fOffset,
-base->as<IntLiteral>().fValue));
}
if (base->fKind == Expression::kFloatLiteral_Kind) {
if (base->kind() == Expression::Kind::kFloatLiteral) {
double value = -base->as<FloatLiteral>().fValue;
return std::unique_ptr<Expression>(new FloatLiteral(fContext, base->fOffset,
value));
}
if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind) {
if (!base->fType.isNumber() && base->fType.typeKind() != Type::TypeKind::kVector) {
fErrors.error(expression.fOffset,
"'-' cannot operate on '" + base->fType.displayName() + "'");
return nullptr;
@ -2364,7 +2373,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
"' cannot operate on '" + base->fType.displayName() + "'");
return nullptr;
}
if (base->fKind == Expression::kBoolLiteral_Kind) {
if (base->kind() == Expression::Kind::kBoolLiteral) {
return std::unique_ptr<Expression>(
new BoolLiteral(fContext, base->fOffset, !base->as<BoolLiteral>().fValue));
}
@ -2386,22 +2395,23 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression> base,
const ASTNode& index) {
if (base->fKind == Expression::kTypeReference_Kind) {
if (base->kind() == Expression::Kind::kTypeReference) {
if (index.fKind == ASTNode::Kind::kInt) {
const Type& oldType = base->as<TypeReference>().fValue;
SKSL_INT size = index.getInt();
const Type* newType = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Type>(oldType.name() + "[" + to_string(size) + "]",
Type::kArray_Kind, oldType, size));
return std::make_unique<TypeReference>(fContext, base->fOffset, *newType);
Type::TypeKind::kArray, oldType, size));
return std::make_unique<TypeReference>(fContext, base->fOffset, newType);
} else {
fErrors.error(base->fOffset, "array size must be a constant");
return nullptr;
}
}
if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::kMatrix_Kind &&
base->fType.kind() != Type::kVector_Kind) {
if (base->fType.typeKind() != Type::TypeKind::kArray &&
base->fType.typeKind() != Type::TypeKind::kMatrix &&
base->fType.typeKind() != Type::TypeKind::kVector) {
fErrors.error(base->fOffset, "expected array, but found '" + base->fType.displayName() +
"'");
return nullptr;
@ -2416,13 +2426,12 @@ std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
return nullptr;
}
}
return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(base),
std::move(converted)));
return std::make_unique<IndexExpression>(fContext, std::move(base), std::move(converted));
}
std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression> base,
StringFragment field) {
if (base->fKind == Expression::kExternalValue_Kind) {
if (base->kind() == Expression::Kind::kExternalValue) {
const ExternalValue& ev = *base->as<ExternalValueReference>().fValue;
ExternalValue* result = ev.getChild(String(field).c_str());
if (!result) {
@ -2460,7 +2469,7 @@ static int count_contiguous_swizzle_chunks(const std::vector<int>& components) {
std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expression> base,
StringFragment fields) {
if (base->fType.kind() != Type::kVector_Kind && !base->fType.isNumber()) {
if (base->fType.typeKind() != Type::TypeKind::kVector && !base->fType.isNumber()) {
fErrors.error(base->fOffset, "cannot swizzle value of type '" + base->fType.displayName() +
"'");
return nullptr;
@ -2530,10 +2539,10 @@ std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi
// 1)
int offset = base->fOffset;
std::unique_ptr<Expression> expr;
switch (base->fKind) {
case Expression::kVariableReference_Kind:
case Expression::kFloatLiteral_Kind:
case Expression::kIntLiteral_Kind:
switch (base->kind()) {
case Expression::Kind::kVariableReference:
case Expression::Kind::kFloatLiteral:
case Expression::Kind::kIntLiteral:
// the value being swizzled is just a constant or variable reference, so we can
// safely re-use copies of it without reevaluation concerns
expr = std::move(base);
@ -2623,7 +2632,7 @@ std::unique_ptr<Expression> IRGenerator::findEnumRef(
StringFragment field,
std::vector<std::unique_ptr<ProgramElement>>& elements) {
for (const auto& e : elements) {
if (e->fKind == ProgramElement::kEnum_Kind && type.name() == e->as<Enum>().fTypeName) {
if (e->kind() == ProgramElement::Kind::kEnum && type.name() == e->as<Enum>().fTypeName) {
std::shared_ptr<SymbolTable> old = fSymbolTable;
fSymbolTable = e->as<Enum>().fSymbols;
std::unique_ptr<Expression> result = convertIdentifier(ASTNode(&fFile->fNodes, offset,
@ -2671,12 +2680,11 @@ std::unique_ptr<Expression> IRGenerator::convertIndexExpression(const ASTNode& i
}
if (iter != index.end()) {
return this->convertIndex(std::move(base), *(iter++));
} else if (base->fKind == Expression::kTypeReference_Kind) {
} else if (base->kind() == Expression::Kind::kTypeReference) {
const Type& oldType = base->as<TypeReference>().fValue;
const Type* newType = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Type>(
oldType.name() + "[]", Type::kArray_Kind, oldType, /*columns=*/-1));
return std::unique_ptr<Expression>(new TypeReference(fContext, base->fOffset,
*newType));
oldType.name() + "[]", Type::TypeKind::kArray, oldType, /*columns=*/-1));
return std::make_unique<TypeReference>(fContext, base->fOffset, newType);
}
fErrors.error(index.fOffset, "'[]' must follow a type name");
return nullptr;
@ -2709,16 +2717,16 @@ std::unique_ptr<Expression> IRGenerator::convertFieldExpression(const ASTNode& f
if (base->fType == *fContext.fSkCaps_Type) {
return this->getCap(fieldNode.fOffset, field);
}
if (base->fKind == Expression::kTypeReference_Kind) {
if (base->kind() == Expression::Kind::kTypeReference) {
return this->convertTypeField(base->fOffset, base->as<TypeReference>().fValue,
field);
}
if (base->fKind == Expression::kExternalValue_Kind) {
if (base->kind() == Expression::Kind::kExternalValue) {
return this->convertField(std::move(base), field);
}
switch (base->fType.kind()) {
case Type::kOther_Kind:
case Type::kStruct_Kind:
switch (base->fType.typeKind()) {
case Type::TypeKind::kOther:
case Type::TypeKind::kStruct:
return this->convertField(std::move(base), field);
default:
return this->convertSwizzle(std::move(base), field);
@ -2742,11 +2750,11 @@ std::unique_ptr<Expression> IRGenerator::convertPostfixExpression(const ASTNode&
}
void IRGenerator::checkValid(const Expression& expr) {
switch (expr.fKind) {
case Expression::kFunctionReference_Kind:
switch (expr.kind()) {
case Expression::Kind::kFunctionReference:
fErrors.error(expr.fOffset, "expected '(' to begin function call");
break;
case Expression::kTypeReference_Kind:
case Expression::Kind::kTypeReference:
fErrors.error(expr.fOffset, "expected '(' to begin constructor invocation");
break;
default:
@ -2776,8 +2784,8 @@ bool IRGenerator::checkSwizzleWrite(const Swizzle& swizzle) {
}
bool IRGenerator::setRefKind(Expression& expr, VariableReference::RefKind kind) {
switch (expr.fKind) {
case Expression::kVariableReference_Kind: {
switch (expr.kind()) {
case Expression::Kind::kVariableReference: {
const Variable& var = expr.as<VariableReference>().fVariable;
if (var.fModifiers.fFlags &
(Modifiers::kConst_Flag | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag)) {
@ -2787,19 +2795,19 @@ bool IRGenerator::setRefKind(Expression& expr, VariableReference::RefKind kind)
expr.as<VariableReference>().setRefKind(kind);
return true;
}
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
return this->setRefKind(*expr.as<FieldAccess>().fBase, kind);
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
const Swizzle& swizzle = expr.as<Swizzle>();
return this->checkSwizzleWrite(swizzle) && this->setRefKind(*swizzle.fBase, kind);
}
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
return this->setRefKind(*expr.as<IndexExpression>().fBase, kind);
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
const TernaryExpression& t = expr.as<TernaryExpression>();
return this->setRefKind(*t.fIfTrue, kind) && this->setRefKind(*t.fIfFalse, kind);
}
case Expression::kExternalValue_Kind: {
case Expression::Kind::kExternalValue: {
const ExternalValue& v = *expr.as<ExternalValueReference>().fValue;
if (!v.canWrite()) {
fErrors.error(expr.fOffset,

View File

@ -64,8 +64,8 @@ static int count_all_returns(const FunctionDefinition& funcDef) {
}
bool visitStatement(const Statement& stmt) override {
switch (stmt.fKind) {
case Statement::kReturn_Kind:
switch (stmt.kind()) {
case Statement::Kind::kReturn:
++fNumReturns;
[[fallthrough]];
@ -89,21 +89,21 @@ static int count_returns_at_end_of_control_flow(const FunctionDefinition& funcDe
}
bool visitStatement(const Statement& stmt) override {
switch (stmt.fKind) {
case Statement::kBlock_Kind: {
switch (stmt.kind()) {
case Statement::Kind::kBlock: {
// Check only the last statement of a block.
const auto& blockStmts = stmt.as<Block>().fStatements;
return (blockStmts.size() > 0) ? this->visitStatement(*blockStmts.back())
: false;
}
case Statement::kSwitch_Kind:
case Statement::kWhile_Kind:
case Statement::kDo_Kind:
case Statement::kFor_Kind:
case Statement::Kind::kSwitch:
case Statement::Kind::kWhile:
case Statement::Kind::kDo:
case Statement::Kind::kFor:
// Don't introspect switches or loop structures at all.
return false;
case Statement::kReturn_Kind:
case Statement::Kind::kReturn:
++fNumReturns;
[[fallthrough]];
@ -127,18 +127,18 @@ static int count_returns_in_breakable_constructs(const FunctionDefinition& funcD
}
bool visitStatement(const Statement& stmt) override {
switch (stmt.fKind) {
case Statement::kSwitch_Kind:
case Statement::kWhile_Kind:
case Statement::kDo_Kind:
case Statement::kFor_Kind: {
switch (stmt.kind()) {
case Statement::Kind::kSwitch:
case Statement::Kind::kWhile:
case Statement::Kind::kDo:
case Statement::Kind::kFor: {
++fInsideBreakableConstruct;
bool result = this->INHERITED::visitStatement(stmt);
--fInsideBreakableConstruct;
return result;
}
case Statement::kReturn_Kind:
case Statement::Kind::kReturn:
fNumReturns += (fInsideBreakableConstruct > 0) ? 1 : 0;
[[fallthrough]];
@ -166,7 +166,7 @@ static bool has_early_return(const FunctionDefinition& funcDef) {
}
static const Type* copy_if_needed(const Type* src, SymbolTable& symbolTable) {
if (src->kind() == Type::kArray_Kind) {
if (src->typeKind() == Type::TypeKind::kArray) {
return symbolTable.takeOwnershipOfSymbol(std::make_unique<Type>(*src));
}
return src;
@ -199,8 +199,8 @@ std::unique_ptr<Expression> Inliner::inlineExpression(int offset,
return args;
};
switch (expression.fKind) {
case Expression::kBinary_Kind: {
switch (expression.kind()) {
case Expression::Kind::kBinary: {
const BinaryExpression& b = expression.as<BinaryExpression>();
return std::make_unique<BinaryExpression>(offset,
expr(b.fLeft),
@ -208,59 +208,59 @@ std::unique_ptr<Expression> Inliner::inlineExpression(int offset,
expr(b.fRight),
b.fType);
}
case Expression::kBoolLiteral_Kind:
case Expression::kIntLiteral_Kind:
case Expression::kFloatLiteral_Kind:
case Expression::kNullLiteral_Kind:
case Expression::Kind::kBoolLiteral:
case Expression::Kind::kIntLiteral:
case Expression::Kind::kFloatLiteral:
case Expression::Kind::kNullLiteral:
return expression.clone();
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
const Constructor& constructor = expression.as<Constructor>();
return std::make_unique<Constructor>(offset, constructor.fType,
argList(constructor.fArguments));
}
case Expression::kExternalFunctionCall_Kind: {
case Expression::Kind::kExternalFunctionCall: {
const ExternalFunctionCall& externalCall = expression.as<ExternalFunctionCall>();
return std::make_unique<ExternalFunctionCall>(offset, externalCall.fType,
externalCall.fFunction,
argList(externalCall.fArguments));
}
case Expression::kExternalValue_Kind:
case Expression::Kind::kExternalValue:
return expression.clone();
case Expression::kFieldAccess_Kind: {
case Expression::Kind::kFieldAccess: {
const FieldAccess& f = expression.as<FieldAccess>();
return std::make_unique<FieldAccess>(expr(f.fBase), f.fFieldIndex, f.fOwnerKind);
}
case Expression::kFunctionCall_Kind: {
case Expression::Kind::kFunctionCall: {
const FunctionCall& funcCall = expression.as<FunctionCall>();
return std::make_unique<FunctionCall>(offset, funcCall.fType, funcCall.fFunction,
argList(funcCall.fArguments));
}
case Expression::kFunctionReference_Kind:
case Expression::Kind::kFunctionReference:
return expression.clone();
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
const IndexExpression& idx = expression.as<IndexExpression>();
return std::make_unique<IndexExpression>(*fContext, expr(idx.fBase), expr(idx.fIndex));
}
case Expression::kPrefix_Kind: {
case Expression::Kind::kPrefix: {
const PrefixExpression& p = expression.as<PrefixExpression>();
return std::make_unique<PrefixExpression>(p.fOperator, expr(p.fOperand));
}
case Expression::kPostfix_Kind: {
case Expression::Kind::kPostfix: {
const PostfixExpression& p = expression.as<PostfixExpression>();
return std::make_unique<PostfixExpression>(expr(p.fOperand), p.fOperator);
}
case Expression::kSetting_Kind:
case Expression::Kind::kSetting:
return expression.clone();
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
const Swizzle& s = expression.as<Swizzle>();
return std::make_unique<Swizzle>(*fContext, expr(s.fBase), s.fComponents);
}
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
const TernaryExpression& t = expression.as<TernaryExpression>();
return std::make_unique<TernaryExpression>(offset, expr(t.fTest),
expr(t.fIfTrue), expr(t.fIfFalse));
}
case Expression::kVariableReference_Kind: {
case Expression::Kind::kVariableReference: {
const VariableReference& v = expression.as<VariableReference>();
auto found = varMap->find(&v.fVariable);
if (found != varMap->end()) {
@ -300,26 +300,26 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
}
return nullptr;
};
switch (statement.fKind) {
case Statement::kBlock_Kind: {
switch (statement.kind()) {
case Statement::Kind::kBlock: {
const Block& b = statement.as<Block>();
return std::make_unique<Block>(offset, stmts(b.fStatements), b.fSymbols, b.fIsScope);
}
case Statement::kBreak_Kind:
case Statement::kContinue_Kind:
case Statement::kDiscard_Kind:
case Statement::Kind::kBreak:
case Statement::Kind::kContinue:
case Statement::Kind::kDiscard:
return statement.clone();
case Statement::kDo_Kind: {
case Statement::Kind::kDo: {
const DoStatement& d = statement.as<DoStatement>();
return std::make_unique<DoStatement>(offset, stmt(d.fStatement), expr(d.fTest));
}
case Statement::kExpression_Kind: {
case Statement::Kind::kExpression: {
const ExpressionStatement& e = statement.as<ExpressionStatement>();
return std::make_unique<ExpressionStatement>(expr(e.fExpression));
}
case Statement::kFor_Kind: {
case Statement::Kind::kFor: {
const ForStatement& f = statement.as<ForStatement>();
// need to ensure initializer is evaluated first so that we've already remapped its
// declarations by the time we evaluate test & next
@ -327,14 +327,14 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
return std::make_unique<ForStatement>(offset, std::move(initializer), expr(f.fTest),
expr(f.fNext), stmt(f.fStatement), f.fSymbols);
}
case Statement::kIf_Kind: {
case Statement::Kind::kIf: {
const IfStatement& i = statement.as<IfStatement>();
return std::make_unique<IfStatement>(offset, i.fIsStatic, expr(i.fTest),
stmt(i.fIfTrue), stmt(i.fIfFalse));
}
case Statement::kNop_Kind:
case Statement::Kind::kNop:
return statement.clone();
case Statement::kReturn_Kind: {
case Statement::Kind::kReturn: {
const ReturnStatement& r = statement.as<ReturnStatement>();
if (r.fExpression) {
auto assignment = std::make_unique<ExpressionStatement>(
@ -362,7 +362,7 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
}
}
}
case Statement::kSwitch_Kind: {
case Statement::Kind::kSwitch: {
const SwitchStatement& ss = statement.as<SwitchStatement>();
std::vector<std::unique_ptr<SwitchCase>> cases;
for (const auto& sc : ss.fCases) {
@ -372,7 +372,7 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
return std::make_unique<SwitchStatement>(offset, ss.fIsStatic, expr(ss.fValue),
std::move(cases), ss.fSymbols);
}
case Statement::kVarDeclaration_Kind: {
case Statement::Kind::kVarDeclaration: {
const VarDeclaration& decl = statement.as<VarDeclaration>();
std::vector<std::unique_ptr<Expression>> sizes;
for (const auto& size : decl.fSizes) {
@ -396,7 +396,7 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
return std::make_unique<VarDeclaration>(clone, std::move(sizes),
std::move(initialValue));
}
case Statement::kVarDeclarations_Kind: {
case Statement::Kind::kVarDeclarations: {
const VarDeclarations& decls = *statement.as<VarDeclarationsStatement>().fDeclaration;
std::vector<std::unique_ptr<VarDeclaration>> vars;
for (const auto& var : decls.fVars) {
@ -406,7 +406,7 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
return std::unique_ptr<Statement>(new VarDeclarationsStatement(
std::make_unique<VarDeclarations>(offset, typePtr, std::move(vars))));
}
case Statement::kWhile_Kind: {
case Statement::Kind::kWhile: {
const WhileStatement& w = statement.as<WhileStatement>();
return std::make_unique<WhileStatement>(offset, expr(w.fTest), stmt(w.fStatement));
}
@ -508,7 +508,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call,
for (int i = 0; i < (int) arguments.size(); ++i) {
const Variable* param = function.fDeclaration.fParameters[i];
if (arguments[i]->fKind == Expression::kVariableReference_Kind) {
if (arguments[i]->kind() == Expression::Kind::kVariableReference) {
// The argument is just a variable, so we only need to copy it if it's an out parameter
// or it's written to within the function.
if ((param->fModifiers.fFlags & Modifiers::kOut_Flag) ||
@ -549,7 +549,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call,
const Variable* p = function.fDeclaration.fParameters[i];
if (p->fModifiers.fFlags & Modifiers::kOut_Flag) {
SkASSERT(varMap.find(p) != varMap.end());
if (arguments[i]->fKind == Expression::kVariableReference_Kind &&
if (arguments[i]->kind() == Expression::Kind::kVariableReference &&
&arguments[i]->as<VariableReference>().fVariable == varMap[p]) {
// We didn't create a temporary for this parameter, so there's nothing to copy back
// out.

View File

@ -46,17 +46,17 @@ public:
*/
size_t alignment(const Type& type) const {
// See OpenGL Spec 7.6.2.2 Standard Uniform Block Layout
switch (type.kind()) {
case Type::kScalar_Kind:
switch (type.typeKind()) {
case Type::TypeKind::kScalar:
return this->size(type);
case Type::kVector_Kind:
case Type::TypeKind::kVector:
return vector_alignment(this->size(type.componentType()), type.columns());
case Type::kMatrix_Kind:
case Type::TypeKind::kMatrix:
return this->roundUpIfNeeded(vector_alignment(this->size(type.componentType()),
type.rows()));
case Type::kArray_Kind:
case Type::TypeKind::kArray:
return this->roundUpIfNeeded(this->alignment(type.componentType()));
case Type::kStruct_Kind: {
case Type::TypeKind::kStruct: {
size_t result = 0;
for (const auto& f : type.fields()) {
size_t alignment = this->alignment(*f.fType);
@ -76,12 +76,12 @@ public:
* the case of matrices) to the start of the next.
*/
size_t stride(const Type& type) const {
switch (type.kind()) {
case Type::kMatrix_Kind: {
switch (type.typeKind()) {
case Type::TypeKind::kMatrix: {
size_t base = vector_alignment(this->size(type.componentType()), type.rows());
return this->roundUpIfNeeded(base);
}
case Type::kArray_Kind: {
case Type::TypeKind::kArray: {
int stride = this->size(type.componentType());
if (stride > 0) {
int align = this->alignment(type.componentType());
@ -100,23 +100,23 @@ public:
* Returns the size of a type in bytes.
*/
size_t size(const Type& type) const {
switch (type.kind()) {
case Type::kScalar_Kind:
switch (type.typeKind()) {
case Type::TypeKind::kScalar:
if (type.name() == "bool") {
return 1;
}
// FIXME need to take precision into account, once we figure out how we want to
// handle it...
return 4;
case Type::kVector_Kind:
case Type::TypeKind::kVector:
if (fStd == kMetal_Standard && type.columns() == 3) {
return 4 * this->size(type.componentType());
}
return type.columns() * this->size(type.componentType());
case Type::kMatrix_Kind: // fall through
case Type::kArray_Kind:
case Type::TypeKind::kMatrix: // fall through
case Type::TypeKind::kArray:
return type.columns() * this->stride(type);
case Type::kStruct_Kind: {
case Type::TypeKind::kStruct: {
size_t total = 0;
for (const auto& f : type.fields()) {
size_t alignment = this->alignment(*f.fType);

View File

@ -77,13 +77,13 @@ void MetalCodeGenerator::writeExtension(const Extension& ext) {
}
String MetalCodeGenerator::typeName(const Type& type) {
switch (type.kind()) {
case Type::kVector_Kind:
switch (type.typeKind()) {
case Type::TypeKind::kVector:
return this->typeName(type.componentType()) + to_string(type.columns());
case Type::kMatrix_Kind:
case Type::TypeKind::kMatrix:
return this->typeName(type.componentType()) + to_string(type.columns()) + "x" +
to_string(type.rows());
case Type::kSampler_Kind:
case Type::TypeKind::kSampler:
return "texture2d<float>"; // FIXME - support other texture types;
default:
if (type == *fContext.fHalf_Type) {
@ -100,7 +100,7 @@ String MetalCodeGenerator::typeName(const Type& type) {
}
void MetalCodeGenerator::writeType(const Type& type) {
if (type.kind() == Type::kStruct_Kind) {
if (type.typeKind() == Type::TypeKind::kStruct) {
for (const Type* search : fWrittenStructs) {
if (*search == type) {
// already written
@ -120,47 +120,47 @@ void MetalCodeGenerator::writeType(const Type& type) {
}
void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) {
switch (expr.fKind) {
case Expression::kBinary_Kind:
switch (expr.kind()) {
case Expression::Kind::kBinary:
this->writeBinaryExpression(expr.as<BinaryExpression>(), parentPrecedence);
break;
case Expression::kBoolLiteral_Kind:
case Expression::Kind::kBoolLiteral:
this->writeBoolLiteral(expr.as<BoolLiteral>());
break;
case Expression::kConstructor_Kind:
case Expression::Kind::kConstructor:
this->writeConstructor(expr.as<Constructor>(), parentPrecedence);
break;
case Expression::kIntLiteral_Kind:
case Expression::Kind::kIntLiteral:
this->writeIntLiteral(expr.as<IntLiteral>());
break;
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
this->writeFieldAccess(expr.as<FieldAccess>());
break;
case Expression::kFloatLiteral_Kind:
case Expression::Kind::kFloatLiteral:
this->writeFloatLiteral(expr.as<FloatLiteral>());
break;
case Expression::kFunctionCall_Kind:
case Expression::Kind::kFunctionCall:
this->writeFunctionCall(expr.as<FunctionCall>());
break;
case Expression::kPrefix_Kind:
case Expression::Kind::kPrefix:
this->writePrefixExpression(expr.as<PrefixExpression>(), parentPrecedence);
break;
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
this->writePostfixExpression(expr.as<PostfixExpression>(), parentPrecedence);
break;
case Expression::kSetting_Kind:
case Expression::Kind::kSetting:
this->writeSetting(expr.as<Setting>());
break;
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
this->writeSwizzle(expr.as<Swizzle>());
break;
case Expression::kVariableReference_Kind:
case Expression::Kind::kVariableReference:
this->writeVariableReference(expr.as<VariableReference>());
break;
case Expression::kTernary_Kind:
case Expression::Kind::kTernary:
this->writeTernaryExpression(expr.as<TernaryExpression>(), parentPrecedence);
break;
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
this->writeIndexExpression(expr.as<IndexExpression>());
break;
default:
@ -447,16 +447,16 @@ void MetalCodeGenerator::assembleMatrixFromExpressions(
if (argIndex < args.size()) {
const Type& argType = args[argIndex]->fType;
switch (argType.kind()) {
case Type::kScalar_Kind: {
switch (argType.typeKind()) {
case Type::TypeKind::kScalar: {
fExtraFunctions.printf("x%zu", argIndex);
break;
}
case Type::kVector_Kind: {
case Type::TypeKind::kVector: {
fExtraFunctions.printf("x%zu[%d]", argIndex, argPosition);
break;
}
case Type::kMatrix_Kind: {
case Type::TypeKind::kMatrix: {
fExtraFunctions.printf("x%zu[%d][%d]", argIndex,
argPosition / argType.rows(),
argPosition % argType.rows());
@ -527,7 +527,7 @@ String MetalCodeGenerator::getMatrixConstructHelper(const Constructor& c) {
fExtraFunctions.printf(") {\n return float%dx%d(", columns, rows);
if (args.size() == 1 && args.front()->fType.kind() == Type::kMatrix_Kind) {
if (args.size() == 1 && args.front()->fType.typeKind() == Type::TypeKind::kMatrix) {
this->assembleMatrixFromMatrix(args.front()->fType, rows, columns);
} else {
this->assembleMatrixFromExpressions(args, rows, columns);
@ -549,7 +549,7 @@ bool MetalCodeGenerator::canCoerce(const Type& t1, const Type& t2) {
bool MetalCodeGenerator::matrixConstructHelperIsNeeded(const Constructor& c) {
// A matrix construct helper is only necessary if we are, in fact, constructing a matrix.
if (c.fType.kind() != Type::kMatrix_Kind) {
if (c.fType.typeKind() != Type::TypeKind::kMatrix) {
return false;
}
@ -577,7 +577,7 @@ bool MetalCodeGenerator::matrixConstructHelperIsNeeded(const Constructor& c) {
int position = 0;
for (const std::unique_ptr<Expression>& expr : c.fArguments) {
// If an input argument is a matrix, we need a helper function.
if (expr->fType.kind() == Type::kMatrix_Kind) {
if (expr->fType.typeKind() == Type::TypeKind::kMatrix) {
return true;
}
position += expr->fType.columns();
@ -606,7 +606,7 @@ void MetalCodeGenerator::writeConstructor(const Constructor& c, Precedence paren
// Metal supports creating matrices with a scalar on the diagonal via the single-argument
// matrix constructor.
if (c.fType.kind() == Type::kMatrix_Kind && arg.fType.isNumber()) {
if (c.fType.typeKind() == Type::TypeKind::kMatrix && arg.fType.isNumber()) {
const Type& matrix = c.fType;
this->write("float");
this->write(to_string(matrix.columns()));
@ -641,7 +641,8 @@ void MetalCodeGenerator::writeConstructor(const Constructor& c, Precedence paren
for (const std::unique_ptr<Expression>& arg : c.fArguments) {
this->write(separator);
separator = ", ";
if (Type::kMatrix_Kind == c.fType.kind() && arg->fType.columns() < c.fType.rows()) {
if (c.fType.typeKind() == Type::TypeKind::kMatrix &&
arg->fType.columns() < c.fType.rows()) {
// Merge scalars and smaller vectors together.
if (!scalarCount) {
this->writeType(c.fType.componentType());
@ -695,7 +696,7 @@ void MetalCodeGenerator::writeVariableReference(const VariableReference& ref) {
} else if (ref.fVariable.fModifiers.fFlags & Modifiers::kOut_Flag) {
this->write("_out->");
} else if (ref.fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag &&
ref.fVariable.fType.kind() != Type::kSampler_Kind) {
ref.fVariable.fType.typeKind() != Type::TypeKind::kSampler) {
this->write("_uniforms.");
} else {
this->write("_globals->");
@ -818,13 +819,13 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
bool needParens = precedence >= parentPrecedence;
switch (b.fOperator) {
case Token::Kind::TK_EQEQ:
if (b.fLeft->fType.kind() == Type::kVector_Kind) {
if (b.fLeft->fType.typeKind() == Type::TypeKind::kVector) {
this->write("all");
needParens = true;
}
break;
case Token::Kind::TK_NEQ:
if (b.fLeft->fType.kind() == Type::kVector_Kind) {
if (b.fLeft->fType.typeKind() == Type::TypeKind::kVector) {
this->write("any");
needParens = true;
}
@ -836,20 +837,21 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
this->write("(");
}
if (Compiler::IsAssignment(b.fOperator) &&
Expression::kVariableReference_Kind == b.fLeft->fKind &&
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 (b.fOperator == Token::Kind::TK_STAREQ && b.fLeft->fType.kind() == Type::kMatrix_Kind &&
b.fRight->fType.kind() == Type::kMatrix_Kind) {
if (b.fOperator == Token::Kind::TK_STAREQ &&
b.fLeft->fType.typeKind() == Type::TypeKind::kMatrix &&
b.fRight->fType.typeKind() == Type::TypeKind::kMatrix) {
this->writeMatrixTimesEqualHelper(b.fLeft->fType, b.fRight->fType, b.fType);
}
this->writeExpression(*b.fLeft, precedence);
if (b.fOperator != Token::Kind::TK_EQ && Compiler::IsAssignment(b.fOperator) &&
Expression::kSwizzle_Kind == b.fLeft->fKind && !b.fLeft->hasSideEffects()) {
b.fLeft->kind() == Expression::Kind::kSwizzle && !b.fLeft->hasSideEffects()) {
// This doesn't compile in Metal:
// float4 x = float4(1);
// x.xy *= float2x2(...);
@ -951,14 +953,14 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
to_string(fUniformBuffer) + ")]]");
}
for (const auto& e : fProgram) {
if (ProgramElement::kVar_Kind == e.fKind) {
if (e.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = e.as<VarDeclarations>();
if (!decls.fVars.size()) {
continue;
}
for (const auto& stmt: decls.fVars) {
VarDeclaration& var = stmt->as<VarDeclaration>();
if (var.fVar->fType.kind() == Type::kSampler_Kind) {
if (var.fVar->fType.typeKind() == Type::TypeKind::kSampler) {
if (var.fVar->fModifiers.fLayout.fBinding < 0) {
fErrors.error(decls.fOffset,
"Metal samplers must have 'layout(binding=...)'");
@ -976,7 +978,7 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
this->write(")]]");
}
}
} else if (ProgramElement::kInterfaceBlock_Kind == e.fKind) {
} else if (e.kind() == ProgramElement::Kind::kInterfaceBlock) {
InterfaceBlock& intf = (InterfaceBlock&) e;
if ("sk_PerVertex" == intf.fTypeName) {
continue;
@ -1038,7 +1040,7 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
this->writeModifiers(param->fModifiers, false);
std::vector<int> sizes;
const Type* type = &param->fType;
while (Type::kArray_Kind == type->kind()) {
while (type->typeKind() == Type::TypeKind::kArray) {
sizes.push_back(type->columns());
type = &type->componentType();
}
@ -1112,7 +1114,7 @@ void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
this->writeLine(intf.fTypeName + " {");
const Type* structType = &intf.fVariable.fType;
fWrittenStructs.push_back(structType);
while (Type::kArray_Kind == structType->kind()) {
while (structType->typeKind() == Type::TypeKind::kArray) {
structType = &structType->componentType();
}
fIndentation++;
@ -1168,7 +1170,7 @@ void MetalCodeGenerator::writeFields(const std::vector<Type::Field>& fields, int
}
currentOffset += memoryLayout.size(*fieldType);
std::vector<int> sizes;
while (fieldType->kind() == Type::kArray_Kind) {
while (fieldType->typeKind() == Type::TypeKind::kArray) {
sizes.push_back(fieldType->columns());
fieldType = &fieldType->componentType();
}
@ -1236,45 +1238,45 @@ void MetalCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool
}
void MetalCodeGenerator::writeStatement(const Statement& s) {
switch (s.fKind) {
case Statement::kBlock_Kind:
switch (s.kind()) {
case Statement::Kind::kBlock:
this->writeBlock(s.as<Block>());
break;
case Statement::kExpression_Kind:
case Statement::Kind::kExpression:
this->writeExpression(*s.as<ExpressionStatement>().fExpression, kTopLevel_Precedence);
this->write(";");
break;
case Statement::kReturn_Kind:
case Statement::Kind::kReturn:
this->writeReturnStatement(s.as<ReturnStatement>());
break;
case Statement::kVarDeclarations_Kind:
case Statement::Kind::kVarDeclarations:
this->writeVarDeclarations(*s.as<VarDeclarationsStatement>().fDeclaration, false);
break;
case Statement::kIf_Kind:
case Statement::Kind::kIf:
this->writeIfStatement(s.as<IfStatement>());
break;
case Statement::kFor_Kind:
case Statement::Kind::kFor:
this->writeForStatement(s.as<ForStatement>());
break;
case Statement::kWhile_Kind:
case Statement::Kind::kWhile:
this->writeWhileStatement(s.as<WhileStatement>());
break;
case Statement::kDo_Kind:
case Statement::Kind::kDo:
this->writeDoStatement(s.as<DoStatement>());
break;
case Statement::kSwitch_Kind:
case Statement::Kind::kSwitch:
this->writeSwitchStatement(s.as<SwitchStatement>());
break;
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
this->write("break;");
break;
case Statement::kContinue_Kind:
case Statement::Kind::kContinue:
this->write("continue;");
break;
case Statement::kDiscard_Kind:
case Statement::Kind::kDiscard:
this->write("discard_fragment();");
break;
case Statement::kNop_Kind:
case Statement::Kind::kNop:
this->write(";");
break;
default:
@ -1391,14 +1393,14 @@ void MetalCodeGenerator::writeHeader() {
void MetalCodeGenerator::writeUniformStruct() {
for (const auto& e : fProgram) {
if (ProgramElement::kVar_Kind == e.fKind) {
if (e.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = e.as<VarDeclarations>();
if (!decls.fVars.size()) {
continue;
}
const Variable& first = *decls.fVars[0]->as<VarDeclaration>().fVar;
if (first.fModifiers.fFlags & Modifiers::kUniform_Flag &&
first.fType.kind() != Type::kSampler_Kind) {
first.fType.typeKind() != Type::TypeKind::kSampler) {
if (-1 == fUniformBuffer) {
this->write("struct Uniforms {\n");
fUniformBuffer = first.fModifiers.fLayout.fSet;
@ -1430,7 +1432,7 @@ void MetalCodeGenerator::writeUniformStruct() {
void MetalCodeGenerator::writeInputStruct() {
this->write("struct Inputs {\n");
for (const auto& e : fProgram) {
if (ProgramElement::kVar_Kind == e.fKind) {
if (e.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = e.as<VarDeclarations>();
if (!decls.fVars.size()) {
continue;
@ -1469,7 +1471,7 @@ void MetalCodeGenerator::writeOutputStruct() {
this->write(" float4 sk_FragColor [[color(0)]];\n");
}
for (const auto& e : fProgram) {
if (ProgramElement::kVar_Kind == e.fKind) {
if (e.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = e.as<VarDeclarations>();
if (!decls.fVars.size()) {
continue;
@ -1509,7 +1511,7 @@ void MetalCodeGenerator::writeOutputStruct() {
void MetalCodeGenerator::writeInterfaceBlocks() {
bool wroteInterfaceBlock = false;
for (const auto& e : fProgram) {
if (ProgramElement::kInterfaceBlock_Kind == e.fKind) {
if (e.kind() == ProgramElement::Kind::kInterfaceBlock) {
this->writeInterfaceBlock(e.as<InterfaceBlock>());
wroteInterfaceBlock = true;
}
@ -1527,7 +1529,7 @@ void MetalCodeGenerator::visitGlobalStruct(GlobalStructVisitor* visitor) {
visitor->VisitInterfaceBlock(*interfaceType, interfaceName);
}
for (const ProgramElement& element : fProgram) {
if (element.fKind != ProgramElement::kVar_Kind) {
if (element.kind() != ProgramElement::Kind::kVar) {
continue;
}
const VarDeclarations& decls = static_cast<const VarDeclarations&>(element);
@ -1536,11 +1538,11 @@ void MetalCodeGenerator::visitGlobalStruct(GlobalStructVisitor* visitor) {
}
const Variable& first = *((VarDeclaration&) *decls.fVars[0]).fVar;
if ((!first.fModifiers.fFlags && -1 == first.fModifiers.fLayout.fBuiltin) ||
first.fType.kind() == Type::kSampler_Kind) {
first.fType.typeKind() == Type::TypeKind::kSampler) {
for (const auto& stmt : decls.fVars) {
VarDeclaration& var = static_cast<VarDeclaration&>(*stmt);
if (var.fVar->fType.kind() == Type::kSampler_Kind) {
if (var.fVar->fType.typeKind() == Type::TypeKind::kSampler) {
// Samplers are represented as a "texture/sampler" duo in the global struct.
visitor->VisitTexture(first.fType, var.fVar->fName);
visitor->VisitSampler(first.fType, String(var.fVar->fName) + SAMPLER_SUFFIX);
@ -1658,10 +1660,10 @@ void MetalCodeGenerator::writeGlobalInit() {
}
void MetalCodeGenerator::writeProgramElement(const ProgramElement& e) {
switch (e.fKind) {
case ProgramElement::kExtension_Kind:
switch (e.kind()) {
case ProgramElement::Kind::kExtension:
break;
case ProgramElement::kVar_Kind: {
case ProgramElement::Kind::kVar: {
const VarDeclarations& decl = e.as<VarDeclarations>();
if (decl.fVars.size() > 0) {
int builtin = decl.fVars[0]->as<VarDeclaration>().fVar->fModifiers.fLayout.fBuiltin;
@ -1675,13 +1677,13 @@ void MetalCodeGenerator::writeProgramElement(const ProgramElement& e) {
}
break;
}
case ProgramElement::kInterfaceBlock_Kind:
case ProgramElement::Kind::kInterfaceBlock:
// handled in writeInterfaceBlocks, do nothing
break;
case ProgramElement::kFunction_Kind:
case ProgramElement::Kind::kFunction:
this->writeFunction(e.as<FunctionDefinition>());
break;
case ProgramElement::kModifiers_Kind:
case ProgramElement::Kind::kModifiers:
this->writeModifiers(e.as<ModifiersDeclaration>().fModifiers, true);
this->writeLine(";");
break;
@ -1697,8 +1699,8 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Expressi
if (!e) {
return kNo_Requirements;
}
switch (e->fKind) {
case Expression::kFunctionCall_Kind: {
switch (e->kind()) {
case Expression::Kind::kFunctionCall: {
const FunctionCall& f = e->as<FunctionCall>();
Requirements result = this->requirements(f.fFunction);
for (const auto& arg : f.fArguments) {
@ -1706,7 +1708,7 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Expressi
}
return result;
}
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
const Constructor& c = e->as<Constructor>();
Requirements result = kNo_Requirements;
for (const auto& arg : c.fArguments) {
@ -1714,33 +1716,34 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Expressi
}
return result;
}
case Expression::kFieldAccess_Kind: {
case Expression::Kind::kFieldAccess: {
const FieldAccess& f = e->as<FieldAccess>();
if (FieldAccess::kAnonymousInterfaceBlock_OwnerKind == f.fOwnerKind) {
return kGlobals_Requirement;
}
return this->requirements(f.fBase.get());
}
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
return this->requirements(e->as<Swizzle>().fBase.get());
case Expression::kBinary_Kind: {
const BinaryExpression& b = e->as<BinaryExpression>();
return this->requirements(b.fLeft.get()) | this->requirements(b.fRight.get());
case Expression::Kind::kBinary: {
const BinaryExpression& bin = e->as<BinaryExpression>();
return this->requirements(bin.fLeft.get()) |
this->requirements(bin.fRight.get());
}
case Expression::kIndex_Kind: {
case Expression::Kind::kIndex: {
const IndexExpression& idx = e->as<IndexExpression>();
return this->requirements(idx.fBase.get()) | this->requirements(idx.fIndex.get());
}
case Expression::kPrefix_Kind:
case Expression::Kind::kPrefix:
return this->requirements(e->as<PrefixExpression>().fOperand.get());
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
return this->requirements(e->as<PostfixExpression>().fOperand.get());
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
const TernaryExpression& t = e->as<TernaryExpression>();
return this->requirements(t.fTest.get()) | this->requirements(t.fIfTrue.get()) |
this->requirements(t.fIfFalse.get());
}
case Expression::kVariableReference_Kind: {
case Expression::Kind::kVariableReference: {
const VariableReference& v = e->as<VariableReference>();
Requirements result = kNo_Requirements;
if (v.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
@ -1751,7 +1754,7 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Expressi
} else if (v.fVariable.fModifiers.fFlags & Modifiers::kOut_Flag) {
result = kOutputs_Requirement;
} else if (v.fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag &&
v.fVariable.fType.kind() != Type::kSampler_Kind) {
v.fVariable.fType.typeKind() != Type::TypeKind::kSampler) {
result = kUniforms_Requirement;
} else {
result = kGlobals_Requirement;
@ -1768,19 +1771,19 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Statemen
if (!s) {
return kNo_Requirements;
}
switch (s->fKind) {
case Statement::kBlock_Kind: {
switch (s->kind()) {
case Statement::Kind::kBlock: {
Requirements result = kNo_Requirements;
for (const auto& child : s->as<Block>().fStatements) {
result |= this->requirements(child.get());
}
return result;
}
case Statement::kVarDeclaration_Kind: {
case Statement::Kind::kVarDeclaration: {
const VarDeclaration& var = s->as<VarDeclaration>();
return this->requirements(var.fValue.get());
}
case Statement::kVarDeclarations_Kind: {
case Statement::Kind::kVarDeclarations: {
Requirements result = kNo_Requirements;
const VarDeclarations& decls = *s->as<VarDeclarationsStatement>().fDeclaration;
for (const auto& stmt : decls.fVars) {
@ -1788,36 +1791,36 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Statemen
}
return result;
}
case Statement::kExpression_Kind:
case Statement::Kind::kExpression:
return this->requirements(s->as<ExpressionStatement>().fExpression.get());
case Statement::kReturn_Kind: {
case Statement::Kind::kReturn: {
const ReturnStatement& r = s->as<ReturnStatement>();
return this->requirements(r.fExpression.get());
}
case Statement::kIf_Kind: {
case Statement::Kind::kIf: {
const IfStatement& i = s->as<IfStatement>();
return this->requirements(i.fTest.get()) |
this->requirements(i.fIfTrue.get()) |
this->requirements(i.fIfFalse.get());
}
case Statement::kFor_Kind: {
case Statement::Kind::kFor: {
const ForStatement& f = s->as<ForStatement>();
return this->requirements(f.fInitializer.get()) |
this->requirements(f.fTest.get()) |
this->requirements(f.fNext.get()) |
this->requirements(f.fStatement.get());
}
case Statement::kWhile_Kind: {
case Statement::Kind::kWhile: {
const WhileStatement& w = s->as<WhileStatement>();
return this->requirements(w.fTest.get()) |
this->requirements(w.fStatement.get());
}
case Statement::kDo_Kind: {
case Statement::Kind::kDo: {
const DoStatement& d = s->as<DoStatement>();
return this->requirements(d.fTest.get()) |
this->requirements(d.fStatement.get());
}
case Statement::kSwitch_Kind: {
case Statement::Kind::kSwitch: {
const SwitchStatement& sw = s->as<SwitchStatement>();
Requirements result = this->requirements(sw.fValue.get());
for (const auto& c : sw.fCases) {
@ -1840,7 +1843,7 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Function
if (found == fRequirements.end()) {
fRequirements[&f] = kNo_Requirements;
for (const auto& e : fProgram) {
if (ProgramElement::kFunction_Kind == e.fKind) {
if (e.kind() == ProgramElement::Kind::kFunction) {
const FunctionDefinition& def = e.as<FunctionDefinition>();
if (&def.fDeclaration == &f) {
Requirements reqs = this->requirements(def.fBody.get());

View File

@ -255,7 +255,7 @@ void Parser::error(int offset, String msg) {
bool Parser::isType(StringFragment name) {
const Symbol* s = fSymbols[name];
return s && s->fKind == Symbol::kType_Kind;
return s && s->kind() == Symbol::Kind::kType;
}
/* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? |
@ -357,7 +357,7 @@ ASTNode::ID Parser::enumDeclaration() {
if (!this->expect(Token::Kind::TK_LBRACE, "'{'")) {
return ASTNode::ID::Invalid();
}
fSymbols.add(this->text(name), std::make_unique<Type>(this->text(name), Type::kEnum_Kind));
fSymbols.add(this->text(name), std::make_unique<Type>(this->text(name), Type::TypeKind::kEnum));
CREATE_NODE(result, name.fOffset, ASTNode::Kind::kEnum, this->text(name));
if (!this->checkNext(Token::Kind::TK_RBRACE)) {
Token id;
@ -504,7 +504,7 @@ ASTNode::ID Parser::structDeclaration() {
}
ASTNode& declsNode = getNode(decls);
const Symbol* symbol = fSymbols[(declsNode.begin() + 1)->getTypeData().fName];
SkASSERT(symbol && symbol->fKind == Symbol::kType_Kind);
SkASSERT(symbol && symbol->kind() == Symbol::Kind::kType);
const Type* type = (const Type*) symbol;
for (auto iter = declsNode.begin() + 2; iter != declsNode.end(); ++iter) {
ASTNode& var = *iter;
@ -518,7 +518,8 @@ ASTNode::ID Parser::structDeclaration() {
uint64_t columns = size.getInt();
String typeName = type->name() + "[" + to_string(columns) + "]";
type = fSymbols.takeOwnershipOfSymbol(
std::make_unique<Type>(typeName, Type::kArray_Kind, *type, (int)columns));
std::make_unique<Type>(typeName, Type::TypeKind::kArray, *type,
(int)columns));
}
fields.push_back(Type::Field(declsNode.begin()->getModifiers(), vd.fName, type));
if (vd.fSizeCount ? (var.begin() + (vd.fSizeCount - 1))->fNext : var.fFirstChild) {

View File

@ -34,15 +34,15 @@ String PipelineStageCodeGenerator::getTypeName(const Type& type) {
void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
if (c.fFunction.fBuiltin && c.fFunction.fName == "sample" &&
c.fArguments[0]->fType.kind() != Type::Kind::kSampler_Kind) {
c.fArguments[0]->fType.typeKind() != Type::TypeKind::kSampler) {
SkASSERT(c.fArguments.size() <= 2);
SkASSERT("fragmentProcessor" == c.fArguments[0]->fType.name() ||
"fragmentProcessor?" == c.fArguments[0]->fType.name());
SkASSERT(Expression::kVariableReference_Kind == c.fArguments[0]->fKind);
SkASSERT(c.fArguments[0]->kind() == Expression::Kind::kVariableReference);
int index = 0;
bool found = false;
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const std::unique_ptr<Statement>& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
@ -60,8 +60,8 @@ void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
SkASSERT(found);
size_t childCallIndex = fArgs->fFormatArgs.size();
this->write(Compiler::kFormatArgPlaceholderStr);
bool matrixCall =
c.fArguments.size() == 2 && c.fArguments[1]->fType.kind() == Type::kMatrix_Kind;
bool matrixCall = c.fArguments.size() == 2 &&
c.fArguments[1]->fType.typeKind() == Type::TypeKind::kMatrix;
fArgs->fFormatArgs.push_back(Compiler::FormatArg(
matrixCall ? Compiler::FormatArg::Kind::kChildProcessorWithMatrix
: Compiler::FormatArg::Kind::kChildProcessor,
@ -81,7 +81,7 @@ void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
} else {
int index = 0;
for (const ProgramElement& e : fProgram) {
if (e.fKind == ProgramElement::kFunction_Kind) {
if (e.kind() == ProgramElement::Kind::kFunction) {
if (&e.as<FunctionDefinition>().fDeclaration == &c.fFunction) {
break;
}
@ -124,7 +124,7 @@ void PipelineStageCodeGenerator::writeVariableReference(const VariableReference&
if (found) {
break;
}
if (e.fKind == ProgramElement::Kind::kVar_Kind) {
if (e.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = e.as<VarDeclarations>();
for (const auto& decl : decls.fVars) {
const Variable& var = *decl->as<VarDeclaration>().fVar;
@ -212,10 +212,10 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
}
void PipelineStageCodeGenerator::writeProgramElement(const ProgramElement& p) {
if (p.fKind == ProgramElement::kSection_Kind) {
if (p.kind() == ProgramElement::Kind::kSection) {
return;
}
if (p.fKind == ProgramElement::kVar_Kind) {
if (p.kind() == ProgramElement::Kind::kVar) {
const VarDeclarations& decls = p.as<VarDeclarations>();
if (!decls.fVars.size()) {
return;

View File

@ -134,7 +134,7 @@ const Symbol* Rehydrator::symbol() {
uint8_t count = this->readU8();
const Type* result = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Type>(componentType->name() + "[" + to_string(count) + "]",
Type::kArray_Kind, *componentType, count));
Type::TypeKind::kArray, *componentType, count));
this->addSymbol(id, result);
return result;
}
@ -142,7 +142,7 @@ const Symbol* Rehydrator::symbol() {
uint16_t id = this->readU16();
StringFragment name = this->readString();
const Type* result = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Type>(name, Type::kEnum_Kind));
std::make_unique<Type>(name, Type::TypeKind::kEnum));
this->addSymbol(id, result);
return result;
}
@ -154,7 +154,7 @@ const Symbol* Rehydrator::symbol() {
std::vector<const Variable*> parameters;
parameters.reserve(parameterCount);
for (int i = 0; i < parameterCount; ++i) {
parameters.push_back(this->symbolRef<Variable>(Symbol::kVariable_Kind));
parameters.push_back(this->symbolRef<Variable>(Symbol::Kind::kVariable));
}
const Type* returnType = this->type();
const FunctionDeclaration* result =
@ -165,7 +165,7 @@ const Symbol* Rehydrator::symbol() {
return result;
}
case kField_Command: {
const Variable* owner = this->symbolRef<Variable>(Symbol::kVariable_Kind);
const Variable* owner = this->symbolRef<Variable>(Symbol::Kind::kVariable);
uint8_t index = this->readU8();
const Field* result = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Field>(/*offset=*/-1, *owner, index));
@ -175,7 +175,7 @@ const Symbol* Rehydrator::symbol() {
uint16_t id = this->readU16();
const Type* base = this->type();
const Type* result = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Type>(base->name() + "?", Type::kNullable_Kind, *base));
std::make_unique<Type>(base->name() + "?", Type::TypeKind::kNullable, *base));
this->addSymbol(id, result);
return result;
}
@ -205,7 +205,7 @@ const Symbol* Rehydrator::symbol() {
uint16_t id = this->readU16();
StringFragment name = this->readString();
const Symbol* result = (*fSymbolTable)[name];
SkASSERT(result && result->fKind == Symbol::kType_Kind);
SkASSERT(result && result->kind() == Symbol::Kind::kType);
this->addSymbol(id, result);
return result;
}
@ -216,7 +216,7 @@ const Symbol* Rehydrator::symbol() {
functions.reserve(length);
for (int i = 0; i < length; ++i) {
const Symbol* f = this->symbol();
SkASSERT(f && f->fKind == Symbol::kFunctionDeclaration_Kind);
SkASSERT(f && f->kind() == Symbol::Kind::kFunctionDeclaration);
functions.push_back((const FunctionDeclaration*) f);
}
const UnresolvedFunction* result = fSymbolTable->takeOwnershipOfSymbol(
@ -244,7 +244,7 @@ const Symbol* Rehydrator::symbol() {
const Type* Rehydrator::type() {
const Symbol* result = this->symbol();
SkASSERT(result->fKind == Symbol::kType_Kind);
SkASSERT(result->kind() == Symbol::Kind::kType);
return (const Type*) result;
}
@ -267,7 +267,7 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
StringFragment typeName = this->readString();
std::shared_ptr<SymbolTable> symbols = this->symbolTable();
for (auto& s : symbols->fOwnedSymbols) {
SkASSERT(s->fKind == Symbol::kVariable_Kind);
SkASSERT(s->kind() == Symbol::Kind::kVariable);
Variable& v = (Variable&) *s;
int value = this->readS32();
v.fInitialValue = symbols->takeOwnershipOfIRNode(
@ -278,13 +278,13 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
}
case Rehydrator::kFunctionDefinition_Command: {
const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
Symbol::kFunctionDeclaration_Kind);
Symbol::Kind::kFunctionDeclaration);
std::unique_ptr<Statement> body = this->statement();
std::unordered_set<const FunctionDeclaration*> refs;
uint8_t refCount = this->readU8();
for (int i = 0; i < refCount; ++i) {
refs.insert(this->symbolRef<FunctionDeclaration>(
Symbol::kFunctionDeclaration_Kind));
Symbol::Kind::kFunctionDeclaration));
}
FunctionDefinition* result = new FunctionDefinition(-1, *decl, std::move(body),
std::move(refs));
@ -293,7 +293,7 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
}
case Rehydrator::kInterfaceBlock_Command: {
const Symbol* var = this->symbol();
SkASSERT(var && var->fKind == Symbol::kVariable_Kind);
SkASSERT(var && var->kind() == Symbol::Kind::kVariable);
StringFragment typeName = this->readString();
StringFragment instanceName = this->readString();
uint8_t sizeCount = this->readU8();
@ -313,7 +313,7 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
vars.reserve(count);
for (int i = 0 ; i < count; ++i) {
std::unique_ptr<Statement> s = this->statement();
SkASSERT(s->fKind == Statement::kVarDeclaration_Kind);
SkASSERT(s->kind() == Statement::Kind::kVarDeclaration);
vars.emplace_back((VarDeclaration*) s.release());
}
return std::unique_ptr<ProgramElement>(new VarDeclarations(-1, baseType,
@ -407,7 +407,7 @@ std::unique_ptr<Statement> Rehydrator::statement() {
fSymbolTable));
}
case Rehydrator::kVarDeclaration_Command: {
Variable* var = this->symbolRef<Variable>(Symbol::kVariable_Kind);
Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
uint8_t sizeCount = this->readU8();
std::vector<std::unique_ptr<Expression>> sizes;
sizes.reserve(sizeCount);
@ -431,7 +431,7 @@ std::unique_ptr<Statement> Rehydrator::statement() {
vars.reserve(count);
for (int i = 0 ; i < count; ++i) {
std::unique_ptr<Statement> s = this->statement();
SkASSERT(s->fKind == Statement::kVarDeclaration_Kind);
SkASSERT(s->kind() == Statement::Kind::kVarDeclaration);
vars.emplace_back((VarDeclaration*) s.release());
}
return std::make_unique<VarDeclarationsStatement>(
@ -489,16 +489,16 @@ std::unique_ptr<Expression> Rehydrator::expression() {
return std::unique_ptr<Expression>(new FloatLiteral(fContext, -1, u.fFloat));
}
case Rehydrator::kFunctionCall_Command: {
const Type* type = this->type();
const Type& type = *this->type();
const FunctionDeclaration* f = this->symbolRef<FunctionDeclaration>(
Symbol::kFunctionDeclaration_Kind);
Symbol::Kind::kFunctionDeclaration);
uint8_t argCount = this->readU8();
std::vector<std::unique_ptr<Expression>> args;
args.reserve(argCount);
for (int i = 0; i < argCount; ++i) {
args.push_back(this->expression());
}
return std::unique_ptr<Expression>(new FunctionCall(-1, *type, *f, std::move(args)));
return std::make_unique<FunctionCall>(-1, type, *f, std::move(args));
}
case Rehydrator::kIndex_Command: {
std::unique_ptr<Expression> base = this->expression();
@ -547,7 +547,7 @@ std::unique_ptr<Expression> Rehydrator::expression() {
std::move(ifTrue)));
}
case Rehydrator::kVariableReference_Command: {
const Variable* var = this->symbolRef<Variable>(Symbol::kVariable_Kind);
const Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8();
return std::unique_ptr<Expression>(new VariableReference(-1, *var, refKind));
}

View File

@ -156,7 +156,7 @@ static bool is_float(const Context& context, const Type& type) {
}
static bool is_signed(const Context& context, const Type& type) {
if (type.kind() == Type::kVector_Kind) {
if (type.typeKind() == Type::TypeKind::kVector) {
return is_signed(context, type.componentType());
}
return type == *context.fInt_Type || type == *context.fShort_Type ||
@ -164,7 +164,7 @@ static bool is_signed(const Context& context, const Type& type) {
}
static bool is_unsigned(const Context& context, const Type& type) {
if (type.kind() == Type::kVector_Kind) {
if (type.typeKind() == Type::TypeKind::kVector) {
return is_unsigned(context, type.componentType());
}
return type == *context.fUInt_Type || type == *context.fUShort_Type ||
@ -172,7 +172,7 @@ static bool is_unsigned(const Context& context, const Type& type) {
}
static bool is_bool(const Context& context, const Type& type) {
if (type.kind() == Type::kVector_Kind) {
if (type.typeKind() == Type::TypeKind::kVector) {
return is_bool(context, type.componentType());
}
return type == *context.fBool_Type;
@ -423,7 +423,7 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, SpvDecorationOffset,
(SpvId) offset, fDecorationBuffer);
}
if (field.fType->kind() == Type::kMatrix_Kind) {
if (field.fType->typeKind() == Type::TypeKind::kMatrix) {
this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationColMajor,
fDecorationBuffer);
this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationMatrixStride,
@ -435,8 +435,9 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
SpvDecorationRelaxedPrecision, fDecorationBuffer);
}
offset += size;
Type::Kind kind = field.fType->kind();
if ((kind == Type::kArray_Kind || kind == Type::kStruct_Kind) && offset % alignment != 0) {
Type::TypeKind kind = field.fType->typeKind();
if ((kind == Type::TypeKind::kArray || kind == Type::TypeKind::kStruct) &&
offset % alignment != 0) {
offset += alignment - offset % alignment;
}
}
@ -452,7 +453,7 @@ Type SPIRVCodeGenerator::getActualType(const Type& type) {
if (type.isUnsigned()) {
return *fContext.fUInt_Type;
}
if (type.kind() == Type::kMatrix_Kind || type.kind() == Type::kVector_Kind) {
if (type.typeKind() == Type::TypeKind::kMatrix || type.typeKind() == Type::TypeKind::kVector) {
if (type.componentType() == *fContext.fHalf_Type) {
return fContext.fFloat_Type->toCompound(fContext, type.columns(), type.rows());
}
@ -478,8 +479,8 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
auto entry = fTypeMap.find(key);
if (entry == fTypeMap.end()) {
SpvId result = this->nextId();
switch (type.kind()) {
case Type::kScalar_Kind:
switch (type.typeKind()) {
case Type::TypeKind::kScalar:
if (type == *fContext.fBool_Type) {
this->writeInstruction(SpvOpTypeBool, result, fConstantBuffer);
} else if (type == *fContext.fInt_Type || type == *fContext.fShort_Type ||
@ -494,20 +495,20 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
SkASSERT(false);
}
break;
case Type::kVector_Kind:
case Type::TypeKind::kVector:
this->writeInstruction(SpvOpTypeVector, result,
this->getType(type.componentType(), layout),
type.columns(), fConstantBuffer);
break;
case Type::kMatrix_Kind:
case Type::TypeKind::kMatrix:
this->writeInstruction(SpvOpTypeMatrix, result,
this->getType(index_type(fContext, type), layout),
type.columns(), fConstantBuffer);
break;
case Type::kStruct_Kind:
case Type::TypeKind::kStruct:
this->writeStruct(type, layout, result);
break;
case Type::kArray_Kind: {
case Type::TypeKind::kArray: {
if (type.columns() > 0) {
IntLiteral count(fContext, -1, type.columns());
this->writeInstruction(SpvOpTypeArray, result,
@ -527,7 +528,7 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
}
break;
}
case Type::kSampler_Kind: {
case Type::TypeKind::kSampler: {
SpvId image = result;
if (SpvDimSubpassData != type.dimensions()) {
image = this->getType(type.textureType(), layout);
@ -540,11 +541,11 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
}
break;
}
case Type::kSeparateSampler_Kind: {
case Type::TypeKind::kSeparateSampler: {
this->writeInstruction(SpvOpTypeSampler, result, fConstantBuffer);
break;
}
case Type::kTexture_Kind: {
case Type::TypeKind::kTexture: {
this->writeInstruction(SpvOpTypeImage, result,
this->getType(*fContext.fFloat_Type, layout),
type.dimensions(), type.isDepth(), type.isArrayed(),
@ -569,7 +570,7 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
}
SpvId SPIRVCodeGenerator::getImageType(const Type& type) {
SkASSERT(type.kind() == Type::kSampler_Kind);
SkASSERT(type.typeKind() == Type::TypeKind::kSampler);
this->getType(type);
String key = type.name() + to_string((int) fDefaultLayout.fStd);
SkASSERT(fImageTypeMap.find(key) != fImageTypeMap.end());
@ -653,32 +654,32 @@ SpvId SPIRVCodeGenerator::getPointerType(const Type& rawType, const MemoryLayout
}
SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, OutputStream& out) {
switch (expr.fKind) {
case Expression::kBinary_Kind:
switch (expr.kind()) {
case Expression::Kind::kBinary:
return this->writeBinaryExpression(expr.as<BinaryExpression>(), out);
case Expression::kBoolLiteral_Kind:
case Expression::Kind::kBoolLiteral:
return this->writeBoolLiteral(expr.as<BoolLiteral>());
case Expression::kConstructor_Kind:
case Expression::Kind::kConstructor:
return this->writeConstructor(expr.as<Constructor>(), out);
case Expression::kIntLiteral_Kind:
case Expression::Kind::kIntLiteral:
return this->writeIntLiteral(expr.as<IntLiteral>());
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
return this->writeFieldAccess(expr.as<FieldAccess>(), out);
case Expression::kFloatLiteral_Kind:
case Expression::Kind::kFloatLiteral:
return this->writeFloatLiteral(expr.as<FloatLiteral>());
case Expression::kFunctionCall_Kind:
case Expression::Kind::kFunctionCall:
return this->writeFunctionCall(expr.as<FunctionCall>(), out);
case Expression::kPrefix_Kind:
case Expression::Kind::kPrefix:
return this->writePrefixExpression(expr.as<PrefixExpression>(), out);
case Expression::kPostfix_Kind:
case Expression::Kind::kPostfix:
return this->writePostfixExpression(expr.as<PostfixExpression>(), out);
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
return this->writeSwizzle(expr.as<Swizzle>(), out);
case Expression::kVariableReference_Kind:
case Expression::Kind::kVariableReference:
return this->writeVariableReference(expr.as<VariableReference>(), out);
case Expression::kTernary_Kind:
case Expression::Kind::kTernary:
return this->writeTernaryExpression(expr.as<TernaryExpression>(), out);
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
return this->writeIndexExpression(expr.as<IndexExpression>(), out);
default:
#ifdef SK_DEBUG
@ -764,7 +765,7 @@ std::vector<SpvId> SPIRVCodeGenerator::vectorize(
OutputStream& out) {
int vectorSize = 0;
for (const auto& a : args) {
if (a->fType.kind() == Type::kVector_Kind) {
if (a->fType.typeKind() == Type::TypeKind::kVector) {
if (vectorSize) {
SkASSERT(a->fType.columns() == vectorSize);
}
@ -776,7 +777,7 @@ std::vector<SpvId> SPIRVCodeGenerator::vectorize(
std::vector<SpvId> result;
for (const auto& a : args) {
SpvId raw = this->writeExpression(*a, out);
if (vectorSize && a->fType.kind() == Type::kScalar_Kind) {
if (vectorSize && a->fType.typeKind() == Type::TypeKind::kScalar) {
SpvId vector = this->nextId();
this->writeOpCode(SpvOpCompositeConstruct, 3 + vectorSize, out);
this->writeWord(this->getType(a->fType.toCompound(fContext, vectorSize, 1)), out);
@ -1071,7 +1072,7 @@ SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, OutputStream&
}
SpvId SPIRVCodeGenerator::writeConstantVector(const Constructor& c) {
SkASSERT(c.fType.kind() == Type::kVector_Kind && c.isCompileTimeConstant());
SkASSERT(c.fType.typeKind() == Type::TypeKind::kVector && c.isCompileTimeConstant());
SpvId result = this->nextId();
std::vector<SpvId> arguments;
for (size_t i = 0; i < c.fArguments.size(); i++) {
@ -1180,8 +1181,8 @@ void SPIRVCodeGenerator::writeUniformScaleMatrix(SpvId id, SpvId diagonal, const
void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcType,
const Type& dstType, OutputStream& out) {
SkASSERT(srcType.kind() == Type::kMatrix_Kind);
SkASSERT(dstType.kind() == Type::kMatrix_Kind);
SkASSERT(srcType.typeKind() == Type::TypeKind::kMatrix);
SkASSERT(dstType.typeKind() == Type::TypeKind::kMatrix);
SkASSERT(srcType.componentType() == dstType.componentType());
SpvId srcColumnType = this->getType(srcType.componentType().toCompound(fContext,
srcType.rows(),
@ -1288,7 +1289,7 @@ void SPIRVCodeGenerator::addColumnEntry(SpvId columnType, Precision precision,
}
SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStream& out) {
SkASSERT(c.fType.kind() == Type::kMatrix_Kind);
SkASSERT(c.fType.typeKind() == Type::TypeKind::kMatrix);
// go ahead and write the arguments so we don't try to write new instructions in the middle of
// an instruction
std::vector<SpvId> arguments;
@ -1298,11 +1299,13 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStr
SpvId result = this->nextId();
int rows = c.fType.rows();
int columns = c.fType.columns();
if (arguments.size() == 1 && c.fArguments[0]->fType.kind() == Type::kScalar_Kind) {
if (arguments.size() == 1 && c.fArguments[0]->fType.typeKind() == Type::TypeKind::kScalar) {
this->writeUniformScaleMatrix(result, arguments[0], c.fType, out);
} else if (arguments.size() == 1 && c.fArguments[0]->fType.kind() == Type::kMatrix_Kind) {
} else if (arguments.size() == 1 &&
c.fArguments[0]->fType.typeKind() == Type::TypeKind::kMatrix) {
this->writeMatrixCopy(result, arguments[0], c.fArguments[0]->fType, c.fType, out);
} else if (arguments.size() == 1 && c.fArguments[0]->fType.kind() == Type::kVector_Kind) {
} else if (arguments.size() == 1 &&
c.fArguments[0]->fType.typeKind() == Type::TypeKind::kVector) {
SkASSERT(c.fType.rows() == 2 && c.fType.columns() == 2);
SkASSERT(c.fArguments[0]->fType.columns() == 4);
SpvId componentType = this->getType(c.fType.componentType());
@ -1327,8 +1330,9 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStr
int currentCount = 0;
Precision precision = c.fType.highPrecision() ? Precision::kHigh : Precision::kLow;
for (size_t i = 0; i < arguments.size(); i++) {
if (currentCount == 0 && c.fArguments[i]->fType.kind() == Type::kVector_Kind &&
c.fArguments[i]->fType.columns() == c.fType.rows()) {
if (currentCount == 0 &&
c.fArguments[i]->fType.typeKind() == Type::TypeKind::kVector &&
c.fArguments[i]->fType.columns() == c.fType.rows()) {
// this is a complete column by itself
columnIds.push_back(arguments[i]);
} else {
@ -1360,7 +1364,7 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStr
}
SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, OutputStream& out) {
SkASSERT(c.fType.kind() == Type::kVector_Kind);
SkASSERT(c.fType.typeKind() == Type::TypeKind::kVector);
if (c.isCompileTimeConstant()) {
return this->writeConstantVector(c);
}
@ -1368,7 +1372,7 @@ SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, OutputStr
// an instruction
std::vector<SpvId> arguments;
for (size_t i = 0; i < c.fArguments.size(); i++) {
if (c.fArguments[i]->fType.kind() == Type::kVector_Kind) {
if (c.fArguments[i]->fType.typeKind() == Type::TypeKind::kVector) {
// SPIR-V doesn't support vector(vector-of-different-type) directly, so we need to
// extract the components and convert them in that case manually. On top of that,
// as of this writing there's a bug in the Intel Vulkan driver where OpCreateComposite
@ -1448,7 +1452,7 @@ SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, OutputStr
}
}
SpvId result = this->nextId();
if (arguments.size() == 1 && c.fArguments[0]->fType.kind() == Type::kScalar_Kind) {
if (arguments.size() == 1 && c.fArguments[0]->fType.typeKind() == Type::TypeKind::kScalar) {
this->writeOpCode(SpvOpCompositeConstruct, 3 + c.fType.columns(), out);
this->writeWord(this->getType(c.fType), out);
this->writeWord(result, out);
@ -1468,7 +1472,7 @@ SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, OutputStr
}
SpvId SPIRVCodeGenerator::writeArrayConstructor(const Constructor& c, OutputStream& out) {
SkASSERT(c.fType.kind() == Type::kArray_Kind);
SkASSERT(c.fType.typeKind() == Type::TypeKind::kArray);
// go ahead and write the arguments so we don't try to write new instructions in the middle of
// an instruction
std::vector<SpvId> arguments;
@ -1501,12 +1505,12 @@ SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, OutputStream& o
c.fType == *fContext.fUByte_Type) {
return this->writeUIntConstructor(c, out);
}
switch (c.fType.kind()) {
case Type::kVector_Kind:
switch (c.fType.typeKind()) {
case Type::TypeKind::kVector:
return this->writeVectorConstructor(c, out);
case Type::kMatrix_Kind:
case Type::TypeKind::kMatrix:
return this->writeMatrixConstructor(c, out);
case Type::kArray_Kind:
case Type::TypeKind::kArray:
return this->writeArrayConstructor(c, out);
default:
#ifdef SK_DEBUG
@ -1534,8 +1538,8 @@ SpvStorageClass_ get_storage_class(const Modifiers& modifiers) {
}
SpvStorageClass_ get_storage_class(const Expression& expr) {
switch (expr.fKind) {
case Expression::kVariableReference_Kind: {
switch (expr.kind()) {
case Expression::Kind::kVariableReference: {
const Variable& var = ((VariableReference&) expr).fVariable;
if (var.fStorage != Variable::kGlobal_Storage) {
return SpvStorageClassFunction;
@ -1546,9 +1550,9 @@ SpvStorageClass_ get_storage_class(const Expression& expr) {
}
return result;
}
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
return get_storage_class(*((FieldAccess&) expr).fBase);
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
return get_storage_class(*((IndexExpression&) expr).fBase);
default:
return SpvStorageClassFunction;
@ -1557,14 +1561,14 @@ SpvStorageClass_ get_storage_class(const Expression& expr) {
std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, OutputStream& out) {
std::vector<SpvId> chain;
switch (expr.fKind) {
case Expression::kIndex_Kind: {
switch (expr.kind()) {
case Expression::Kind::kIndex: {
IndexExpression& indexExpr = (IndexExpression&) expr;
chain = this->getAccessChain(*indexExpr.fBase, out);
chain.push_back(this->writeExpression(*indexExpr.fIndex, out));
break;
}
case Expression::kFieldAccess_Kind: {
case Expression::Kind::kFieldAccess: {
FieldAccess& fieldExpr = (FieldAccess&) expr;
chain = this->getAccessChain(*fieldExpr.fBase, out);
IntLiteral index(fContext, -1, fieldExpr.fFieldIndex);
@ -1695,13 +1699,13 @@ private:
std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr,
OutputStream& out) {
Precision precision = expr.fType.highPrecision() ? Precision::kHigh : Precision::kLow;
switch (expr.fKind) {
case Expression::kVariableReference_Kind: {
switch (expr.kind()) {
case Expression::Kind::kVariableReference: {
SpvId type;
const Variable& var = ((VariableReference&) expr).fVariable;
if (var.fModifiers.fLayout.fBuiltin == SK_IN_BUILTIN) {
type = this->getType(Type("sk_in", Type::kArray_Kind, var.fType.componentType(),
fSkInCount));
type = this->getType(Type("sk_in", Type::TypeKind::kArray,
var.fType.componentType(), fSkInCount));
} else {
type = this->getType(expr.fType);
}
@ -1712,8 +1716,8 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
type,
precision));
}
case Expression::kIndex_Kind: // fall through
case Expression::kFieldAccess_Kind: {
case Expression::Kind::kIndex: // fall through
case Expression::Kind::kFieldAccess: {
std::vector<SpvId> chain = this->getAccessChain(expr, out);
SpvId member = this->nextId();
this->writeOpCode(SpvOpAccessChain, (SpvId) (3 + chain.size()), out);
@ -1728,7 +1732,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
this->getType(expr.fType),
precision));
}
case Expression::kSwizzle_Kind: {
case Expression::Kind::kSwizzle: {
Swizzle& swizzle = (Swizzle&) expr;
size_t count = swizzle.fComponents.size();
SpvId base = this->getLValue(*swizzle.fBase, out)->getPointer();
@ -1758,7 +1762,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
precision));
}
}
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
TernaryExpression& t = (TernaryExpression&) expr;
SpvId test = this->writeExpression(*t.fTest, out);
SpvId end = this->nextId();
@ -1929,7 +1933,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
}
SpvId SPIRVCodeGenerator::writeIndexExpression(const IndexExpression& expr, OutputStream& out) {
if (expr.fBase->fType.kind() == Type::Kind::kVector_Kind) {
if (expr.fBase->fType.typeKind() == Type::TypeKind::kVector) {
SpvId base = this->writeExpression(*expr.fBase, out);
SpvId index = this->writeExpression(*expr.fIndex, out);
SpvId result = this->nextId();
@ -2018,7 +2022,7 @@ SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType,
SpvId SPIRVCodeGenerator::foldToBool(SpvId id, const Type& operandType, SpvOp op,
OutputStream& out) {
if (operandType.kind() == Type::kVector_Kind) {
if (operandType.typeKind() == Type::TypeKind::kVector) {
SpvId result = this->nextId();
this->writeInstruction(op, this->getType(*fContext.fBool_Type), result, id, out);
return result;
@ -2031,7 +2035,7 @@ SpvId SPIRVCodeGenerator::writeMatrixComparison(const Type& operandType, SpvId l
SpvOp_ vectorMergeOperator, SpvOp_ mergeOperator,
OutputStream& out) {
SpvOp_ compareOp = is_float(fContext, operandType) ? floatOperator : intOperator;
SkASSERT(operandType.kind() == Type::kMatrix_Kind);
SkASSERT(operandType.typeKind() == Type::TypeKind::kMatrix);
SpvId columnType = this->getType(operandType.componentType().toCompound(fContext,
operandType.rows(),
1));
@ -2066,7 +2070,7 @@ SpvId SPIRVCodeGenerator::writeComponentwiseMatrixBinary(const Type& operandType
SpvOp_ intOperator,
OutputStream& out) {
SpvOp_ op = is_float(fContext, operandType) ? floatOperator : intOperator;
SkASSERT(operandType.kind() == Type::kMatrix_Kind);
SkASSERT(operandType.typeKind() == Type::TypeKind::kMatrix);
SpvId columnType = this->getType(operandType.componentType().toCompound(fContext,
operandType.rows(),
1));
@ -2109,7 +2113,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
// IR allows mismatched types in expressions (e.g. float2 * float), but they need special
// handling in SPIR-V
if (this->getActualType(leftType) != this->getActualType(rightType)) {
if (leftType.kind() == Type::kVector_Kind && rightType.isNumber()) {
if (leftType.typeKind() == Type::TypeKind::kVector && rightType.isNumber()) {
if (op == Token::Kind::TK_SLASH) {
SpvId one = this->writeExpression(*create_literal_1(fContext, rightType), out);
SpvId inverse = this->nextId();
@ -2134,7 +2138,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
}
rhs = vec;
operandType = &leftType;
} else if (rightType.kind() == Type::kVector_Kind && leftType.isNumber()) {
} else if (rightType.typeKind() == Type::TypeKind::kVector && leftType.isNumber()) {
if (op == Token::Kind::TK_STAR) {
SpvId result = this->nextId();
this->writeInstruction(SpvOpVectorTimesScalar, this->getType(resultType),
@ -2152,26 +2156,26 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
}
lhs = vec;
operandType = &rightType;
} else if (leftType.kind() == Type::kMatrix_Kind) {
} else if (leftType.typeKind() == Type::TypeKind::kMatrix) {
SpvOp_ spvop;
if (rightType.kind() == Type::kMatrix_Kind) {
if (rightType.typeKind() == Type::TypeKind::kMatrix) {
spvop = SpvOpMatrixTimesMatrix;
} else if (rightType.kind() == Type::kVector_Kind) {
} else if (rightType.typeKind() == Type::TypeKind::kVector) {
spvop = SpvOpMatrixTimesVector;
} else {
SkASSERT(rightType.kind() == Type::kScalar_Kind);
SkASSERT(rightType.typeKind() == Type::TypeKind::kScalar);
spvop = SpvOpMatrixTimesScalar;
}
SpvId result = this->nextId();
this->writeInstruction(spvop, this->getType(resultType), result, lhs, rhs, out);
return result;
} else if (rightType.kind() == Type::kMatrix_Kind) {
} else if (rightType.typeKind() == Type::TypeKind::kMatrix) {
SpvId result = this->nextId();
if (leftType.kind() == Type::kVector_Kind) {
if (leftType.typeKind() == Type::TypeKind::kVector) {
this->writeInstruction(SpvOpVectorTimesMatrix, this->getType(resultType), result,
lhs, rhs, out);
} else {
SkASSERT(leftType.kind() == Type::kScalar_Kind);
SkASSERT(leftType.typeKind() == Type::TypeKind::kScalar);
this->writeInstruction(SpvOpMatrixTimesScalar, this->getType(resultType), result,
rhs, lhs, out);
}
@ -2187,13 +2191,13 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
}
switch (op) {
case Token::Kind::TK_EQEQ: {
if (operandType->kind() == Type::kMatrix_Kind) {
if (operandType->typeKind() == Type::TypeKind::kMatrix) {
return this->writeMatrixComparison(*operandType, lhs, rhs, SpvOpFOrdEqual,
SpvOpIEqual, SpvOpAll, SpvOpLogicalAnd, out);
}
SkASSERT(resultType == *fContext.fBool_Type);
const Type* tmpType;
if (operandType->kind() == Type::kVector_Kind) {
if (operandType->typeKind() == Type::TypeKind::kVector) {
tmpType = &fContext.fBool_Type->toCompound(fContext,
operandType->columns(),
operandType->rows());
@ -2206,13 +2210,13 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
*operandType, SpvOpAll, out);
}
case Token::Kind::TK_NEQ:
if (operandType->kind() == Type::kMatrix_Kind) {
if (operandType->typeKind() == Type::TypeKind::kMatrix) {
return this->writeMatrixComparison(*operandType, lhs, rhs, SpvOpFOrdNotEqual,
SpvOpINotEqual, SpvOpAny, SpvOpLogicalOr, out);
}
SkASSERT(resultType == *fContext.fBool_Type);
const Type* tmpType;
if (operandType->kind() == Type::kVector_Kind) {
if (operandType->typeKind() == Type::TypeKind::kVector) {
tmpType = &fContext.fBool_Type->toCompound(fContext,
operandType->columns(),
operandType->rows());
@ -2244,8 +2248,8 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
SpvOpFOrdLessThanEqual, SpvOpSLessThanEqual,
SpvOpULessThanEqual, SpvOpUndef, out);
case Token::Kind::TK_PLUS:
if (leftType.kind() == Type::kMatrix_Kind &&
rightType.kind() == Type::kMatrix_Kind) {
if (leftType.typeKind() == Type::TypeKind::kMatrix &&
rightType.typeKind() == Type::TypeKind::kMatrix) {
SkASSERT(leftType == rightType);
return this->writeComponentwiseMatrixBinary(leftType, lhs, rhs,
SpvOpFAdd, SpvOpIAdd, out);
@ -2253,8 +2257,8 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFAdd,
SpvOpIAdd, SpvOpIAdd, SpvOpUndef, out);
case Token::Kind::TK_MINUS:
if (leftType.kind() == Type::kMatrix_Kind &&
rightType.kind() == Type::kMatrix_Kind) {
if (leftType.typeKind() == Type::TypeKind::kMatrix &&
rightType.typeKind() == Type::TypeKind::kMatrix) {
SkASSERT(leftType == rightType);
return this->writeComponentwiseMatrixBinary(leftType, lhs, rhs,
SpvOpFSub, SpvOpISub, out);
@ -2262,8 +2266,8 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFSub,
SpvOpISub, SpvOpISub, SpvOpUndef, out);
case Token::Kind::TK_STAR:
if (leftType.kind() == Type::kMatrix_Kind &&
rightType.kind() == Type::kMatrix_Kind) {
if (leftType.typeKind() == Type::TypeKind::kMatrix &&
rightType.typeKind() == Type::TypeKind::kMatrix) {
// matrix multiply
SpvId result = this->nextId();
this->writeInstruction(SpvOpMatrixTimesMatrix, this->getType(resultType), result,
@ -2701,13 +2705,15 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool a
SpvId typeId;
if (intf.fVariable.fModifiers.fLayout.fBuiltin == SK_IN_BUILTIN) {
for (const auto& e : fProgram) {
if (e.fKind == ProgramElement::kModifiers_Kind) {
if (e.kind() == ProgramElement::Kind::kModifiers) {
const Modifiers& m = ((ModifiersDeclaration&) e).fModifiers;
update_sk_in_count(m, &fSkInCount);
}
}
typeId = this->getType(Type("sk_in", Type::kArray_Kind, intf.fVariable.fType.componentType(),
fSkInCount), memoryLayout);
typeId = this->getType(Type("sk_in", Type::TypeKind::kArray,
intf.fVariable.fType.componentType(),
fSkInCount),
memoryLayout);
} else {
typeId = this->getType(*type, memoryLayout);
}
@ -2762,7 +2768,7 @@ bool is_dead(const Variable& var) {
void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclarations& decl,
OutputStream& out) {
for (size_t i = 0; i < decl.fVars.size(); i++) {
if (decl.fVars[i]->fKind == Statement::kNop_Kind) {
if (decl.fVars[i]->kind() == Statement::Kind::kNop) {
continue;
}
const VarDeclaration& varDecl = (VarDeclaration&) *decl.fVars[i];
@ -2791,9 +2797,9 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio
} else if (var->fModifiers.fFlags & Modifiers::kOut_Flag) {
storageClass = SpvStorageClassOutput;
} else if (var->fModifiers.fFlags & Modifiers::kUniform_Flag) {
if (var->fType.kind() == Type::kSampler_Kind ||
var->fType.kind() == Type::kSeparateSampler_Kind ||
var->fType.kind() == Type::kTexture_Kind) {
if (var->fType.typeKind() == Type::TypeKind::kSampler ||
var->fType.typeKind() == Type::TypeKind::kSeparateSampler ||
var->fType.typeKind() == Type::TypeKind::kTexture) {
storageClass = SpvStorageClassUniformConstant;
} else {
storageClass = SpvStorageClassUniform;
@ -2805,7 +2811,7 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio
fVariableMap[var] = id;
SpvId type;
if (var->fModifiers.fLayout.fBuiltin == SK_IN_BUILTIN) {
type = this->getPointerType(Type("sk_in", Type::kArray_Kind,
type = this->getPointerType(Type("sk_in", Type::TypeKind::kArray,
var->fType.componentType(), fSkInCount),
storageClass);
} else {
@ -2834,7 +2840,7 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio
void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, OutputStream& out) {
for (const auto& stmt : decl.fVars) {
SkASSERT(stmt->fKind == Statement::kVarDeclaration_Kind);
SkASSERT(stmt->kind() == Statement::Kind::kVarDeclaration);
VarDeclaration& varDecl = (VarDeclaration&) *stmt;
const Variable* var = varDecl.fVar;
// These haven't been implemented in our SPIR-V generator yet and we only currently use them
@ -2857,43 +2863,43 @@ void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, Outpu
}
void SPIRVCodeGenerator::writeStatement(const Statement& s, OutputStream& out) {
switch (s.fKind) {
case Statement::kNop_Kind:
switch (s.kind()) {
case Statement::Kind::kNop:
break;
case Statement::kBlock_Kind:
case Statement::Kind::kBlock:
this->writeBlock((Block&) s, out);
break;
case Statement::kExpression_Kind:
case Statement::Kind::kExpression:
this->writeExpression(*s.as<ExpressionStatement>().fExpression, out);
break;
case Statement::kReturn_Kind:
case Statement::Kind::kReturn:
this->writeReturnStatement(s.as<ReturnStatement>(), out);
break;
case Statement::kVarDeclarations_Kind:
case Statement::Kind::kVarDeclarations:
this->writeVarDeclarations(*s.as<VarDeclarationsStatement>().fDeclaration, out);
break;
case Statement::kIf_Kind:
case Statement::Kind::kIf:
this->writeIfStatement(s.as<IfStatement>(), out);
break;
case Statement::kFor_Kind:
case Statement::Kind::kFor:
this->writeForStatement(s.as<ForStatement>(), out);
break;
case Statement::kWhile_Kind:
case Statement::Kind::kWhile:
this->writeWhileStatement(s.as<WhileStatement>(), out);
break;
case Statement::kDo_Kind:
case Statement::Kind::kDo:
this->writeDoStatement(s.as<DoStatement>(), out);
break;
case Statement::kSwitch_Kind:
case Statement::Kind::kSwitch:
this->writeSwitchStatement(s.as<SwitchStatement>(), out);
break;
case Statement::kBreak_Kind:
case Statement::Kind::kBreak:
this->writeInstruction(SpvOpBranch, fBreakTarget.top(), out);
break;
case Statement::kContinue_Kind:
case Statement::Kind::kContinue:
this->writeInstruction(SpvOpBranch, fContinueTarget.top(), out);
break;
case Statement::kDiscard_Kind:
case Statement::Kind::kDiscard:
this->writeInstruction(SpvOpKill, out);
break;
default:
@ -3084,7 +3090,7 @@ void SPIRVCodeGenerator::writeGeometryShaderExecutionMode(SpvId entryPoint, Outp
SkASSERT(fProgram.fKind == Program::kGeometry_Kind);
int invocations = 1;
for (const auto& e : fProgram) {
if (e.fKind == ProgramElement::kModifiers_Kind) {
if (e.kind() == ProgramElement::Kind::kModifiers) {
const Modifiers& m = ((ModifiersDeclaration&) e).fModifiers;
if (m.fFlags & Modifiers::kIn_Flag) {
if (m.fLayout.fInvocations != -1) {
@ -3153,13 +3159,13 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
// assign IDs to functions, determine sk_in size
int skInSize = -1;
for (const auto& e : program) {
switch (e.fKind) {
case ProgramElement::kFunction_Kind: {
switch (e.kind()) {
case ProgramElement::Kind::kFunction: {
FunctionDefinition& f = (FunctionDefinition&) e;
fFunctionMap[&f.fDeclaration] = this->nextId();
break;
}
case ProgramElement::kModifiers_Kind: {
case ProgramElement::Kind::kModifiers: {
Modifiers& m = ((ModifiersDeclaration&) e).fModifiers;
if (m.fFlags & Modifiers::kIn_Flag) {
switch (m.fLayout.fPrimitive) {
@ -3185,7 +3191,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
}
}
for (const auto& e : program) {
if (e.fKind == ProgramElement::kInterfaceBlock_Kind) {
if (e.kind() == ProgramElement::Kind::kInterfaceBlock) {
InterfaceBlock& intf = (InterfaceBlock&) e;
if (SK_IN_BUILTIN == intf.fVariable.fModifiers.fLayout.fBuiltin) {
SkASSERT(skInSize != -1);
@ -3201,12 +3207,12 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
}
}
for (const auto& e : program) {
if (e.fKind == ProgramElement::kVar_Kind) {
if (e.kind() == ProgramElement::Kind::kVar) {
this->writeGlobalVars(program.fKind, ((VarDeclarations&) e), body);
}
}
for (const auto& e : program) {
if (e.fKind == ProgramElement::kFunction_Kind) {
if (e.kind() == ProgramElement::Kind::kFunction) {
this->writeFunction(((FunctionDefinition&) e), body);
}
}
@ -3262,7 +3268,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
out);
}
for (const auto& e : program) {
if (e.fKind == ProgramElement::kExtension_Kind) {
if (e.kind() == ProgramElement::Kind::kExtension) {
this->writeInstruction(SpvOpSourceExtension, ((Extension&) e).fName.c_str(), out);
}
}

View File

@ -29,8 +29,8 @@ namespace SkSL {
SectionAndParameterHelper::SectionAndParameterHelper(const Program* program, ErrorReporter& errors)
: fProgram(*program) {
for (const auto& p : fProgram) {
switch (p.fKind) {
case ProgramElement::kVar_Kind: {
switch (p.kind()) {
case ProgramElement::Kind::kVar: {
const VarDeclarations& decls = (const VarDeclarations&) p;
for (const auto& raw : decls.fVars) {
const VarDeclaration& decl = (VarDeclaration&) *raw;
@ -40,7 +40,7 @@ SectionAndParameterHelper::SectionAndParameterHelper(const Program* program, Err
}
break;
}
case ProgramElement::kSection_Kind: {
case ProgramElement::Kind::kSection: {
const Section& s = (const Section&) p;
if (IsSupportedSection(s.fName.c_str())) {
if (SectionRequiresArgument(s.fName.c_str()) && !s.fArgument.size()) {

View File

@ -20,20 +20,20 @@
namespace SkSL {
static inline bool check_ref(Expression* expr) {
switch (expr->fKind) {
case Expression::kExternalValue_Kind:
switch (expr->kind()) {
case Expression::Kind::kExternalValue:
return true;
case Expression::kFieldAccess_Kind:
case Expression::Kind::kFieldAccess:
return check_ref(((FieldAccess*) expr)->fBase.get());
case Expression::kIndex_Kind:
case Expression::Kind::kIndex:
return check_ref(((IndexExpression*) expr)->fBase.get());
case Expression::kSwizzle_Kind:
case Expression::Kind::kSwizzle:
return check_ref(((Swizzle*) expr)->fBase.get());
case Expression::kTernary_Kind: {
case Expression::Kind::kTernary: {
TernaryExpression* t = (TernaryExpression*) expr;
return check_ref(t->fIfTrue.get()) && check_ref(t->fIfFalse.get());
}
case Expression::kVariableReference_Kind: {
case Expression::Kind::kVariableReference: {
VariableReference* ref = (VariableReference*) expr;
return ref->fRefKind == VariableReference::kWrite_RefKind ||
ref->fRefKind == VariableReference::kReadWrite_RefKind;
@ -47,7 +47,7 @@ static inline bool check_ref(Expression* expr) {
* A binary operation.
*/
struct BinaryExpression : public Expression {
static constexpr Kind kExpressionKind = kBinary_Kind;
static constexpr Kind kExpressionKind = Kind::kBinary;
BinaryExpression(int offset, std::unique_ptr<Expression> left, Token::Kind op,
std::unique_ptr<Expression> right, const Type& type)

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A block of multiple statements functioning as a single statement.
*/
struct Block : public Statement {
static constexpr Kind kStatementKind = kBlock_Kind;
static constexpr Kind kStatementKind = Kind::kBlock;
Block(int offset, std::vector<std::unique_ptr<Statement>> statements,
const std::shared_ptr<SymbolTable> symbols = nullptr, bool isScope = true)

View File

@ -17,7 +17,7 @@ namespace SkSL {
* Represents 'true' or 'false'.
*/
struct BoolLiteral : public Expression {
static constexpr Kind kExpressionKind = kBoolLiteral_Kind;
static constexpr Kind kExpressionKind = Kind::kBoolLiteral;
BoolLiteral(const Context& context, int offset, bool value)
: INHERITED(offset, kExpressionKind, *context.fBool_Type)

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A 'break' statement.
*/
struct BreakStatement : public Statement {
static constexpr Kind kStatementKind = kBreak_Kind;
static constexpr Kind kStatementKind = Kind::kBreak;
BreakStatement(int offset)
: INHERITED(offset, kStatementKind) {}

View File

@ -26,7 +26,7 @@ namespace SkSL {
* collection of vectors and scalars totalling exactly the right number of scalar components.
*/
struct Constructor : public Expression {
static constexpr Kind kExpressionKind = kConstructor_Kind;
static constexpr Kind kExpressionKind = Kind::kConstructor;
Constructor(int offset, const Type& type, std::vector<std::unique_ptr<Expression>> arguments)
: INHERITED(offset, kExpressionKind, type)
@ -34,7 +34,7 @@ struct Constructor : public Expression {
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override {
if (fArguments.size() == 1 && fArguments[0]->fKind == Expression::kIntLiteral_Kind) {
if (fArguments.size() == 1 && fArguments[0]->kind() == Expression::Kind::kIntLiteral) {
if (fType.isFloat()) {
// promote float(1) to 1.0
int64_t intValue = fArguments[0]->as<IntLiteral>().fValue;
@ -100,9 +100,9 @@ struct Constructor : public Expression {
}
bool compareConstant(const Context& context, const Expression& other) const override {
SkASSERT(other.fKind == Expression::kConstructor_Kind && other.fType == fType);
SkASSERT(other.kind() == Expression::Kind::kConstructor && other.fType == fType);
Constructor& c = (Constructor&) other;
if (c.fType.kind() == Type::kVector_Kind) {
if (c.fType.typeKind() == Type::TypeKind::kVector) {
bool isFloat = c.fType.columns() > 1 ? c.fType.componentType().isFloat()
: c.fType.isFloat();
for (int i = 0; i < fType.columns(); i++) {
@ -119,7 +119,7 @@ struct Constructor : public Expression {
// shouldn't be possible to have a constant constructor that isn't a vector or matrix;
// a constant scalar constructor should have been collapsed down to the appropriate
// literal
SkASSERT(fType.kind() == Type::kMatrix_Kind);
SkASSERT(fType.typeKind() == Type::TypeKind::kMatrix);
for (int col = 0; col < fType.columns(); col++) {
for (int row = 0; row < fType.rows(); row++) {
if (getMatComponent(col, row) != c.getMatComponent(col, row)) {
@ -132,8 +132,8 @@ struct Constructor : public Expression {
template <typename type>
type getVecComponent(int index) const {
SkASSERT(fType.kind() == Type::kVector_Kind);
if (fArguments.size() == 1 && fArguments[0]->fType.kind() == Type::kScalar_Kind) {
SkASSERT(fType.typeKind() == Type::TypeKind::kVector);
if (fArguments.size() == 1 && fArguments[0]->fType.typeKind() == Type::TypeKind::kScalar) {
// This constructor just wraps a scalar. Propagate out the value.
if (std::is_floating_point<type>::value) {
return fArguments[0]->getConstantFloat();
@ -150,7 +150,7 @@ struct Constructor : public Expression {
break;
}
if (arg->fType.kind() == Type::kScalar_Kind) {
if (arg->fType.typeKind() == Type::TypeKind::kScalar) {
if (index == current) {
// We're on the proper argument, and it's a scalar; fetch it.
if (std::is_floating_point<type>::value) {
@ -163,8 +163,8 @@ struct Constructor : public Expression {
continue;
}
switch (arg->fKind) {
case kConstructor_Kind: {
switch (arg->kind()) {
case Kind::kConstructor: {
const Constructor& constructor = static_cast<const Constructor&>(*arg);
if (current + constructor.fType.columns() > index) {
// We've found a constructor that overlaps the proper argument. Descend into
@ -177,7 +177,7 @@ struct Constructor : public Expression {
}
break;
}
case kPrefix_Kind: {
case Kind::kPrefix: {
const PrefixExpression& prefix = static_cast<const PrefixExpression&>(*arg);
if (current + prefix.fType.columns() > index) {
// We found a prefix operator that contains the proper argument. Descend
@ -186,7 +186,7 @@ struct Constructor : public Expression {
SkASSERT(prefix.fOperator == Token::Kind::TK_MINUS);
// We expect the - prefix to always be attached to a constructor.
SkASSERT(prefix.fOperand->fKind == kConstructor_Kind);
SkASSERT(prefix.fOperand->kind() == Kind::kConstructor);
const Constructor& constructor =
static_cast<const Constructor&>(*prefix.fOperand);
@ -227,10 +227,10 @@ struct Constructor : public Expression {
SKSL_FLOAT getMatComponent(int col, int row) const override {
SkASSERT(this->isCompileTimeConstant());
SkASSERT(fType.kind() == Type::kMatrix_Kind);
SkASSERT(fType.typeKind() == Type::TypeKind::kMatrix);
SkASSERT(col < fType.columns() && row < fType.rows());
if (fArguments.size() == 1) {
if (fArguments[0]->fType.kind() == Type::kScalar_Kind) {
if (fArguments[0]->fType.typeKind() == Type::TypeKind::kScalar) {
// single scalar argument, so matrix is of the form:
// x 0 0
// 0 x 0
@ -238,8 +238,8 @@ struct Constructor : public Expression {
// return x if col == row
return col == row ? fArguments[0]->getConstantFloat() : 0.0;
}
if (fArguments[0]->fType.kind() == Type::kMatrix_Kind) {
SkASSERT(fArguments[0]->fKind == Expression::kConstructor_Kind);
if (fArguments[0]->fType.typeKind() == Type::TypeKind::kMatrix) {
SkASSERT(fArguments[0]->kind() == Expression::Kind::kConstructor);
// single matrix argument. make sure we're within the argument's bounds.
const Type& argType = ((Constructor&) *fArguments[0]).fType;
if (col < argType.columns() && row < argType.rows()) {

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A 'continue' statement.
*/
struct ContinueStatement : public Statement {
static constexpr Kind kStatementKind = kContinue_Kind;
static constexpr Kind kStatementKind = Kind::kContinue;
ContinueStatement(int offset)
: INHERITED(offset, kStatementKind) {}

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A 'discard' statement.
*/
struct DiscardStatement : public Statement {
static constexpr Kind kStatementKind = kDiscard_Kind;
static constexpr Kind kStatementKind = Kind::kDiscard;
DiscardStatement(int offset)
: INHERITED(offset, kStatementKind) {}

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A 'do' statement.
*/
struct DoStatement : public Statement {
static constexpr Kind kStatementKind = kDo_Kind;
static constexpr Kind kStatementKind = Kind::kDo;
DoStatement(int offset, std::unique_ptr<Statement> statement,
std::unique_ptr<Expression> test)

View File

@ -21,7 +21,7 @@ namespace SkSL {
struct Symbol;
struct Enum : public ProgramElement {
static constexpr Kind kProgramElementKind = kEnum_Kind;
static constexpr Kind kProgramElementKind = Kind::kEnum;
Enum(int offset, StringFragment typeName, std::shared_ptr<SymbolTable> symbols,
bool isBuiltin = true)

View File

@ -8,6 +8,7 @@
#ifndef SKSL_EXPRESSION
#define SKSL_EXPRESSION
#include "src/sksl/ir/SkSLStatement.h"
#include "src/sksl/ir/SkSLType.h"
#include <unordered_map>
@ -24,27 +25,30 @@ typedef std::unordered_map<const Variable*, std::unique_ptr<Expression>*> Defini
* Abstract supertype of all expressions.
*/
struct Expression : public IRNode {
enum Kind {
kBinary_Kind,
kBoolLiteral_Kind,
kConstructor_Kind,
kExternalFunctionCall_Kind,
kExternalValue_Kind,
kIntLiteral_Kind,
kFieldAccess_Kind,
kFloatLiteral_Kind,
kFunctionReference_Kind,
kFunctionCall_Kind,
kIndex_Kind,
kNullLiteral_Kind,
kPrefix_Kind,
kPostfix_Kind,
kSetting_Kind,
kSwizzle_Kind,
kTernary_Kind,
kTypeReference_Kind,
kVariableReference_Kind,
kDefined_Kind
enum class Kind {
kBinary = (int) Statement::Kind::kLast + 1,
kBoolLiteral,
kConstructor,
kDefined,
kExternalFunctionCall,
kExternalValue,
kIntLiteral,
kFieldAccess,
kFloatLiteral,
kFunctionReference,
kFunctionCall,
kIndex,
kNullLiteral,
kPrefix,
kPostfix,
kSetting,
kSwizzle,
kTernary,
kTypeReference,
kVariableReference,
kFirst = kBinary,
kLast = kVariableReference
};
enum class Property {
@ -53,9 +57,15 @@ struct Expression : public IRNode {
};
Expression(int offset, Kind kind, const Type& type)
: INHERITED(offset)
, fKind(kind)
, fType(std::move(type)) {}
: INHERITED(offset, (int) kind)
, fType(std::move(type)) {
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
Kind kind() const {
return (Kind) fKind;
}
/**
* Use is<T> to check the type of an expression.
@ -63,7 +73,7 @@ struct Expression : public IRNode {
*/
template <typename T>
bool is() const {
return this->fKind == T::kExpressionKind;
return this->kind() == T::kExpressionKind;
}
/**
@ -179,7 +189,6 @@ struct Expression : public IRNode {
virtual std::unique_ptr<Expression> clone() const = 0;
const Kind fKind;
const Type& fType;
using INHERITED = IRNode;

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A lone expression being used as a statement.
*/
struct ExpressionStatement : public Statement {
static constexpr Kind kStatementKind = kExpression_Kind;
static constexpr Kind kStatementKind = Kind::kExpression;
ExpressionStatement(std::unique_ptr<Expression> expression)
: INHERITED(expression->fOffset, kStatementKind)

View File

@ -16,7 +16,7 @@ namespace SkSL {
* An extension declaration.
*/
struct Extension : public ProgramElement {
static constexpr Kind kProgramElementKind = kExtension_Kind;
static constexpr Kind kProgramElementKind = Kind::kExtension;
Extension(int offset, String name)
: INHERITED(offset, kProgramElementKind)

View File

@ -18,7 +18,7 @@ namespace SkSL {
* An external function invocation.
*/
struct ExternalFunctionCall : public Expression {
static constexpr Kind kExpressionKind = kExternalFunctionCall_Kind;
static constexpr Kind kExpressionKind = Kind::kExternalFunctionCall;
ExternalFunctionCall(int offset, const Type& type, const ExternalValue* function,
std::vector<std::unique_ptr<Expression>> arguments)

View File

@ -17,7 +17,7 @@ namespace SkSL {
* Represents an identifier referring to an ExternalValue.
*/
struct ExternalValueReference : public Expression {
static constexpr Kind kExpressionKind = kExternalValue_Kind;
static constexpr Kind kExpressionKind = Kind::kExternalValue;
ExternalValueReference(int offset, const ExternalValue* ev)
: INHERITED(offset, kExpressionKind, ev->type())

View File

@ -22,7 +22,7 @@ namespace SkSL {
* result of declaring anonymous interface blocks.
*/
struct Field : public Symbol {
static constexpr Kind kSymbolKind = kField_Kind;
static constexpr Kind kSymbolKind = Kind::kField;
Field(int offset, const Variable& owner, int fieldIndex)
: INHERITED(offset, kSymbolKind, owner.fType.fields()[fieldIndex].fName)

View File

@ -24,7 +24,7 @@ struct FieldAccess : public Expression {
kAnonymousInterfaceBlock_OwnerKind
};
static constexpr Kind kExpressionKind = kFieldAccess_Kind;
static constexpr Kind kExpressionKind = Kind::kFieldAccess;
FieldAccess(std::unique_ptr<Expression> base, int fieldIndex,
OwnerKind ownerKind = kDefault_OwnerKind)

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A literal floating point number.
*/
struct FloatLiteral : public Expression {
static constexpr Kind kExpressionKind = kFloatLiteral_Kind;
static constexpr Kind kExpressionKind = Kind::kFloatLiteral;
FloatLiteral(const Context& context, int offset, double value)
: INHERITED(offset, kExpressionKind, *context.fFloatLiteral_Type)

View File

@ -18,7 +18,7 @@ namespace SkSL {
* A 'for' statement.
*/
struct ForStatement : public Statement {
static constexpr Kind kStatementKind = kFor_Kind;
static constexpr Kind kStatementKind = Kind::kFor;
ForStatement(int offset, std::unique_ptr<Statement> initializer,
std::unique_ptr<Expression> test, std::unique_ptr<Expression> next,

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A function invocation.
*/
struct FunctionCall : public Expression {
static constexpr Kind kExpressionKind = kFunctionCall_Kind;
static constexpr Kind kExpressionKind = Kind::kFunctionCall;
FunctionCall(int offset, const Type& type, const FunctionDeclaration& function,
std::vector<std::unique_ptr<Expression>> arguments)

View File

@ -25,7 +25,7 @@ struct FunctionDefinition;
* A function declaration (not a definition -- does not contain a body).
*/
struct FunctionDeclaration : public Symbol {
static constexpr Kind kSymbolKind = kFunctionDeclaration_Kind;
static constexpr Kind kSymbolKind = Kind::kFunctionDeclaration;
FunctionDeclaration(int offset, Modifiers modifiers, StringFragment name,
std::vector<const Variable*> parameters, const Type& returnType,
@ -81,7 +81,7 @@ struct FunctionDeclaration : public Symbol {
SkASSERT(arguments.size() == fParameters.size());
int genericIndex = -1;
for (size_t i = 0; i < arguments.size(); i++) {
if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) {
if (fParameters[i]->fType.typeKind() == Type::TypeKind::kGeneric) {
std::vector<const Type*> types = fParameters[i]->fType.coercibleTypes();
if (genericIndex == -1) {
for (size_t j = 0; j < types.size(); j++) {
@ -99,7 +99,7 @@ struct FunctionDeclaration : public Symbol {
outParameterTypes->push_back(&fParameters[i]->fType);
}
}
if (fReturnType.kind() == Type::kGeneric_Kind) {
if (fReturnType.typeKind() == Type::TypeKind::kGeneric) {
if (genericIndex == -1) {
return false;
}

View File

@ -22,7 +22,7 @@ struct ASTNode;
* A function definition (a declaration plus an associated block of code).
*/
struct FunctionDefinition : public ProgramElement {
static constexpr Kind kProgramElementKind = kFunction_Kind;
static constexpr Kind kProgramElementKind = Kind::kFunction;
FunctionDefinition(int offset,
const FunctionDeclaration& declaration,

View File

@ -19,7 +19,7 @@ namespace SkSL {
* always eventually replaced by FunctionCalls in valid programs.
*/
struct FunctionReference : public Expression {
static constexpr Kind kExpressionKind = kFunctionReference_Kind;
static constexpr Kind kExpressionKind = Kind::kFunctionReference;
FunctionReference(const Context& context, int offset,
std::vector<const FunctionDeclaration*> function)

View File

@ -18,8 +18,9 @@ namespace SkSL {
* version of the program (all types determined, everything validated), ready for code generation.
*/
struct IRNode {
IRNode(int offset)
: fOffset(offset) {}
IRNode(int offset, int kind)
: fOffset(offset)
, fKind(kind) {}
virtual ~IRNode() {}
@ -28,6 +29,9 @@ struct IRNode {
// character offset of this element within the program being compiled, for error reporting
// purposes
int fOffset;
protected:
int fKind;
};
} // namespace SkSL

View File

@ -17,7 +17,7 @@ namespace SkSL {
* An 'if' statement.
*/
struct IfStatement : public Statement {
static constexpr Kind kStatementKind = kIf_Kind;
static constexpr Kind kStatementKind = Kind::kIf;
IfStatement(int offset, bool isStatic, std::unique_ptr<Expression> test,
std::unique_ptr<Statement> ifTrue, std::unique_ptr<Statement> ifFalse)

View File

@ -18,7 +18,7 @@ namespace SkSL {
* Given a type, returns the type that will result from extracting an array value from it.
*/
static const Type& index_type(const Context& context, const Type& type) {
if (type.kind() == Type::kMatrix_Kind) {
if (type.typeKind() == Type::TypeKind::kMatrix) {
if (type.componentType() == *context.fFloat_Type) {
switch (type.rows()) {
case 2: return *context.fFloat2_Type;
@ -42,7 +42,7 @@ static const Type& index_type(const Context& context, const Type& type) {
* An expression which extracts a value from an array or matrix, as in 'm[2]'.
*/
struct IndexExpression : public Expression {
static constexpr Kind kExpressionKind = kIndex_Kind;
static constexpr Kind kExpressionKind = Kind::kIndex;
IndexExpression(const Context& context, std::unique_ptr<Expression> base,
std::unique_ptr<Expression> index)
@ -73,7 +73,7 @@ struct IndexExpression : public Expression {
private:
IndexExpression(std::unique_ptr<Expression> base, std::unique_ptr<Expression> index,
const Type* type)
: INHERITED(base->fOffset, kIndex_Kind, *type)
: INHERITED(base->fOffset, Kind::kIndex, *type)
, fBase(std::move(base))
, fIndex(std::move(index)) {}
};

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A literal integer.
*/
struct IntLiteral : public Expression {
static constexpr Kind kExpressionKind = kIntLiteral_Kind;
static constexpr Kind kExpressionKind = Kind::kIntLiteral;
// FIXME: we will need to revisit this if/when we add full support for both signed and unsigned
// 64-bit integers, but for right now an int64_t will hold every value we care about
@ -47,7 +47,7 @@ struct IntLiteral : public Expression {
int coercionCost(const Type& target) const override {
if (target.isSigned() || target.isUnsigned() || target.isFloat() ||
target.kind() == Type::kEnum_Kind) {
target.typeKind() == Type::TypeKind::kEnum) {
return 0;
}
return INHERITED::coercionCost(target);

View File

@ -25,7 +25,7 @@ namespace SkSL {
* At the IR level, this is represented by a single variable of struct type.
*/
struct InterfaceBlock : public ProgramElement {
static constexpr Kind kProgramElementKind = kInterfaceBlock_Kind;
static constexpr Kind kProgramElementKind = Kind::kInterfaceBlock;
InterfaceBlock(int offset, const Variable* var, String typeName, String instanceName,
std::vector<std::unique_ptr<Expression>> sizes,
@ -51,7 +51,7 @@ struct InterfaceBlock : public ProgramElement {
String description() const override {
String result = fVariable.fModifiers.description() + fTypeName + " {\n";
const Type* structType = &fVariable.fType;
while (structType->kind() == Type::kArray_Kind) {
while (structType->typeKind() == Type::TypeKind::kArray) {
structType = &structType->componentType();
}
for (const auto& f : structType->fields()) {

View File

@ -19,7 +19,7 @@ namespace SkSL {
* layout(blend_support_all_equations) out;
*/
struct ModifiersDeclaration : public ProgramElement {
static constexpr Kind kProgramElementKind = kModifiers_Kind;
static constexpr Kind kProgramElementKind = Kind::kModifiers;
ModifiersDeclaration(Modifiers modifiers)
: INHERITED(-1, kProgramElementKind)

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A no-op statement that does nothing.
*/
struct Nop : public Statement {
static constexpr Kind kStatementKind = kNop_Kind;
static constexpr Kind kStatementKind = Kind::kNop;
Nop()
: INHERITED(-1, kStatementKind) {}

View File

@ -17,7 +17,7 @@ namespace SkSL {
* Represents 'null'.
*/
struct NullLiteral : public Expression {
static constexpr Kind kExpressionKind = kNullLiteral_Kind;
static constexpr Kind kExpressionKind = Kind::kNullLiteral;
NullLiteral(const Context& context, int offset)
: INHERITED(offset, kExpressionKind, *context.fNull_Type) {}

View File

@ -18,7 +18,7 @@ namespace SkSL {
* An expression modified by a unary operator appearing after it, such as 'i++'.
*/
struct PostfixExpression : public Expression {
static constexpr Kind kExpressionKind = kPostfix_Kind;
static constexpr Kind kExpressionKind = Kind::kPostfix;
PostfixExpression(std::unique_ptr<Expression> operand, Token::Kind op)
: INHERITED(operand->fOffset, kExpressionKind, operand->fType)

View File

@ -20,7 +20,7 @@ namespace SkSL {
* An expression modified by a unary operator appearing before it, such as '!flag'.
*/
struct PrefixExpression : public Expression {
static constexpr Kind kExpressionKind = kPrefix_Kind;
static constexpr Kind kExpressionKind = Kind::kPrefix;
PrefixExpression(Token::Kind op, std::unique_ptr<Expression> operand)
: INHERITED(operand->fOffset, kExpressionKind, operand->fType)
@ -41,7 +41,7 @@ struct PrefixExpression : public Expression {
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override {
if (fOperand->fKind == Expression::kFloatLiteral_Kind) {
if (fOperand->kind() == Expression::Kind::kFloatLiteral) {
return std::unique_ptr<Expression>(new FloatLiteral(
irGenerator.fContext,
fOffset,

View File

@ -18,19 +18,27 @@ namespace SkSL {
* Represents a top-level element (e.g. function or global variable) in a program.
*/
struct ProgramElement : public IRNode {
enum Kind {
kEnum_Kind,
kExtension_Kind,
kFunction_Kind,
kInterfaceBlock_Kind,
kModifiers_Kind,
kSection_Kind,
kVar_Kind
enum class Kind {
kEnum = 0,
kExtension,
kFunction,
kInterfaceBlock,
kModifiers,
kSection,
kVar,
kFirst = kEnum,
kLast = kVar
};
ProgramElement(int offset, Kind kind)
: INHERITED(offset)
, fKind(kind) {}
: INHERITED(offset, (int) kind) {
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
Kind kind() const {
return (Kind) fKind;
}
/**
* Use is<T> to check the type of a program element.
@ -38,7 +46,7 @@ struct ProgramElement : public IRNode {
*/
template <typename T>
bool is() const {
return this->fKind == T::kProgramElementKind;
return this->kind() == T::kProgramElementKind;
}
/**
@ -56,8 +64,6 @@ struct ProgramElement : public IRNode {
return static_cast<T&>(*this);
}
Kind fKind;
virtual std::unique_ptr<ProgramElement> clone() const = 0;
using INHERITED = IRNode;

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A 'return' statement.
*/
struct ReturnStatement : public Statement {
static constexpr Kind kStatementKind = kReturn_Kind;
static constexpr Kind kStatementKind = Kind::kReturn;
ReturnStatement(int offset)
: INHERITED(offset, kStatementKind) {}

View File

@ -16,7 +16,7 @@ namespace SkSL {
* A section declaration (e.g. @body { body code here })..
*/
struct Section : public ProgramElement {
static constexpr Kind kProgramElementKind = kSection_Kind;
static constexpr Kind kProgramElementKind = Kind::kSection;
Section(int offset, String name, String arg, String text)
: INHERITED(offset, kProgramElementKind)

View File

@ -18,7 +18,7 @@ namespace SkSL {
* collapsed down to their constant representations during the compilation process.
*/
struct Setting : public Expression {
static constexpr Kind kExpressionKind = kSetting_Kind;
static constexpr Kind kExpressionKind = Kind::kSetting;
Setting(int offset, String name, std::unique_ptr<Expression> value)
: INHERITED(offset, kExpressionKind, value->fType)

View File

@ -18,25 +18,33 @@ namespace SkSL {
*/
struct Statement : public IRNode {
enum Kind {
kBlock_Kind,
kBreak_Kind,
kContinue_Kind,
kDiscard_Kind,
kDo_Kind,
kExpression_Kind,
kFor_Kind,
kIf_Kind,
kNop_Kind,
kReturn_Kind,
kSwitch_Kind,
kVarDeclaration_Kind,
kVarDeclarations_Kind,
kWhile_Kind
kBlock = (int) Symbol::Kind::kLast + 1,
kBreak,
kContinue,
kDiscard,
kDo,
kExpression,
kFor,
kIf,
kNop,
kReturn,
kSwitch,
kVarDeclaration,
kVarDeclarations,
kWhile,
kFirst = kBlock,
kLast = kWhile
};
Statement(int offset, Kind kind)
: INHERITED(offset)
, fKind(kind) {}
: INHERITED(offset, (int) kind) {
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
Kind kind() const {
return (Kind) fKind;
}
/**
* Use is<T> to check the type of a statement.
@ -69,8 +77,6 @@ struct Statement : public IRNode {
virtual std::unique_ptr<Statement> clone() const = 0;
const Kind fKind;
using INHERITED = IRNode;
};

View File

@ -19,7 +19,7 @@ namespace SkSL {
struct SwitchCase : public Statement {
SwitchCase(int offset, std::unique_ptr<Expression> value,
std::vector<std::unique_ptr<Statement>> statements)
: INHERITED(offset, kSwitch_Kind)
: INHERITED(offset, Kind::kSwitch)
, fValue(std::move(value))
, fStatements(std::move(statements)) {}

View File

@ -19,7 +19,7 @@ class SymbolTable;
* A 'switch' statement.
*/
struct SwitchStatement : public Statement {
static constexpr Kind kStatementKind = kSwitch_Kind;
static constexpr Kind kStatementKind = Kind::kSwitch;
SwitchStatement(int offset, bool isStatic, std::unique_ptr<Expression> value,
std::vector<std::unique_ptr<SwitchCase>> cases,

View File

@ -97,7 +97,7 @@ static const Type& get_type(const Context& context, Expression& value, size_t co
* Represents a vector swizzle operation such as 'float2(1, 2, 3).zyx'.
*/
struct Swizzle : public Expression {
static constexpr Kind kExpressionKind = kSwizzle_Kind;
static constexpr Kind kExpressionKind = Kind::kSwizzle;
Swizzle(const Context& context, std::unique_ptr<Expression> base, std::vector<int> components)
: INHERITED(base->fOffset, kExpressionKind, get_type(context, *base, components.size()))
@ -108,7 +108,7 @@ struct Swizzle : public Expression {
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override {
if (fBase->fKind == Expression::kConstructor_Kind) {
if (fBase->kind() == Expression::Kind::kConstructor) {
Constructor& constructor = static_cast<Constructor&>(*fBase);
if (constructor.isCompileTimeConstant()) {
// we're swizzling a constant vector, e.g. float4(1).x. Simplify it.
@ -151,7 +151,7 @@ struct Swizzle : public Expression {
private:
Swizzle(const Type& type, std::unique_ptr<Expression> base, std::vector<int> components)
: INHERITED(base->fOffset, kSwizzle_Kind, type)
: INHERITED(base->fOffset, kExpressionKind, type)
, fBase(std::move(base))
, fComponents(std::move(components)) {
SkASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);

View File

@ -9,6 +9,7 @@
#define SKSL_SYMBOL
#include "src/sksl/ir/SkSLIRNode.h"
#include "src/sksl/ir/SkSLProgramElement.h"
namespace SkSL {
@ -16,29 +17,37 @@ namespace SkSL {
* Represents a symboltable entry.
*/
struct Symbol : public IRNode {
enum Kind {
kFunctionDeclaration_Kind,
kUnresolvedFunction_Kind,
kType_Kind,
kVariable_Kind,
kField_Kind,
kExternal_Kind
enum class Kind {
kExternal = (int) ProgramElement::Kind::kLast + 1,
kField,
kFunctionDeclaration,
kType,
kUnresolvedFunction,
kVariable,
kFirst = kExternal,
kLast = kVariable
};
Symbol(int offset, Kind kind, StringFragment name)
: INHERITED(offset)
, fKind(kind)
, fName(name) {}
: INHERITED(offset, (int) kind)
, fName(name) {
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
~Symbol() override {}
Kind kind() const {
return (Kind) fKind;
}
/**
* Use is<T> to check the type of a symbol.
* e.g. replace `sym.fKind == Symbol::kVariable_Kind` with `sym.is<Variable>()`.
*/
template <typename T>
bool is() const {
return this->fKind == T::kSymbolKind;
return this->kind() == T::kSymbolKind;
}
/**
@ -56,7 +65,6 @@ struct Symbol : public IRNode {
return static_cast<T&>(*this);
}
Kind fKind;
StringFragment fName;
using INHERITED = IRNode;

View File

@ -11,10 +11,10 @@
namespace SkSL {
std::vector<const FunctionDeclaration*> SymbolTable::GetFunctions(const Symbol& s) {
switch (s.fKind) {
case Symbol::kFunctionDeclaration_Kind:
switch (s.kind()) {
case Symbol::Kind::kFunctionDeclaration:
return { &s.as<FunctionDeclaration>() };
case Symbol::kUnresolvedFunction_Kind:
case Symbol::Kind::kUnresolvedFunction:
return s.as<UnresolvedFunction>().fFunctions;
default:
return std::vector<const FunctionDeclaration*>();
@ -70,16 +70,16 @@ void SymbolTable::addWithoutOwnership(StringFragment name, const Symbol* symbol)
const auto& existing = fSymbols.find(name);
if (existing == fSymbols.end()) {
fSymbols[name] = symbol;
} else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) {
} else if (symbol->kind() == Symbol::Kind::kFunctionDeclaration) {
const Symbol* oldSymbol = existing->second;
if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) {
if (oldSymbol->kind() == Symbol::Kind::kFunctionDeclaration) {
std::vector<const FunctionDeclaration*> functions;
functions.push_back(&oldSymbol->as<FunctionDeclaration>());
functions.push_back(&symbol->as<FunctionDeclaration>());
std::unique_ptr<const Symbol> u = std::unique_ptr<const Symbol>(
new UnresolvedFunction(std::move(functions)));
fSymbols[name] = this->takeOwnershipOfSymbol(std::move(u));
} else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) {
} else if (oldSymbol->kind() == Symbol::Kind::kUnresolvedFunction) {
std::vector<const FunctionDeclaration*> functions;
for (const auto* f : oldSymbol->as<UnresolvedFunction>().fFunctions) {
functions.push_back(f);

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A ternary expression (test ? ifTrue : ifFalse).
*/
struct TernaryExpression : public Expression {
static constexpr Kind kExpressionKind = kTernary_Kind;
static constexpr Kind kExpressionKind = Kind::kTernary;
TernaryExpression(int offset, std::unique_ptr<Expression> test,
std::unique_ptr<Expression> ifTrue, std::unique_ptr<Expression> ifFalse)

View File

@ -14,23 +14,23 @@ int Type::coercionCost(const Type& other) const {
if (*this == other) {
return 0;
}
if (this->kind() == kNullable_Kind && other.kind() != kNullable_Kind) {
if (this->typeKind() == TypeKind::kNullable && other.typeKind() != TypeKind::kNullable) {
int result = this->componentType().coercionCost(other);
if (result != INT_MAX) {
++result;
}
return result;
}
if (this->fName == "null" && other.kind() == kNullable_Kind) {
if (this->fName == "null" && other.typeKind() == TypeKind::kNullable) {
return 0;
}
if (this->kind() == kVector_Kind && other.kind() == kVector_Kind) {
if (this->typeKind() == TypeKind::kVector && other.typeKind() == TypeKind::kVector) {
if (this->columns() == other.columns()) {
return this->componentType().coercionCost(other.componentType());
}
return INT_MAX;
}
if (this->kind() == kMatrix_Kind) {
if (this->typeKind() == TypeKind::kMatrix) {
if (this->columns() == other.columns() && this->rows() == other.rows()) {
return this->componentType().coercionCost(other.componentType());
}
@ -48,7 +48,7 @@ int Type::coercionCost(const Type& other) const {
}
const Type& Type::toCompound(const Context& context, int columns, int rows) const {
SkASSERT(this->kind() == Type::kScalar_Kind);
SkASSERT(this->typeKind() == Type::TypeKind::kScalar);
if (columns == 1 && rows == 1) {
return *this;
}

View File

@ -26,7 +26,7 @@ class Context;
*/
class Type : public Symbol {
public:
static constexpr Kind kSymbolKind = kType_Kind;
static constexpr Kind kSymbolKind = Kind::kType;
struct Field {
Field(Modifiers modifiers, StringFragment name, const Type* type)
@ -43,26 +43,26 @@ public:
const Type* fType;
};
enum Kind {
kArray_Kind,
kEnum_Kind,
kGeneric_Kind,
kNullable_Kind,
kMatrix_Kind,
kOther_Kind,
kSampler_Kind,
kSeparateSampler_Kind,
kScalar_Kind,
kStruct_Kind,
kTexture_Kind,
kVector_Kind
enum class TypeKind {
kArray,
kEnum,
kGeneric,
kNullable,
kMatrix,
kOther,
kSampler,
kSeparateSampler,
kScalar,
kStruct,
kTexture,
kVector
};
enum NumberKind {
kFloat_NumberKind,
kSigned_NumberKind,
kUnsigned_NumberKind,
kNonnumeric_NumberKind
enum class NumberKind {
kFloat,
kSigned,
kUnsigned,
kNonnumeric
};
// Create an "other" (special) type with the given name. These types cannot be directly
@ -70,8 +70,8 @@ public:
Type(const char* name)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kOther_Kind)
, fNumberKind(kNonnumeric_NumberKind) {
, fTypeKind(TypeKind::kOther)
, fNumberKind(NumberKind::kNonnumeric) {
fName.fChars = fNameString.c_str();
fName.fLength = fNameString.size();
}
@ -80,19 +80,19 @@ public:
Type(const char* name, std::vector<Field> fields)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kOther_Kind)
, fNumberKind(kNonnumeric_NumberKind)
, fTypeKind(TypeKind::kOther)
, fNumberKind(NumberKind::kNonnumeric)
, fFields(std::move(fields)) {
fName.fChars = fNameString.c_str();
fName.fLength = fNameString.size();
}
// Create a simple type.
Type(String name, Kind kind)
Type(String name, TypeKind kind)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(std::move(name))
, fTypeKind(kind)
, fNumberKind(kNonnumeric_NumberKind) {
, fNumberKind(NumberKind::kNonnumeric) {
fName.fChars = fNameString.c_str();
fName.fLength = fNameString.size();
}
@ -101,8 +101,8 @@ public:
Type(const char* name, std::vector<const Type*> types)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kGeneric_Kind)
, fNumberKind(kNonnumeric_NumberKind)
, fTypeKind(TypeKind::kGeneric)
, fNumberKind(NumberKind::kNonnumeric)
, fCoercibleTypes(std::move(types)) {
fName.fChars = fNameString.c_str();
fName.fLength = fNameString.size();
@ -112,8 +112,8 @@ public:
Type(int offset, String name, std::vector<Field> fields)
: INHERITED(offset, kSymbolKind, StringFragment())
, fNameString(std::move(name))
, fTypeKind(kStruct_Kind)
, fNumberKind(kNonnumeric_NumberKind)
, fTypeKind(TypeKind::kStruct)
, fNumberKind(NumberKind::kNonnumeric)
, fFields(std::move(fields)) {
fName.fChars = fNameString.c_str();
fName.fLength = fNameString.size();
@ -123,7 +123,7 @@ public:
Type(const char* name, NumberKind numberKind, int priority, bool highPrecision = false)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kScalar_Kind)
, fTypeKind(TypeKind::kScalar)
, fNumberKind(numberKind)
, fPriority(priority)
, fColumns(1)
@ -140,7 +140,7 @@ public:
std::vector<const Type*> coercibleTypes)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kScalar_Kind)
, fTypeKind(TypeKind::kScalar)
, fNumberKind(numberKind)
, fPriority(priority)
, fCoercibleTypes(std::move(coercibleTypes))
@ -151,11 +151,11 @@ public:
}
// Create a nullable type.
Type(String name, Kind kind, const Type& componentType)
Type(String name, TypeKind kind, const Type& componentType)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(std::move(name))
, fTypeKind(kind)
, fNumberKind(kNonnumeric_NumberKind)
, fNumberKind(NumberKind::kNonnumeric)
, fComponentType(&componentType)
, fColumns(1)
, fRows(1)
@ -166,14 +166,14 @@ public:
// Create a vector type.
Type(const char* name, const Type& componentType, int columns)
: Type(name, kVector_Kind, componentType, columns) {}
: Type(name, TypeKind::kVector, componentType, columns) {}
// Create a vector or array type.
Type(String name, Kind kind, const Type& componentType, int columns)
Type(String name, TypeKind kind, const Type& componentType, int columns)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(std::move(name))
, fTypeKind(kind)
, fNumberKind(kNonnumeric_NumberKind)
, fNumberKind(NumberKind::kNonnumeric)
, fComponentType(&componentType)
, fColumns(columns)
, fRows(1)
@ -186,8 +186,8 @@ public:
Type(const char* name, const Type& componentType, int columns, int rows)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kMatrix_Kind)
, fNumberKind(kNonnumeric_NumberKind)
, fTypeKind(TypeKind::kMatrix)
, fNumberKind(NumberKind::kNonnumeric)
, fComponentType(&componentType)
, fColumns(columns)
, fRows(rows)
@ -201,8 +201,8 @@ public:
bool isSampled)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kTexture_Kind)
, fNumberKind(kNonnumeric_NumberKind)
, fTypeKind(TypeKind::kTexture)
, fNumberKind(NumberKind::kNonnumeric)
, fDimensions(dimensions)
, fIsDepth(isDepth)
, fIsArrayed(isArrayed)
@ -217,8 +217,8 @@ public:
Type(const char* name, const Type& textureType)
: INHERITED(-1, kSymbolKind, StringFragment())
, fNameString(name)
, fTypeKind(kSampler_Kind)
, fNumberKind(kNonnumeric_NumberKind)
, fTypeKind(TypeKind::kSampler)
, fNumberKind(NumberKind::kNonnumeric)
, fDimensions(textureType.dimensions())
, fIsDepth(textureType.isDepth())
, fIsArrayed(textureType.isArrayed())
@ -259,7 +259,7 @@ public:
/**
* Returns the category (scalar, vector, matrix, etc.) of this type.
*/
Kind kind() const {
TypeKind typeKind() const {
return fTypeKind;
}
@ -267,28 +267,28 @@ public:
* Returns true if this is a numeric scalar type.
*/
bool isNumber() const {
return fNumberKind != kNonnumeric_NumberKind;
return fNumberKind != NumberKind::kNonnumeric;
}
/**
* Returns true if this is a floating-point scalar type (float or half).
*/
bool isFloat() const {
return fNumberKind == kFloat_NumberKind;
return fNumberKind == NumberKind::kFloat;
}
/**
* Returns true if this is a signed scalar type (int or short).
*/
bool isSigned() const {
return fNumberKind == kSigned_NumberKind;
return fNumberKind == NumberKind::kSigned;
}
/**
* Returns true if this is an unsigned scalar type (uint or ushort).
*/
bool isUnsigned() const {
return fNumberKind == kUnsigned_NumberKind;
return fNumberKind == NumberKind::kUnsigned;
}
/**
@ -343,7 +343,7 @@ public:
* For nullable types, returns the base type, otherwise returns the type itself.
*/
const Type& nonnullable() const {
if (fTypeKind == kNullable_Kind) {
if (fTypeKind == TypeKind::kNullable) {
return this->componentType();
}
return *this;
@ -355,8 +355,8 @@ public:
* For all other types, causes an SkASSERTion failure.
*/
int columns() const {
SkASSERT(fTypeKind == kScalar_Kind || fTypeKind == kVector_Kind ||
fTypeKind == kMatrix_Kind || fTypeKind == kArray_Kind);
SkASSERT(fTypeKind == TypeKind::kScalar || fTypeKind == TypeKind::kVector ||
fTypeKind == TypeKind::kMatrix || fTypeKind == TypeKind::kArray);
return fColumns;
}
@ -370,7 +370,7 @@ public:
}
const std::vector<Field>& fields() const {
SkASSERT(fTypeKind == kStruct_Kind || fTypeKind == kOther_Kind);
SkASSERT(fTypeKind == TypeKind::kStruct || fTypeKind == TypeKind::kOther);
return fFields;
}
@ -384,27 +384,27 @@ public:
}
SpvDim_ dimensions() const {
SkASSERT(kSampler_Kind == fTypeKind || kTexture_Kind == fTypeKind);
SkASSERT(TypeKind::kSampler == fTypeKind || TypeKind::kTexture == fTypeKind);
return fDimensions;
}
bool isDepth() const {
SkASSERT(kSampler_Kind == fTypeKind || kTexture_Kind == fTypeKind);
SkASSERT(TypeKind::kSampler == fTypeKind || TypeKind::kTexture == fTypeKind);
return fIsDepth;
}
bool isArrayed() const {
SkASSERT(kSampler_Kind == fTypeKind || kTexture_Kind == fTypeKind);
SkASSERT(TypeKind::kSampler == fTypeKind || TypeKind::kTexture == fTypeKind);
return fIsArrayed;
}
bool isMultisampled() const {
SkASSERT(kSampler_Kind == fTypeKind || kTexture_Kind == fTypeKind);
SkASSERT(TypeKind::kSampler == fTypeKind || TypeKind::kTexture == fTypeKind);
return fIsMultisampled;
}
bool isSampled() const {
SkASSERT(kSampler_Kind == fTypeKind || kTexture_Kind == fTypeKind);
SkASSERT(TypeKind::kSampler == fTypeKind || TypeKind::kTexture == fTypeKind);
return fIsSampled;
}
@ -425,7 +425,7 @@ private:
using INHERITED = Symbol;
String fNameString;
Kind fTypeKind;
TypeKind fTypeKind;
// always kNonnumeric_NumberKind for non-scalar values
NumberKind fNumberKind;
int fPriority = -1;

View File

@ -18,11 +18,11 @@ namespace SkSL {
* always eventually replaced by Constructors in valid programs.
*/
struct TypeReference : public Expression {
static constexpr Kind kExpressionKind = kTypeReference_Kind;
static constexpr Kind kExpressionKind = Kind::kTypeReference;
TypeReference(const Context& context, int offset, const Type& value)
TypeReference(const Context& context, int offset, const Type* value)
: INHERITED(offset, kExpressionKind, *context.fInvalid_Type)
, fValue(value) {}
, fValue(*value) {}
bool hasProperty(Property property) const override {
return false;

View File

@ -16,7 +16,7 @@ namespace SkSL {
* A symbol representing multiple functions with the same name.
*/
struct UnresolvedFunction : public Symbol {
static constexpr Kind kSymbolKind = kUnresolvedFunction_Kind;
static constexpr Kind kSymbolKind = Kind::kUnresolvedFunction;
UnresolvedFunction(std::vector<const FunctionDeclaration*> funcs)
: INHERITED(-1, kSymbolKind, funcs[0]->fName)

View File

@ -21,7 +21,7 @@ namespace SkSL {
* instances.
*/
struct VarDeclaration : public Statement {
static constexpr Kind kStatementKind = kVarDeclaration_Kind;
static constexpr Kind kStatementKind = Kind::kVarDeclaration;
VarDeclaration(const Variable* var,
std::vector<std::unique_ptr<Expression>> sizes,
@ -70,7 +70,7 @@ struct VarDeclaration : public Statement {
* A variable declaration statement, which may consist of one or more individual variables.
*/
struct VarDeclarations : public ProgramElement {
static constexpr Kind kProgramElementKind = kVar_Kind;
static constexpr Kind kProgramElementKind = Kind::kVar;
VarDeclarations(int offset, const Type* baseType,
std::vector<std::unique_ptr<VarDeclaration>> vars)
@ -97,8 +97,8 @@ struct VarDeclarations : public ProgramElement {
}
String result;
for (const auto& var : fVars) {
if (var->fKind != Statement::kNop_Kind) {
SkASSERT(var->fKind == Statement::kVarDeclaration_Kind);
if (var->kind() != Statement::Kind::kNop) {
SkASSERT(var->kind() == Statement::Kind::kVarDeclaration);
result = ((const VarDeclaration&) *var).fVar->fModifiers.description();
break;
}
@ -106,10 +106,10 @@ struct VarDeclarations : public ProgramElement {
result += fBaseType.description() + " ";
String separator;
for (const auto& rawVar : fVars) {
if (rawVar->fKind == Statement::kNop_Kind) {
if (rawVar->kind() == Statement::Kind::kNop) {
continue;
}
SkASSERT(rawVar->fKind == Statement::kVarDeclaration_Kind);
SkASSERT(rawVar->kind() == Statement::Kind::kVarDeclaration);
VarDeclaration& var = (VarDeclaration&) *rawVar;
result += separator;
separator = ", ";

View File

@ -17,7 +17,7 @@ namespace SkSL {
* One or more variable declarations appearing as a statement within a function.
*/
struct VarDeclarationsStatement : public Statement {
static constexpr Kind kStatementKind = kVarDeclarations_Kind;
static constexpr Kind kStatementKind = Kind::kVarDeclarations;
VarDeclarationsStatement(std::unique_ptr<VarDeclarations> decl)
: INHERITED(decl->fOffset, kStatementKind)

View File

@ -23,7 +23,7 @@ struct Expression;
* read or write that storage location.
*/
struct Variable : public Symbol {
static constexpr Kind kSymbolKind = kVariable_Kind;
static constexpr Kind kSymbolKind = Kind::kVariable;
enum Storage {
kGlobal_Storage,

View File

@ -54,21 +54,21 @@ void VariableReference::setRefKind(RefKind refKind) {
std::unique_ptr<Expression> VariableReference::copy_constant(const IRGenerator& irGenerator,
const Expression* expr) {
SkASSERT(expr->isCompileTimeConstant());
switch (expr->fKind) {
case Expression::kIntLiteral_Kind:
switch (expr->kind()) {
case Expression::Kind::kIntLiteral:
return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
-1,
((IntLiteral*) expr)->fValue));
case Expression::kFloatLiteral_Kind:
case Expression::Kind::kFloatLiteral:
return std::unique_ptr<Expression>(new FloatLiteral(
irGenerator.fContext,
-1,
((FloatLiteral*) expr)->fValue));
case Expression::kBoolLiteral_Kind:
case Expression::Kind::kBoolLiteral:
return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
-1,
((BoolLiteral*) expr)->fValue));
case Expression::kConstructor_Kind: {
case Expression::Kind::kConstructor: {
const Constructor* c = (const Constructor*) expr;
std::vector<std::unique_ptr<Expression>> args;
for (const auto& arg : c->fArguments) {
@ -77,7 +77,7 @@ std::unique_ptr<Expression> VariableReference::copy_constant(const IRGenerator&
return std::unique_ptr<Expression>(new Constructor(-1, c->fType,
std::move(args)));
}
case Expression::kSetting_Kind: {
case Expression::Kind::kSetting: {
const Setting* s = (const Setting*) expr;
return std::unique_ptr<Expression>(new Setting(-1, s->fName,
copy_constant(irGenerator,
@ -94,7 +94,8 @@ std::unique_ptr<Expression> VariableReference::constantPropagate(const IRGenerat
return nullptr;
}
if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue &&
fVariable.fInitialValue->isCompileTimeConstant() && fType.kind() != Type::kArray_Kind) {
fVariable.fInitialValue->isCompileTimeConstant() &&
fType.typeKind() != Type::TypeKind::kArray) {
return copy_constant(irGenerator, fVariable.fInitialValue);
}
auto exprIter = definitions.find(&fVariable);

View File

@ -23,7 +23,7 @@ class IRGenerator;
* there is only one Variable 'x', but two VariableReferences to it.
*/
struct VariableReference : public Expression {
static constexpr Kind kExpressionKind = kVariableReference_Kind;
static constexpr Kind kExpressionKind = Kind::kVariableReference;
enum RefKind {
kRead_RefKind,

View File

@ -17,7 +17,7 @@ namespace SkSL {
* A 'while' loop.
*/
struct WhileStatement : public Statement {
static constexpr Kind kStatementKind = kWhile_Kind;
static constexpr Kind kStatementKind = Kind::kWhile;
WhileStatement(int offset, std::unique_ptr<Expression> test,
std::unique_ptr<Statement> statement)

View File

@ -80,12 +80,14 @@ DEF_TEST(SkSLMemoryLayout140Test, r) {
REPORTER_ASSERT(r, 16 == layout.alignment(s5));
// arrays
SkSL::Type array1(SkSL::String("float[4]"), SkSL::Type::kArray_Kind, *context.fFloat_Type, 4);
SkSL::Type array1(SkSL::String("float[4]"), SkSL::Type::TypeKind::kArray, *context.fFloat_Type,
4);
REPORTER_ASSERT(r, 64 == layout.size(array1));
REPORTER_ASSERT(r, 16 == layout.alignment(array1));
REPORTER_ASSERT(r, 16 == layout.stride(array1));
SkSL::Type array2(SkSL::String("float4[4]"), SkSL::Type::kArray_Kind, *context.fFloat4_Type, 4);
SkSL::Type array2(SkSL::String("float4[4]"), SkSL::Type::TypeKind::kArray,
*context.fFloat4_Type, 4);
REPORTER_ASSERT(r, 64 == layout.size(array2));
REPORTER_ASSERT(r, 16 == layout.alignment(array2));
REPORTER_ASSERT(r, 16 == layout.stride(array2));
@ -161,12 +163,14 @@ DEF_TEST(SkSLMemoryLayout430Test, r) {
REPORTER_ASSERT(r, 16 == layout.alignment(s5));
// arrays
SkSL::Type array1(SkSL::String("float[4]"), SkSL::Type::kArray_Kind, *context.fFloat_Type, 4);
SkSL::Type array1(SkSL::String("float[4]"), SkSL::Type::TypeKind::kArray, *context.fFloat_Type,
4);
REPORTER_ASSERT(r, 16 == layout.size(array1));
REPORTER_ASSERT(r, 4 == layout.alignment(array1));
REPORTER_ASSERT(r, 4 == layout.stride(array1));
SkSL::Type array2(SkSL::String("float4[4]"), SkSL::Type::kArray_Kind, *context.fFloat4_Type, 4);
SkSL::Type array2(SkSL::String("float4[4]"), SkSL::Type::TypeKind::kArray,
*context.fFloat4_Type, 4);
REPORTER_ASSERT(r, 64 == layout.size(array2));
REPORTER_ASSERT(r, 16 == layout.alignment(array2));
REPORTER_ASSERT(r, 16 == layout.stride(array2));