Moved SkSL type into IRNode, now accessed via a method
This change doesn't accomplish anything by itself, but is a necessary
prerequisite for followup changes to node handling. Eventually all data
is going to be stored within IRNode itself, and the subclasses will not
add any fields; this is just the first step in that process.
Change-Id: If2bea4c62bd8f680e9d9f39248bb9679332b245b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315867
Reviewed-by: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index 6485a68..e868785 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -160,16 +160,17 @@
for (const auto& varDecl : varDecls.fVars) {
const SkSL::Variable& var =
*(static_cast<const SkSL::VarDeclaration&>(*varDecl).fVar);
+ const SkSL::Type& varType = var.type();
// Varyings (only used in conjunction with drawVertices)
if (var.fModifiers.fFlags & SkSL::Modifiers::kVarying_Flag) {
varyings.push_back({var.fName,
- var.fType.typeKind() == SkSL::Type::TypeKind::kVector
- ? var.fType.columns()
+ varType.typeKind() == SkSL::Type::TypeKind::kVector
+ ? varType.columns()
: 1});
}
// Fragment Processors (aka 'shader'): These are child effects
- else if (&var.fType == ctx.fFragmentProcessor_Type.get()) {
+ else if (&varType == ctx.fFragmentProcessor_Type.get()) {
children.push_back(var.fName);
sampleUsages.push_back(SkSL::Analysis::GetSampleUsage(*program, var));
}
@@ -180,7 +181,7 @@
uni.fFlags = 0;
uni.fCount = 1;
- const SkSL::Type* type = &var.fType;
+ const SkSL::Type* type = &var.type();
if (type->typeKind() == SkSL::Type::TypeKind::kArray) {
uni.fFlags |= Uniform::kArray_Flag;
uni.fCount = type->columns();
diff --git a/src/sksl/SkSLAnalysis.cpp b/src/sksl/SkSLAnalysis.cpp
index 3140ee1..6496965 100644
--- a/src/sksl/SkSLAnalysis.cpp
+++ b/src/sksl/SkSLAnalysis.cpp
@@ -95,9 +95,9 @@
// Determine the type of call at this site, and merge it with the accumulated state
const Expression* lastArg = fc.fArguments.back().get();
- if (lastArg->fType == *fContext.fFloat2_Type) {
+ if (lastArg->type() == *fContext.fFloat2_Type) {
fUsage.merge(SampleUsage::Explicit());
- } else if (lastArg->fType == *fContext.fFloat3x3_Type) {
+ } else if (lastArg->type() == *fContext.fFloat3x3_Type) {
// Determine the type of matrix for this call site
if (lastArg->isConstantOrUniform()) {
if (lastArg->kind() == Expression::Kind::kVariableReference ||
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 6712336..a213ca4 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -162,16 +162,16 @@
const VarDeclarations& decl = e.as<VarDeclarations>();
for (const auto& v : decl.fVars) {
const Variable* declVar = v->as<VarDeclaration>().fVar;
- if (declVar->fType == *fContext.fFragmentProcessor_Type) {
+ if (declVar->type() == *fContext.fFragmentProcessor_Type) {
fOutput->fChildFPCount++;
}
if (declVar->fModifiers.fLayout.fBuiltin >= 0 || is_in(*declVar)) {
continue;
}
if (is_uniform(*declVar)) {
- this->gatherUniforms(declVar->fType, declVar->fName);
+ this->gatherUniforms(declVar->type(), declVar->fName);
} else {
- fOutput->fGlobalSlotCount += SlotCount(declVar->fType);
+ fOutput->fGlobalSlotCount += SlotCount(declVar->type());
}
}
break;
@@ -434,7 +434,7 @@
}
int result = fParameterCount + fLocals.size();
fLocals.push_back(&var);
- for (int i = 0; i < SlotCount(var.fType) - 1; ++i) {
+ for (int i = 0; i < SlotCount(var.type()) - 1; ++i) {
fLocals.push_back(nullptr);
}
SkASSERT(result <= 255);
@@ -447,20 +447,20 @@
SkASSERT(offset <= 255);
return { offset, Storage::kLocal };
}
- offset += SlotCount(p->fType);
+ offset += SlotCount(p->type());
}
SkASSERT(false);
return Location::MakeInvalid();
}
case Variable::kGlobal_Storage: {
- if (var.fType == *fContext.fFragmentProcessor_Type) {
+ if (var.type() == *fContext.fFragmentProcessor_Type) {
int offset = 0;
for (const auto& e : fProgram) {
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;
- if (declVar->fType != *fContext.fFragmentProcessor_Type) {
+ if (declVar->type() != *fContext.fFragmentProcessor_Type) {
continue;
}
if (declVar == &var) {
@@ -500,7 +500,7 @@
SkASSERT(offset <= 255);
return { offset, isUniform ? Storage::kUniform : Storage::kGlobal };
}
- offset += SlotCount(declVar->fType);
+ offset += SlotCount(declVar->type());
}
}
}
@@ -520,7 +520,7 @@
Location baseLoc = this->getLocation(*f.fBase);
int offset = 0;
for (int i = 0; i < f.fFieldIndex; ++i) {
- offset += SlotCount(*f.fBase->fType.fields()[i].fType);
+ offset += SlotCount(*f.fBase->type().fields()[i].fType);
}
if (baseLoc.isOnStack()) {
if (offset != 0) {
@@ -535,8 +535,8 @@
}
case Expression::Kind::kIndex: {
const IndexExpression& i = expr.as<IndexExpression>();
- int stride = SlotCount(i.fType);
- int length = i.fBase->fType.columns();
+ int stride = SlotCount(i.type());
+ int length = i.fBase->type().columns();
SkASSERT(length <= 255);
int offset = -1;
if (i.fIndex->isCompileTimeConstant()) {
@@ -688,8 +688,8 @@
discard = false;
return discard;
}
- const Type& lType = b.fLeft->fType;
- const Type& rType = b.fRight->fType;
+ const Type& lType = b.fLeft->type();
+ const Type& rType = b.fRight->type();
bool lVecOrMtx = (lType.typeKind() == Type::TypeKind::kVector ||
lType.typeKind() == Type::TypeKind::kMatrix);
bool rVecOrMtx = (rType.typeKind() == Type::TypeKind::kVector ||
@@ -776,7 +776,7 @@
!(lType.typeKind() == Type::TypeKind::kVector &&
rType.typeKind() == Type::TypeKind::kVector)) {
this->write(ByteCodeInstruction::kMatrixMultiply,
- SlotCount(b.fType) - (SlotCount(lType) + SlotCount(rType)));
+ SlotCount(b.type()) - (SlotCount(lType) + SlotCount(rType)));
int rCols = rType.columns(),
rRows = rType.rows(),
lCols = lType.columns(),
@@ -786,7 +786,7 @@
std::swap(rCols, rRows);
}
SkASSERT(lCols == rRows);
- SkASSERT(SlotCount(b.fType) == lRows * rCols);
+ SkASSERT(SlotCount(b.type()) == lRows * rCols);
this->write8(lCols);
this->write8(lRows);
this->write8(rCols);
@@ -908,8 +908,8 @@
this->writeExpression(*arg);
}
if (c.fArguments.size() == 1) {
- const Type& inType = c.fArguments[0]->fType;
- const Type& outType = c.fType;
+ const Type& inType = c.fArguments[0]->type();
+ const Type& outType = c.type();
TypeCategory inCategory = type_category(inType);
TypeCategory outCategory = type_category(outType);
int inCount = SlotCount(inType);
@@ -959,12 +959,12 @@
int argumentCount = 0;
for (const auto& arg : f.fArguments) {
this->writeExpression(*arg);
- argumentCount += SlotCount(arg->fType);
+ argumentCount += SlotCount(arg->type());
}
- this->write(ByteCodeInstruction::kCallExternal, SlotCount(f.fType) - argumentCount);
+ this->write(ByteCodeInstruction::kCallExternal, SlotCount(f.type()) - argumentCount);
SkASSERT(argumentCount <= 255);
this->write8(argumentCount);
- this->write8(SlotCount(f.fType));
+ this->write8(SlotCount(f.type()));
int index = fOutput->fExternalValues.size();
fOutput->fExternalValues.push_back(f.fFunction);
SkASSERT(index <= 255);
@@ -995,7 +995,7 @@
}
Location location = this->getLocation(expr);
- int count = SlotCount(expr.fType);
+ int count = SlotCount(expr.type());
if (count == 0) {
return;
}
@@ -1042,7 +1042,7 @@
const size_t nargs = args.size();
SkASSERT(nargs >= 1);
- int count = SlotCount(args[0]->fType);
+ int count = SlotCount(args[0]->type());
// Several intrinsics have variants where one argument is either scalar, or the same size as
// the first argument. Call dupSmallerType(SlotCount(argType)) to ensure equal component count.
@@ -1055,9 +1055,9 @@
if (intrin.is_special && intrin.special == SpecialIntrinsic::kSample) {
// Sample is very special, the first argument is an FP, which can't be pushed to the stack.
- if (nargs > 2 || args[0]->fType != *fContext.fFragmentProcessor_Type ||
- (nargs == 2 && (args[1]->fType != *fContext.fFloat2_Type &&
- args[1]->fType != *fContext.fFloat3x3_Type))) {
+ if (nargs > 2 || args[0]->type() != *fContext.fFragmentProcessor_Type ||
+ (nargs == 2 && (args[1]->type() != *fContext.fFloat2_Type &&
+ args[1]->type() != *fContext.fFloat3x3_Type))) {
fErrors.error(c.fOffset, "Unsupported form of sample");
return;
}
@@ -1065,7 +1065,7 @@
if (nargs == 2) {
// Write our coords or matrix
this->writeExpression(*args[1]);
- this->write(args[1]->fType == *fContext.fFloat3x3_Type
+ this->write(args[1]->type() == *fContext.fFloat3x3_Type
? ByteCodeInstruction::kSampleMatrix
: ByteCodeInstruction::kSampleExplicit);
} else {
@@ -1083,7 +1083,7 @@
// These intrinsics are extra-special, we need instructions interleaved with arguments
bool saturate = (intrin.special == SpecialIntrinsic::kSaturate);
SkASSERT(nargs == (saturate ? 1 : 3));
- int limitCount = saturate ? 1 : SlotCount(args[1]->fType);
+ int limitCount = saturate ? 1 : SlotCount(args[1]->type());
// 'x'
this->writeExpression(*args[0]);
@@ -1096,7 +1096,7 @@
this->writeExpression(*args[1]);
}
dupSmallerType(limitCount);
- this->writeTypedInstruction(args[0]->fType,
+ this->writeTypedInstruction(args[0]->type(),
ByteCodeInstruction::kMaxS,
ByteCodeInstruction::kMaxS,
ByteCodeInstruction::kMaxF,
@@ -1107,11 +1107,11 @@
this->write(ByteCodeInstruction::kPushImmediate);
this->write32(float_to_bits(1.0f));
} else {
- SkASSERT(limitCount == SlotCount(args[2]->fType));
+ SkASSERT(limitCount == SlotCount(args[2]->type()));
this->writeExpression(*args[2]);
}
dupSmallerType(limitCount);
- this->writeTypedInstruction(args[0]->fType,
+ this->writeTypedInstruction(args[0]->type(),
ByteCodeInstruction::kMinS,
ByteCodeInstruction::kMinS,
ByteCodeInstruction::kMinF,
@@ -1140,7 +1140,7 @@
case SpecialIntrinsic::kDot: {
SkASSERT(nargs == 2);
- SkASSERT(count == SlotCount(args[1]->fType));
+ SkASSERT(count == SlotCount(args[1]->type()));
this->write(ByteCodeInstruction::kMultiplyF, count);
for (int i = count-1; i --> 0;) {
this->write(ByteCodeInstruction::kAddF, 1);
@@ -1161,15 +1161,15 @@
case SpecialIntrinsic::kMin: {
SkASSERT(nargs == 2);
// There are variants where the second argument is scalar
- dupSmallerType(SlotCount(args[1]->fType));
+ dupSmallerType(SlotCount(args[1]->type()));
if (intrin.special == SpecialIntrinsic::kMax) {
- this->writeTypedInstruction(args[0]->fType,
+ this->writeTypedInstruction(args[0]->type(),
ByteCodeInstruction::kMaxS,
ByteCodeInstruction::kMaxS,
ByteCodeInstruction::kMaxF,
count);
} else {
- this->writeTypedInstruction(args[0]->fType,
+ this->writeTypedInstruction(args[0]->type(),
ByteCodeInstruction::kMinS,
ByteCodeInstruction::kMinS,
ByteCodeInstruction::kMinF,
@@ -1180,10 +1180,10 @@
case SpecialIntrinsic::kMix: {
// Two main variants of mix to handle
SkASSERT(nargs == 3);
- SkASSERT(count == SlotCount(args[1]->fType));
- int selectorCount = SlotCount(args[2]->fType);
+ SkASSERT(count == SlotCount(args[1]->type()));
+ int selectorCount = SlotCount(args[2]->type());
- if (is_generic_type(&args[2]->fType, fContext.fGenBType_Type.get())) {
+ if (is_generic_type(&args[2]->type(), fContext.fGenBType_Type.get())) {
// mix(genType, genType, genBoolType)
SkASSERT(selectorCount == count);
this->write(ByteCodeInstruction::kMix, count);
@@ -1225,7 +1225,7 @@
}
default:
- this->writeTypedInstruction(args[0]->fType,
+ this->writeTypedInstruction(args[0]->type(),
intrin.inst_s,
intrin.inst_u,
intrin.inst_f,
@@ -1260,7 +1260,7 @@
}
// We may need to deal with out parameters, so the sequence is tricky
- if (int returnCount = SlotCount(f.fType)) {
+ if (int returnCount = SlotCount(f.type())) {
this->write(ByteCodeInstruction::kReserve, returnCount);
}
@@ -1307,7 +1307,7 @@
lvalues.back()->store(true);
lvalues.pop_back();
} else {
- popCount += SlotCount(arg->fType);
+ popCount += SlotCount(arg->type());
}
}
pop();
@@ -1327,19 +1327,20 @@
switch (p.fOperator) {
case Token::Kind::TK_PLUSPLUS: // fall through
case Token::Kind::TK_MINUSMINUS: {
- SkASSERT(SlotCount(p.fOperand->fType) == 1);
+ SkASSERT(SlotCount(p.fOperand->type()) == 1);
std::unique_ptr<LValue> lvalue = this->getLValue(*p.fOperand);
lvalue->load();
this->write(ByteCodeInstruction::kPushImmediate);
- this->write32(type_category(p.fType) == TypeCategory::kFloat ? float_to_bits(1.0f) : 1);
+ this->write32(type_category(p.type()) == TypeCategory::kFloat ? float_to_bits(1.0f)
+ : 1);
if (p.fOperator == Token::Kind::TK_PLUSPLUS) {
- this->writeTypedInstruction(p.fType,
+ this->writeTypedInstruction(p.type(),
ByteCodeInstruction::kAddI,
ByteCodeInstruction::kAddI,
ByteCodeInstruction::kAddF,
1);
} else {
- this->writeTypedInstruction(p.fType,
+ this->writeTypedInstruction(p.type(),
ByteCodeInstruction::kSubtractI,
ByteCodeInstruction::kSubtractI,
ByteCodeInstruction::kSubtractF,
@@ -1351,17 +1352,17 @@
}
case Token::Kind::TK_MINUS: {
this->writeExpression(*p.fOperand);
- this->writeTypedInstruction(p.fType,
+ this->writeTypedInstruction(p.type(),
ByteCodeInstruction::kNegateI,
ByteCodeInstruction::kNegateI,
ByteCodeInstruction::kNegateF,
- SlotCount(p.fOperand->fType));
+ SlotCount(p.fOperand->type()));
break;
}
case Token::Kind::TK_LOGICALNOT:
case Token::Kind::TK_BITWISENOT: {
- SkASSERT(SlotCount(p.fOperand->fType) == 1);
- SkDEBUGCODE(TypeCategory tc = type_category(p.fOperand->fType));
+ SkASSERT(SlotCount(p.fOperand->type()) == 1);
+ SkDEBUGCODE(TypeCategory tc = type_category(p.fOperand->type()));
SkASSERT((p.fOperator == Token::Kind::TK_LOGICALNOT && tc == TypeCategory::kBool) ||
(p.fOperator == Token::Kind::TK_BITWISENOT && (tc == TypeCategory::kSigned ||
tc == TypeCategory::kUnsigned)));
@@ -1379,7 +1380,7 @@
switch (p.fOperator) {
case Token::Kind::TK_PLUSPLUS: // fall through
case Token::Kind::TK_MINUSMINUS: {
- SkASSERT(SlotCount(p.fOperand->fType) == 1);
+ SkASSERT(SlotCount(p.fOperand->type()) == 1);
std::unique_ptr<LValue> lvalue = this->getLValue(*p.fOperand);
lvalue->load();
// If we're not supposed to discard the result, then make a copy *before* the +/-
@@ -1387,15 +1388,16 @@
this->write(ByteCodeInstruction::kDup, 1);
}
this->write(ByteCodeInstruction::kPushImmediate);
- this->write32(type_category(p.fType) == TypeCategory::kFloat ? float_to_bits(1.0f) : 1);
+ this->write32(type_category(p.type()) == TypeCategory::kFloat ? float_to_bits(1.0f)
+ : 1);
if (p.fOperator == Token::Kind::TK_PLUSPLUS) {
- this->writeTypedInstruction(p.fType,
+ this->writeTypedInstruction(p.type(),
ByteCodeInstruction::kAddI,
ByteCodeInstruction::kAddI,
ByteCodeInstruction::kAddF,
1);
} else {
- this->writeTypedInstruction(p.fType,
+ this->writeTypedInstruction(p.type(),
ByteCodeInstruction::kSubtractI,
ByteCodeInstruction::kSubtractI,
ByteCodeInstruction::kSubtractF,
@@ -1419,8 +1421,8 @@
}
this->writeExpression(*s.fBase);
- this->write(ByteCodeInstruction::kSwizzle, s.fComponents.size() - s.fBase->fType.columns());
- this->write8(s.fBase->fType.columns());
+ this->write(ByteCodeInstruction::kSwizzle, s.fComponents.size() - s.fBase->type().columns());
+ this->write8(s.fBase->type().columns());
this->write8(s.fComponents.size());
for (int c : s.fComponents) {
this->write8(c);
@@ -1428,9 +1430,9 @@
}
void ByteCodeGenerator::writeTernaryExpression(const TernaryExpression& t) {
- int count = SlotCount(t.fType);
- SkASSERT(count == SlotCount(t.fIfTrue->fType));
- SkASSERT(count == SlotCount(t.fIfFalse->fType));
+ int count = SlotCount(t.type());
+ SkASSERT(count == SlotCount(t.fIfTrue->type()));
+ SkASSERT(count == SlotCount(t.fIfFalse->type()));
this->writeExpression(*t.fTest);
this->write(ByteCodeInstruction::kMaskPush);
@@ -1493,7 +1495,7 @@
SkASSERT(false);
}
if (discard) {
- int count = SlotCount(e.fType);
+ int count = SlotCount(e.type());
if (count > 0) {
this->write(ByteCodeInstruction::kPop, count);
}
@@ -1588,7 +1590,7 @@
}
void store(bool discard) override {
- int count = ByteCodeGenerator::SlotCount(fExpression.fType);
+ int count = ByteCodeGenerator::SlotCount(fExpression.type());
if (!discard) {
fGenerator.write(ByteCodeInstruction::kDup, count);
}
@@ -1734,7 +1736,7 @@
fErrors.error(r.fOffset, "return not allowed inside conditional or loop");
return;
}
- int count = SlotCount(r.fExpression->fType);
+ int count = SlotCount(r.fExpression->type());
this->writeExpression(*r.fExpression);
// Technically, the kReturn also pops fOutput->fLocalCount values from the stack, too, but we
@@ -1757,7 +1759,7 @@
Location location = this->getLocation(*decl.fVar);
if (decl.fValue) {
this->writeExpression(*decl.fValue);
- int count = SlotCount(decl.fValue->fType);
+ int count = SlotCount(decl.fValue->type());
this->write(ByteCodeInstruction::kStore, count);
this->write8(location.fSlot);
}
@@ -1829,7 +1831,7 @@
: fName(declaration->fName) {
fParameterCount = 0;
for (const auto& p : declaration->fParameters) {
- int slots = ByteCodeGenerator::SlotCount(p->fType);
+ int slots = ByteCodeGenerator::SlotCount(p->type());
fParameters.push_back({ slots, (bool)(p->fModifiers.fFlags & Modifiers::kOut_Flag) });
fParameterCount += slots;
}
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index db959be..3eacb80 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -21,7 +21,7 @@
static bool needs_uniform_var(const Variable& var) {
return (var.fModifiers.fFlags & Modifiers::kUniform_Flag) &&
- var.fType.typeKind() != Type::TypeKind::kSampler;
+ var.type().typeKind() != Type::TypeKind::kSampler;
}
CPPCodeGenerator::CPPCodeGenerator(const Context* context, const Program* program,
@@ -90,8 +90,8 @@
} else {
var = &b.fRight->as<VariableReference>().fVariable;
}
- SkASSERT(var->fType.typeKind() == Type::TypeKind::kNullable &&
- var->fType.componentType() == *fContext.fFragmentProcessor_Type);
+ SkASSERT(var->type().typeKind() == Type::TypeKind::kNullable &&
+ var->type().componentType() == *fContext.fFragmentProcessor_Type);
this->write("%s");
const char* op = "";
switch (b.fOperator) {
@@ -128,7 +128,7 @@
if (var.fModifiers.fLayout.fCType == SkSL::Layout::CType::kSkPMColor4f) {
return "{SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN}";
}
- return default_value(var.fType);
+ return default_value(var.type());
}
static bool is_private(const Variable& var) {
@@ -141,7 +141,7 @@
static bool is_uniform_in(const Variable& var) {
return (var.fModifiers.fFlags & Modifiers::kUniform_Flag) &&
(var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
- var.fType.typeKind() != Type::TypeKind::kSampler;
+ var.type().typeKind() != Type::TypeKind::kSampler;
}
String CPPCodeGenerator::formatRuntimeValue(const Type& type,
@@ -257,7 +257,7 @@
void CPPCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
if (is_private(var)) {
- this->writeRuntimeValue(var.fType, var.fModifiers.fLayout, var.fName);
+ this->writeRuntimeValue(var.type(), var.fModifiers.fLayout, var.fName);
} else {
this->writeExpression(value, kTopLevel_Precedence);
}
@@ -269,7 +269,7 @@
if (&var == param) {
return "args.fTexSamplers[" + to_string(samplerCount) + "]";
}
- if (param->fType.typeKind() == Type::TypeKind::kSampler) {
+ if (param->type().typeKind() == Type::TypeKind::kSampler) {
++samplerCount;
}
}
@@ -327,7 +327,7 @@
this->write("sk_Height");
break;
default:
- if (ref.fVariable.fType.typeKind() == Type::TypeKind::kSampler) {
+ if (ref.fVariable.type().typeKind() == Type::TypeKind::kSampler) {
this->write("%s");
fFormatArgs.push_back("fragBuilder->getProgramBuilder()->samplerVariable(" +
this->getSamplerHandle(ref.fVariable) + ")");
@@ -343,14 +343,14 @@
code = String::printf("%sVar.isValid() ? %s : \"%s\"",
HCodeGenerator::FieldName(name.c_str()).c_str(),
var.c_str(),
- default_value(ref.fVariable.fType).c_str());
+ default_value(ref.fVariable.type()).c_str());
} else {
code = var;
}
fFormatArgs.push_back(code);
} else if (SectionAndParameterHelper::IsParameter(ref.fVariable)) {
String name(ref.fVariable.fName);
- this->writeRuntimeValue(ref.fVariable.fType, ref.fVariable.fModifiers.fLayout,
+ this->writeRuntimeValue(ref.fVariable.type(), ref.fVariable.fModifiers.fLayout,
String::printf("_outer.%s", name.c_str()).c_str());
} else {
this->write(ref.fVariable.fName);
@@ -380,7 +380,7 @@
}
void CPPCodeGenerator::writeFieldAccess(const FieldAccess& access) {
- if (access.fBase->fType.name() == "fragmentProcessor") {
+ if (access.fBase->type().name() == "fragmentProcessor") {
// Special field access on fragment processors are converted into function calls on
// GrFragmentProcessor's getters.
if (access.fBase->kind() != Expression::Kind::kVariableReference) {
@@ -414,7 +414,7 @@
const VarDeclaration& decl = raw->as<VarDeclaration>();
if (decl.fVar == &var) {
found = true;
- } else if (decl.fVar->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+ } else if (decl.fVar->type().nonnullable() == *fContext.fFragmentProcessor_Type) {
++index;
}
}
@@ -429,11 +429,11 @@
void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
if (c.fFunction.fBuiltin && c.fFunction.fName == "sample" &&
- c.fArguments[0]->fType.typeKind() != Type::TypeKind::kSampler) {
+ c.fArguments[0]->type().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() ||
- "fragmentProcessor?" == c.fArguments[0]->fType.name());
+ SkASSERT("fragmentProcessor" == c.fArguments[0]->type().name() ||
+ "fragmentProcessor?" == c.fArguments[0]->type().name());
// Actually fail during compilation if arguments with valid types are
// provided that are not variable references, since sample() is a
@@ -450,7 +450,7 @@
this->newExtraEmitCodeBlock();
String inputColor;
- if (c.fArguments.size() > 1 && c.fArguments[1]->fType.name() == "half4") {
+ if (c.fArguments.size() > 1 && c.fArguments[1]->type().name() == "half4") {
// Use the invokeChild() variant that accepts an input color, so convert the 2nd
// argument's expression into C++ code that produces sksl stored in an SkString.
String inputColorName = "_input" + to_string(c.fOffset);
@@ -462,12 +462,12 @@
String inputCoord;
String invokeFunction = "invokeChild";
- if (c.fArguments.back()->fType.name() == "float2") {
+ if (c.fArguments.back()->type().name() == "float2") {
// Invoking child with explicit coordinates at this call site
inputCoord = "_coords" + to_string(c.fOffset);
addExtraEmitCodeLine(convertSKSLExpressionToCPP(*c.fArguments.back(), inputCoord));
inputCoord.append(".c_str()");
- } else if (c.fArguments.back()->fType.name() == "float3x3") {
+ } else if (c.fArguments.back()->type().name() == "float3x3") {
// Invoking child with a matrix, sampling relative to the input coords.
invokeFunction = "invokeChildWithMatrix";
SampleUsage usage = Analysis::GetSampleUsage(fProgram, child);
@@ -616,7 +616,7 @@
const char* separator = "";
for (const auto& param : decl.fParameters) {
args += String(separator) + "GrShaderVar(\"" + param->fName + "\", " +
- glsltype_string(fContext, param->fType) + ")";
+ glsltype_string(fContext, param->type()) + ")";
separator = ", ";
}
args += "};";
@@ -681,19 +681,19 @@
this->writef(" if (%s) {\n ", String(var.fModifiers.fLayout.fWhen).c_str());
}
String name(var.fName);
- if (var.fType.typeKind() != Type::TypeKind::kArray) {
+ if (var.type().typeKind() != Type::TypeKind::kArray) {
this->writef(" %sVar = args.fUniformHandler->addUniform(&_outer, "
"kFragment_GrShaderFlag, %s, \"%s\");\n",
HCodeGenerator::FieldName(name.c_str()).c_str(),
- glsltype_string(fContext, var.fType),
+ glsltype_string(fContext, var.type()),
name.c_str());
} else {
this->writef(" %sVar = args.fUniformHandler->addUniformArray(&_outer, "
"kFragment_GrShaderFlag, %s, \"%s\", %d);\n",
HCodeGenerator::FieldName(name.c_str()).c_str(),
- glsltype_string(fContext, var.fType.componentType()),
+ glsltype_string(fContext, var.type().componentType()),
name.c_str(),
- var.fType.columns());
+ var.type().columns());
}
if (var.fModifiers.fLayout.fWhen.fLength) {
this->write(" }\n");
@@ -710,13 +710,13 @@
for (const auto& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
if (is_private(*decl.fVar)) {
- if (decl.fVar->fType == *fContext.fFragmentProcessor_Type) {
+ if (decl.fVar->type() == *fContext.fFragmentProcessor_Type) {
fErrors.error(decl.fOffset,
"fragmentProcessor variables must be declared 'in'");
return;
}
this->writef("%s %s = %s;\n",
- HCodeGenerator::FieldType(fContext, decl.fVar->fType,
+ HCodeGenerator::FieldType(fContext, decl.fVar->type(),
decl.fVar->fModifiers.fLayout).c_str(),
String(decl.fVar->fName).c_str(),
default_value(*decl.fVar).c_str());
@@ -762,7 +762,7 @@
}
static bool is_accessible(const Variable& var) {
- const Type& type = var.fType.nonnullable();
+ const Type& type = var.type().nonnullable();
return Type::TypeKind::kSampler != type.typeKind() &&
Type::TypeKind::kOther != type.typeKind();
}
@@ -1040,7 +1040,7 @@
if (needsValueDeclaration) {
valueVar.appendf("%sValue", name);
// Use AccessType since that will match the return type of _outer's public API.
- String valueType = HCodeGenerator::AccessType(fContext, u->fType,
+ String valueType = HCodeGenerator::AccessType(fContext, u->type(),
u->fModifiers.fLayout);
this->writef("%s%s %s = _outer.%s;\n",
indent.c_str(), valueType.c_str(), valueVar.c_str(), name);
@@ -1085,7 +1085,7 @@
const Variable& variable = *decl.fVar;
String nameString(variable.fName);
const char* name = nameString.c_str();
- if (variable.fType.typeKind() == Type::TypeKind::kSampler) {
+ if (variable.type().typeKind() == Type::TypeKind::kSampler) {
this->writef(" const GrSurfaceProxyView& %sView = "
"_outer.textureSampler(%d).view();\n",
name, samplerIndex);
@@ -1098,14 +1098,14 @@
" (void) %s;\n",
name, HCodeGenerator::FieldName(name).c_str(), name);
} else if (SectionAndParameterHelper::IsParameter(variable) &&
- variable.fType != *fContext.fFragmentProcessor_Type) {
+ variable.type() != *fContext.fFragmentProcessor_Type) {
if (!wroteProcessor) {
this->writef(" const %s& _outer = _proc.cast<%s>();\n", fullName,
fullName);
wroteProcessor = true;
}
- if (variable.fType.nonnullable() != *fContext.fFragmentProcessor_Type) {
+ if (variable.type().nonnullable() != *fContext.fFragmentProcessor_Type) {
this->writef(" auto %s = _outer.%s;\n"
" (void) %s;\n",
name, name, name);
@@ -1122,7 +1122,7 @@
void CPPCodeGenerator::writeOnTextureSampler() {
bool foundSampler = false;
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
- if (param->fType.typeKind() == Type::TypeKind::kSampler) {
+ if (param->type().typeKind() == Type::TypeKind::kSampler) {
if (!foundSampler) {
this->writef(
"const GrFragmentProcessor::TextureSampler& %s::onTextureSampler(int "
@@ -1153,7 +1153,7 @@
fFullName.c_str(), fFullName.c_str(), fFullName.c_str());
for (const Variable* param : fSectionAndParameterHelper.getParameters()) {
String fieldName = HCodeGenerator::FieldName(String(param->fName).c_str());
- if (param->fType.nonnullable() != *fContext.fFragmentProcessor_Type) {
+ if (param->type().nonnullable() != *fContext.fFragmentProcessor_Type) {
this->writef("\n, %s(src.%s)",
fieldName.c_str(),
fieldName.c_str());
@@ -1163,7 +1163,7 @@
this->writef(" this->cloneAndRegisterAllChildProcessors(src);\n");
int samplerCount = 0;
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
- if (param->fType.typeKind() == Type::TypeKind::kSampler) {
+ if (param->type().typeKind() == Type::TypeKind::kSampler) {
++samplerCount;
}
}
@@ -1197,14 +1197,16 @@
for (const Variable* param : fSectionAndParameterHelper.getParameters()) {
// dumpInfo() doesn't need to log child FPs.
- if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+ if (param->type().nonnullable() == *fContext.fFragmentProcessor_Type) {
continue;
}
// Add this field onto the format string and argument list.
String fieldName = HCodeGenerator::FieldName(String(param->fName).c_str());
- String runtimeValue = this->formatRuntimeValue(param->fType, param->fModifiers.fLayout,
- param->fName, &argumentList);
+ String runtimeValue = this->formatRuntimeValue(param->type(),
+ param->fModifiers.fLayout,
+ param->fName,
+ &argumentList);
formatString.appendf("%s%s=%s",
formatString.empty() ? "" : ", ",
fieldName.c_str(),
@@ -1257,6 +1259,7 @@
for (const auto& raw : decls.fVars) {
const VarDeclaration& decl = raw->as<VarDeclaration>();
const Variable& var = *decl.fVar;
+ const Type& varType = var.type();
String nameString(var.fName);
const char* name = nameString.c_str();
if (var.fModifiers.fLayout.fKey != Layout::kNo_Key &&
@@ -1268,7 +1271,7 @@
case Layout::kKey_Key:
if (is_private(var)) {
this->writef("%s %s =",
- HCodeGenerator::FieldType(fContext, var.fType,
+ HCodeGenerator::FieldType(fContext, varType,
var.fModifiers.fLayout).c_str(),
String(var.fName).c_str());
if (decl.fValue) {
@@ -1283,7 +1286,7 @@
if (var.fModifiers.fLayout.fWhen.fLength) {
this->writef("if (%s) {", String(var.fModifiers.fLayout.fWhen).c_str());
}
- if (var.fType == *fContext.fHalf4_Type) {
+ if (varType == *fContext.fHalf4_Type) {
this->writef(" uint16_t red = SkFloatToHalf(%s.fR);\n",
HCodeGenerator::FieldName(name).c_str());
this->writef(" uint16_t green = SkFloatToHalf(%s.fG);\n",
@@ -1294,24 +1297,24 @@
HCodeGenerator::FieldName(name).c_str());
this->write(" b->add32(((uint32_t)red << 16) | green);\n");
this->write(" b->add32(((uint32_t)blue << 16) | alpha);\n");
- } else if (var.fType == *fContext.fHalf_Type ||
- var.fType == *fContext.fFloat_Type) {
+ } else if (varType == *fContext.fHalf_Type ||
+ varType == *fContext.fFloat_Type) {
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.typeKind() == Type::TypeKind::kEnum) {
+ } else if (varType.isInteger() || varType == *fContext.fBool_Type ||
+ varType.typeKind() == Type::TypeKind::kEnum) {
this->writef(" b->add32((uint32_t) %s);\n",
HCodeGenerator::FieldName(name).c_str());
} else {
ABORT("NOT YET IMPLEMENTED: automatic key handling for %s\n",
- var.fType.displayName().c_str());
+ varType.displayName().c_str());
}
if (var.fModifiers.fLayout.fWhen.fLength) {
this->write("}");
}
break;
case Layout::kIdentity_Key:
- if (var.fType.typeKind() != Type::TypeKind::kMatrix) {
+ if (varType.typeKind() != Type::TypeKind::kMatrix) {
fErrors.error(var.fOffset,
"layout(key=identity) requires matrix type");
}
@@ -1335,7 +1338,7 @@
for (const auto& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
if ((decl.fVar->fModifiers.fFlags & Modifiers::kUniform_Flag) &&
- decl.fVar->fType.typeKind() != Type::TypeKind::kSampler) {
+ decl.fVar->type().typeKind() != Type::TypeKind::kSampler) {
uniforms.push_back(decl.fVar);
}
@@ -1411,7 +1414,7 @@
" (void) that;\n",
fullName, fullName, fullName);
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
- if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+ if (param->type().nonnullable() == *fContext.fFragmentProcessor_Type) {
continue;
}
String nameString(param->fName);
diff --git a/src/sksl/SkSLCPPUniformCTypes.h b/src/sksl/SkSLCPPUniformCTypes.h
index c6d3686..79ea4ac 100644
--- a/src/sksl/SkSLCPPUniformCTypes.h
+++ b/src/sksl/SkSLCPPUniformCTypes.h
@@ -50,7 +50,7 @@
const Layout& layout);
static const UniformCTypeMapper* Get(const Context& context, const Variable& variable) {
- return Get(context, variable.fType, variable.fModifiers.fLayout);
+ return Get(context, variable.type(), variable.fModifiers.fLayout);
}
// The C++ type name that this mapper applies to
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 31737d5..749815f 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -237,7 +237,7 @@
fIRGenerator->fSymbolTable->add(
skCapsName,
std::make_unique<Variable>(/*offset=*/-1, Modifiers(), skCapsName,
- *fContext->fSkCaps_Type, Variable::kGlobal_Storage));
+ fContext->fSkCaps_Type.get(), Variable::kGlobal_Storage));
fIRGenerator->fIntrinsics = fGPUIntrinsics.get();
std::vector<std::unique_ptr<ProgramElement>> gpuIntrinsics;
@@ -660,12 +660,13 @@
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.typeKind()) {
+ const Type& constructorType = constructor.type();
+ bool isFloat = constructorType.columns() > 1
+ ? constructorType.componentType().isFloat()
+ : constructorType.isFloat();
+ switch (constructorType.typeKind()) {
case Type::TypeKind::kVector:
- for (int i = 0; i < constructor.fType.columns(); ++i) {
+ for (int i = 0; i < constructorType.columns(); ++i) {
if (isFloat) {
if (constructor.getFVecComponent(i) != value) {
return false;
@@ -765,7 +766,7 @@
/**
* Constructs the specified type using a single argument.
*/
-static std::unique_ptr<Expression> construct(const Type& type, std::unique_ptr<Expression> v) {
+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));
std::unique_ptr<Expression> result = std::make_unique<Constructor>(-1, type, std::move(args));
@@ -784,14 +785,14 @@
bool* outNeedsRescan) {
SkASSERT((*(*iter)->expression())->kind() == Expression::Kind::kBinary);
SkASSERT(type.typeKind() == Type::TypeKind::kVector);
- SkASSERT((*otherExpression)->fType.typeKind() == Type::TypeKind::kScalar);
+ SkASSERT((*otherExpression)->type().typeKind() == Type::TypeKind::kScalar);
*outUpdated = true;
std::unique_ptr<Expression>* target = (*iter)->expression();
if (!b->tryRemoveExpression(iter)) {
- *target = construct(type, std::move(*otherExpression));
+ *target = construct(&type, std::move(*otherExpression));
*outNeedsRescan = true;
} else {
- *target = construct(type, std::move(*otherExpression));
+ *target = construct(&type, std::move(*otherExpression));
if (!b->tryInsertExpression(iter, target)) {
*outNeedsRescan = true;
}
@@ -807,7 +808,7 @@
bool* outUpdated,
bool* outNeedsRescan) {
BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
- vectorize(b, iter, bin.fRight->fType, &bin.fLeft, outUpdated, outNeedsRescan);
+ vectorize(b, iter, bin.fRight->type(), &bin.fLeft, outUpdated, outNeedsRescan);
}
/**
@@ -819,7 +820,7 @@
bool* outUpdated,
bool* outNeedsRescan) {
BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
- vectorize(b, iter, bin.fLeft->fType, &bin.fRight, outUpdated, outNeedsRescan);
+ vectorize(b, iter, bin.fLeft->type(), &bin.fRight, outUpdated, outNeedsRescan);
}
// Mark that an expression which we were writing to is no longer being written to
@@ -856,7 +857,7 @@
std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator, definitions);
if (optimized) {
*outUpdated = true;
- optimized = fIRGenerator->coerce(std::move(optimized), expr->fType);
+ optimized = fIRGenerator->coerce(std::move(optimized), expr->type());
SkASSERT(optimized);
if (!try_replace_expression(&b, iter, &optimized)) {
*outNeedsRescan = true;
@@ -901,18 +902,20 @@
delete_left(&b, iter, outUpdated, outNeedsRescan);
break;
}
+ const Type& leftType = bin->fLeft->type();
+ const Type& rightType = bin->fRight->type();
// collapse useless expressions like x * 1 or x + 0
- 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))) {
+ if (((leftType.typeKind() != Type::TypeKind::kScalar) &&
+ (leftType.typeKind() != Type::TypeKind::kVector)) ||
+ ((rightType.typeKind() != Type::TypeKind::kScalar) &&
+ (rightType.typeKind() != Type::TypeKind::kVector))) {
break;
}
switch (bin->fOperator) {
case Token::Kind::TK_STAR:
if (is_constant(*bin->fLeft, 1)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kVector &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kScalar) {
+ if (leftType.typeKind() == Type::TypeKind::kVector &&
+ rightType.typeKind() == Type::TypeKind::kScalar) {
// float4(1) * x -> float4(x)
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
} else {
@@ -923,8 +926,8 @@
}
}
else if (is_constant(*bin->fLeft, 0)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kVector &&
+ if (leftType.typeKind() == Type::TypeKind::kScalar &&
+ rightType.typeKind() == Type::TypeKind::kVector &&
!bin->fRight->hasSideEffects()) {
// 0 * float4(x) -> float4(0)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
@@ -938,8 +941,8 @@
}
}
else if (is_constant(*bin->fRight, 1)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
+ if (leftType.typeKind() == Type::TypeKind::kScalar &&
+ rightType.typeKind() == Type::TypeKind::kVector) {
// x * float4(1) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@@ -950,8 +953,8 @@
}
}
else if (is_constant(*bin->fRight, 0)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kVector &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kScalar &&
+ if (leftType.typeKind() == Type::TypeKind::kVector &&
+ rightType.typeKind() == Type::TypeKind::kScalar &&
!bin->fLeft->hasSideEffects()) {
// float4(x) * 0 -> float4(0)
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
@@ -967,8 +970,8 @@
break;
case Token::Kind::TK_PLUS:
if (is_constant(*bin->fLeft, 0)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kVector &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kScalar) {
+ if (leftType.typeKind() == Type::TypeKind::kVector &&
+ rightType.typeKind() == Type::TypeKind::kScalar) {
// float4(0) + x -> float4(x)
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
} else {
@@ -978,8 +981,8 @@
delete_left(&b, iter, outUpdated, outNeedsRescan);
}
} else if (is_constant(*bin->fRight, 0)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
+ if (leftType.typeKind() == Type::TypeKind::kScalar &&
+ rightType.typeKind() == Type::TypeKind::kVector) {
// x + float4(0) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@@ -992,8 +995,8 @@
break;
case Token::Kind::TK_MINUS:
if (is_constant(*bin->fRight, 0)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
+ if (leftType.typeKind() == Type::TypeKind::kScalar &&
+ rightType.typeKind() == Type::TypeKind::kVector) {
// x - float4(0) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@@ -1006,8 +1009,8 @@
break;
case Token::Kind::TK_SLASH:
if (is_constant(*bin->fRight, 1)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kVector) {
+ if (leftType.typeKind() == Type::TypeKind::kScalar &&
+ rightType.typeKind() == Type::TypeKind::kVector) {
// x / float4(1) -> float4(x)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
} else {
@@ -1017,8 +1020,8 @@
delete_right(&b, iter, outUpdated, outNeedsRescan);
}
} else if (is_constant(*bin->fLeft, 0)) {
- if (bin->fLeft->fType.typeKind() == Type::TypeKind::kScalar &&
- bin->fRight->fType.typeKind() == Type::TypeKind::kVector &&
+ if (leftType.typeKind() == Type::TypeKind::kScalar &&
+ rightType.typeKind() == Type::TypeKind::kVector &&
!bin->fRight->hasSideEffects()) {
// 0 / float4(x) -> float4(0)
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
@@ -1064,7 +1067,7 @@
case Expression::Kind::kSwizzle: {
Swizzle& s = expr->as<Swizzle>();
// detect identity swizzles like foo.rgba
- if ((int) s.fComponents.size() == s.fBase->fType.columns()) {
+ if ((int) s.fComponents.size() == s.fBase->type().columns()) {
bool identity = true;
for (int i = 0; i < (int) s.fComponents.size(); ++i) {
if (s.fComponents[i] != i) {
diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h
index 992d74c..e7208ea 100644
--- a/src/sksl/SkSLContext.h
+++ b/src/sksl/SkSLContext.h
@@ -186,7 +186,7 @@
fBool3_Type.get(), fBool4_Type.get() }))
, fSkCaps_Type(new Type("$sk_Caps"))
, fFragmentProcessor_Type(fp_type(fInt_Type.get(), fBool_Type.get()))
- , fDefined_Expression(new Defined(*fInvalid_Type)) {}
+ , fDefined_Expression(new Defined(fInvalid_Type.get())) {}
static std::vector<const Type*> static_type(const Type& t) {
return { &t, &t, &t, &t };
@@ -353,7 +353,7 @@
public:
static constexpr Kind kExpressionKind = Kind::kDefined;
- Defined(const Type& type)
+ Defined(const Type* type)
: INHERITED(-1, kExpressionKind, type) {}
bool hasProperty(Property property) const override {
@@ -365,7 +365,7 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new Defined(fType));
+ return std::unique_ptr<Expression>(new Defined(&this->type()));
}
using INHERITED = Expression;
diff --git a/src/sksl/SkSLDehydrator.cpp b/src/sksl/SkSLDehydrator.cpp
index b9b0646..0035a21 100644
--- a/src/sksl/SkSLDehydrator.cpp
+++ b/src/sksl/SkSLDehydrator.cpp
@@ -210,7 +210,7 @@
this->writeId(&v);
this->write(v.fModifiers);
this->write(v.fName);
- this->write(v.fType);
+ this->write(v.type());
this->writeU8(v.fStorage);
break;
}
@@ -261,7 +261,7 @@
this->write(b.fLeft.get());
this->writeU8((int) b.fOperator);
this->write(b.fRight.get());
- this->write(b.fType);
+ this->write(b.type());
break;
}
case Expression::Kind::kBoolLiteral: {
@@ -273,7 +273,7 @@
case Expression::Kind::kConstructor: {
const Constructor& c = e->as<Constructor>();
this->writeU8(Rehydrator::kConstructor_Command);
- this->write(c.fType);
+ this->write(c.type());
this->writeU8(c.fArguments.size());
for (const auto& a : c.fArguments) {
this->write(a.get());
@@ -305,7 +305,7 @@
case Expression::Kind::kFunctionCall: {
const FunctionCall& f = e->as<FunctionCall>();
this->writeU8(Rehydrator::kFunctionCall_Command);
- this->write(f.fType);
+ this->write(f.type());
this->writeId(&f.fFunction);
this->writeU8(f.fArguments.size());
for (const auto& a : f.fArguments) {
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 92c3a87..8863901 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -251,10 +251,10 @@
SkASSERT(!fProgram.fSettings.fCaps->canUseMinAndAbsTogether());
String tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
String tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
- this->fFunctionHeader += String(" ") + this->getTypePrecision(absExpr.fType) +
- this->getTypeName(absExpr.fType) + " " + tmpVar1 + ";\n";
- this->fFunctionHeader += String(" ") + this->getTypePrecision(otherExpr.fType) +
- this->getTypeName(otherExpr.fType) + " " + tmpVar2 + ";\n";
+ this->fFunctionHeader += String(" ") + this->getTypePrecision(absExpr.type()) +
+ this->getTypeName(absExpr.type()) + " " + tmpVar1 + ";\n";
+ this->fFunctionHeader += String(" ") + this->getTypePrecision(otherExpr.type()) +
+ this->getTypeName(otherExpr.type()) + " " + tmpVar2 + ";\n";
this->write("((" + tmpVar1 + " = ");
this->writeExpression(absExpr, kTopLevel_Precedence);
this->write(") < (" + tmpVar2 + " = ");
@@ -270,7 +270,8 @@
void GLSLCodeGenerator::writeDeterminantHack(const Expression& mat) {
String name;
- if (mat.fType == *fContext.fFloat2x2_Type || mat.fType == *fContext.fHalf2x2_Type) {
+ const Type& type = mat.type();
+ if (type == *fContext.fFloat2x2_Type || type == *fContext.fHalf2x2_Type) {
name = "_determinant2";
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
@@ -281,7 +282,7 @@
).c_str());
}
}
- else if (mat.fType == *fContext.fFloat3x3_Type || mat.fType == *fContext.fHalf3x3_Type) {
+ else if (type == *fContext.fFloat3x3_Type || type == *fContext.fHalf3x3_Type) {
name = "_determinant3";
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
@@ -298,7 +299,7 @@
).c_str());
}
}
- else if (mat.fType == *fContext.fFloat4x4_Type || mat.fType == *fContext.fHalf4x4_Type) {
+ else if (type == *fContext.fFloat4x4_Type || type == *fContext.fHalf4x4_Type) {
name = "_determinant3";
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
@@ -335,7 +336,8 @@
void GLSLCodeGenerator::writeInverseHack(const Expression& mat) {
String name;
- if (mat.fType == *fContext.fFloat2x2_Type || mat.fType == *fContext.fHalf2x2_Type) {
+ const Type& type = mat.type();
+ if (type == *fContext.fFloat2x2_Type || type == *fContext.fHalf2x2_Type) {
name = "_inverse2";
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
@@ -347,7 +349,7 @@
).c_str());
}
}
- else if (mat.fType == *fContext.fFloat3x3_Type || mat.fType == *fContext.fHalf3x3_Type) {
+ else if (type == *fContext.fFloat3x3_Type || type == *fContext.fHalf3x3_Type) {
name = "_inverse3";
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
@@ -367,7 +369,7 @@
).c_str());
}
}
- else if (mat.fType == *fContext.fFloat4x4_Type || mat.fType == *fContext.fHalf4x4_Type) {
+ else if (type == *fContext.fFloat4x4_Type || type == *fContext.fHalf4x4_Type) {
name = "_inverse4";
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
@@ -421,19 +423,20 @@
}
void GLSLCodeGenerator::writeTransposeHack(const Expression& mat) {
- String name = "transpose" + to_string(mat.fType.columns()) + to_string(mat.fType.rows());
+ const Type& type = mat.type();
+ String name = "transpose" + to_string(type.columns()) + to_string(type.rows());
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
- String type = this->getTypeName(mat.fType);
- const Type& base = mat.fType.componentType();
+ String typeName = this->getTypeName(type);
+ const Type& base = type.componentType();
String transposed = this->getTypeName(base.toCompound(fContext,
- mat.fType.rows(),
- mat.fType.columns()));
- fExtraFunctions.writeText((transposed + " " + name + "(" + type + " m) {\nreturn " +
+ type.rows(),
+ type.columns()));
+ fExtraFunctions.writeText((transposed + " " + name + "(" + typeName + " m) {\nreturn " +
transposed + "(").c_str());
const char* separator = "";
- for (int row = 0; row < mat.fType.rows(); ++row) {
- for (int column = 0; column < mat.fType.columns(); ++column) {
+ for (int row = 0; row < type.rows(); ++row) {
+ for (int column = 0; column < type.columns(); ++column) {
fExtraFunctions.writeText(separator);
fExtraFunctions.writeText(("m[" + to_string(column) + "][" + to_string(row) +
"]").c_str());
@@ -487,7 +490,7 @@
if (!fProgram.fSettings.fCaps->emulateAbsIntFunction())
break;
SkASSERT(c.fArguments.size() == 1);
- if (c.fArguments[0]->fType != *fContext.fInt_Type)
+ if (c.fArguments[0]->type() != *fContext.fInt_Type)
break;
// abs(int) on Intel OSX is incorrect, so emulate it:
String name = "_absemulation";
@@ -618,36 +621,38 @@
case FunctionClass::kTexture: {
const char* dim = "";
bool proj = false;
- switch (c.fArguments[0]->fType.dimensions()) {
+ const Type& arg0Type = c.fArguments[0]->type();
+ const Type& arg1Type = c.fArguments[1]->type();
+ switch (arg0Type.dimensions()) {
case SpvDim1D:
dim = "1D";
isTextureFunctionWithBias = true;
- if (c.fArguments[1]->fType == *fContext.fFloat_Type) {
+ if (arg1Type == *fContext.fFloat_Type) {
proj = false;
} else {
- SkASSERT(c.fArguments[1]->fType == *fContext.fFloat2_Type);
+ SkASSERT(arg1Type == *fContext.fFloat2_Type);
proj = true;
}
break;
case SpvDim2D:
dim = "2D";
- if (c.fArguments[0]->fType != *fContext.fSamplerExternalOES_Type) {
+ if (arg0Type != *fContext.fSamplerExternalOES_Type) {
isTextureFunctionWithBias = true;
}
- if (c.fArguments[1]->fType == *fContext.fFloat2_Type) {
+ if (arg1Type == *fContext.fFloat2_Type) {
proj = false;
} else {
- SkASSERT(c.fArguments[1]->fType == *fContext.fFloat3_Type);
+ SkASSERT(arg1Type == *fContext.fFloat3_Type);
proj = true;
}
break;
case SpvDim3D:
dim = "3D";
isTextureFunctionWithBias = true;
- if (c.fArguments[1]->fType == *fContext.fFloat3_Type) {
+ if (arg1Type == *fContext.fFloat3_Type) {
proj = false;
} else {
- SkASSERT(c.fArguments[1]->fType == *fContext.fFloat4_Type);
+ SkASSERT(arg1Type == *fContext.fFloat4_Type);
proj = true;
}
break;
@@ -712,16 +717,16 @@
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.typeKind() == Type::TypeKind::kScalar &&
- c.fArguments[0]->fType == *fContext.fFloatLiteral_Type))) {
+ (this->getTypeName(c.type()) == this->getTypeName(c.fArguments[0]->type()) ||
+ (c.type().typeKind() == Type::TypeKind::kScalar &&
+ c.fArguments[0]->type() == *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
// out the inner expression here.
this->writeExpression(*c.fArguments[0], parentPrecedence);
return;
}
- this->writeType(c.fType);
+ this->writeType(c.type());
this->write("(");
const char* separator = "";
for (const auto& arg : c.fArguments) {
@@ -832,7 +837,7 @@
}
bool is_sk_position(const FieldAccess& f) {
- return "sk_Position" == f.fBase->fType.fields()[f.fFieldIndex].fName;
+ return "sk_Position" == f.fBase->type().fields()[f.fFieldIndex].fName;
}
void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) {
@@ -840,24 +845,25 @@
this->writeExpression(*f.fBase, kPostfix_Precedence);
this->write(".");
}
- switch (f.fBase->fType.fields()[f.fFieldIndex].fModifiers.fLayout.fBuiltin) {
+ const Type& baseType = f.fBase->type();
+ switch (baseType.fields()[f.fFieldIndex].fModifiers.fLayout.fBuiltin) {
case SK_CLIPDISTANCE_BUILTIN:
this->write("gl_ClipDistance");
break;
default:
- StringFragment name = f.fBase->fType.fields()[f.fFieldIndex].fName;
+ StringFragment name = baseType.fields()[f.fFieldIndex].fName;
if (name == "sk_Position") {
this->write("gl_Position");
} else if (name == "sk_PointSize") {
this->write("gl_PointSize");
} else {
- this->write(f.fBase->fType.fields()[f.fFieldIndex].fName);
+ this->write(baseType.fields()[f.fFieldIndex].fName);
}
}
}
void GLSLCodeGenerator::writeConstantSwizzle(const Swizzle& swizzle, const String& constants) {
- this->writeType(swizzle.fType);
+ this->writeType(swizzle.type());
this->write("(");
this->write(constants);
this->write(")");
@@ -872,7 +878,7 @@
void GLSLCodeGenerator::writeSwizzleConstructor(const Swizzle& swizzle, const String& constants,
const String& mask,
GLSLCodeGenerator::SwizzleOrder order) {
- this->writeType(swizzle.fType);
+ this->writeType(swizzle.type());
this->write("(");
if (order == SwizzleOrder::CONSTANTS_FIRST) {
this->write(constants);
@@ -1190,11 +1196,12 @@
}
void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) {
- if (i.fType == *fContext.fUInt_Type) {
+ const Type& type = i.type();
+ if (type == *fContext.fUInt_Type) {
this->write(to_string(i.fValue & 0xffffffff) + "u");
- } else if (i.fType == *fContext.fUShort_Type) {
+ } else if (type == *fContext.fUShort_Type) {
this->write(to_string(i.fValue & 0xffff) + "u");
- } else if (i.fType == *fContext.fUByte_Type) {
+ } else if (type == *fContext.fUByte_Type) {
this->write(to_string(i.fValue & 0xff) + "u");
} else {
this->write(to_string((int32_t) i.fValue));
@@ -1226,7 +1233,7 @@
separator = ", ";
this->writeModifiers(param->fModifiers, false);
std::vector<int> sizes;
- const Type* type = ¶m->fType;
+ const Type* type = ¶m->type();
while (type->typeKind() == Type::TypeKind::kArray) {
sizes.push_back(type->columns());
type = &type->componentType();
@@ -1349,7 +1356,7 @@
this->writeModifiers(intf.fVariable.fModifiers, true);
this->writeLine(intf.fTypeName + " {");
fIndentation++;
- const Type* structType = &intf.fVariable.fType;
+ const Type* structType = &intf.fVariable.type();
while (structType->typeKind() == Type::TypeKind::kArray) {
structType = &structType->componentType();
}
@@ -1441,7 +1448,7 @@
this->write(" = ");
this->writeVarInitializer(*var.fVar, *var.fValue);
}
- if (!fFoundExternalSamplerDecl && var.fVar->fType == *fContext.fSamplerExternalOES_Type) {
+ if (!fFoundExternalSamplerDecl && var.fVar->type() == *fContext.fSamplerExternalOES_Type) {
if (fProgram.fSettings.fCaps->externalTextureExtensionString()) {
this->writeExtension(fProgram.fSettings.fCaps->externalTextureExtensionString());
}
@@ -1451,7 +1458,7 @@
}
fFoundExternalSamplerDecl = true;
}
- if (!fFoundRectSamplerDecl && var.fVar->fType == *fContext.fSampler2DRect_Type) {
+ if (!fFoundRectSamplerDecl && var.fVar->type() == *fContext.fSampler2DRect_Type) {
fFoundRectSamplerDecl = true;
}
}
@@ -1555,7 +1562,7 @@
std::unique_ptr<Expression> and_true(new BinaryExpression(
-1, f.fTest->clone(), Token::Kind::TK_LOGICALAND,
std::make_unique<BoolLiteral>(fContext, -1, true),
- *fContext.fBool_Type));
+ fContext.fBool_Type.get()));
this->writeExpression(*and_true, kTopLevel_Precedence);
} else {
this->writeExpression(*f.fTest, kTopLevel_Precedence);
diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp
index 8841435..e5bdd94 100644
--- a/src/sksl/SkSLHCodeGenerator.cpp
+++ b/src/sksl/SkSLHCodeGenerator.cpp
@@ -189,7 +189,7 @@
this->writef(" static std::unique_ptr<GrFragmentProcessor> Make(");
separator = "";
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
- this->writef("%s%s %s", separator, ParameterType(fContext, param->fType,
+ this->writef("%s%s %s", separator, ParameterType(fContext, param->type(),
param->fModifiers.fLayout).c_str(),
String(param->fName).c_str());
separator = ", ";
@@ -200,8 +200,8 @@
fFullName.c_str());
separator = "";
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
- if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type ||
- param->fType.nonnullable().typeKind() == Type::TypeKind::kSampler) {
+ if (param->type().nonnullable() == *fContext.fFragmentProcessor_Type ||
+ param->type().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());
@@ -233,7 +233,7 @@
this->writef(" %s(", fFullName.c_str());
const char* separator = "";
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
- this->writef("%s%s %s", separator, ParameterType(fContext, param->fType,
+ this->writef("%s%s %s", separator, ParameterType(fContext, param->type(),
param->fModifiers.fLayout).c_str(),
String(param->fName).c_str());
separator = ", ";
@@ -249,7 +249,7 @@
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
String nameString(param->fName);
const char* name = nameString.c_str();
- const Type& type = param->fType.nonnullable();
+ const Type& type = param->type().nonnullable();
if (type.typeKind() == Type::TypeKind::kSampler) {
this->writef("\n , %s(std::move(%s)", FieldName(name).c_str(), name);
for (const Section* s : fSectionAndParameterHelper.getSections(
@@ -274,10 +274,11 @@
int samplerCount = 0;
for (const Variable* param : fSectionAndParameterHelper.getParameters()) {
- if (param->fType.typeKind() == Type::TypeKind::kSampler) {
+ const Type& paramType = param->type();
+ if (paramType.typeKind() == Type::TypeKind::kSampler) {
++samplerCount;
- } else if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
- if (param->fType.typeKind() != Type::TypeKind::kNullable) {
+ } else if (paramType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+ if (paramType.typeKind() != Type::TypeKind::kNullable) {
this->writef(" SkASSERT(%s);", String(param->fName).c_str());
}
@@ -310,10 +311,10 @@
this->writeSection(kFieldsSection);
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
String name = FieldName(String(param->fName).c_str());
- if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+ if (param->type().nonnullable() == *fContext.fFragmentProcessor_Type) {
// Don't need to write any fields, FPs are held as children
} else {
- this->writef(" %s %s;\n", FieldType(fContext, param->fType,
+ this->writef(" %s %s;\n", FieldType(fContext, param->type(),
param->fModifiers.fLayout).c_str(),
name.c_str());
}
@@ -374,7 +375,7 @@
"GrProcessorKeyBuilder*) const override;\n"
" bool onIsEqual(const GrFragmentProcessor&) const override;\n");
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
- if (param->fType.typeKind() == Type::TypeKind::kSampler) {
+ if (param->type().typeKind() == Type::TypeKind::kSampler) {
this->writef(" const TextureSampler& onTextureSampler(int) const override;");
break;
}
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index c12b7ed..d2dec9b 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -442,11 +442,11 @@
sizes.push_back(nullptr);
}
}
- auto var = std::make_unique<Variable>(varDecl.fOffset, modifiers, varData.fName, *type,
+ auto var = std::make_unique<Variable>(varDecl.fOffset, modifiers, varData.fName, type,
storage);
if (var->fName == Compiler::RTADJUST_NAME) {
SkASSERT(!fRTAdjust);
- SkASSERT(var->fType == *fContext.fFloat4_Type);
+ SkASSERT(var->type() == *fContext.fFloat4_Type);
fRTAdjust = var.get();
}
std::unique_ptr<Expression> value;
@@ -674,8 +674,8 @@
if (!value) {
return nullptr;
}
- if (value->fType != *fContext.fUInt_Type &&
- value->fType.typeKind() != Type::TypeKind::kEnum) {
+ if (value->type() != *fContext.fUInt_Type &&
+ value->type().typeKind() != Type::TypeKind::kEnum) {
value = this->coerce(std::move(value), *fContext.fInt_Type);
if (!value) {
return nullptr;
@@ -694,7 +694,7 @@
if (!caseValue) {
return nullptr;
}
- caseValue = this->coerce(std::move(caseValue), value->fType);
+ caseValue = this->coerce(std::move(caseValue), value->type());
if (!caseValue) {
return nullptr;
}
@@ -809,7 +809,7 @@
std::unique_ptr<Expression>(new VariableReference(-1, *loopIdx)),
Token::Kind::TK_LT,
std::make_unique<IntLiteral>(fContext, -1, fInvocations),
- *fContext.fBool_Type));
+ fContext.fBool_Type.get()));
std::unique_ptr<Expression> next(new PostfixExpression(
std::unique_ptr<Expression>(
new VariableReference(-1,
@@ -835,7 +835,7 @@
VariableReference::kWrite_RefKind)),
Token::Kind::TK_EQ,
std::make_unique<IntLiteral>(fContext, -1, 0),
- *fContext.fInt_Type));
+ fContext.fInt_Type.get()));
std::unique_ptr<Statement> initializer(new ExpressionStatement(std::move(assignment)));
std::unique_ptr<Statement> loop = std::unique_ptr<Statement>(
new ForStatement(-1,
@@ -869,7 +869,7 @@
{ __VA_ARGS__ }))
#define OP(left, op, right) std::unique_ptr<Expression>( \
new BinaryExpression(-1, left, op, right, \
- *fContext.fFloat2_Type))
+ fContext.fFloat2_Type.get()))
std::vector<std::unique_ptr<Expression>> children;
children.push_back(OP(OP(SWIZZLE(POS, 0, 1), Token::Kind::TK_STAR, SWIZZLE(ADJUST, 0, 2)),
Token::Kind::TK_PLUS,
@@ -877,9 +877,10 @@
children.push_back(std::unique_ptr<Expression>(new FloatLiteral(fContext, -1, 0.0)));
children.push_back(SWIZZLE(POS, 3));
std::unique_ptr<Expression> result = OP(POS, Token::Kind::TK_EQ,
- std::unique_ptr<Expression>(new Constructor(-1,
- *fContext.fFloat4_Type,
- std::move(children))));
+ std::unique_ptr<Expression>(new Constructor(
+ -1,
+ fContext.fFloat4_Type.get(),
+ std::move(children))));
return std::unique_ptr<Statement>(new ExpressionStatement(std::move(result)));
}
@@ -984,12 +985,12 @@
}
StringFragment name = pd.fName;
const Variable* var = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Variable>(
- param.fOffset, pd.fModifiers, name, *type, Variable::kParameter_Storage));
+ param.fOffset, pd.fModifiers, name, type, Variable::kParameter_Storage));
parameters.push_back(var);
}
auto paramIsCoords = [&](int idx) {
- return parameters[idx]->fType == *fContext.fFloat2_Type &&
+ return parameters[idx]->type() == *fContext.fFloat2_Type &&
parameters[idx]->fModifiers.fFlags == 0;
};
@@ -1046,7 +1047,7 @@
if (parameters.size() == other->fParameters.size()) {
bool match = true;
for (size_t i = 0; i < parameters.size(); i++) {
- if (parameters[i]->fType != other->fParameters[i]->fType) {
+ if (parameters[i]->type() != other->fParameters[i]->type()) {
match = false;
break;
}
@@ -1164,17 +1165,17 @@
}
if (vd.fVar == fRTAdjust) {
foundRTAdjust = true;
- SkASSERT(vd.fVar->fType == *fContext.fFloat4_Type);
+ SkASSERT(vd.fVar->type() == *fContext.fFloat4_Type);
fRTAdjustFieldIndex = fields.size();
}
fields.push_back(Type::Field(vd.fVar->fModifiers, vd.fVar->fName,
- &vd.fVar->fType));
+ &vd.fVar->type()));
if (vd.fValue) {
fErrors.error(decl->fOffset,
"initializers are not permitted on interface block fields");
}
- if (vd.fVar->fType.typeKind() == Type::TypeKind::kArray &&
- vd.fVar->fType.columns() == -1) {
+ if (vd.fVar->type().typeKind() == Type::TypeKind::kArray &&
+ vd.fVar->type().columns() == -1) {
haveRuntimeArray = true;
}
}
@@ -1215,7 +1216,7 @@
std::make_unique<Variable>(intf.fOffset,
id.fModifiers,
id.fInstanceName.fLength ? id.fInstanceName : id.fTypeName,
- *type,
+ type,
Variable::kGlobal_Storage));
if (foundRTAdjust) {
fRTAdjustInterfaceBlock = var;
@@ -1285,7 +1286,7 @@
value = std::unique_ptr<Expression>(new IntLiteral(fContext, e.fOffset, currentValue));
++currentValue;
fSymbolTable->add(child.getString(),
- std::make_unique<Variable>(e.fOffset, modifiers, child.getString(), *type,
+ std::make_unique<Variable>(e.fOffset, modifiers, child.getString(), type,
Variable::kGlobal_Storage, value.get()));
fSymbolTable->takeOwnershipOfIRNode(std::move(value));
}
@@ -1419,8 +1420,8 @@
!(var->fModifiers.fFlags & Modifiers::kUniform_Flag) &&
!var->fModifiers.fLayout.fKey &&
var->fModifiers.fLayout.fBuiltin == -1 &&
- var->fType.nonnullable() != *fContext.fFragmentProcessor_Type &&
- var->fType.typeKind() != Type::TypeKind::kSampler) {
+ var->type().nonnullable() != *fContext.fFragmentProcessor_Type &&
+ var->type().typeKind() != Type::TypeKind::kSampler) {
bool valid = false;
for (const auto& decl : fFile->root()) {
if (decl.fKind == ASTNode::Kind::kSection) {
@@ -1481,16 +1482,16 @@
if (!expr) {
return nullptr;
}
- if (expr->fType == type) {
+ if (expr->type() == type) {
return expr;
}
this->checkValid(*expr);
- if (expr->fType == *fContext.fInvalid_Type) {
+ if (expr->type() == *fContext.fInvalid_Type) {
return nullptr;
}
if (expr->coercionCost(type) == INT_MAX) {
fErrors.error(expr->fOffset, "expected '" + type.displayName() + "', but found '" +
- expr->fType.displayName() + "'");
+ expr->type().displayName() + "'");
return nullptr;
}
if (type.typeKind() == Type::TypeKind::kScalar) {
@@ -1515,11 +1516,11 @@
}
if (expr->kind() == Expression::Kind::kNullLiteral) {
SkASSERT(type.typeKind() == Type::TypeKind::kNullable);
- return std::unique_ptr<Expression>(new NullLiteral(expr->fOffset, type));
+ return std::unique_ptr<Expression>(new NullLiteral(expr->fOffset, &type));
}
std::vector<std::unique_ptr<Expression>> args;
args.push_back(std::move(expr));
- return std::unique_ptr<Expression>(new Constructor(-1, type, std::move(args)));
+ return std::unique_ptr<Expression>(new Constructor(-1, &type, std::move(args)));
}
static bool is_matrix_multiply(const Type& left, const Type& right) {
@@ -1850,16 +1851,18 @@
default: return nullptr;
}
}
- if (left.fType.typeKind() == Type::TypeKind::kVector && left.fType.componentType().isFloat() &&
- left.fType == right.fType) {
+ const Type& leftType = left.type();
+ const Type& rightType = right.type();
+ if (leftType.typeKind() == Type::TypeKind::kVector && leftType.componentType().isFloat() &&
+ leftType == rightType) {
std::vector<std::unique_ptr<Expression>> args;
#define RETURN_VEC_COMPONENTWISE_RESULT(op) \
- for (int i = 0; i < left.fType.columns(); i++) { \
+ for (int i = 0; i < leftType.columns(); i++) { \
float value = left.getFVecComponent(i) op \
right.getFVecComponent(i); \
args.emplace_back(new FloatLiteral(fContext, -1, value)); \
} \
- return std::unique_ptr<Expression>(new Constructor(-1, left.fType, \
+ return std::unique_ptr<Expression>(new Constructor(-1, &leftType, \
std::move(args)))
switch (op) {
case Token::Kind::TK_EQEQ:
@@ -1872,7 +1875,7 @@
case Token::Kind::TK_MINUS: RETURN_VEC_COMPONENTWISE_RESULT(-);
case Token::Kind::TK_STAR: RETURN_VEC_COMPONENTWISE_RESULT(*);
case Token::Kind::TK_SLASH:
- for (int i = 0; i < left.fType.columns(); i++) {
+ for (int i = 0; i < leftType.columns(); i++) {
SKSL_FLOAT rvalue = right.getFVecComponent(i);
if (rvalue == 0.0) {
fErrors.error(right.fOffset, "division by zero");
@@ -1881,14 +1884,14 @@
float value = left.getFVecComponent(i) / rvalue;
args.emplace_back(new FloatLiteral(fContext, -1, value));
}
- return std::unique_ptr<Expression>(new Constructor(-1, left.fType,
+ return std::unique_ptr<Expression>(new Constructor(-1, &leftType,
std::move(args)));
default:
return nullptr;
}
}
- if (left.fType.typeKind() == Type::TypeKind::kMatrix &&
- right.fType.typeKind() == Type::TypeKind::kMatrix &&
+ if (leftType.typeKind() == Type::TypeKind::kMatrix &&
+ rightType.typeKind() == Type::TypeKind::kMatrix &&
left.kind() == right.kind()) {
switch (op) {
case Token::Kind::TK_EQEQ:
@@ -1928,23 +1931,23 @@
const Type* rightType;
const Type* resultType;
const Type* rawLeftType;
- if (left->kind() == Expression::Kind::kIntLiteral && right->fType.isInteger()) {
- rawLeftType = &right->fType;
+ if (left->kind() == Expression::Kind::kIntLiteral && right->type().isInteger()) {
+ rawLeftType = &right->type();
} else {
- rawLeftType = &left->fType;
+ rawLeftType = &left->type();
}
const Type* rawRightType;
- if (right->kind() == Expression::Kind::kIntLiteral && left->fType.isInteger()) {
- rawRightType = &left->fType;
+ if (right->kind() == Expression::Kind::kIntLiteral && left->type().isInteger()) {
+ rawRightType = &left->type();
} else {
- rawRightType = &right->fType;
+ rawRightType = &right->type();
}
if (!determine_binary_type(fContext, op, *rawLeftType, *rawRightType,
&leftType, &rightType, &resultType)) {
fErrors.error(expression.fOffset, String("type mismatch: '") +
Compiler::OperatorName(expression.getToken().fKind) +
- "' cannot operate on '" + left->fType.displayName() +
- "', '" + right->fType.displayName() + "'");
+ "' cannot operate on '" + left->type().displayName() +
+ "', '" + right->type().displayName() + "'");
return nullptr;
}
if (Compiler::IsAssignment(op)) {
@@ -1962,7 +1965,7 @@
std::unique_ptr<Expression> result = this->constantFold(*left, op, *right);
if (!result) {
result = std::make_unique<BinaryExpression>(expression.fOffset, std::move(left), op,
- std::move(right), *resultType);
+ std::move(right), resultType);
}
return result;
}
@@ -1991,11 +1994,11 @@
const Type* trueType;
const Type* falseType;
const Type* resultType;
- if (!determine_binary_type(fContext, Token::Kind::TK_EQEQ, ifTrue->fType, ifFalse->fType,
+ if (!determine_binary_type(fContext, Token::Kind::TK_EQEQ, ifTrue->type(), ifFalse->type(),
&trueType, &falseType, &resultType) || trueType != falseType) {
fErrors.error(node.fOffset, "ternary operator result mismatch: '" +
- ifTrue->fType.displayName() + "', '" +
- ifFalse->fType.displayName() + "'");
+ ifTrue->type().displayName() + "', '" +
+ ifFalse->type().displayName() + "'");
return nullptr;
}
if (trueType->nonnullable() == *fContext.fFragmentProcessor_Type) {
@@ -2072,7 +2075,7 @@
for (size_t i = 0; i < arguments.size(); i++) {
msg += separator;
separator = ", ";
- msg += arguments[i]->fType.displayName();
+ msg += arguments[i]->type().displayName();
}
msg += ")";
fErrors.error(offset, msg);
@@ -2091,7 +2094,7 @@
}
}
- auto funcCall = std::make_unique<FunctionCall>(offset, *returnType, function,
+ auto funcCall = std::make_unique<FunctionCall>(offset, returnType, function,
std::move(arguments));
if (fCanInline && fInliner->isSafeToInline(*funcCall, fSettings->fInlineThreshold)) {
Inliner::InlinedCall inlinedCall = fInliner->inlineCall(funcCall.get(), fSymbolTable.get());
@@ -2161,7 +2164,7 @@
return nullptr;
}
}
- return std::make_unique<ExternalFunctionCall>(offset, v->callReturnType(), v,
+ return std::make_unique<ExternalFunctionCall>(offset, &v->callReturnType(), v,
std::move(arguments));
}
case Expression::Kind::kFunctionReference: {
@@ -2184,7 +2187,7 @@
for (size_t i = 0; i < arguments.size(); i++) {
msg += separator;
separator = ", ";
- msg += arguments[i]->fType.displayName();
+ msg += arguments[i]->type().displayName();
}
msg += ")";
fErrors.error(offset, msg);
@@ -2209,7 +2212,8 @@
to_string((uint64_t) args.size()) + ")");
return nullptr;
}
- if (type == args[0]->fType) {
+ const Type& argType = args[0]->type();
+ if (type == argType) {
return std::move(args[0]);
}
if (type.isFloat() && args.size() == 1 && args[0]->kind() == Expression::Kind::kFloatLiteral) {
@@ -2226,7 +2230,7 @@
args[0]->as<IntLiteral>().fValue,
&type));
}
- if (args[0]->fType == *fContext.fBool_Type) {
+ if (argType == *fContext.fBool_Type) {
std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, offset, 0));
std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, offset, 1));
return std::unique_ptr<Expression>(
@@ -2235,13 +2239,13 @@
this->coerce(std::move(zero),
type)));
}
- if (!args[0]->fType.isNumber()) {
+ if (!argType.isNumber()) {
fErrors.error(offset, "invalid argument to '" + type.displayName() +
"' constructor (expected a number or bool, but found '" +
- args[0]->fType.displayName() + "')");
+ argType.displayName() + "')");
return nullptr;
}
- return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
+ return std::unique_ptr<Expression>(new Constructor(offset, &type, std::move(args)));
}
static int component_count(const Type& type) {
@@ -2262,25 +2266,26 @@
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) {
+ args[0]->type().typeKind() == Type::TypeKind::kMatrix) {
// matrix from matrix is always legal
- return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
+ return std::unique_ptr<Expression>(new Constructor(offset, &type, std::move(args)));
}
int actual = 0;
int expected = type.rows() * type.columns();
- if (args.size() != 1 || expected != component_count(args[0]->fType) ||
- type.componentType().isNumber() != args[0]->fType.componentType().isNumber()) {
+ if (args.size() != 1 || expected != component_count(args[0]->type()) ||
+ type.componentType().isNumber() != args[0]->type().componentType().isNumber()) {
for (size_t i = 0; i < args.size(); i++) {
- if (args[i]->fType.typeKind() == Type::TypeKind::kVector) {
+ const Type& argType = args[i]->type();
+ if (argType.typeKind() == Type::TypeKind::kVector) {
if (type.componentType().isNumber() !=
- args[i]->fType.componentType().isNumber()) {
- fErrors.error(offset, "'" + args[i]->fType.displayName() + "' is not a valid "
+ argType.componentType().isNumber()) {
+ fErrors.error(offset, "'" + argType.displayName() + "' is not a valid "
"parameter to '" + type.displayName() +
"' constructor");
return nullptr;
}
- actual += args[i]->fType.columns();
- } else if (args[i]->fType.typeKind() == Type::TypeKind::kScalar) {
+ actual += argType.columns();
+ } else if (argType.typeKind() == Type::TypeKind::kScalar) {
actual += 1;
if (type.typeKind() != Type::TypeKind::kScalar) {
args[i] = this->coerce(std::move(args[i]), type.componentType());
@@ -2289,7 +2294,7 @@
}
}
} else {
- fErrors.error(offset, "'" + args[i]->fType.displayName() + "' is not a valid "
+ fErrors.error(offset, "'" + argType.displayName() + "' is not a valid "
"parameter to '" + type.displayName() + "' constructor");
return nullptr;
}
@@ -2301,7 +2306,7 @@
return nullptr;
}
}
- return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
+ return std::unique_ptr<Expression>(new Constructor(offset, &type, std::move(args)));
}
std::unique_ptr<Expression> IRGenerator::convertConstructor(
@@ -2309,7 +2314,7 @@
const Type& type,
std::vector<std::unique_ptr<Expression>> args) {
// FIXME: add support for structs
- if (args.size() == 1 && args[0]->fType == type &&
+ if (args.size() == 1 && args[0]->type() == type &&
type.nonnullable() != *fContext.fFragmentProcessor_Type) {
// argument is already the right type, just return it
return std::move(args[0]);
@@ -2325,7 +2330,7 @@
return nullptr;
}
}
- return std::make_unique<Constructor>(offset, type, std::move(args));
+ 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 {
@@ -2340,12 +2345,13 @@
if (!base) {
return nullptr;
}
+ const Type& baseType = base->type();
switch (expression.getToken().fKind) {
case Token::Kind::TK_PLUS:
- if (!base->fType.isNumber() && base->fType.typeKind() != Type::TypeKind::kVector &&
- base->fType != *fContext.fFloatLiteral_Type) {
+ if (!baseType.isNumber() && baseType.typeKind() != Type::TypeKind::kVector &&
+ baseType != *fContext.fFloatLiteral_Type) {
fErrors.error(expression.fOffset,
- "'+' cannot operate on '" + base->fType.displayName() + "'");
+ "'+' cannot operate on '" + baseType.displayName() + "'");
return nullptr;
}
return base;
@@ -2359,36 +2365,36 @@
return std::unique_ptr<Expression>(new FloatLiteral(fContext, base->fOffset,
value));
}
- if (!base->fType.isNumber() && base->fType.typeKind() != Type::TypeKind::kVector) {
+ if (!baseType.isNumber() && baseType.typeKind() != Type::TypeKind::kVector) {
fErrors.error(expression.fOffset,
- "'-' cannot operate on '" + base->fType.displayName() + "'");
+ "'-' cannot operate on '" + baseType.displayName() + "'");
return nullptr;
}
return std::unique_ptr<Expression>(new PrefixExpression(Token::Kind::TK_MINUS,
std::move(base)));
case Token::Kind::TK_PLUSPLUS:
- if (!base->fType.isNumber()) {
+ if (!baseType.isNumber()) {
fErrors.error(expression.fOffset,
String("'") + Compiler::OperatorName(expression.getToken().fKind) +
- "' cannot operate on '" + base->fType.displayName() + "'");
+ "' cannot operate on '" + baseType.displayName() + "'");
return nullptr;
}
this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
break;
case Token::Kind::TK_MINUSMINUS:
- if (!base->fType.isNumber()) {
+ if (!baseType.isNumber()) {
fErrors.error(expression.fOffset,
String("'") + Compiler::OperatorName(expression.getToken().fKind) +
- "' cannot operate on '" + base->fType.displayName() + "'");
+ "' cannot operate on '" + baseType.displayName() + "'");
return nullptr;
}
this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
break;
case Token::Kind::TK_LOGICALNOT:
- if (base->fType != *fContext.fBool_Type) {
+ if (baseType != *fContext.fBool_Type) {
fErrors.error(expression.fOffset,
String("'") + Compiler::OperatorName(expression.getToken().fKind) +
- "' cannot operate on '" + base->fType.displayName() + "'");
+ "' cannot operate on '" + baseType.displayName() + "'");
return nullptr;
}
if (base->kind() == Expression::Kind::kBoolLiteral) {
@@ -2397,10 +2403,10 @@
}
break;
case Token::Kind::TK_BITWISENOT:
- if (base->fType != *fContext.fInt_Type && base->fType != *fContext.fUInt_Type) {
+ if (baseType != *fContext.fInt_Type && baseType != *fContext.fUInt_Type) {
fErrors.error(expression.fOffset,
String("'") + Compiler::OperatorName(expression.getToken().fKind) +
- "' cannot operate on '" + base->fType.displayName() + "'");
+ "' cannot operate on '" + baseType.displayName() + "'");
return nullptr;
}
break;
@@ -2427,10 +2433,11 @@
return nullptr;
}
}
- 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() +
+ const Type& baseType = base->type();
+ if (baseType.typeKind() != Type::TypeKind::kArray &&
+ baseType.typeKind() != Type::TypeKind::kMatrix &&
+ baseType.typeKind() != Type::TypeKind::kVector) {
+ fErrors.error(base->fOffset, "expected array, but found '" + baseType.displayName() +
"'");
return nullptr;
}
@@ -2438,7 +2445,7 @@
if (!converted) {
return nullptr;
}
- if (converted->fType != *fContext.fUInt_Type) {
+ if (converted->type() != *fContext.fUInt_Type) {
converted = this->coerce(std::move(converted), *fContext.fInt_Type);
if (!converted) {
return nullptr;
@@ -2459,14 +2466,15 @@
}
return std::unique_ptr<Expression>(new ExternalValueReference(base->fOffset, result));
}
- auto fields = base->fType.fields();
+ const Type& baseType = base->type();
+ auto fields = baseType.fields();
for (size_t i = 0; i < fields.size(); i++) {
if (fields[i].fName == field) {
return std::unique_ptr<Expression>(new FieldAccess(std::move(base), (int) i));
}
}
- fErrors.error(base->fOffset, "type '" + base->fType.displayName() + "' does not have a "
- "field named '" + field + "");
+ fErrors.error(base->fOffset, "type '" + baseType.displayName() + "' does not have a field "
+ "named '" + field + "");
return nullptr;
}
@@ -2487,8 +2495,9 @@
std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expression> base,
StringFragment fields) {
- if (base->fType.typeKind() != Type::TypeKind::kVector && !base->fType.isNumber()) {
- fErrors.error(base->fOffset, "cannot swizzle value of type '" + base->fType.displayName() +
+ const Type& baseType = base->type();
+ if (baseType.typeKind() != Type::TypeKind::kVector && !baseType.isNumber()) {
+ fErrors.error(base->fOffset, "cannot swizzle value of type '" + baseType.displayName() +
"'");
return nullptr;
}
@@ -2514,7 +2523,7 @@
case 'g':
case 't':
case 'T':
- if (base->fType.columns() >= 2) {
+ if (baseType.columns() >= 2) {
swizzleComponents.push_back(1);
break;
}
@@ -2523,7 +2532,7 @@
case 'b':
case 'p':
case 'R':
- if (base->fType.columns() >= 3) {
+ if (baseType.columns() >= 3) {
swizzleComponents.push_back(2);
break;
}
@@ -2532,7 +2541,7 @@
case 'a':
case 'q':
case 'B':
- if (base->fType.columns() >= 4) {
+ if (baseType.columns() >= 4) {
swizzleComponents.push_back(3);
break;
}
@@ -2552,7 +2561,7 @@
fErrors.error(base->fOffset, "swizzle must refer to base expression");
return nullptr;
}
- if (base->fType.isNumber()) {
+ if (baseType.isNumber()) {
// Swizzling a single scalar. Something like foo.x0x1 is equivalent to float4(foo, 0, foo,
// 1)
int offset = base->fOffset;
@@ -2583,14 +2592,14 @@
std::make_unique<Variable>(offset,
Modifiers(),
namePtr->c_str(),
- base->fType,
+ &baseType,
Variable::kLocal_Storage,
base.get()));
expr = std::make_unique<VariableReference>(offset, *var);
std::vector<std::unique_ptr<VarDeclaration>> variables;
variables.emplace_back(new VarDeclaration(var, {}, std::move(base)));
fExtraStatements.emplace_back(new VarDeclarationsStatement(
- std::make_unique<VarDeclarations>(offset, &expr->fType,
+ std::make_unique<VarDeclarations>(offset, &expr->type(),
std::move(variables))));
}
}
@@ -2608,9 +2617,9 @@
std::vector<std::unique_ptr<Expression>> constructorArgs;
constructorArgs.push_back(std::move(args.back()));
args.pop_back();
- args.emplace_back(new Constructor(offset, expr->fType.toCompound(fContext,
- count,
- 1),
+ args.emplace_back(new Constructor(offset, &expr->type().toCompound(fContext,
+ count,
+ 1),
std::move(constructorArgs)));
}
break;
@@ -2624,7 +2633,7 @@
}
}
return std::unique_ptr<Expression>(new Constructor(offset,
- expr->fType.toCompound(
+ &expr->type().toCompound(
fContext,
swizzleComponents.size(),
1),
@@ -2735,13 +2744,14 @@
return nullptr;
}
StringFragment field = fieldNode.getString();
- if (base->fType == *fContext.fSkCaps_Type) {
+ const Type& baseType = base->type();
+ if (baseType == *fContext.fSkCaps_Type) {
return this->getCap(fieldNode.fOffset, field);
}
if (base->kind() == Expression::Kind::kExternalValue) {
return this->convertField(std::move(base), field);
}
- switch (base->fType.typeKind()) {
+ switch (baseType.typeKind()) {
case Type::TypeKind::kOther:
case Type::TypeKind::kStruct:
return this->convertField(std::move(base), field);
@@ -2768,10 +2778,11 @@
if (!base) {
return nullptr;
}
- if (!base->fType.isNumber()) {
+ const Type& baseType = base->type();
+ if (!baseType.isNumber()) {
fErrors.error(expression.fOffset,
"'" + String(Compiler::OperatorName(expression.getToken().fKind)) +
- "' cannot operate on '" + base->fType.displayName() + "'");
+ "' cannot operate on '" + baseType.displayName() + "'");
return nullptr;
}
this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
@@ -2788,7 +2799,7 @@
fErrors.error(expr.fOffset, "expected '(' to begin constructor invocation");
break;
default:
- if (expr.fType == *fContext.fInvalid_Type) {
+ if (expr.type() == *fContext.fInvalid_Type) {
fErrors.error(expr.fOffset, "invalid expression");
}
}
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 459362f..4270261 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -237,7 +237,7 @@
expr(b.fLeft),
b.fOperator,
expr(b.fRight),
- b.fType);
+ &b.type());
}
case Expression::Kind::kBoolLiteral:
case Expression::Kind::kIntLiteral:
@@ -246,12 +246,12 @@
return expression.clone();
case Expression::Kind::kConstructor: {
const Constructor& constructor = expression.as<Constructor>();
- return std::make_unique<Constructor>(offset, constructor.fType,
+ return std::make_unique<Constructor>(offset, &constructor.type(),
argList(constructor.fArguments));
}
case Expression::Kind::kExternalFunctionCall: {
const ExternalFunctionCall& externalCall = expression.as<ExternalFunctionCall>();
- return std::make_unique<ExternalFunctionCall>(offset, externalCall.fType,
+ return std::make_unique<ExternalFunctionCall>(offset, &externalCall.type(),
externalCall.fFunction,
argList(externalCall.fArguments));
}
@@ -263,7 +263,7 @@
}
case Expression::Kind::kFunctionCall: {
const FunctionCall& funcCall = expression.as<FunctionCall>();
- return std::make_unique<FunctionCall>(offset, funcCall.fType, funcCall.fFunction,
+ return std::make_unique<FunctionCall>(offset, &funcCall.type(), funcCall.fFunction,
argList(funcCall.fArguments));
}
case Expression::Kind::kFunctionReference:
@@ -376,7 +376,7 @@
VariableReference::kWrite_RefKind),
Token::Kind::TK_EQ,
expr(r.fExpression),
- returnVar->fType));
+ &returnVar->type()));
if (haveEarlyReturns) {
std::vector<std::unique_ptr<Statement>> block;
block.push_back(std::move(assignment));
@@ -416,12 +416,12 @@
// its symbols
std::unique_ptr<String> name(new String(old->fName));
const String* namePtr = symbolTableForStatement->takeOwnershipOfString(std::move(name));
- const Type* typePtr = copy_if_needed(&old->fType, *symbolTableForStatement);
+ const Type* typePtr = copy_if_needed(&old->type(), *symbolTableForStatement);
const Variable* clone = symbolTableForStatement->takeOwnershipOfSymbol(
std::make_unique<Variable>(offset,
old->fModifiers,
namePtr->c_str(),
- *typePtr,
+ typePtr,
old->fStorage,
initialValue.get()));
(*varMap)[old] = clone;
@@ -521,7 +521,7 @@
StringFragment nameFrag{namePtr->c_str(), namePtr->length()};
// Add our new variable to the symbol table.
- auto newVar = std::make_unique<Variable>(/*offset=*/-1, Modifiers(), nameFrag, *type,
+ auto newVar = std::make_unique<Variable>(/*offset=*/-1, Modifiers(), nameFrag, type,
Variable::kLocal_Storage, initialValue->get());
const Variable* variableSymbol = symbolTableForCall->add(nameFrag, std::move(newVar));
@@ -569,8 +569,8 @@
}
}
- varMap[param] = makeInlineVar(String(param->fName), &arguments[i]->fType, param->fModifiers,
- &arguments[i]);
+ varMap[param] = makeInlineVar(String(param->fName), &arguments[i]->type(),
+ param->fModifiers, &arguments[i]);
}
const Block& body = function.fBody->as<Block>();
@@ -612,7 +612,7 @@
arguments[i]->clone(),
Token::Kind::TK_EQ,
std::move(varRef),
- arguments[i]->fType)));
+ &arguments[i]->type())));
}
}
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index ecb2d70..96af1a0 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -271,9 +271,10 @@
}
void MetalCodeGenerator::writeInverseHack(const Expression& mat) {
- String typeName = mat.fType.name();
+ const Type& type = mat.type();
+ const String& typeName = type.name();
String name = typeName + "_inverse";
- if (mat.fType == *fContext.fFloat2x2_Type || mat.fType == *fContext.fHalf2x2_Type) {
+ if (type == *fContext.fFloat2x2_Type || type == *fContext.fHalf2x2_Type) {
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
fExtraFunctions.writeText((
@@ -283,7 +284,7 @@
).c_str());
}
}
- else if (mat.fType == *fContext.fFloat3x3_Type || mat.fType == *fContext.fHalf3x3_Type) {
+ else if (type == *fContext.fFloat3x3_Type || type == *fContext.fHalf3x3_Type) {
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
fExtraFunctions.writeText((
@@ -304,7 +305,7 @@
).c_str());
}
}
- else if (mat.fType == *fContext.fFloat4x4_Type || mat.fType == *fContext.fHalf4x4_Type) {
+ else if (type == *fContext.fFloat4x4_Type || type == *fContext.fHalf4x4_Type) {
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
fWrittenIntrinsics.insert(name);
fExtraFunctions.writeText((
@@ -352,32 +353,33 @@
void MetalCodeGenerator::writeSpecialIntrinsic(const FunctionCall & c, SpecialIntrinsic kind) {
switch (kind) {
- case kTexture_SpecialIntrinsic:
+ case kTexture_SpecialIntrinsic: {
this->writeExpression(*c.fArguments[0], kSequence_Precedence);
this->write(".sample(");
this->writeExpression(*c.fArguments[0], kSequence_Precedence);
this->write(SAMPLER_SUFFIX);
this->write(", ");
- if (c.fArguments[1]->fType == *fContext.fFloat3_Type) {
+ const Type& arg1Type = c.fArguments[1]->type();
+ if (arg1Type == *fContext.fFloat3_Type) {
// have to store the vector in a temp variable to avoid double evaluating it
String tmpVar = "tmpCoord" + to_string(fVarCount++);
- this->fFunctionHeader += " " + this->typeName(c.fArguments[1]->fType) + " " +
- tmpVar + ";\n";
+ this->fFunctionHeader += " " + this->typeName(arg1Type) + " " + tmpVar + ";\n";
this->write("(" + tmpVar + " = ");
this->writeExpression(*c.fArguments[1], kSequence_Precedence);
this->write(", " + tmpVar + ".xy / " + tmpVar + ".z))");
} else {
- SkASSERT(c.fArguments[1]->fType == *fContext.fFloat2_Type);
+ SkASSERT(arg1Type == *fContext.fFloat2_Type);
this->writeExpression(*c.fArguments[1], kSequence_Precedence);
this->write(")");
}
break;
+ }
case kMod_SpecialIntrinsic: {
// fmod(x, y) in metal calculates x - y * trunc(x / y) instead of x - y * floor(x / y)
String tmpX = "tmpX" + to_string(fVarCount++);
String tmpY = "tmpY" + to_string(fVarCount++);
- this->fFunctionHeader += " " + this->typeName(c.fArguments[0]->fType) + " " + tmpX +
- ", " + tmpY + ";\n";
+ this->fFunctionHeader += " " + this->typeName(c.fArguments[0]->type()) +
+ " " + tmpX + ", " + tmpY + ";\n";
this->write("(" + tmpX + " = ");
this->writeExpression(*c.fArguments[0], kSequence_Precedence);
this->write(", " + tmpY + " = ");
@@ -446,7 +448,7 @@
rowSeparator = ", ";
if (argIndex < args.size()) {
- const Type& argType = args[argIndex]->fType;
+ const Type& argType = args[argIndex]->type();
switch (argType.typeKind()) {
case Type::TypeKind::kScalar: {
fExtraFunctions.printf("x%zu", argIndex);
@@ -494,7 +496,7 @@
// constructor for any given permutation of input argument types. Returns the name of the
// generated constructor method.
String MetalCodeGenerator::getMatrixConstructHelper(const Constructor& c) {
- const Type& matrix = c.fType;
+ const Type& matrix = c.type();
int columns = matrix.columns();
int rows = matrix.rows();
const std::vector<std::unique_ptr<Expression>>& args = c.fArguments;
@@ -503,7 +505,7 @@
String name;
name.appendf("float%dx%d_from", columns, rows);
for (const std::unique_ptr<Expression>& expr : args) {
- name.appendf("_%s", expr->fType.displayName().c_str());
+ name.appendf("_%s", expr->type().displayName().c_str());
}
// If a helper-method has already been synthesized, we don't need to synthesize it again.
@@ -521,14 +523,14 @@
const char* argSeparator = "";
for (const std::unique_ptr<Expression>& expr : args) {
fExtraFunctions.printf("%s%s x%zu", argSeparator,
- expr->fType.displayName().c_str(), argIndex++);
+ expr->type().displayName().c_str(), argIndex++);
argSeparator = ", ";
}
fExtraFunctions.printf(") {\n return float%dx%d(", columns, rows);
- if (args.size() == 1 && args.front()->fType.typeKind() == Type::TypeKind::kMatrix) {
- this->assembleMatrixFromMatrix(args.front()->fType, rows, columns);
+ if (args.size() == 1 && args.front()->type().typeKind() == Type::TypeKind::kMatrix) {
+ this->assembleMatrixFromMatrix(args.front()->type(), rows, columns);
} else {
this->assembleMatrixFromExpressions(args, rows, columns);
}
@@ -549,7 +551,7 @@
bool MetalCodeGenerator::matrixConstructHelperIsNeeded(const Constructor& c) {
// A matrix construct helper is only necessary if we are, in fact, constructing a matrix.
- if (c.fType.typeKind() != Type::TypeKind::kMatrix) {
+ if (c.type().typeKind() != Type::TypeKind::kMatrix) {
return false;
}
@@ -577,15 +579,15 @@
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.typeKind() == Type::TypeKind::kMatrix) {
+ if (expr->type().typeKind() == Type::TypeKind::kMatrix) {
return true;
}
- position += expr->fType.columns();
- if (position > c.fType.rows()) {
+ position += expr->type().columns();
+ if (position > c.type().rows()) {
// An input argument would span multiple rows; a helper function is required.
return true;
}
- if (position == c.fType.rows()) {
+ if (position == c.type().rows()) {
// We've advanced to the end of a row. Wrap to the start of the next row.
position = 0;
}
@@ -595,19 +597,21 @@
}
void MetalCodeGenerator::writeConstructor(const Constructor& c, Precedence parentPrecedence) {
+ const Type& constructorType = c.type();
// Handle special cases for single-argument constructors.
if (c.fArguments.size() == 1) {
// If the type is coercible, emit it directly.
const Expression& arg = *c.fArguments.front();
- if (this->canCoerce(c.fType, arg.fType)) {
+ const Type& argType = arg.type();
+ if (this->canCoerce(constructorType, argType)) {
this->writeExpression(arg, parentPrecedence);
return;
}
// Metal supports creating matrices with a scalar on the diagonal via the single-argument
// matrix constructor.
- if (c.fType.typeKind() == Type::TypeKind::kMatrix && arg.fType.isNumber()) {
- const Type& matrix = c.fType;
+ if (constructorType.typeKind() == Type::TypeKind::kMatrix && argType.isNumber()) {
+ const Type& matrix = constructorType;
this->write("float");
this->write(to_string(matrix.columns()));
this->write("x");
@@ -634,25 +638,26 @@
}
// Explicitly invoke the constructor, passing in the necessary arguments.
- this->writeType(c.fType);
+ this->writeType(constructorType);
this->write("(");
const char* separator = "";
int scalarCount = 0;
for (const std::unique_ptr<Expression>& arg : c.fArguments) {
+ const Type& argType = arg->type();
this->write(separator);
separator = ", ";
- if (c.fType.typeKind() == Type::TypeKind::kMatrix &&
- arg->fType.columns() < c.fType.rows()) {
+ if (constructorType.typeKind() == Type::TypeKind::kMatrix &&
+ argType.columns() < constructorType.rows()) {
// Merge scalars and smaller vectors together.
if (!scalarCount) {
- this->writeType(c.fType.componentType());
- this->write(to_string(c.fType.rows()));
+ this->writeType(constructorType.componentType());
+ this->write(to_string(constructorType.rows()));
this->write("(");
}
- scalarCount += arg->fType.columns();
+ scalarCount += argType.columns();
}
this->writeExpression(*arg, kSequence_Precedence);
- if (scalarCount && scalarCount == c.fType.rows()) {
+ if (scalarCount && scalarCount == constructorType.rows()) {
this->write(")");
scalarCount = 0;
}
@@ -696,7 +701,7 @@
} else if (ref.fVariable.fModifiers.fFlags & Modifiers::kOut_Flag) {
this->write("_out->");
} else if (ref.fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag &&
- ref.fVariable.fType.typeKind() != Type::TypeKind::kSampler) {
+ ref.fVariable.type().typeKind() != Type::TypeKind::kSampler) {
this->write("_uniforms.");
} else {
this->write("_globals->");
@@ -714,7 +719,7 @@
}
void MetalCodeGenerator::writeFieldAccess(const FieldAccess& f) {
- const Type::Field* field = &f.fBase->fType.fields()[f.fFieldIndex];
+ const Type::Field* field = &f.fBase->type().fields()[f.fFieldIndex];
if (FieldAccess::kDefault_OwnerKind == f.fOwnerKind) {
this->writeExpression(*f.fBase, kPostfix_Precedence);
this->write(".");
@@ -743,7 +748,7 @@
void MetalCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
int last = swizzle.fComponents.back();
if (last == SKSL_SWIZZLE_0 || last == SKSL_SWIZZLE_1) {
- this->writeType(swizzle.fType);
+ this->writeType(swizzle.type());
this->write("(");
}
this->writeExpression(*swizzle.fBase, kPostfix_Precedence);
@@ -815,17 +820,19 @@
void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
Precedence parentPrecedence) {
+ const Type& leftType = b.fLeft->type();
+ const Type& rightType = b.fRight->type();
Precedence precedence = GetBinaryPrecedence(b.fOperator);
bool needParens = precedence >= parentPrecedence;
switch (b.fOperator) {
case Token::Kind::TK_EQEQ:
- if (b.fLeft->fType.typeKind() == Type::TypeKind::kVector) {
+ if (leftType.typeKind() == Type::TypeKind::kVector) {
this->write("all");
needParens = true;
}
break;
case Token::Kind::TK_NEQ:
- if (b.fLeft->fType.typeKind() == Type::TypeKind::kVector) {
+ if (leftType.typeKind() == Type::TypeKind::kVector) {
this->write("any");
needParens = true;
}
@@ -845,9 +852,9 @@
this->write("*");
}
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);
+ leftType.typeKind() == Type::TypeKind::kMatrix &&
+ rightType.typeKind() == Type::TypeKind::kMatrix) {
+ this->writeMatrixTimesEqualHelper(leftType, rightType, b.type());
}
this->writeExpression(*b.fLeft, precedence);
if (b.fOperator != Token::Kind::TK_EQ && Compiler::IsAssignment(b.fOperator) &&
@@ -918,7 +925,7 @@
}
void MetalCodeGenerator::writeIntLiteral(const IntLiteral& i) {
- if (i.fType == *fContext.fUInt_Type) {
+ if (i.type() == *fContext.fUInt_Type) {
this->write(to_string(i.fValue & 0xffffffff) + "u");
} else {
this->write(to_string((int32_t) i.fValue));
@@ -960,7 +967,7 @@
}
for (const auto& stmt: decls.fVars) {
VarDeclaration& var = stmt->as<VarDeclaration>();
- if (var.fVar->fType.typeKind() == Type::TypeKind::kSampler) {
+ if (var.fVar->type().typeKind() == Type::TypeKind::kSampler) {
if (var.fVar->fModifiers.fLayout.fBinding < 0) {
fErrors.error(decls.fOffset,
"Metal samplers must have 'layout(binding=...)'");
@@ -984,7 +991,7 @@
continue;
}
this->write(", constant ");
- this->writeType(intf.fVariable.fType);
+ this->writeType(intf.fVariable.type());
this->write("& " );
this->write(fInterfaceBlockNameMap[&intf]);
this->write(" [[buffer(");
@@ -1039,7 +1046,7 @@
separator = ", ";
this->writeModifiers(param->fModifiers, false);
std::vector<int> sizes;
- const Type* type = ¶m->fType;
+ const Type* type = ¶m->type();
while (type->typeKind() == Type::TypeKind::kArray) {
sizes.push_back(type->columns());
type = &type->componentType();
@@ -1112,7 +1119,7 @@
this->writeModifiers(intf.fVariable.fModifiers, true);
this->write("struct ");
this->writeLine(intf.fTypeName + " {");
- const Type* structType = &intf.fVariable.fType;
+ const Type* structType = &intf.fVariable.type();
fWrittenStructs.push_back(structType);
while (structType->typeKind() == Type::TypeKind::kArray) {
structType = &structType->componentType();
@@ -1408,7 +1415,7 @@
}
const Variable& first = *decls.fVars[0]->as<VarDeclaration>().fVar;
if (first.fModifiers.fFlags & Modifiers::kUniform_Flag &&
- first.fType.typeKind() != Type::TypeKind::kSampler) {
+ first.type().typeKind() != Type::TypeKind::kSampler) {
if (-1 == fUniformBuffer) {
this->write("struct Uniforms {\n");
fUniformBuffer = first.fModifiers.fLayout.fSet;
@@ -1422,7 +1429,7 @@
}
}
this->write(" ");
- this->writeType(first.fType);
+ this->writeType(first.type());
this->write(" ");
for (const auto& stmt : decls.fVars) {
const VarDeclaration& var = stmt->as<VarDeclaration>();
@@ -1449,7 +1456,7 @@
if (first.fModifiers.fFlags & Modifiers::kIn_Flag &&
-1 == first.fModifiers.fLayout.fBuiltin) {
this->write(" ");
- this->writeType(first.fType);
+ this->writeType(first.type());
this->write(" ");
for (const auto& stmt : decls.fVars) {
const VarDeclaration& var = stmt->as<VarDeclaration>();
@@ -1488,7 +1495,7 @@
if (first.fModifiers.fFlags & Modifiers::kOut_Flag &&
-1 == first.fModifiers.fLayout.fBuiltin) {
this->write(" ");
- this->writeType(first.fType);
+ this->writeType(first.type());
this->write(" ");
for (const auto& stmt : decls.fVars) {
const VarDeclaration& var = stmt->as<VarDeclaration>();
@@ -1546,14 +1553,14 @@
}
const Variable& first = *((VarDeclaration&) *decls.fVars[0]).fVar;
if ((!first.fModifiers.fFlags && -1 == first.fModifiers.fLayout.fBuiltin) ||
- first.fType.typeKind() == Type::TypeKind::kSampler) {
+ first.type().typeKind() == Type::TypeKind::kSampler) {
for (const auto& stmt : decls.fVars) {
VarDeclaration& var = static_cast<VarDeclaration&>(*stmt);
- if (var.fVar->fType.typeKind() == Type::TypeKind::kSampler) {
+ if (var.fVar->type().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);
+ visitor->VisitTexture(first.type(), var.fVar->fName);
+ visitor->VisitSampler(first.type(), String(var.fVar->fName) + SAMPLER_SUFFIX);
} else {
// Visit a regular variable.
visitor->VisitVariable(*var.fVar, var.fValue.get());
@@ -1591,7 +1598,7 @@
void VisitVariable(const Variable& var, const Expression* value) override {
this->AddElement();
fCodeGen->write(" ");
- fCodeGen->writeType(var.fType);
+ fCodeGen->writeType(var.type());
fCodeGen->write(" ");
fCodeGen->writeName(var.fName);
fCodeGen->write(";\n");
@@ -1762,7 +1769,7 @@
} else if (v.fVariable.fModifiers.fFlags & Modifiers::kOut_Flag) {
result = kOutputs_Requirement;
} else if (v.fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag &&
- v.fVariable.fType.typeKind() != Type::TypeKind::kSampler) {
+ v.fVariable.type().typeKind() != Type::TypeKind::kSampler) {
result = kUniforms_Requirement;
} else {
result = kGlobals_Requirement;
diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
index a45ba6e..b1cccce 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -34,10 +34,11 @@
void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
if (c.fFunction.fBuiltin && c.fFunction.fName == "sample" &&
- c.fArguments[0]->fType.typeKind() != Type::TypeKind::kSampler) {
+ c.fArguments[0]->type().typeKind() != Type::TypeKind::kSampler) {
SkASSERT(c.fArguments.size() <= 2);
- SkASSERT("fragmentProcessor" == c.fArguments[0]->fType.name() ||
- "fragmentProcessor?" == c.fArguments[0]->fType.name());
+ SkDEBUGCODE(const Type& arg0Type = c.fArguments[0]->type());
+ SkASSERT("fragmentProcessor" == arg0Type.name() ||
+ "fragmentProcessor?" == arg0Type.name());
SkASSERT(c.fArguments[0]->kind() == Expression::Kind::kVariableReference);
int index = 0;
bool found = false;
@@ -48,7 +49,7 @@
VarDeclaration& decl = raw->as<VarDeclaration>();
if (decl.fVar == &c.fArguments[0]->as<VariableReference>().fVariable) {
found = true;
- } else if (decl.fVar->fType == *fContext.fFragmentProcessor_Type) {
+ } else if (decl.fVar->type() == *fContext.fFragmentProcessor_Type) {
++index;
}
}
@@ -61,7 +62,7 @@
size_t childCallIndex = fArgs->fFormatArgs.size();
this->write(Compiler::kFormatArgPlaceholderStr);
bool matrixCall = c.fArguments.size() == 2 &&
- c.fArguments[1]->fType.typeKind() == Type::TypeKind::kMatrix;
+ c.fArguments[1]->type().typeKind() == Type::TypeKind::kMatrix;
fArgs->fFormatArgs.push_back(Compiler::FormatArg(
matrixCall ? Compiler::FormatArg::Kind::kChildProcessorWithMatrix
: Compiler::FormatArg::Kind::kChildProcessor,
@@ -194,7 +195,7 @@
result.fName = decl.fName;
for (const Variable* v : decl.fParameters) {
GrSLType paramSLType;
- if (!type_to_grsltype(fContext, v->fType, ¶mSLType)) {
+ if (!type_to_grsltype(fContext, v->type(), ¶mSLType)) {
fErrors.error(v->fOffset, "unsupported parameter type");
return;
}
diff --git a/src/sksl/SkSLRehydrator.cpp b/src/sksl/SkSLRehydrator.cpp
index 0f51e27..b49d5f8 100644
--- a/src/sksl/SkSLRehydrator.cpp
+++ b/src/sksl/SkSLRehydrator.cpp
@@ -232,7 +232,7 @@
const Type* type = this->type();
Variable::Storage storage = (Variable::Storage) this->readU8();
const Variable* result = fSymbolTable->takeOwnershipOfSymbol(
- std::make_unique<Variable>(/*offset=*/-1, m, name, *type, storage));
+ std::make_unique<Variable>(/*offset=*/-1, m, name, type, storage));
this->addSymbol(id, result);
return result;
}
@@ -466,12 +466,12 @@
Token::Kind op = (Token::Kind) this->readU8();
std::unique_ptr<Expression> right = this->expression();
const Type* type = this->type();
- return std::unique_ptr<Expression>(new BinaryExpression(-1, std::move(left), op,
- std::move(right), *type));
+ return std::make_unique<BinaryExpression>(-1, std::move(left), op, std::move(right),
+ type);
}
case Rehydrator::kBoolLiteral_Command: {
bool value = this->readU8();
- return std::unique_ptr<Expression>(new BoolLiteral(fContext, -1, value));
+ return std::make_unique<BoolLiteral>(fContext, -1, value);
}
case Rehydrator::kConstructor_Command: {
const Type* type = this->type();
@@ -481,21 +481,21 @@
for (int i = 0; i < argCount; ++i) {
args.push_back(this->expression());
}
- return std::unique_ptr<Expression>(new Constructor(-1, *type, std::move(args)));
+ return std::make_unique<Constructor>(-1, type, std::move(args));
}
case Rehydrator::kFieldAccess_Command: {
std::unique_ptr<Expression> base = this->expression();
int index = this->readU8();
FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8();
- return std::unique_ptr<Expression>(new FieldAccess(std::move(base), index, ownerKind));
+ return std::make_unique<FieldAccess>(std::move(base), index, ownerKind);
}
case Rehydrator::kFloatLiteral_Command: {
FloatIntUnion u;
u.fInt = this->readS32();
- return std::unique_ptr<Expression>(new FloatLiteral(fContext, -1, u.fFloat));
+ return std::make_unique<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::Kind::kFunctionDeclaration);
uint8_t argCount = this->readU8();
@@ -509,29 +509,28 @@
case Rehydrator::kIndex_Command: {
std::unique_ptr<Expression> base = this->expression();
std::unique_ptr<Expression> index = this->expression();
- return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(base),
- std::move(index)));
+ return std::make_unique<IndexExpression>(fContext, std::move(base), std::move(index));
}
case Rehydrator::kIntLiteral_Command: {
int value = this->readS32();
- return std::unique_ptr<Expression>(new IntLiteral(fContext, -1, value));
+ return std::make_unique<IntLiteral>(fContext, -1, value);
}
case Rehydrator::kNullLiteral_Command:
- return std::unique_ptr<Expression>(new NullLiteral(fContext, -1));
+ return std::make_unique<NullLiteral>(fContext, -1);
case Rehydrator::kPostfix_Command: {
Token::Kind op = (Token::Kind) this->readU8();
std::unique_ptr<Expression> operand = this->expression();
- return std::unique_ptr<Expression>(new PostfixExpression(std::move(operand), op));
+ return std::make_unique<PostfixExpression>(std::move(operand), op);
}
case Rehydrator::kPrefix_Command: {
Token::Kind op = (Token::Kind) this->readU8();
std::unique_ptr<Expression> operand = this->expression();
- return std::unique_ptr<Expression>(new PrefixExpression(op, std::move(operand)));
+ return std::make_unique<PrefixExpression>(op, std::move(operand));
}
case Rehydrator::kSetting_Command: {
StringFragment name = this->readString();
std::unique_ptr<Expression> value = this->expression();
- return std::unique_ptr<Expression>(new Setting(-1, name, std::move(value)));
+ return std::make_unique<Setting>(-1, name, std::move(value));
}
case Rehydrator::kSwizzle_Command: {
std::unique_ptr<Expression> base = this->expression();
@@ -541,21 +540,19 @@
for (int i = 0; i < count; ++i) {
components.push_back(this->readU8());
}
- return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base),
- std::move(components)));
+ return std::make_unique<Swizzle>(fContext, std::move(base), std::move(components));
}
case Rehydrator::kTernary_Command: {
std::unique_ptr<Expression> test = this->expression();
std::unique_ptr<Expression> ifTrue = this->expression();
std::unique_ptr<Expression> ifFalse = this->expression();
- return std::unique_ptr<Expression>(new TernaryExpression(-1, std::move(test),
- std::move(ifFalse),
- std::move(ifTrue)));
+ return std::make_unique<TernaryExpression>(-1, std::move(test), std::move(ifFalse),
+ std::move(ifTrue));
}
case Rehydrator::kVariableReference_Command: {
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));
+ return std::make_unique<VariableReference>(-1, *var, refKind);
}
case Rehydrator::kVoid_Command:
return nullptr;
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index da91466..e5d1126 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -583,7 +583,7 @@
for (size_t i = 0; i < function.fParameters.size(); i++) {
key += separator;
separator = ", ";
- key += to_string(this->getType(function.fParameters[i]->fType));
+ key += to_string(this->getType(function.fParameters[i]->type()));
}
key += ")";
auto entry = fTypeMap.find(key);
@@ -616,7 +616,7 @@
// as glslang does, fixes it. It's entirely possible I simply missed whichever part of
// the spec makes this make sense.
// if (is_out(function->fParameters[i])) {
- parameterTypes.push_back(this->getPointerType(function.fParameters[i]->fType,
+ parameterTypes.push_back(this->getPointerType(function.fParameters[i]->type(),
SpvStorageClassFunction));
// } else {
// parameterTypes.push_back(this->getType(function.fParameters[i]->fType));
@@ -695,7 +695,7 @@
SkASSERT(intrinsic != fIntrinsicMap.end());
int32_t intrinsicId;
if (c.fArguments.size() > 0) {
- const Type& type = c.fArguments[0]->fType;
+ const Type& type = c.fArguments[0]->type();
if (std::get<0>(intrinsic->second) == kSpecial_IntrinsicKind || is_float(fContext, type)) {
intrinsicId = std::get<1>(intrinsic->second);
} else if (is_signed(fContext, type)) {
@@ -722,7 +722,7 @@
}
}
this->writeOpCode(SpvOpExtInst, 5 + (int32_t) arguments.size(), out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(c.type()), out);
this->writeWord(result, out);
this->writeWord(fGLSLExtendedInstructions, out);
this->writeWord(intrinsicId, out);
@@ -741,9 +741,9 @@
arguments.push_back(this->writeExpression(*c.fArguments[i], out));
}
}
- if (c.fType != *fContext.fVoid_Type) {
+ if (c.type() != *fContext.fVoid_Type) {
this->writeOpCode((SpvOp_) intrinsicId, 3 + (int32_t) arguments.size(), out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(c.type()), out);
this->writeWord(result, out);
} else {
this->writeOpCode((SpvOp_) intrinsicId, 1 + (int32_t) arguments.size(), out);
@@ -765,27 +765,28 @@
OutputStream& out) {
int vectorSize = 0;
for (const auto& a : args) {
- if (a->fType.typeKind() == Type::TypeKind::kVector) {
+ if (a->type().typeKind() == Type::TypeKind::kVector) {
if (vectorSize) {
- SkASSERT(a->fType.columns() == vectorSize);
+ SkASSERT(a->type().columns() == vectorSize);
}
else {
- vectorSize = a->fType.columns();
+ vectorSize = a->type().columns();
}
}
}
std::vector<SpvId> result;
- for (const auto& a : args) {
- SpvId raw = this->writeExpression(*a, out);
- if (vectorSize && a->fType.typeKind() == Type::TypeKind::kScalar) {
+ for (const auto& arg : args) {
+ const Type& argType = arg->type();
+ SpvId raw = this->writeExpression(*arg, out);
+ if (vectorSize && argType.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);
+ this->writeWord(this->getType(argType.toCompound(fContext, vectorSize, 1)), out);
this->writeWord(vector, out);
for (int i = 0; i < vectorSize; i++) {
this->writeWord(raw, out);
}
- this->writePrecisionModifier(a->fType, vector);
+ this->writePrecisionModifier(argType, vector);
result.push_back(vector);
} else {
result.push_back(raw);
@@ -820,6 +821,7 @@
SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind,
OutputStream& out) {
SpvId result = this->nextId();
+ const Type& callType = c.type();
switch (kind) {
case kAtan_SpecialIntrinsic: {
std::vector<SpvId> arguments;
@@ -827,7 +829,7 @@
arguments.push_back(this->writeExpression(*c.fArguments[i], out));
}
this->writeOpCode(SpvOpExtInst, 5 + (int32_t) arguments.size(), out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(callType), out);
this->writeWord(result, out);
this->writeWord(fGLSLExtendedInstructions, out);
this->writeWord(arguments.size() == 2 ? GLSLstd450Atan2 : GLSLstd450Atan, out);
@@ -841,7 +843,7 @@
SpvId img = this->writeExpression(*c.fArguments[0], out);
SpvId sampler = this->writeExpression(*c.fArguments[1], out);
this->writeInstruction(SpvOpSampledImage,
- this->getType(c.fType),
+ this->getType(callType),
result,
img,
sampler,
@@ -853,11 +855,11 @@
std::vector<std::unique_ptr<Expression>> args;
args.emplace_back(new IntLiteral(fContext, -1, 0));
args.emplace_back(new IntLiteral(fContext, -1, 0));
- Constructor ctor(-1, *fContext.fInt2_Type, std::move(args));
+ Constructor ctor(-1, fContext.fInt2_Type.get(), std::move(args));
SpvId coords = this->writeConstantVector(ctor);
if (1 == c.fArguments.size()) {
this->writeInstruction(SpvOpImageRead,
- this->getType(c.fType),
+ this->getType(callType),
result,
img,
coords,
@@ -866,7 +868,7 @@
SkASSERT(2 == c.fArguments.size());
SpvId sample = this->writeExpression(*c.fArguments[1], out);
this->writeInstruction(SpvOpImageRead,
- this->getType(c.fType),
+ this->getType(callType),
result,
img,
coords,
@@ -878,26 +880,27 @@
}
case kTexture_SpecialIntrinsic: {
SpvOp_ op = SpvOpImageSampleImplicitLod;
- switch (c.fArguments[0]->fType.dimensions()) {
+ const Type& arg1Type = c.fArguments[1]->type();
+ switch (c.fArguments[0]->type().dimensions()) {
case SpvDim1D:
- if (c.fArguments[1]->fType == *fContext.fFloat2_Type) {
+ if (arg1Type == *fContext.fFloat2_Type) {
op = SpvOpImageSampleProjImplicitLod;
} else {
- SkASSERT(c.fArguments[1]->fType == *fContext.fFloat_Type);
+ SkASSERT(arg1Type == *fContext.fFloat_Type);
}
break;
case SpvDim2D:
- if (c.fArguments[1]->fType == *fContext.fFloat3_Type) {
+ if (arg1Type == *fContext.fFloat3_Type) {
op = SpvOpImageSampleProjImplicitLod;
} else {
- SkASSERT(c.fArguments[1]->fType == *fContext.fFloat2_Type);
+ SkASSERT(arg1Type == *fContext.fFloat2_Type);
}
break;
case SpvDim3D:
- if (c.fArguments[1]->fType == *fContext.fFloat4_Type) {
+ if (arg1Type == *fContext.fFloat4_Type) {
op = SpvOpImageSampleProjImplicitLod;
} else {
- SkASSERT(c.fArguments[1]->fType == *fContext.fFloat3_Type);
+ SkASSERT(arg1Type == *fContext.fFloat3_Type);
}
break;
case SpvDimCube: // fall through
@@ -906,7 +909,7 @@
case SpvDimSubpassData:
break;
}
- SpvId type = this->getType(c.fType);
+ SpvId type = this->getType(callType);
SpvId sampler = this->writeExpression(*c.fArguments[0], out);
SpvId uv = this->writeExpression(*c.fArguments[1], out);
if (c.fArguments.size() == 3) {
@@ -932,7 +935,7 @@
case kMod_SpecialIntrinsic: {
std::vector<SpvId> args = this->vectorize(c.fArguments, out);
SkASSERT(args.size() == 2);
- const Type& operandType = c.fArguments[0]->fType;
+ const Type& operandType = c.fArguments[0]->type();
SpvOp_ op;
if (is_float(fContext, operandType)) {
op = SpvOpFMod;
@@ -954,14 +957,15 @@
case kDFdy_SpecialIntrinsic: {
SpvId fn = this->writeExpression(*c.fArguments[0], out);
this->writeOpCode(SpvOpDPdy, 4, out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(callType), out);
this->writeWord(result, out);
this->writeWord(fn, out);
if (fProgram.fSettings.fFlipY) {
// Flipping Y also negates the Y derivatives.
SpvId flipped = this->nextId();
- this->writeInstruction(SpvOpFNegate, this->getType(c.fType), flipped, result, out);
- this->writePrecisionModifier(c.fType, flipped);
+ this->writeInstruction(SpvOpFNegate, this->getType(callType), flipped, result,
+ out);
+ this->writePrecisionModifier(callType, flipped);
return flipped;
}
break;
@@ -969,28 +973,28 @@
case kClamp_SpecialIntrinsic: {
std::vector<SpvId> args = this->vectorize(c.fArguments, out);
SkASSERT(args.size() == 3);
- this->writeGLSLExtendedInstruction(c.fType, result, GLSLstd450FClamp, GLSLstd450SClamp,
+ this->writeGLSLExtendedInstruction(callType, result, GLSLstd450FClamp, GLSLstd450SClamp,
GLSLstd450UClamp, args, out);
break;
}
case kMax_SpecialIntrinsic: {
std::vector<SpvId> args = this->vectorize(c.fArguments, out);
SkASSERT(args.size() == 2);
- this->writeGLSLExtendedInstruction(c.fType, result, GLSLstd450FMax, GLSLstd450SMax,
+ this->writeGLSLExtendedInstruction(callType, result, GLSLstd450FMax, GLSLstd450SMax,
GLSLstd450UMax, args, out);
break;
}
case kMin_SpecialIntrinsic: {
std::vector<SpvId> args = this->vectorize(c.fArguments, out);
SkASSERT(args.size() == 2);
- this->writeGLSLExtendedInstruction(c.fType, result, GLSLstd450FMin, GLSLstd450SMin,
+ this->writeGLSLExtendedInstruction(callType, result, GLSLstd450FMin, GLSLstd450SMin,
GLSLstd450UMin, args, out);
break;
}
case kMix_SpecialIntrinsic: {
std::vector<SpvId> args = this->vectorize(c.fArguments, out);
SkASSERT(args.size() == 3);
- this->writeGLSLExtendedInstruction(c.fType, result, GLSLstd450FMix, SpvOpUndef,
+ this->writeGLSLExtendedInstruction(callType, result, GLSLstd450FMix, SpvOpUndef,
SpvOpUndef, args, out);
break;
}
@@ -1001,7 +1005,7 @@
finalArgs.emplace_back(new FloatLiteral(fContext, -1, 0));
finalArgs.emplace_back(new FloatLiteral(fContext, -1, 1));
std::vector<SpvId> spvArgs = this->vectorize(finalArgs, out);
- this->writeGLSLExtendedInstruction(c.fType, result, GLSLstd450FClamp, GLSLstd450SClamp,
+ this->writeGLSLExtendedInstruction(callType, result, GLSLstd450FClamp, GLSLstd450SClamp,
GLSLstd450UClamp, spvArgs, out);
break;
}
@@ -1035,7 +1039,7 @@
// update the lvalue.
tmpValueId = lv->load(out);
tmpVar = this->nextId();
- lvalues.push_back(std::make_tuple(tmpVar, &c.fArguments[i]->fType, std::move(lv)));
+ lvalues.push_back(std::make_tuple(tmpVar, &c.fArguments[i]->type(), std::move(lv)));
}
} else {
// see getFunctionType for an explanation of why we're always using pointer parameters
@@ -1043,7 +1047,7 @@
tmpVar = this->nextId();
}
this->writeInstruction(SpvOpVariable,
- this->getPointerType(c.fArguments[i]->fType,
+ this->getPointerType(c.fArguments[i]->type(),
SpvStorageClassFunction),
tmpVar,
SpvStorageClassFunction,
@@ -1053,7 +1057,7 @@
}
SpvId result = this->nextId();
this->writeOpCode(SpvOpFunctionCall, 4 + (int32_t) c.fArguments.size(), out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(c.type()), out);
this->writeWord(result, out);
this->writeWord(entry->second, out);
for (SpvId id : arguments) {
@@ -1072,25 +1076,26 @@
}
SpvId SPIRVCodeGenerator::writeConstantVector(const Constructor& c) {
- SkASSERT(c.fType.typeKind() == Type::TypeKind::kVector && c.isCompileTimeConstant());
+ const Type& type = c.type();
+ SkASSERT(type.typeKind() == Type::TypeKind::kVector && c.isCompileTimeConstant());
SpvId result = this->nextId();
std::vector<SpvId> arguments;
for (size_t i = 0; i < c.fArguments.size(); i++) {
arguments.push_back(this->writeExpression(*c.fArguments[i], fConstantBuffer));
}
- SpvId type = this->getType(c.fType);
+ SpvId typeId = this->getType(type);
if (c.fArguments.size() == 1) {
// with a single argument, a vector will have all of its entries equal to the argument
- this->writeOpCode(SpvOpConstantComposite, 3 + c.fType.columns(), fConstantBuffer);
- this->writeWord(type, fConstantBuffer);
+ this->writeOpCode(SpvOpConstantComposite, 3 + type.columns(), fConstantBuffer);
+ this->writeWord(typeId, fConstantBuffer);
this->writeWord(result, fConstantBuffer);
- for (int i = 0; i < c.fType.columns(); i++) {
+ for (int i = 0; i < type.columns(); i++) {
this->writeWord(arguments[0], fConstantBuffer);
}
} else {
this->writeOpCode(SpvOpConstantComposite, 3 + (int32_t) c.fArguments.size(),
fConstantBuffer);
- this->writeWord(type, fConstantBuffer);
+ this->writeWord(typeId, fConstantBuffer);
this->writeWord(result, fConstantBuffer);
for (SpvId id : arguments) {
this->writeWord(id, fConstantBuffer);
@@ -1100,52 +1105,58 @@
}
SpvId SPIRVCodeGenerator::writeFloatConstructor(const Constructor& c, OutputStream& out) {
- SkASSERT(c.fType.isFloat());
+ const Type& constructorType = c.type();
SkASSERT(c.fArguments.size() == 1);
- SkASSERT(c.fArguments[0]->fType.isNumber());
+ const Type& argType = c.fArguments[0]->type();
+ SkASSERT(constructorType.isFloat());
+ SkASSERT(argType.isNumber());
SpvId result = this->nextId();
SpvId parameter = this->writeExpression(*c.fArguments[0], out);
- if (c.fArguments[0]->fType.isSigned()) {
- this->writeInstruction(SpvOpConvertSToF, this->getType(c.fType), result, parameter,
+ if (argType.isSigned()) {
+ this->writeInstruction(SpvOpConvertSToF, this->getType(constructorType), result, parameter,
out);
} else {
- SkASSERT(c.fArguments[0]->fType.isUnsigned());
- this->writeInstruction(SpvOpConvertUToF, this->getType(c.fType), result, parameter,
+ SkASSERT(argType.isUnsigned());
+ this->writeInstruction(SpvOpConvertUToF, this->getType(constructorType), result, parameter,
out);
}
return result;
}
SpvId SPIRVCodeGenerator::writeIntConstructor(const Constructor& c, OutputStream& out) {
- SkASSERT(c.fType.isSigned());
+ const Type& constructorType = c.type();
SkASSERT(c.fArguments.size() == 1);
- SkASSERT(c.fArguments[0]->fType.isNumber());
+ const Type& argType = c.fArguments[0]->type();
+ SkASSERT(constructorType.isSigned());
+ SkASSERT(argType.isNumber());
SpvId result = this->nextId();
SpvId parameter = this->writeExpression(*c.fArguments[0], out);
- if (c.fArguments[0]->fType.isFloat()) {
- this->writeInstruction(SpvOpConvertFToS, this->getType(c.fType), result, parameter,
+ if (argType.isFloat()) {
+ this->writeInstruction(SpvOpConvertFToS, this->getType(constructorType), result, parameter,
out);
}
else {
- SkASSERT(c.fArguments[0]->fType.isUnsigned());
- this->writeInstruction(SpvOpBitcast, this->getType(c.fType), result, parameter,
+ SkASSERT(argType.isUnsigned());
+ this->writeInstruction(SpvOpBitcast, this->getType(constructorType), result, parameter,
out);
}
return result;
}
SpvId SPIRVCodeGenerator::writeUIntConstructor(const Constructor& c, OutputStream& out) {
- SkASSERT(c.fType.isUnsigned());
+ const Type& constructorType = c.type();
SkASSERT(c.fArguments.size() == 1);
- SkASSERT(c.fArguments[0]->fType.isNumber());
+ const Type& argType = c.fArguments[0]->type();
+ SkASSERT(constructorType.isUnsigned());
+ SkASSERT(argType.isNumber());
SpvId result = this->nextId();
SpvId parameter = this->writeExpression(*c.fArguments[0], out);
- if (c.fArguments[0]->fType.isFloat()) {
- this->writeInstruction(SpvOpConvertFToU, this->getType(c.fType), result, parameter,
+ if (argType.isFloat()) {
+ this->writeInstruction(SpvOpConvertFToU, this->getType(constructorType), result, parameter,
out);
} else {
- SkASSERT(c.fArguments[0]->fType.isSigned());
- this->writeInstruction(SpvOpBitcast, this->getType(c.fType), result, parameter,
+ SkASSERT(argType.isSigned());
+ this->writeInstruction(SpvOpBitcast, this->getType(constructorType), result, parameter,
out);
}
return result;
@@ -1289,7 +1300,10 @@
}
SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStream& out) {
- SkASSERT(c.fType.typeKind() == Type::TypeKind::kMatrix);
+ const Type& type = c.type();
+ SkASSERT(type.typeKind() == Type::TypeKind::kMatrix);
+ SkASSERT(c.fArguments.size() > 0);
+ const Type& arg0Type = c.fArguments[0]->type();
// 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;
@@ -1297,51 +1311,51 @@
arguments.push_back(this->writeExpression(*c.fArguments[i], out));
}
SpvId result = this->nextId();
- int rows = c.fType.rows();
- int columns = c.fType.columns();
- if (arguments.size() == 1 && c.fArguments[0]->fType.typeKind() == Type::TypeKind::kScalar) {
- this->writeUniformScaleMatrix(result, arguments[0], c.fType, out);
+ int rows = type.rows();
+ int columns = type.columns();
+ if (arguments.size() == 1 && arg0Type.typeKind() == Type::TypeKind::kScalar) {
+ this->writeUniformScaleMatrix(result, arguments[0], type, out);
+ } else if (arguments.size() == 1 && arg0Type.typeKind() == Type::TypeKind::kMatrix) {
+ this->writeMatrixCopy(result, arguments[0], arg0Type, type, out);
} 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.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());
+ arg0Type.typeKind() == Type::TypeKind::kVector) {
+ SkASSERT(type.rows() == 2 && type.columns() == 2);
+ SkASSERT(arg0Type.columns() == 4);
+ SpvId componentType = this->getType(type.componentType());
SpvId v[4];
for (int i = 0; i < 4; ++i) {
v[i] = this->nextId();
- this->writeInstruction(SpvOpCompositeExtract, componentType, v[i], arguments[0], i, out);
+ this->writeInstruction(SpvOpCompositeExtract, componentType, v[i], arguments[0], i,
+ out);
}
- SpvId columnType = this->getType(c.fType.componentType().toCompound(fContext, 2, 1));
+ SpvId columnType = this->getType(type.componentType().toCompound(fContext, 2, 1));
SpvId column1 = this->nextId();
this->writeInstruction(SpvOpCompositeConstruct, columnType, column1, v[0], v[1], out);
SpvId column2 = this->nextId();
this->writeInstruction(SpvOpCompositeConstruct, columnType, column2, v[2], v[3], out);
- this->writeInstruction(SpvOpCompositeConstruct, this->getType(c.fType), result, column1,
+ this->writeInstruction(SpvOpCompositeConstruct, this->getType(type), result, column1,
column2, out);
} else {
- SpvId columnType = this->getType(c.fType.componentType().toCompound(fContext, rows, 1));
+ SpvId columnType = this->getType(type.componentType().toCompound(fContext, rows, 1));
std::vector<SpvId> columnIds;
// ids of vectors and scalars we have written to the current column so far
std::vector<SpvId> currentColumn;
// the total number of scalars represented by currentColumn's entries
int currentCount = 0;
- Precision precision = c.fType.highPrecision() ? Precision::kHigh : Precision::kLow;
+ Precision precision = type.highPrecision() ? Precision::kHigh : Precision::kLow;
for (size_t i = 0; i < arguments.size(); i++) {
- if (currentCount == 0 &&
- c.fArguments[i]->fType.typeKind() == Type::TypeKind::kVector &&
- c.fArguments[i]->fType.columns() == c.fType.rows()) {
+ const Type& argType = c.fArguments[i]->type();
+ if (currentCount == 0 && argType.typeKind() == Type::TypeKind::kVector &&
+ argType.columns() == type.rows()) {
// this is a complete column by itself
columnIds.push_back(arguments[i]);
} else {
- if (c.fArguments[i]->fType.columns() == 1) {
+ if (argType.columns() == 1) {
this->addColumnEntry(columnType, precision, ¤tColumn, &columnIds,
¤tCount, rows, arguments[i], out);
} else {
- SpvId componentType = this->getType(c.fArguments[i]->fType.componentType());
- for (int j = 0; j < c.fArguments[i]->fType.columns(); ++j) {
+ SpvId componentType = this->getType(argType.componentType());
+ for (int j = 0; j < argType.columns(); ++j) {
SpvId swizzle = this->nextId();
this->writeInstruction(SpvOpCompositeExtract, componentType, swizzle,
arguments[i], j, out);
@@ -1353,18 +1367,19 @@
}
SkASSERT(columnIds.size() == (size_t) columns);
this->writeOpCode(SpvOpCompositeConstruct, 3 + columns, out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(type), out);
this->writeWord(result, out);
for (SpvId id : columnIds) {
this->writeWord(id, out);
}
}
- this->writePrecisionModifier(c.fType, result);
+ this->writePrecisionModifier(type, result);
return result;
}
SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, OutputStream& out) {
- SkASSERT(c.fType.typeKind() == Type::TypeKind::kVector);
+ const Type& type = c.type();
+ SkASSERT(type.typeKind() == Type::TypeKind::kVector);
if (c.isCompileTimeConstant()) {
return this->writeConstantVector(c);
}
@@ -1372,7 +1387,8 @@
// an instruction
std::vector<SpvId> arguments;
for (size_t i = 0; i < c.fArguments.size(); i++) {
- if (c.fArguments[i]->fType.typeKind() == Type::TypeKind::kVector) {
+ const Type& argType = c.fArguments[i]->type();
+ if (argType.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
@@ -1380,8 +1396,8 @@
// pass them into OpCreateComposite individually.
SpvId vec = this->writeExpression(*c.fArguments[i], out);
SpvOp_ op = SpvOpUndef;
- const Type& src = c.fArguments[i]->fType.componentType();
- const Type& dst = c.fType.componentType();
+ const Type& src = argType.componentType();
+ const Type& dst = type.componentType();
if (dst == *fContext.fFloat_Type || dst == *fContext.fHalf_Type) {
if (src == *fContext.fFloat_Type || src == *fContext.fHalf_Type) {
if (c.fArguments.size() == 1) {
@@ -1435,7 +1451,7 @@
SkASSERT(false);
}
}
- for (int j = 0; j < c.fArguments[i]->fType.columns(); j++) {
+ for (int j = 0; j < argType.columns(); j++) {
SpvId swizzle = this->nextId();
this->writeInstruction(SpvOpCompositeExtract, this->getType(src), swizzle, vec, j,
out);
@@ -1452,17 +1468,17 @@
}
}
SpvId result = this->nextId();
- 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);
+ if (arguments.size() == 1 && c.fArguments[0]->type().typeKind() == Type::TypeKind::kScalar) {
+ this->writeOpCode(SpvOpCompositeConstruct, 3 + type.columns(), out);
+ this->writeWord(this->getType(type), out);
this->writeWord(result, out);
- for (int i = 0; i < c.fType.columns(); i++) {
+ for (int i = 0; i < type.columns(); i++) {
this->writeWord(arguments[0], out);
}
} else {
SkASSERT(arguments.size() > 1);
this->writeOpCode(SpvOpCompositeConstruct, 3 + (int32_t) arguments.size(), out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(type), out);
this->writeWord(result, out);
for (SpvId id : arguments) {
this->writeWord(id, out);
@@ -1472,7 +1488,8 @@
}
SpvId SPIRVCodeGenerator::writeArrayConstructor(const Constructor& c, OutputStream& out) {
- SkASSERT(c.fType.typeKind() == Type::TypeKind::kArray);
+ const Type& type = c.type();
+ SkASSERT(type.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;
@@ -1481,7 +1498,7 @@
}
SpvId result = this->nextId();
this->writeOpCode(SpvOpCompositeConstruct, 3 + (int32_t) c.fArguments.size(), out);
- this->writeWord(this->getType(c.fType), out);
+ this->writeWord(this->getType(type), out);
this->writeWord(result, out);
for (SpvId id : arguments) {
this->writeWord(id, out);
@@ -1490,22 +1507,23 @@
}
SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, OutputStream& out) {
+ const Type& type = c.type();
if (c.fArguments.size() == 1 &&
- this->getActualType(c.fType) == this->getActualType(c.fArguments[0]->fType)) {
+ this->getActualType(type) == this->getActualType(c.fArguments[0]->type())) {
return this->writeExpression(*c.fArguments[0], out);
}
- if (c.fType == *fContext.fFloat_Type || c.fType == *fContext.fHalf_Type) {
+ if (type == *fContext.fFloat_Type || type == *fContext.fHalf_Type) {
return this->writeFloatConstructor(c, out);
- } else if (c.fType == *fContext.fInt_Type ||
- c.fType == *fContext.fShort_Type ||
- c.fType == *fContext.fByte_Type) {
+ } else if (type == *fContext.fInt_Type ||
+ type == *fContext.fShort_Type ||
+ type == *fContext.fByte_Type) {
return this->writeIntConstructor(c, out);
- } else if (c.fType == *fContext.fUInt_Type ||
- c.fType == *fContext.fUShort_Type ||
- c.fType == *fContext.fUByte_Type) {
+ } else if (type == *fContext.fUInt_Type ||
+ type == *fContext.fUShort_Type ||
+ type == *fContext.fUByte_Type) {
return this->writeUIntConstructor(c, out);
}
- switch (c.fType.typeKind()) {
+ switch (type.typeKind()) {
case Type::TypeKind::kVector:
return this->writeVectorConstructor(c, out);
case Type::TypeKind::kMatrix:
@@ -1698,22 +1716,23 @@
std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr,
OutputStream& out) {
- Precision precision = expr.fType.highPrecision() ? Precision::kHigh : Precision::kLow;
+ const Type& type = expr.type();
+ Precision precision = type.highPrecision() ? Precision::kHigh : Precision::kLow;
switch (expr.kind()) {
case Expression::Kind::kVariableReference: {
- SpvId type;
+ SpvId typeId;
const Variable& var = ((VariableReference&) expr).fVariable;
if (var.fModifiers.fLayout.fBuiltin == SK_IN_BUILTIN) {
- type = this->getType(Type("sk_in", Type::TypeKind::kArray,
- var.fType.componentType(), fSkInCount));
+ typeId = this->getType(Type("sk_in", Type::TypeKind::kArray,
+ var.type().componentType(), fSkInCount));
} else {
- type = this->getType(expr.fType);
+ typeId = this->getType(type);
}
auto entry = fVariableMap.find(&var);
SkASSERT(entry != fVariableMap.end());
return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue(*this,
entry->second,
- type,
+ typeId,
precision));
}
case Expression::Kind::kIndex: // fall through
@@ -1721,16 +1740,16 @@
std::vector<SpvId> chain = this->getAccessChain(expr, out);
SpvId member = this->nextId();
this->writeOpCode(SpvOpAccessChain, (SpvId) (3 + chain.size()), out);
- this->writeWord(this->getPointerType(expr.fType, get_storage_class(expr)), out);
+ this->writeWord(this->getPointerType(type, get_storage_class(expr)), out);
this->writeWord(member, out);
for (SpvId idx : chain) {
this->writeWord(idx, out);
}
return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue(
- *this,
- member,
- this->getType(expr.fType),
- precision));
+ *this,
+ member,
+ this->getType(type),
+ precision));
}
case Expression::Kind::kSwizzle: {
Swizzle& swizzle = (Swizzle&) expr;
@@ -1741,25 +1760,25 @@
IntLiteral index(fContext, -1, swizzle.fComponents[0]);
SpvId member = this->nextId();
this->writeInstruction(SpvOpAccessChain,
- this->getPointerType(swizzle.fType,
+ this->getPointerType(type,
get_storage_class(*swizzle.fBase)),
member,
base,
this->writeIntLiteral(index),
out);
return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue(
- *this,
- member,
- this->getType(expr.fType),
- precision));
+ *this,
+ member,
+ this->getType(type),
+ precision));
} else {
return std::unique_ptr<SPIRVCodeGenerator::LValue>(new SwizzleLValue(
- *this,
- base,
- swizzle.fComponents,
- swizzle.fBase->fType,
- expr.fType,
- precision));
+ *this,
+ base,
+ swizzle.fComponents,
+ swizzle.fBase->type(),
+ type,
+ precision));
}
}
case Expression::Kind::kTernary: {
@@ -1783,26 +1802,27 @@
this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result, ifTrue,
ifTrueLabel, ifFalse, ifFalseLabel, out);
return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue(
- *this,
- result,
- this->getType(expr.fType),
- precision));
+ *this,
+ result,
+ this->getType(type),
+ precision));
}
- default:
+ default: {
// expr isn't actually an lvalue, create a dummy variable for it. This case happens due
// to the need to store values in temporary variables during function calls (see
// comments in getFunctionType); erroneous uses of rvalues as lvalues should have been
// caught by IRGenerator
SpvId result = this->nextId();
- SpvId type = this->getPointerType(expr.fType, SpvStorageClassFunction);
- this->writeInstruction(SpvOpVariable, type, result, SpvStorageClassFunction,
+ SpvId pointerType = this->getPointerType(type, SpvStorageClassFunction);
+ this->writeInstruction(SpvOpVariable, pointerType, result, SpvStorageClassFunction,
fVariableBuffer);
this->writeInstruction(SpvOpStore, result, this->writeExpression(expr, out), out);
return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue(
- *this,
- result,
- this->getType(expr.fType),
- precision));
+ *this,
+ result,
+ this->getType(type),
+ precision));
+ }
}
}
@@ -1811,8 +1831,8 @@
auto entry = fVariableMap.find(&ref.fVariable);
SkASSERT(entry != fVariableMap.end());
SpvId var = entry->second;
- this->writeInstruction(SpvOpLoad, this->getType(ref.fVariable.fType), result, var, out);
- this->writePrecisionModifier(ref.fVariable.fType, result);
+ this->writeInstruction(SpvOpLoad, this->getType(ref.fVariable.type()), result, var, out);
+ this->writePrecisionModifier(ref.fVariable.type(), result);
if (ref.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN &&
(fProgram.fSettings.fFlipY || fProgram.fSettings.fInverseW)) {
// The x component never changes, so just grab it
@@ -1854,7 +1874,7 @@
std::make_unique<Variable>(/*offset=*/-1,
Modifiers(layout, Modifiers::kUniform_Flag),
name,
- intfStruct,
+ &intfStruct,
Variable::kGlobal_Storage));
InterfaceBlock intf(-1, intfVar, name, String(""),
std::vector<std::unique_ptr<Expression>>(), st);
@@ -1933,11 +1953,11 @@
}
SpvId SPIRVCodeGenerator::writeIndexExpression(const IndexExpression& expr, OutputStream& out) {
- if (expr.fBase->fType.typeKind() == Type::TypeKind::kVector) {
+ if (expr.fBase->type().typeKind() == Type::TypeKind::kVector) {
SpvId base = this->writeExpression(*expr.fBase, out);
SpvId index = this->writeExpression(*expr.fIndex, out);
SpvId result = this->nextId();
- this->writeInstruction(SpvOpVectorExtractDynamic, this->getType(expr.fType), result, base,
+ this->writeInstruction(SpvOpVectorExtractDynamic, this->getType(expr.type()), result, base,
index, out);
return result;
}
@@ -1953,11 +1973,11 @@
SpvId result = this->nextId();
size_t count = swizzle.fComponents.size();
if (count == 1) {
- this->writeInstruction(SpvOpCompositeExtract, this->getType(swizzle.fType), result, base,
+ this->writeInstruction(SpvOpCompositeExtract, this->getType(swizzle.type()), result, base,
swizzle.fComponents[0], out);
} else {
this->writeOpCode(SpvOpVectorShuffle, 5 + (int32_t) count, out);
- this->writeWord(this->getType(swizzle.fType), out);
+ this->writeWord(this->getType(swizzle.type()), out);
this->writeWord(result, out);
this->writeWord(base, out);
SpvId other = base;
@@ -1981,11 +2001,12 @@
}
}
this->writeWord(other, out);
+ int baseColumns = swizzle.fBase->type().columns();
for (int component : swizzle.fComponents) {
if (component == SKSL_SWIZZLE_0) {
- this->writeWord(swizzle.fBase->fType.columns(), out);
+ this->writeWord(baseColumns, out);
} else if (component == SKSL_SWIZZLE_1) {
- this->writeWord(swizzle.fBase->fType.columns() + 1, out);
+ this->writeWord(baseColumns + 1, out);
} else {
this->writeWord(component, out);
}
@@ -2333,9 +2354,9 @@
lhs = this->writeExpression(*b.fLeft, out);
}
SpvId rhs = this->writeExpression(*b.fRight, out);
- SpvId result = this->writeBinaryExpression(b.fLeft->fType, lhs,
+ SpvId result = this->writeBinaryExpression(b.fLeft->type(), lhs,
Compiler::RemoveAssignment(b.fOperator),
- b.fRight->fType, rhs, b.fType, out);
+ b.fRight->type(), rhs, b.type(), out);
if (lvalue) {
lvalue->store(result, out);
}
@@ -2385,22 +2406,23 @@
}
SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, OutputStream& out) {
+ const Type& type = t.type();
SpvId test = this->writeExpression(*t.fTest, out);
- if (t.fIfTrue->fType.columns() == 1 &&
+ if (t.fIfTrue->type().columns() == 1 &&
t.fIfTrue->isCompileTimeConstant() &&
t.fIfFalse->isCompileTimeConstant()) {
// both true and false are constants, can just use OpSelect
SpvId result = this->nextId();
SpvId trueId = this->writeExpression(*t.fIfTrue, out);
SpvId falseId = this->writeExpression(*t.fIfFalse, out);
- this->writeInstruction(SpvOpSelect, this->getType(t.fType), result, test, trueId, falseId,
+ this->writeInstruction(SpvOpSelect, this->getType(type), result, test, trueId, falseId,
out);
return result;
}
// was originally using OpPhi to choose the result, but for some reason that is crashing on
// Adreno. Switched to storing the result in a temp variable as glslang does.
SpvId var = this->nextId();
- this->writeInstruction(SpvOpVariable, this->getPointerType(t.fType, SpvStorageClassFunction),
+ this->writeInstruction(SpvOpVariable, this->getPointerType(type, SpvStorageClassFunction),
var, SpvStorageClassFunction, fVariableBuffer);
SpvId trueLabel = this->nextId();
SpvId falseLabel = this->nextId();
@@ -2415,26 +2437,27 @@
this->writeInstruction(SpvOpBranch, end, out);
this->writeLabel(end, out);
SpvId result = this->nextId();
- this->writeInstruction(SpvOpLoad, this->getType(t.fType), result, var, out);
- this->writePrecisionModifier(t.fType, result);
+ this->writeInstruction(SpvOpLoad, this->getType(type), result, var, out);
+ this->writePrecisionModifier(type, result);
return result;
}
SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, OutputStream& out) {
+ const Type& type = p.type();
if (p.fOperator == Token::Kind::TK_MINUS) {
SpvId result = this->nextId();
- SpvId typeId = this->getType(p.fType);
+ SpvId typeId = this->getType(type);
SpvId expr = this->writeExpression(*p.fOperand, out);
- if (is_float(fContext, p.fType)) {
+ if (is_float(fContext, type)) {
this->writeInstruction(SpvOpFNegate, typeId, result, expr, out);
- } else if (is_signed(fContext, p.fType)) {
+ } else if (is_signed(fContext, type)) {
this->writeInstruction(SpvOpSNegate, typeId, result, expr, out);
} else {
#ifdef SK_DEBUG
ABORT("unsupported prefix expression %s", p.description().c_str());
#endif
}
- this->writePrecisionModifier(p.fType, result);
+ this->writePrecisionModifier(type, result);
return result;
}
switch (p.fOperator) {
@@ -2442,8 +2465,8 @@
return this->writeExpression(*p.fOperand, out);
case Token::Kind::TK_PLUSPLUS: {
std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out);
- SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out);
- SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load(out), one,
+ SpvId one = this->writeExpression(*create_literal_1(fContext, type), out);
+ SpvId result = this->writeBinaryOperation(type, type, lv->load(out), one,
SpvOpFAdd, SpvOpIAdd, SpvOpIAdd, SpvOpUndef,
out);
lv->store(result, out);
@@ -2451,23 +2474,22 @@
}
case Token::Kind::TK_MINUSMINUS: {
std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out);
- SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out);
- SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load(out), one,
- SpvOpFSub, SpvOpISub, SpvOpISub, SpvOpUndef,
- out);
+ SpvId one = this->writeExpression(*create_literal_1(fContext, type), out);
+ SpvId result = this->writeBinaryOperation(type, type, lv->load(out), one, SpvOpFSub,
+ SpvOpISub, SpvOpISub, SpvOpUndef, out);
lv->store(result, out);
return result;
}
case Token::Kind::TK_LOGICALNOT: {
- SkASSERT(p.fOperand->fType == *fContext.fBool_Type);
+ SkASSERT(p.fOperand->type() == *fContext.fBool_Type);
SpvId result = this->nextId();
- this->writeInstruction(SpvOpLogicalNot, this->getType(p.fOperand->fType), result,
+ this->writeInstruction(SpvOpLogicalNot, this->getType(p.fOperand->type()), result,
this->writeExpression(*p.fOperand, out), out);
return result;
}
case Token::Kind::TK_BITWISENOT: {
SpvId result = this->nextId();
- this->writeInstruction(SpvOpNot, this->getType(p.fOperand->fType), result,
+ this->writeInstruction(SpvOpNot, this->getType(p.fOperand->type()), result,
this->writeExpression(*p.fOperand, out), out);
return result;
}
@@ -2480,18 +2502,19 @@
}
SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, OutputStream& out) {
+ const Type& type = p.type();
std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out);
SpvId result = lv->load(out);
- SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out);
+ SpvId one = this->writeExpression(*create_literal_1(fContext, type), out);
switch (p.fOperator) {
case Token::Kind::TK_PLUSPLUS: {
- SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, one, SpvOpFAdd,
+ SpvId temp = this->writeBinaryOperation(type, type, result, one, SpvOpFAdd,
SpvOpIAdd, SpvOpIAdd, SpvOpUndef, out);
lv->store(temp, out);
return result;
}
case Token::Kind::TK_MINUSMINUS: {
- SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, one, SpvOpFSub,
+ SpvId temp = this->writeBinaryOperation(type, type, result, one, SpvOpFSub,
SpvOpISub, SpvOpISub, SpvOpUndef, out);
lv->store(temp, out);
return result;
@@ -2508,14 +2531,14 @@
if (b.fValue) {
if (fBoolTrue == 0) {
fBoolTrue = this->nextId();
- this->writeInstruction(SpvOpConstantTrue, this->getType(b.fType), fBoolTrue,
+ this->writeInstruction(SpvOpConstantTrue, this->getType(b.type()), fBoolTrue,
fConstantBuffer);
}
return fBoolTrue;
} else {
if (fBoolFalse == 0) {
fBoolFalse = this->nextId();
- this->writeInstruction(SpvOpConstantFalse, this->getType(b.fType), fBoolFalse,
+ this->writeInstruction(SpvOpConstantFalse, this->getType(b.type()), fBoolFalse,
fConstantBuffer);
}
return fBoolFalse;
@@ -2523,23 +2546,24 @@
}
SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) {
- ConstantType type;
- if (i.fType == *fContext.fInt_Type) {
- type = ConstantType::kInt;
- } else if (i.fType == *fContext.fUInt_Type) {
- type = ConstantType::kUInt;
- } else if (i.fType == *fContext.fShort_Type || i.fType == *fContext.fByte_Type) {
- type = ConstantType::kShort;
- } else if (i.fType == *fContext.fUShort_Type || i.fType == *fContext.fUByte_Type) {
- type = ConstantType::kUShort;
+ const Type& type = i.type();
+ ConstantType constantType;
+ if (type == *fContext.fInt_Type) {
+ constantType = ConstantType::kInt;
+ } else if (type == *fContext.fUInt_Type) {
+ constantType = ConstantType::kUInt;
+ } else if (type == *fContext.fShort_Type || type == *fContext.fByte_Type) {
+ constantType = ConstantType::kShort;
+ } else if (type == *fContext.fUShort_Type || type == *fContext.fUByte_Type) {
+ constantType = ConstantType::kUShort;
} else {
SkASSERT(false);
}
- std::pair<ConstantValue, ConstantType> key(i.fValue, type);
+ std::pair<ConstantValue, ConstantType> key(i.fValue, constantType);
auto entry = fNumberConstants.find(key);
if (entry == fNumberConstants.end()) {
SpvId result = this->nextId();
- this->writeInstruction(SpvOpConstant, this->getType(i.fType), result, (SpvId) i.fValue,
+ this->writeInstruction(SpvOpConstant, this->getType(type), result, (SpvId) i.fValue,
fConstantBuffer);
fNumberConstants[key] = result;
return result;
@@ -2548,21 +2572,22 @@
}
SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
- ConstantType type;
- if (f.fType == *fContext.fHalf_Type) {
- type = ConstantType::kHalf;
+ const Type& type = f.type();
+ ConstantType constantType;
+ if (type == *fContext.fHalf_Type) {
+ constantType = ConstantType::kHalf;
} else {
- type = ConstantType::kFloat;
+ constantType = ConstantType::kFloat;
}
float value = (float) f.fValue;
- std::pair<ConstantValue, ConstantType> key(f.fValue, type);
+ std::pair<ConstantValue, ConstantType> key(f.fValue, constantType);
auto entry = fNumberConstants.find(key);
if (entry == fNumberConstants.end()) {
SpvId result = this->nextId();
uint32_t bits;
SkASSERT(sizeof(bits) == sizeof(value));
memcpy(&bits, &value, sizeof(bits));
- this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits,
+ this->writeInstruction(SpvOpConstant, this->getType(type), result, bits,
fConstantBuffer);
fNumberConstants[key] = result;
return result;
@@ -2579,7 +2604,7 @@
SpvId id = this->nextId();
fVariableMap[f.fParameters[i]] = id;
SpvId type;
- type = this->getPointerType(f.fParameters[i]->fType, SpvStorageClassFunction);
+ type = this->getPointerType(f.fParameters[i]->type(), SpvStorageClassFunction);
this->writeInstruction(SpvOpFunctionParameter, type, id, out);
}
return result;
@@ -2693,7 +2718,7 @@
MemoryLayout(MemoryLayout::k430_Standard) :
fDefaultLayout;
SpvId result = this->nextId();
- const Type* type = &intf.fVariable.fType;
+ const Type* type = &intf.fVariable.type();
if (fProgram.fInputs.fRTHeight && appendRTHeight) {
SkASSERT(fRTHeightStructId == (SpvId) -1);
SkASSERT(fRTHeightFieldIndex == (SpvId) -1);
@@ -2712,7 +2737,7 @@
}
}
typeId = this->getType(Type("sk_in", Type::TypeKind::kArray,
- intf.fVariable.fType.componentType(),
+ intf.fVariable.type().componentType(),
fSkInCount),
memoryLayout);
} else {
@@ -2792,15 +2817,16 @@
if (is_dead(*var)) {
continue;
}
+ const Type& type = var->type();
SpvStorageClass_ storageClass;
if (var->fModifiers.fFlags & Modifiers::kIn_Flag) {
storageClass = SpvStorageClassInput;
} else if (var->fModifiers.fFlags & Modifiers::kOut_Flag) {
storageClass = SpvStorageClassOutput;
} else if (var->fModifiers.fFlags & Modifiers::kUniform_Flag) {
- if (var->fType.typeKind() == Type::TypeKind::kSampler ||
- var->fType.typeKind() == Type::TypeKind::kSeparateSampler ||
- var->fType.typeKind() == Type::TypeKind::kTexture) {
+ if (type.typeKind() == Type::TypeKind::kSampler ||
+ type.typeKind() == Type::TypeKind::kSeparateSampler ||
+ type.typeKind() == Type::TypeKind::kTexture) {
storageClass = SpvStorageClassUniformConstant;
} else {
storageClass = SpvStorageClassUniform;
@@ -2810,17 +2836,17 @@
}
SpvId id = this->nextId();
fVariableMap[var] = id;
- SpvId type;
+ SpvId typeId;
if (var->fModifiers.fLayout.fBuiltin == SK_IN_BUILTIN) {
- type = this->getPointerType(Type("sk_in", Type::TypeKind::kArray,
- var->fType.componentType(), fSkInCount),
+ typeId = this->getPointerType(Type("sk_in", Type::TypeKind::kArray,
+ type.componentType(), fSkInCount),
storageClass);
} else {
- type = this->getPointerType(var->fType, storageClass);
+ typeId = this->getPointerType(type, storageClass);
}
- this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer);
+ this->writeInstruction(SpvOpVariable, typeId, id, storageClass, fConstantBuffer);
this->writeInstruction(SpvOpName, id, var->fName, fNameBuffer);
- this->writePrecisionModifier(var->fType, id);
+ this->writePrecisionModifier(type, id);
if (varDecl.fValue) {
SkASSERT(!fCurrentBlock);
fCurrentBlock = -1;
@@ -2853,7 +2879,7 @@
Modifiers::kRestrict_Flag)));
SpvId id = this->nextId();
fVariableMap[var] = id;
- SpvId type = this->getPointerType(var->fType, SpvStorageClassFunction);
+ SpvId type = this->getPointerType(var->type(), SpvStorageClassFunction);
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
this->writeInstruction(SpvOpName, id, var->fName, fNameBuffer);
if (varDecl.fValue) {
diff --git a/src/sksl/ir/SkSLBinaryExpression.h b/src/sksl/ir/SkSLBinaryExpression.h
index 3a927fc..18ce2b7 100644
--- a/src/sksl/ir/SkSLBinaryExpression.h
+++ b/src/sksl/ir/SkSLBinaryExpression.h
@@ -50,7 +50,7 @@
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)
+ std::unique_ptr<Expression> right, const Type* type)
: INHERITED(offset, kExpressionKind, type)
, fLeft(std::move(left))
, fOperator(op)
@@ -79,7 +79,7 @@
std::unique_ptr<Expression> clone() const override {
return std::unique_ptr<Expression>(new BinaryExpression(fOffset, fLeft->clone(), fOperator,
- fRight->clone(), fType));
+ fRight->clone(), &this->type()));
}
String description() const override {
diff --git a/src/sksl/ir/SkSLBoolLiteral.h b/src/sksl/ir/SkSLBoolLiteral.h
index 8e0c21a..c82014e 100644
--- a/src/sksl/ir/SkSLBoolLiteral.h
+++ b/src/sksl/ir/SkSLBoolLiteral.h
@@ -20,7 +20,7 @@
static constexpr Kind kExpressionKind = Kind::kBoolLiteral;
BoolLiteral(const Context& context, int offset, bool value)
- : INHERITED(offset, kExpressionKind, *context.fBool_Type)
+ : INHERITED(offset, kExpressionKind, context.fBool_Type.get())
, fValue(value) {}
String description() const override {
@@ -41,7 +41,7 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new BoolLiteral(fOffset, fValue, &fType));
+ return std::unique_ptr<Expression>(new BoolLiteral(fOffset, fValue, &this->type()));
}
const bool fValue;
@@ -50,7 +50,7 @@
private:
BoolLiteral(int offset, bool value, const Type* type)
- : INHERITED(offset, kExpressionKind, *type)
+ : INHERITED(offset, kExpressionKind, type)
, fValue(value) {}
};
diff --git a/src/sksl/ir/SkSLConstructor.h b/src/sksl/ir/SkSLConstructor.h
index 051bda1..60abe0a 100644
--- a/src/sksl/ir/SkSLConstructor.h
+++ b/src/sksl/ir/SkSLConstructor.h
@@ -28,25 +28,26 @@
struct Constructor : public Expression {
static constexpr Kind kExpressionKind = Kind::kConstructor;
- Constructor(int offset, const Type& type, std::vector<std::unique_ptr<Expression>> arguments)
+ Constructor(int offset, const Type* type, std::vector<std::unique_ptr<Expression>> arguments)
: INHERITED(offset, kExpressionKind, type)
, fArguments(std::move(arguments)) {}
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override {
if (fArguments.size() == 1 && fArguments[0]->kind() == Expression::Kind::kIntLiteral) {
- if (fType.isFloat()) {
+ const Type& type = this->type();
+ if (type.isFloat()) {
// promote float(1) to 1.0
int64_t intValue = fArguments[0]->as<IntLiteral>().fValue;
return std::unique_ptr<Expression>(new FloatLiteral(irGenerator.fContext,
fOffset,
intValue));
- } else if (fType.isInteger()) {
+ } else if (type.isInteger()) {
// promote uint(1) to 1u
int64_t intValue = fArguments[0]->as<IntLiteral>().fValue;
return std::unique_ptr<Expression>(new IntLiteral(fOffset,
intValue,
- &fType));
+ &type));
}
}
return nullptr;
@@ -66,11 +67,12 @@
for (const auto& arg : fArguments) {
cloned.push_back(arg->clone());
}
- return std::unique_ptr<Expression>(new Constructor(fOffset, fType, std::move(cloned)));
+ return std::unique_ptr<Expression>(new Constructor(fOffset, &this->type(),
+ std::move(cloned)));
}
String description() const override {
- String result = fType.description() + "(";
+ String result = this->type().description() + "(";
String separator;
for (size_t i = 0; i < fArguments.size(); i++) {
result += separator;
@@ -100,12 +102,14 @@
}
bool compareConstant(const Context& context, const Expression& other) const override {
- SkASSERT(other.kind() == Expression::Kind::kConstructor && other.fType == fType);
- Constructor& c = (Constructor&) other;
- 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++) {
+ const Constructor& c = other.as<Constructor>();
+ const Type& myType = this->type();
+ const Type& otherType = c.type();
+ SkASSERT(myType == otherType);
+ if (otherType.typeKind() == Type::TypeKind::kVector) {
+ bool isFloat = otherType.columns() > 1 ? otherType.componentType().isFloat()
+ : otherType.isFloat();
+ for (int i = 0; i < myType.columns(); i++) {
if (isFloat) {
if (this->getFVecComponent(i) != c.getFVecComponent(i)) {
return false;
@@ -119,9 +123,9 @@
// 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.typeKind() == Type::TypeKind::kMatrix);
- for (int col = 0; col < fType.columns(); col++) {
- for (int row = 0; row < fType.rows(); row++) {
+ SkASSERT(myType.typeKind() == Type::TypeKind::kMatrix);
+ for (int col = 0; col < myType.columns(); col++) {
+ for (int row = 0; row < myType.rows(); row++) {
if (getMatComponent(col, row) != c.getMatComponent(col, row)) {
return false;
}
@@ -132,8 +136,9 @@
template <typename type>
type getVecComponent(int index) const {
- SkASSERT(fType.typeKind() == Type::TypeKind::kVector);
- if (fArguments.size() == 1 && fArguments[0]->fType.typeKind() == Type::TypeKind::kScalar) {
+ SkASSERT(this->type().typeKind() == Type::TypeKind::kVector);
+ if (fArguments.size() == 1 &&
+ fArguments[0]->type().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 +155,7 @@
break;
}
- if (arg->fType.typeKind() == Type::TypeKind::kScalar) {
+ if (arg->type().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) {
@@ -166,10 +171,10 @@
switch (arg->kind()) {
case Kind::kConstructor: {
const Constructor& constructor = static_cast<const Constructor&>(*arg);
- if (current + constructor.fType.columns() > index) {
+ if (current + constructor.type().columns() > index) {
// We've found a constructor that overlaps the proper argument. Descend into
// it, honoring the type.
- if (constructor.fType.componentType().isFloat()) {
+ if (constructor.type().componentType().isFloat()) {
return type(constructor.getVecComponent<SKSL_FLOAT>(index - current));
} else {
return type(constructor.getVecComponent<SKSL_INT>(index - current));
@@ -179,7 +184,7 @@
}
case Kind::kPrefix: {
const PrefixExpression& prefix = static_cast<const PrefixExpression&>(*arg);
- if (current + prefix.fType.columns() > index) {
+ if (current + prefix.type().columns() > index) {
// We found a prefix operator that contains the proper argument. Descend
// into it. We only support for constant propagation of the unary minus, so
// we shouldn't see any other tokens here.
@@ -191,7 +196,7 @@
static_cast<const Constructor&>(*prefix.fOperand);
// Descend into this constructor, honoring the type.
- if (constructor.fType.componentType().isFloat()) {
+ if (constructor.type().componentType().isFloat()) {
return -type(constructor.getVecComponent<SKSL_FLOAT>(index - current));
} else {
return -type(constructor.getVecComponent<SKSL_INT>(index - current));
@@ -206,7 +211,7 @@
}
}
- current += arg->fType.columns();
+ current += arg->type().columns();
}
SkDEBUGFAILF("failed to find vector component %d in %s\n", index, description().c_str());
@@ -226,11 +231,13 @@
}
SKSL_FLOAT getMatComponent(int col, int row) const override {
+ SkDEBUGCODE(const Type& myType = this->type();)
SkASSERT(this->isCompileTimeConstant());
- SkASSERT(fType.typeKind() == Type::TypeKind::kMatrix);
- SkASSERT(col < fType.columns() && row < fType.rows());
+ SkASSERT(myType.typeKind() == Type::TypeKind::kMatrix);
+ SkASSERT(col < myType.columns() && row < myType.rows());
if (fArguments.size() == 1) {
- if (fArguments[0]->fType.typeKind() == Type::TypeKind::kScalar) {
+ const Type& argType = fArguments[0]->type();
+ if (argType.typeKind() == Type::TypeKind::kScalar) {
// single scalar argument, so matrix is of the form:
// x 0 0
// 0 x 0
@@ -238,10 +245,9 @@
// return x if col == row
return col == row ? fArguments[0]->getConstantFloat() : 0.0;
}
- if (fArguments[0]->fType.typeKind() == Type::TypeKind::kMatrix) {
+ if (argType.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()) {
// within bounds, defer to argument
return ((Constructor&) *fArguments[0]).getMatComponent(col, row);
@@ -251,18 +257,19 @@
}
}
int currentIndex = 0;
- int targetIndex = col * fType.rows() + row;
+ int targetIndex = col * this->type().rows() + row;
for (const auto& arg : fArguments) {
+ const Type& argType = arg->type();
SkASSERT(targetIndex >= currentIndex);
- SkASSERT(arg->fType.rows() == 1);
- if (currentIndex + arg->fType.columns() > targetIndex) {
- if (arg->fType.columns() == 1) {
+ SkASSERT(argType.rows() == 1);
+ if (currentIndex + argType.columns() > targetIndex) {
+ if (argType.columns() == 1) {
return arg->getConstantFloat();
} else {
return arg->getFVecComponent(targetIndex - currentIndex);
}
}
- currentIndex += arg->fType.columns();
+ currentIndex += argType.columns();
}
ABORT("can't happen, matrix component out of bounds");
}
diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h
index 2203aae..4e6c17c 100644
--- a/src/sksl/ir/SkSLExpression.h
+++ b/src/sksl/ir/SkSLExpression.h
@@ -56,9 +56,8 @@
kContainsRTAdjust
};
- Expression(int offset, Kind kind, const Type& type)
- : INHERITED(offset, (int) kind)
- , fType(std::move(type)) {
+ Expression(int offset, Kind kind, const Type* type)
+ : INHERITED(offset, (int) kind, type) {
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
@@ -156,7 +155,7 @@
}
virtual int coercionCost(const Type& target) const {
- return fType.coercionCost(target);
+ return this->type().coercionCost(target);
}
/**
@@ -189,8 +188,6 @@
virtual std::unique_ptr<Expression> clone() const = 0;
- const Type& fType;
-
using INHERITED = IRNode;
};
diff --git a/src/sksl/ir/SkSLExternalFunctionCall.h b/src/sksl/ir/SkSLExternalFunctionCall.h
index 6e8942c..3776cb0 100644
--- a/src/sksl/ir/SkSLExternalFunctionCall.h
+++ b/src/sksl/ir/SkSLExternalFunctionCall.h
@@ -20,7 +20,7 @@
struct ExternalFunctionCall : public Expression {
static constexpr Kind kExpressionKind = Kind::kExternalFunctionCall;
- ExternalFunctionCall(int offset, const Type& type, const ExternalValue* function,
+ ExternalFunctionCall(int offset, const Type* type, const ExternalValue* function,
std::vector<std::unique_ptr<Expression>> arguments)
: INHERITED(offset, kExpressionKind, type)
, fFunction(function)
@@ -44,7 +44,7 @@
cloned.push_back(arg->clone());
}
return std::unique_ptr<Expression>(new ExternalFunctionCall(fOffset,
- fType,
+ &this->type(),
fFunction,
std::move(cloned)));
}
diff --git a/src/sksl/ir/SkSLExternalValueReference.h b/src/sksl/ir/SkSLExternalValueReference.h
index a68c7ee..49d383c 100644
--- a/src/sksl/ir/SkSLExternalValueReference.h
+++ b/src/sksl/ir/SkSLExternalValueReference.h
@@ -20,7 +20,7 @@
static constexpr Kind kExpressionKind = Kind::kExternalValue;
ExternalValueReference(int offset, const ExternalValue* ev)
- : INHERITED(offset, kExpressionKind, ev->type())
+ : INHERITED(offset, kExpressionKind, &ev->type())
, fValue(ev) {}
bool hasProperty(Property property) const override {
diff --git a/src/sksl/ir/SkSLField.h b/src/sksl/ir/SkSLField.h
index 33ac904..78872c5 100644
--- a/src/sksl/ir/SkSLField.h
+++ b/src/sksl/ir/SkSLField.h
@@ -25,12 +25,12 @@
static constexpr Kind kSymbolKind = Kind::kField;
Field(int offset, const Variable& owner, int fieldIndex)
- : INHERITED(offset, kSymbolKind, owner.fType.fields()[fieldIndex].fName)
+ : INHERITED(offset, kSymbolKind, owner.type().fields()[fieldIndex].fName)
, fOwner(owner)
, fFieldIndex(fieldIndex) {}
String description() const override {
- return fOwner.description() + "." + fOwner.fType.fields()[fFieldIndex].fName;
+ return fOwner.description() + "." + fOwner.type().fields()[fFieldIndex].fName;
}
const Variable& fOwner;
diff --git a/src/sksl/ir/SkSLFieldAccess.h b/src/sksl/ir/SkSLFieldAccess.h
index c78bb42..ee14638 100644
--- a/src/sksl/ir/SkSLFieldAccess.h
+++ b/src/sksl/ir/SkSLFieldAccess.h
@@ -28,7 +28,7 @@
FieldAccess(std::unique_ptr<Expression> base, int fieldIndex,
OwnerKind ownerKind = kDefault_OwnerKind)
- : INHERITED(base->fOffset, kExpressionKind, *base->fType.fields()[fieldIndex].fType)
+ : INHERITED(base->fOffset, kExpressionKind, base->type().fields()[fieldIndex].fType)
, fBase(std::move(base))
, fFieldIndex(fieldIndex)
, fOwnerKind(ownerKind) {}
@@ -43,7 +43,7 @@
}
String description() const override {
- return fBase->description() + "." + fBase->fType.fields()[fFieldIndex].fName;
+ return fBase->description() + "." + fBase->type().fields()[fFieldIndex].fName;
}
std::unique_ptr<Expression> fBase;
diff --git a/src/sksl/ir/SkSLFloatLiteral.h b/src/sksl/ir/SkSLFloatLiteral.h
index dbfb726..0bbdc14 100644
--- a/src/sksl/ir/SkSLFloatLiteral.h
+++ b/src/sksl/ir/SkSLFloatLiteral.h
@@ -20,11 +20,11 @@
static constexpr Kind kExpressionKind = Kind::kFloatLiteral;
FloatLiteral(const Context& context, int offset, double value)
- : INHERITED(offset, kExpressionKind, *context.fFloatLiteral_Type)
+ : INHERITED(offset, kExpressionKind, context.fFloatLiteral_Type.get())
, fValue(value) {}
FloatLiteral(int offset, double value, const Type* type)
- : INHERITED(offset, kExpressionKind, *type)
+ : INHERITED(offset, kExpressionKind, type)
, fValue(value) {}
String description() const override {
@@ -55,7 +55,7 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new FloatLiteral(fOffset, fValue, &fType));
+ return std::unique_ptr<Expression>(new FloatLiteral(fOffset, fValue, &this->type()));
}
const double fValue;
diff --git a/src/sksl/ir/SkSLFunctionCall.h b/src/sksl/ir/SkSLFunctionCall.h
index 119066b..64e9270 100644
--- a/src/sksl/ir/SkSLFunctionCall.h
+++ b/src/sksl/ir/SkSLFunctionCall.h
@@ -19,7 +19,7 @@
struct FunctionCall : public Expression {
static constexpr Kind kExpressionKind = Kind::kFunctionCall;
- FunctionCall(int offset, const Type& type, const FunctionDeclaration& function,
+ FunctionCall(int offset, const Type* type, const FunctionDeclaration& function,
std::vector<std::unique_ptr<Expression>> arguments)
: INHERITED(offset, kExpressionKind, type)
, fFunction(std::move(function))
@@ -49,7 +49,7 @@
for (const auto& arg : fArguments) {
cloned.push_back(arg->clone());
}
- return std::unique_ptr<Expression>(new FunctionCall(fOffset, fType, fFunction,
+ return std::unique_ptr<Expression>(new FunctionCall(fOffset, &this->type(), fFunction,
std::move(cloned)));
}
diff --git a/src/sksl/ir/SkSLFunctionDeclaration.h b/src/sksl/ir/SkSLFunctionDeclaration.h
index 7d1974d..2635d9a 100644
--- a/src/sksl/ir/SkSLFunctionDeclaration.h
+++ b/src/sksl/ir/SkSLFunctionDeclaration.h
@@ -43,7 +43,7 @@
for (auto p : fParameters) {
result += separator;
separator = ", ";
- result += p->fType.displayName();
+ result += p->type().displayName();
}
result += ")";
return result;
@@ -57,7 +57,7 @@
return false;
}
for (size_t i = 0; i < fParameters.size(); i++) {
- if (fParameters[i]->fType != f.fParameters[i]->fType) {
+ if (fParameters[i]->type() != f.fParameters[i]->type()) {
return false;
}
}
@@ -81,11 +81,12 @@
SkASSERT(arguments.size() == fParameters.size());
int genericIndex = -1;
for (size_t i = 0; i < arguments.size(); i++) {
- if (fParameters[i]->fType.typeKind() == Type::TypeKind::kGeneric) {
- std::vector<const Type*> types = fParameters[i]->fType.coercibleTypes();
+ const Type& parameterType = fParameters[i]->type();
+ if (parameterType.typeKind() == Type::TypeKind::kGeneric) {
+ std::vector<const Type*> types = parameterType.coercibleTypes();
if (genericIndex == -1) {
for (size_t j = 0; j < types.size(); j++) {
- if (arguments[i]->fType.canCoerceTo(*types[j])) {
+ if (arguments[i]->type().canCoerceTo(*types[j])) {
genericIndex = j;
break;
}
@@ -96,7 +97,7 @@
}
outParameterTypes->push_back(types[genericIndex]);
} else {
- outParameterTypes->push_back(&fParameters[i]->fType);
+ outParameterTypes->push_back(¶meterType);
}
}
if (fReturnType.typeKind() == Type::TypeKind::kGeneric) {
diff --git a/src/sksl/ir/SkSLFunctionReference.h b/src/sksl/ir/SkSLFunctionReference.h
index af8fff0..da002f2 100644
--- a/src/sksl/ir/SkSLFunctionReference.h
+++ b/src/sksl/ir/SkSLFunctionReference.h
@@ -23,7 +23,7 @@
FunctionReference(const Context& context, int offset,
std::vector<const FunctionDeclaration*> function)
- : INHERITED(offset, kExpressionKind, *context.fInvalid_Type)
+ : INHERITED(offset, kExpressionKind, context.fInvalid_Type.get())
, fFunctions(function) {}
bool hasProperty(Property property) const override {
@@ -31,7 +31,8 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new FunctionReference(fOffset, fFunctions, &fType));
+ return std::unique_ptr<Expression>(new FunctionReference(fOffset, fFunctions,
+ &this->type()));
}
String description() const override {
@@ -45,7 +46,7 @@
private:
FunctionReference(int offset, std::vector<const FunctionDeclaration*> function,
const Type* type)
- : INHERITED(offset, kExpressionKind, *type)
+ : INHERITED(offset, kExpressionKind, type)
, fFunctions(function) {}};
} // namespace SkSL
diff --git a/src/sksl/ir/SkSLIRNode.h b/src/sksl/ir/SkSLIRNode.h
index 9549cd2..4a6aa90 100644
--- a/src/sksl/ir/SkSLIRNode.h
+++ b/src/sksl/ir/SkSLIRNode.h
@@ -13,14 +13,18 @@
namespace SkSL {
+class Type;
+
/**
* Represents a node in the intermediate representation (IR) tree. The IR is a fully-resolved
* version of the program (all types determined, everything validated), ready for code generation.
*/
-struct IRNode {
- IRNode(int offset, int kind)
+class IRNode {
+public:
+ IRNode(int offset, int kind, const Type* type = nullptr)
: fOffset(offset)
- , fKind(kind) {}
+ , fKind(kind)
+ , fType(type) {}
virtual ~IRNode() {}
@@ -30,8 +34,16 @@
// purposes
int fOffset;
+ const Type& type() const {
+ SkASSERT(fType);
+ return *fType;
+ }
+
protected:
int fKind;
+
+private:
+ const Type* fType;
};
} // namespace SkSL
diff --git a/src/sksl/ir/SkSLIndexExpression.h b/src/sksl/ir/SkSLIndexExpression.h
index 6be205d..7911bb1 100644
--- a/src/sksl/ir/SkSLIndexExpression.h
+++ b/src/sksl/ir/SkSLIndexExpression.h
@@ -46,10 +46,10 @@
IndexExpression(const Context& context, std::unique_ptr<Expression> base,
std::unique_ptr<Expression> index)
- : INHERITED(base->fOffset, kExpressionKind, index_type(context, base->fType))
+ : INHERITED(base->fOffset, kExpressionKind, &index_type(context, base->type()))
, fBase(std::move(base))
, fIndex(std::move(index)) {
- SkASSERT(fIndex->fType == *context.fInt_Type || fIndex->fType == *context.fUInt_Type);
+ SkASSERT(fIndex->type() == *context.fInt_Type || fIndex->type() == *context.fUInt_Type);
}
bool hasProperty(Property property) const override {
@@ -58,7 +58,7 @@
std::unique_ptr<Expression> clone() const override {
return std::unique_ptr<Expression>(new IndexExpression(fBase->clone(), fIndex->clone(),
- &fType));
+ &this->type()));
}
String description() const override {
@@ -73,7 +73,7 @@
private:
IndexExpression(std::unique_ptr<Expression> base, std::unique_ptr<Expression> index,
const Type* type)
- : INHERITED(base->fOffset, Kind::kIndex, *type)
+ : INHERITED(base->fOffset, Kind::kIndex, type)
, fBase(std::move(base))
, fIndex(std::move(index)) {}
};
diff --git a/src/sksl/ir/SkSLIntLiteral.h b/src/sksl/ir/SkSLIntLiteral.h
index 70b92e6..1ec16d5 100644
--- a/src/sksl/ir/SkSLIntLiteral.h
+++ b/src/sksl/ir/SkSLIntLiteral.h
@@ -22,11 +22,11 @@
// 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
IntLiteral(const Context& context, int offset, int64_t value)
- : INHERITED(offset, kExpressionKind, *context.fInt_Type)
+ : INHERITED(offset, kExpressionKind, context.fInt_Type.get())
, fValue(value) {}
IntLiteral(int offset, int64_t value, const Type* type = nullptr)
- : INHERITED(offset, kExpressionKind, *type)
+ : INHERITED(offset, kExpressionKind, type)
, fValue(value) {}
String description() const override {
@@ -58,7 +58,7 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new IntLiteral(fOffset, fValue, &fType));
+ return std::unique_ptr<Expression>(new IntLiteral(fOffset, fValue, &this->type()));
}
const int64_t fValue;
diff --git a/src/sksl/ir/SkSLInterfaceBlock.h b/src/sksl/ir/SkSLInterfaceBlock.h
index 41dbd8f..d8f6415 100644
--- a/src/sksl/ir/SkSLInterfaceBlock.h
+++ b/src/sksl/ir/SkSLInterfaceBlock.h
@@ -50,7 +50,7 @@
String description() const override {
String result = fVariable.fModifiers.description() + fTypeName + " {\n";
- const Type* structType = &fVariable.fType;
+ const Type* structType = &fVariable.type();
while (structType->typeKind() == Type::TypeKind::kArray) {
structType = &structType->componentType();
}
diff --git a/src/sksl/ir/SkSLNullLiteral.h b/src/sksl/ir/SkSLNullLiteral.h
index 57b9010..2754ec3 100644
--- a/src/sksl/ir/SkSLNullLiteral.h
+++ b/src/sksl/ir/SkSLNullLiteral.h
@@ -20,9 +20,9 @@
static constexpr Kind kExpressionKind = Kind::kNullLiteral;
NullLiteral(const Context& context, int offset)
- : INHERITED(offset, kExpressionKind, *context.fNull_Type) {}
+ : INHERITED(offset, kExpressionKind, context.fNull_Type.get()) {}
- NullLiteral(int offset, const Type& type)
+ NullLiteral(int offset, const Type* type)
: INHERITED(offset, kExpressionKind, type) {}
String description() const override {
@@ -42,7 +42,7 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new NullLiteral(fOffset, fType));
+ return std::unique_ptr<Expression>(new NullLiteral(fOffset, &this->type()));
}
using INHERITED = Expression;
diff --git a/src/sksl/ir/SkSLPostfixExpression.h b/src/sksl/ir/SkSLPostfixExpression.h
index b635013..6364fa3 100644
--- a/src/sksl/ir/SkSLPostfixExpression.h
+++ b/src/sksl/ir/SkSLPostfixExpression.h
@@ -21,7 +21,7 @@
static constexpr Kind kExpressionKind = Kind::kPostfix;
PostfixExpression(std::unique_ptr<Expression> operand, Token::Kind op)
- : INHERITED(operand->fOffset, kExpressionKind, operand->fType)
+ : INHERITED(operand->fOffset, kExpressionKind, &operand->type())
, fOperand(std::move(operand))
, fOperator(op) {}
diff --git a/src/sksl/ir/SkSLPrefixExpression.h b/src/sksl/ir/SkSLPrefixExpression.h
index c92b7ca..8bc72b7 100644
--- a/src/sksl/ir/SkSLPrefixExpression.h
+++ b/src/sksl/ir/SkSLPrefixExpression.h
@@ -23,7 +23,7 @@
static constexpr Kind kExpressionKind = Kind::kPrefix;
PrefixExpression(Token::Kind op, std::unique_ptr<Expression> operand)
- : INHERITED(operand->fOffset, kExpressionKind, operand->fType)
+ : INHERITED(operand->fOffset, kExpressionKind, &operand->type())
, fOperand(std::move(operand))
, fOperator(op) {}
diff --git a/src/sksl/ir/SkSLSetting.h b/src/sksl/ir/SkSLSetting.h
index 9b8d528..81eb5a7 100644
--- a/src/sksl/ir/SkSLSetting.h
+++ b/src/sksl/ir/SkSLSetting.h
@@ -21,7 +21,7 @@
static constexpr Kind kExpressionKind = Kind::kSetting;
Setting(int offset, String name, std::unique_ptr<Expression> value)
- : INHERITED(offset, kExpressionKind, value->fType)
+ : INHERITED(offset, kExpressionKind, &value->type())
, fName(std::move(name))
, fValue(std::move(value)) {
SkASSERT(fValue->isCompileTimeConstant());
diff --git a/src/sksl/ir/SkSLSwizzle.h b/src/sksl/ir/SkSLSwizzle.h
index bace1e5..879e7c4 100644
--- a/src/sksl/ir/SkSLSwizzle.h
+++ b/src/sksl/ir/SkSLSwizzle.h
@@ -28,7 +28,7 @@
* swizzle with more components than the source vector, as in 'float2(1).xxxx'.
*/
static const Type& get_type(const Context& context, Expression& value, size_t count) {
- const Type& base = value.fType.componentType();
+ const Type& base = value.type().componentType();
if (count == 1) {
return base;
}
@@ -90,7 +90,7 @@
#ifdef SK_DEBUG
ABORT("cannot swizzle %s\n", value.description().c_str());
#endif
- return value.fType;
+ return value.type();
}
/**
@@ -100,7 +100,7 @@
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()))
+ : INHERITED(base->fOffset, kExpressionKind, &get_type(context, *base, components.size()))
, fBase(std::move(base))
, fComponents(std::move(components)) {
SkASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);
@@ -112,12 +112,13 @@
Constructor& constructor = static_cast<Constructor&>(*fBase);
if (constructor.isCompileTimeConstant()) {
// we're swizzling a constant vector, e.g. float4(1).x. Simplify it.
- if (fType.isInteger()) {
+ const Type& type = this->type();
+ if (type.isInteger()) {
SkASSERT(fComponents.size() == 1);
int64_t value = constructor.getIVecComponent(fComponents[0]);
return std::make_unique<IntLiteral>(irGenerator.fContext, constructor.fOffset,
value);
- } else if (fType.isFloat()) {
+ } else if (type.isFloat()) {
SkASSERT(fComponents.size() == 1);
double value = constructor.getFVecComponent(fComponents[0]);
return std::make_unique<FloatLiteral>(irGenerator.fContext, constructor.fOffset,
@@ -133,7 +134,7 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new Swizzle(fType, fBase->clone(), fComponents));
+ return std::unique_ptr<Expression>(new Swizzle(&this->type(), fBase->clone(), fComponents));
}
String description() const override {
@@ -150,7 +151,7 @@
using INHERITED = Expression;
private:
- Swizzle(const Type& type, std::unique_ptr<Expression> base, std::vector<int> components)
+ Swizzle(const Type* type, std::unique_ptr<Expression> base, std::vector<int> components)
: INHERITED(base->fOffset, kExpressionKind, type)
, fBase(std::move(base))
, fComponents(std::move(components)) {
diff --git a/src/sksl/ir/SkSLSymbol.h b/src/sksl/ir/SkSLSymbol.h
index 9f400a8..1decc00 100644
--- a/src/sksl/ir/SkSLSymbol.h
+++ b/src/sksl/ir/SkSLSymbol.h
@@ -29,8 +29,8 @@
kLast = kVariable
};
- Symbol(int offset, Kind kind, StringFragment name)
- : INHERITED(offset, (int) kind)
+ Symbol(int offset, Kind kind, StringFragment name, const Type* type = nullptr)
+ : INHERITED(offset, (int) kind, type)
, fName(name) {
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
diff --git a/src/sksl/ir/SkSLTernaryExpression.h b/src/sksl/ir/SkSLTernaryExpression.h
index cf2faac..f590bf8 100644
--- a/src/sksl/ir/SkSLTernaryExpression.h
+++ b/src/sksl/ir/SkSLTernaryExpression.h
@@ -21,11 +21,11 @@
TernaryExpression(int offset, std::unique_ptr<Expression> test,
std::unique_ptr<Expression> ifTrue, std::unique_ptr<Expression> ifFalse)
- : INHERITED(offset, kExpressionKind, ifTrue->fType)
+ : INHERITED(offset, kExpressionKind, &ifTrue->type())
, fTest(std::move(test))
, fIfTrue(std::move(ifTrue))
, fIfFalse(std::move(ifFalse)) {
- SkASSERT(fIfTrue->fType == fIfFalse->fType);
+ SkASSERT(fIfTrue->type() == fIfFalse->type());
}
bool hasProperty(Property property) const override {
diff --git a/src/sksl/ir/SkSLTypeReference.h b/src/sksl/ir/SkSLTypeReference.h
index 7efb49e..4f738d8 100644
--- a/src/sksl/ir/SkSLTypeReference.h
+++ b/src/sksl/ir/SkSLTypeReference.h
@@ -21,7 +21,7 @@
static constexpr Kind kExpressionKind = Kind::kTypeReference;
TypeReference(const Context& context, int offset, const Type* value)
- : INHERITED(offset, kExpressionKind, *context.fInvalid_Type)
+ : INHERITED(offset, kExpressionKind, context.fInvalid_Type.get())
, fValue(*value) {}
bool hasProperty(Property property) const override {
@@ -33,7 +33,7 @@
}
std::unique_ptr<Expression> clone() const override {
- return std::unique_ptr<Expression>(new TypeReference(fOffset, fValue, &fType));
+ return std::unique_ptr<Expression>(new TypeReference(fOffset, fValue, &this->type()));
}
const Type& fValue;
@@ -42,7 +42,7 @@
private:
TypeReference(int offset, const Type& value, const Type* type)
- : INHERITED(offset, kExpressionKind, *type)
+ : INHERITED(offset, kExpressionKind, type)
, fValue(value) {}
};
diff --git a/src/sksl/ir/SkSLVarDeclarations.h b/src/sksl/ir/SkSLVarDeclarations.h
index 13c02f7..8a94441 100644
--- a/src/sksl/ir/SkSLVarDeclarations.h
+++ b/src/sksl/ir/SkSLVarDeclarations.h
@@ -45,7 +45,7 @@
}
String description() const override {
- String result = fVar->fModifiers.description() + fVar->fType.name() + " " + fVar->fName;
+ String result = fVar->fModifiers.description() + fVar->type().name() + " " + fVar->fName;
for (const auto& size : fSizes) {
if (size) {
result += "[" + size->description() + "]";
diff --git a/src/sksl/ir/SkSLVariable.h b/src/sksl/ir/SkSLVariable.h
index e822aa8..033c9eb 100644
--- a/src/sksl/ir/SkSLVariable.h
+++ b/src/sksl/ir/SkSLVariable.h
@@ -32,11 +32,10 @@
kParameter_Storage
};
- Variable(int offset, Modifiers modifiers, StringFragment name, const Type& type,
+ Variable(int offset, Modifiers modifiers, StringFragment name, const Type* type,
Storage storage, Expression* initialValue = nullptr)
- : INHERITED(offset, kSymbolKind, name)
+ : INHERITED(offset, kSymbolKind, name, type)
, fModifiers(modifiers)
- , fType(type)
, fStorage(storage)
, fInitialValue(initialValue)
, fReadCount(0)
@@ -51,7 +50,7 @@
}
String description() const override {
- return fModifiers.description() + fType.fName + " " + fName;
+ return fModifiers.description() + this->type().fName + " " + fName;
}
bool dead() const {
@@ -66,7 +65,6 @@
}
mutable Modifiers fModifiers;
- const Type& fType;
const Storage fStorage;
const Expression* fInitialValue = nullptr;
diff --git a/src/sksl/ir/SkSLVariableReference.cpp b/src/sksl/ir/SkSLVariableReference.cpp
index 7bbff25..d1544ac 100644
--- a/src/sksl/ir/SkSLVariableReference.cpp
+++ b/src/sksl/ir/SkSLVariableReference.cpp
@@ -15,7 +15,7 @@
namespace SkSL {
VariableReference::VariableReference(int offset, const Variable& variable, RefKind refKind)
-: INHERITED(offset, kExpressionKind, variable.fType)
+: INHERITED(offset, kExpressionKind, &variable.type())
, fVariable(variable)
, fRefKind(refKind) {
if (refKind != kRead_RefKind) {
@@ -74,7 +74,7 @@
for (const auto& arg : c->fArguments) {
args.push_back(copy_constant(irGenerator, arg.get()));
}
- return std::unique_ptr<Expression>(new Constructor(-1, c->fType,
+ return std::unique_ptr<Expression>(new Constructor(-1, &c->type(),
std::move(args)));
}
case Expression::Kind::kSetting: {
@@ -95,7 +95,7 @@
}
if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue &&
fVariable.fInitialValue->isCompileTimeConstant() &&
- fType.typeKind() != Type::TypeKind::kArray) {
+ this->type().typeKind() != Type::TypeKind::kArray) {
return copy_constant(irGenerator, fVariable.fInitialValue);
}
auto exprIter = definitions.find(&fVariable);