Migrate additional casts to as<T>.

These changes shook out a few const-correctness issues and make me
wonder about constness within the symbol table. Please check the
review notes!

Change-Id: Ic204a7b639caab08b9de92fe8d1d029b0ffb6582
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/312082
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-08-20 12:11:48 -04:00 committed by Skia Commit-Bot
parent 2eabdf5b07
commit 403a363c2e
6 changed files with 88 additions and 92 deletions

View File

@ -87,7 +87,7 @@ protected:
bool visitExpression(const Expression& e) override {
// Looking for sample(fp, inColor?, ...)
if (e.fKind == Expression::kFunctionCall_Kind) {
const FunctionCall& fc = (const FunctionCall&) e;
const FunctionCall& fc = e.as<FunctionCall>();
if (is_sample_call_to_fp(fc, fFP)) {
// Determine the type of call at this site, and merge it with the accumulated state
const Expression* lastArg = fc.fArguments.back().get();
@ -136,7 +136,7 @@ public:
bool visitExpression(const Expression& e) override {
if (e.fKind == Expression::kVariableReference_Kind) {
const VariableReference& var = (const VariableReference&) e;
const VariableReference& var = e.as<VariableReference>();
return var.fVariable.fModifiers.fLayout.fBuiltin == fBuiltin;
}
return this->INHERITED::visitExpression(e);
@ -202,37 +202,37 @@ bool ProgramVisitor::visitExpression(const Expression& e) {
// Leaf expressions return false
return false;
case Expression::kBinary_Kind: {
const BinaryExpression& b = (const BinaryExpression&) e;
const BinaryExpression& b = e.as<BinaryExpression>();
return this->visitExpression(*b.fLeft) || this->visitExpression(*b.fRight); }
case Expression::kConstructor_Kind: {
const Constructor& c = (const Constructor&) e;
const Constructor& c = e.as<Constructor>();
for (const auto& arg : c.fArguments) {
if (this->visitExpression(*arg)) { return true; }
}
return false; }
case Expression::kExternalFunctionCall_Kind: {
const ExternalFunctionCall& c = (const ExternalFunctionCall&) e;
const ExternalFunctionCall& c = e.as<ExternalFunctionCall>();
for (const auto& arg : c.fArguments) {
if (this->visitExpression(*arg)) { return true; }
}
return false; }
case Expression::kFunctionCall_Kind: {
const FunctionCall& c = (const FunctionCall&) e;
const FunctionCall& c = e.as<FunctionCall>();
for (const auto& arg : c.fArguments) {
if (this->visitExpression(*arg)) { return true; }
}
return false; }
case Expression::kIndex_Kind:{
const IndexExpression& i = (const IndexExpression&) e;
const IndexExpression& i = e.as<IndexExpression>();
return this->visitExpression(*i.fBase) || this->visitExpression(*i.fIndex); }
case Expression::kPostfix_Kind:
return this->visitExpression(*((const PostfixExpression&) e).fOperand);
return this->visitExpression(*e.as<PostfixExpression>().fOperand);
case Expression::kPrefix_Kind:
return this->visitExpression(*((const PrefixExpression&) e).fOperand);
return this->visitExpression(*e.as<PrefixExpression>().fOperand);
case Expression::kSwizzle_Kind:
return this->visitExpression(*((const Swizzle&) e).fBase);
return this->visitExpression(*e.as<Swizzle>().fBase);
case Expression::kTernary_Kind: {
const TernaryExpression& t = (const TernaryExpression&) e;
const TernaryExpression& t = e.as<TernaryExpression>();
return this->visitExpression(*t.fTest) ||
this->visitExpression(*t.fIfTrue) ||
this->visitExpression(*t.fIfFalse); }

View File

@ -211,7 +211,7 @@ std::unique_ptr<ByteCodeFunction> ByteCodeGenerator::writeFunction(const Functio
// Otherwise, return -1.
static int expression_as_builtin(const Expression& e) {
if (e.fKind == Expression::kVariableReference_Kind) {
const Variable& var(((VariableReference&)e).fVariable);
const Variable& var(e.as<VariableReference>().fVariable);
if (var.fStorage == Variable::kGlobal_Storage) {
return var.fModifiers.fLayout.fBuiltin;
}
@ -450,9 +450,9 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
int offset = 0;
for (const auto& e : fProgram) {
if (e.fKind == ProgramElement::kVar_Kind) {
VarDeclarations& decl = (VarDeclarations&) e;
const VarDeclarations& decl = e.as<VarDeclarations>();
for (const auto& v : decl.fVars) {
const Variable* declVar = ((VarDeclaration&) *v).fVar;
const Variable* declVar = v->as<VarDeclaration>().fVar;
if (declVar->fType != *fContext.fFragmentProcessor_Type) {
continue;
}
@ -480,9 +480,9 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
bool isUniform = is_uniform(var);
for (const auto& e : fProgram) {
if (e.fKind == ProgramElement::kVar_Kind) {
VarDeclarations& decl = (VarDeclarations&) e;
const VarDeclarations& decl = e.as<VarDeclarations>();
for (const auto& v : decl.fVars) {
const Variable* declVar = ((VarDeclaration&) *v).fVar;
const Variable* declVar = v->as<VarDeclaration>().fVar;
if (declVar->fModifiers.fLayout.fBuiltin >= 0 || is_in(*declVar)) {
continue;
}
@ -509,7 +509,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& expr) {
switch (expr.fKind) {
case Expression::kFieldAccess_Kind: {
const FieldAccess& f = (const FieldAccess&)expr;
const FieldAccess& f = expr.as<FieldAccess>();
Location baseLoc = this->getLocation(*f.fBase);
int offset = 0;
for (int i = 0; i < f.fFieldIndex; ++i) {
@ -527,7 +527,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& exp
}
}
case Expression::kIndex_Kind: {
const IndexExpression& i = (const IndexExpression&)expr;
const IndexExpression& i = expr.as<IndexExpression>();
int stride = SlotCount(i.fType);
int length = i.fBase->fType.columns();
SkASSERT(length <= 255);
@ -583,7 +583,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& exp
return baseLoc.makeOnStack();
}
case Expression::kSwizzle_Kind: {
const Swizzle& s = (const Swizzle&)expr;
const Swizzle& s = expr.as<Swizzle>();
SkASSERT(swizzle_is_simple(s));
Location baseLoc = this->getLocation(*s.fBase);
int offset = s.fComponents[0];
@ -599,7 +599,7 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Expression& exp
}
}
case Expression::kVariableReference_Kind: {
const Variable& var = ((const VariableReference&)expr).fVariable;
const Variable& var = expr.as<VariableReference>().fVariable;
return this->getLocation(var);
}
default:
@ -1741,7 +1741,7 @@ void ByteCodeGenerator::writeSwitchStatement(const SwitchStatement& r) {
void ByteCodeGenerator::writeVarDeclarations(const VarDeclarations& v) {
for (const auto& declStatement : v.fVars) {
const VarDeclaration& decl = (VarDeclaration&) *declStatement;
const VarDeclaration& decl = declStatement->as<VarDeclaration>();
// we need to grab the location even if we don't use it, to ensure it has been allocated
Location location = this->getLocation(*decl.fVar);
if (decl.fValue) {

View File

@ -878,11 +878,11 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
break;
}
case Expression::kTernary_Kind: {
TernaryExpression* t = (TernaryExpression*) expr;
TernaryExpression* t = &expr->as<TernaryExpression>();
if (t->fTest->fKind == Expression::kBoolLiteral_Kind) {
// ternary has a constant test, replace it with either the true or
// false branch
if (((BoolLiteral&) *t->fTest).fValue) {
if (t->fTest->as<BoolLiteral>().fValue) {
(*iter)->setExpression(std::move(t->fIfTrue));
} else {
(*iter)->setExpression(std::move(t->fIfFalse));
@ -893,7 +893,7 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
break;
}
case Expression::kBinary_Kind: {
BinaryExpression* bin = (BinaryExpression*) expr;
BinaryExpression* bin = &expr->as<BinaryExpression>();
if (dead_assignment(*bin)) {
delete_left(&b, iter, outUpdated, outNeedsRescan);
break;
@ -1059,7 +1059,7 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
break;
}
case Expression::kSwizzle_Kind: {
Swizzle& s = (Swizzle&) *expr;
Swizzle& s = expr->as<Swizzle>();
// detect identity swizzles like foo.rgba
if ((int) s.fComponents.size() == s.fBase->fType.columns()) {
bool identity = true;
@ -1659,7 +1659,7 @@ bool Compiler::optimize(Program& program) {
if ((*iter)->fKind == ProgramElement::kVar_Kind) {
VarDeclarations& vars = (*iter)->as<VarDeclarations>();
for (auto varIter = vars.fVars.begin(); varIter != vars.fVars.end();) {
const Variable& var = *((VarDeclaration&) **varIter).fVar;
const Variable& var = *(*varIter)->as<VarDeclaration>().fVar;
if (var.dead()) {
varIter = vars.fVars.erase(varIter);
} else {

View File

@ -181,7 +181,7 @@ void IRGenerator::start(const Program::Settings* settings,
if (inherited) {
for (const auto& e : *inherited) {
if (e->fKind == ProgramElement::kInterfaceBlock_Kind) {
InterfaceBlock& intf = (InterfaceBlock&) *e;
InterfaceBlock& intf = e->as<InterfaceBlock>();
if (intf.fVariable.fName == Compiler::PERVERTEX_NAME) {
SkASSERT(!fSkPerVertex);
fSkPerVertex = &intf.fVariable;
@ -233,9 +233,9 @@ std::unique_ptr<Statement> IRGenerator::convertSingleStatement(const ASTNode& st
std::unique_ptr<Statement> result = this->convertExpressionStatement(statement);
if (fRTAdjust && Program::kGeometry_Kind == fKind) {
SkASSERT(result->fKind == Statement::kExpression_Kind);
Expression& expr = *((ExpressionStatement&) *result).fExpression;
Expression& expr = *result->as<ExpressionStatement>().fExpression;
if (expr.fKind == Expression::kFunctionCall_Kind) {
FunctionCall& fc = (FunctionCall&) expr;
FunctionCall& fc = expr.as<FunctionCall>();
if (fc.fFunction.fBuiltin && fc.fFunction.fName == "EmitVertex") {
std::vector<std::unique_ptr<Statement>> statements;
statements.push_back(getNormalizeSkPositionCode());
@ -519,7 +519,7 @@ std::unique_ptr<Statement> IRGenerator::convertIf(const ASTNode& n) {
}
if (test->fKind == Expression::kBoolLiteral_Kind) {
// static boolean value, fold down to a single branch
if (((BoolLiteral&) *test).fValue) {
if (test->as<BoolLiteral>().fValue) {
return ifTrue;
} else if (ifFalse) {
return ifFalse;
@ -1081,7 +1081,8 @@ void IRGenerator::convertFunction(const ASTNode& f) {
body = this->applyInvocationIDWorkaround(std::move(body));
}
// conservatively assume all user-defined functions have side effects
((Modifiers&) decl->fModifiers).fFlags |= Modifiers::kHasSideEffects_Flag;
// TODO(skbug.com/10589): thread-unsafe mutation of object in symbol table
const_cast<Modifiers&>(decl->fModifiers).fFlags |= Modifiers::kHasSideEffects_Flag;
if (Program::kVertex_Kind == fKind && fd.fName == "main" && fRTAdjust) {
body->fStatements.insert(body->fStatements.end(), this->getNormalizeSkPositionCode());
}
@ -1111,7 +1112,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
return nullptr;
}
for (const auto& stmt : decl->fVars) {
VarDeclaration& vd = (VarDeclaration&) *stmt;
VarDeclaration& vd = stmt->as<VarDeclaration>();
if (haveRuntimeArray) {
fErrors.error(decl->fOffset,
"only the last entry in an interface block may be a runtime-sized "
@ -1636,7 +1637,7 @@ static std::unique_ptr<Expression> short_circuit_boolean(const Context& context,
Token::Kind op,
const Expression& right) {
SkASSERT(left.fKind == Expression::kBoolLiteral_Kind);
bool leftVal = ((BoolLiteral&) left).fValue;
bool leftVal = left.as<BoolLiteral>().fValue;
if (op == Token::Kind::TK_LOGICALAND) {
// (true && expr) -> (expr) and (false && expr) -> (false)
return leftVal ? right.clone()
@ -1679,8 +1680,8 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
// types, which will let us be more intelligent about this.
if (left.fKind == Expression::kBoolLiteral_Kind &&
right.fKind == Expression::kBoolLiteral_Kind) {
bool leftVal = ((BoolLiteral&) left).fValue;
bool rightVal = ((BoolLiteral&) right).fValue;
bool leftVal = left.as<BoolLiteral>().fValue;
bool rightVal = right.as<BoolLiteral>().fValue;
bool result;
switch (op) {
case Token::Kind::TK_LOGICALAND: result = leftVal && rightVal; break;
@ -1928,7 +1929,7 @@ std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(const ASTNode&
}
if (test->fKind == Expression::kBoolLiteral_Kind) {
// static boolean test, just return one of the branches
if (((BoolLiteral&) *test).fValue) {
if (test->as<BoolLiteral>().fValue) {
return ifTrue;
} else {
return ifFalse;
@ -1952,7 +1953,7 @@ std::unique_ptr<Expression> IRGenerator::inlineExpression(
};
switch (expression.fKind) {
case Expression::kBinary_Kind: {
const BinaryExpression& b = (const BinaryExpression&) expression;
const BinaryExpression& b = expression.as<BinaryExpression>();
return std::unique_ptr<Expression>(new BinaryExpression(offset,
expr(b.fLeft),
b.fOperator,
@ -1965,7 +1966,7 @@ std::unique_ptr<Expression> IRGenerator::inlineExpression(
case Expression::kNullLiteral_Kind:
return expression.clone();
case Expression::kConstructor_Kind: {
const Constructor& c = (const Constructor&) expression;
const Constructor& c = expression.as<Constructor>();
std::vector<std::unique_ptr<Expression>> args;
for (const auto& arg : c.fArguments) {
args.push_back(expr(arg));
@ -1973,7 +1974,7 @@ std::unique_ptr<Expression> IRGenerator::inlineExpression(
return std::unique_ptr<Expression>(new Constructor(offset, c.fType, std::move(args)));
}
case Expression::kExternalFunctionCall_Kind: {
const ExternalFunctionCall& e = (const ExternalFunctionCall&) expression;
const ExternalFunctionCall& e = expression.as<ExternalFunctionCall>();
std::vector<std::unique_ptr<Expression>> args;
for (const auto& arg : e.fArguments) {
args.push_back(expr(arg));
@ -1985,12 +1986,12 @@ std::unique_ptr<Expression> IRGenerator::inlineExpression(
case Expression::kExternalValue_Kind:
return expression.clone();
case Expression::kFieldAccess_Kind: {
const FieldAccess& f = (const FieldAccess&) expression;
const FieldAccess& f = expression.as<FieldAccess>();
return std::unique_ptr<Expression>(new FieldAccess(expr(f.fBase), f.fFieldIndex,
f.fOwnerKind));
}
case Expression::kFunctionCall_Kind: {
const FunctionCall& c = (const FunctionCall&) expression;
const FunctionCall& c = expression.as<FunctionCall>();
std::vector<std::unique_ptr<Expression>> args;
for (const auto& arg : c.fArguments) {
args.push_back(expr(arg));
@ -1999,33 +2000,33 @@ std::unique_ptr<Expression> IRGenerator::inlineExpression(
std::move(args)));
}
case Expression::kIndex_Kind: {
const IndexExpression& idx = (const IndexExpression&) expression;
const IndexExpression& idx = expression.as<IndexExpression>();
return std::unique_ptr<Expression>(new IndexExpression(fContext, expr(idx.fBase),
expr(idx.fIndex)));
}
case Expression::kPrefix_Kind: {
const PrefixExpression& p = (const PrefixExpression&) expression;
const PrefixExpression& p = expression.as<PrefixExpression>();
return std::unique_ptr<Expression>(new PrefixExpression(p.fOperator, expr(p.fOperand)));
}
case Expression::kPostfix_Kind: {
const PostfixExpression& p = (const PostfixExpression&) expression;
const PostfixExpression& p = expression.as<PostfixExpression>();
return std::unique_ptr<Expression>(new PostfixExpression(expr(p.fOperand),
p.fOperator));
}
case Expression::kSetting_Kind:
return expression.clone();
case Expression::kSwizzle_Kind: {
const Swizzle& s = (const Swizzle&) expression;
const Swizzle& s = expression.as<Swizzle>();
return std::unique_ptr<Expression>(new Swizzle(fContext, expr(s.fBase), s.fComponents));
}
case Expression::kTernary_Kind: {
const TernaryExpression& t = (const TernaryExpression&) expression;
const TernaryExpression& t = expression.as<TernaryExpression>();
return std::unique_ptr<Expression>(new TernaryExpression(offset, expr(t.fTest),
expr(t.fIfTrue),
expr(t.fIfFalse)));
}
case Expression::kVariableReference_Kind: {
const VariableReference& v = (const VariableReference&) expression;
const VariableReference& v = expression.as<VariableReference>();
auto found = varMap->find(&v.fVariable);
if (found != varMap->end()) {
return std::unique_ptr<Expression>(new VariableReference(offset,
@ -2332,8 +2333,7 @@ std::unique_ptr<Expression> IRGenerator::inlineCall(
fExtraStatements.emplace_back(new VarDeclarationsStatement(
std::make_unique<VarDeclarations>(offset, &argVar->fType, std::move(vars))));
}
SkASSERT(function.fBody->fKind == Statement::kBlock_Kind);
const Block& body = (Block&) *function.fBody;
const Block& body = function.fBody->as<Block>();
bool hasEarlyReturn = has_early_return(function);
std::vector<std::unique_ptr<Statement>> inlined;
for (const auto& s : body.fStatements) {
@ -2379,7 +2379,7 @@ void IRGenerator::copyIntrinsicIfNeeded(const FunctionDeclaration& function) {
auto found = fIntrinsics->find(function.description());
if (found != fIntrinsics->end() && !found->second.second) {
found->second.second = true;
FunctionDefinition& original = ((FunctionDefinition&) *found->second.first);
FunctionDefinition& original = found->second.first->as<FunctionDefinition>();
for (const FunctionDeclaration* f : original.fReferencedIntrinsics) {
this->copyIntrinsicIfNeeded(*f);
}
@ -2500,7 +2500,7 @@ std::unique_ptr<Expression> IRGenerator::call(int offset,
switch (functionValue->fKind) {
case Expression::kTypeReference_Kind:
return this->convertConstructor(offset,
((TypeReference&) *functionValue).fValue,
functionValue->as<TypeReference>().fValue,
std::move(arguments));
case Expression::kExternalValue_Kind: {
const ExternalValue* v = functionValue->as<ExternalValueReference>().fValue;
@ -2754,8 +2754,8 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
return nullptr;
}
if (base->fKind == Expression::kBoolLiteral_Kind) {
return std::unique_ptr<Expression>(new BoolLiteral(fContext, base->fOffset,
!((BoolLiteral&) *base).fValue));
return std::unique_ptr<Expression>(
new BoolLiteral(fContext, base->fOffset, !base->as<BoolLiteral>().fValue));
}
break;
case Token::Kind::TK_BITWISENOT:
@ -2777,7 +2777,7 @@ std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
const ASTNode& index) {
if (base->fKind == Expression::kTypeReference_Kind) {
if (index.fKind == ASTNode::Kind::kInt) {
const Type& oldType = ((TypeReference&) *base).fValue;
const Type& oldType = base->as<TypeReference>().fValue;
SKSL_INT size = index.getInt();
const Type* newType = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Type>(oldType.name() + "[" + to_string(size) + "]",
@ -3012,17 +3012,15 @@ std::unique_ptr<Expression> IRGenerator::findEnumRef(
StringFragment field,
std::vector<std::unique_ptr<ProgramElement>>& elements) {
for (const auto& e : elements) {
if (e->fKind == ProgramElement::kEnum_Kind && type.name() == ((Enum&) *e).fTypeName) {
if (e->fKind == ProgramElement::kEnum_Kind && type.name() == e->as<Enum>().fTypeName) {
std::shared_ptr<SymbolTable> old = fSymbolTable;
fSymbolTable = ((Enum&) *e).fSymbols;
fSymbolTable = e->as<Enum>().fSymbols;
std::unique_ptr<Expression> result = convertIdentifier(ASTNode(&fFile->fNodes, offset,
ASTNode::Kind::kIdentifier,
field));
if (result) {
SkASSERT(result->fKind == Expression::kVariableReference_Kind);
const Variable& v = ((VariableReference&) *result).fVariable;
const Variable& v = result->as<VariableReference>().fVariable;
SkASSERT(v.fInitialValue);
SkASSERT(v.fInitialValue->fKind == Expression::kIntLiteral_Kind);
result = std::make_unique<IntLiteral>(
offset, v.fInitialValue->as<IntLiteral>().fValue, &type);
}
@ -3063,7 +3061,7 @@ std::unique_ptr<Expression> IRGenerator::convertIndexExpression(const ASTNode& i
if (iter != index.end()) {
return this->convertIndex(std::move(base), *(iter++));
} else if (base->fKind == Expression::kTypeReference_Kind) {
const Type& oldType = ((TypeReference&) *base).fValue;
const Type& oldType = base->as<TypeReference>().fValue;
const Type* newType = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Type>(
oldType.name() + "[]", Type::kArray_Kind, oldType, /*columns=*/-1));
return std::unique_ptr<Expression>(new TypeReference(fContext, base->fOffset,
@ -3101,7 +3099,7 @@ std::unique_ptr<Expression> IRGenerator::convertFieldExpression(const ASTNode& f
return this->getCap(fieldNode.fOffset, field);
}
if (base->fKind == Expression::kTypeReference_Kind) {
return this->convertTypeField(base->fOffset, ((TypeReference&) *base).fValue,
return this->convertTypeField(base->fOffset, base->as<TypeReference>().fValue,
field);
}
if (base->fKind == Expression::kExternalValue_Kind) {
@ -3166,32 +3164,32 @@ bool IRGenerator::checkSwizzleWrite(const Swizzle& swizzle) {
return true;
}
bool IRGenerator::setRefKind(const Expression& expr, VariableReference::RefKind kind) {
bool IRGenerator::setRefKind(Expression& expr, VariableReference::RefKind kind) {
switch (expr.fKind) {
case Expression::kVariableReference_Kind: {
const Variable& var = ((VariableReference&) expr).fVariable;
const Variable& var = expr.as<VariableReference>().fVariable;
if (var.fModifiers.fFlags &
(Modifiers::kConst_Flag | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag)) {
fErrors.error(expr.fOffset, "cannot modify immutable variable '" + var.fName + "'");
return false;
}
((VariableReference&) expr).setRefKind(kind);
expr.as<VariableReference>().setRefKind(kind);
return true;
}
case Expression::kFieldAccess_Kind:
return this->setRefKind(*((FieldAccess&) expr).fBase, kind);
return this->setRefKind(*expr.as<FieldAccess>().fBase, kind);
case Expression::kSwizzle_Kind: {
const Swizzle& swizzle = (Swizzle&) expr;
const Swizzle& swizzle = expr.as<Swizzle>();
return this->checkSwizzleWrite(swizzle) && this->setRefKind(*swizzle.fBase, kind);
}
case Expression::kIndex_Kind:
return this->setRefKind(*((IndexExpression&) expr).fBase, kind);
return this->setRefKind(*expr.as<IndexExpression>().fBase, kind);
case Expression::kTernary_Kind: {
TernaryExpression& t = (TernaryExpression&) expr;
const TernaryExpression& t = expr.as<TernaryExpression>();
return this->setRefKind(*t.fIfTrue, kind) && this->setRefKind(*t.fIfFalse, kind);
}
case Expression::kExternalValue_Kind: {
const ExternalValue& v = *((ExternalValueReference&) expr).fValue;
const ExternalValue& v = *expr.as<ExternalValueReference>().fValue;
if (!v.canWrite()) {
fErrors.error(expr.fOffset,
"cannot modify immutable external value '" + v.fName + "'");

View File

@ -166,7 +166,7 @@ private:
std::unique_ptr<Statement> getNormalizeSkPositionCode();
void checkValid(const Expression& expr);
bool setRefKind(const Expression& expr, VariableReference::RefKind kind);
bool setRefKind(Expression& expr, VariableReference::RefKind kind);
bool getConstantInt(const Expression& value, int64_t* out);
bool checkSwizzleWrite(const Swizzle& swizzle);
void copyIntrinsicIfNeeded(const FunctionDeclaration& function);

View File

@ -14,14 +14,12 @@
namespace SkSL {
PipelineStageCodeGenerator::PipelineStageCodeGenerator(
const Context* context,
const Program* program,
ErrorReporter* errors,
OutputStream* out,
PipelineStageArgs* outArgs)
: INHERITED(context, program, errors, out)
, fArgs(outArgs) {}
PipelineStageCodeGenerator::PipelineStageCodeGenerator(const Context* context,
const Program* program,
ErrorReporter* errors,
OutputStream* out,
PipelineStageArgs* outArgs)
: INHERITED(context, program, errors, out), fArgs(outArgs) {}
void PipelineStageCodeGenerator::writeHeader() {
}
@ -45,10 +43,10 @@ void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
bool found = false;
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
const VarDeclarations& decls = (const VarDeclarations&) p;
for (const auto& raw : decls.fVars) {
VarDeclaration& decl = (VarDeclaration&) *raw;
if (decl.fVar == &((VariableReference&) *c.fArguments[0]).fVariable) {
const VarDeclarations& decls = p.as<VarDeclarations>();
for (const std::unique_ptr<Statement>& raw : decls.fVars) {
VarDeclaration& decl = raw->as<VarDeclaration>();
if (decl.fVar == &c.fArguments[0]->as<VariableReference>().fVariable) {
found = true;
} else if (decl.fVar->fType == *fContext.fFragmentProcessor_Type) {
++index;
@ -82,9 +80,9 @@ void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
INHERITED::writeFunctionCall(c);
} else {
int index = 0;
for (const auto& e : fProgram) {
for (const ProgramElement& e : fProgram) {
if (e.fKind == ProgramElement::kFunction_Kind) {
if (&((FunctionDefinition&) e).fDeclaration == &c.fFunction) {
if (&e.as<FunctionDefinition>().fDeclaration == &c.fFunction) {
break;
}
++index;
@ -95,7 +93,7 @@ void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
Compiler::FormatArg(Compiler::FormatArg::Kind::kFunctionName, index));
this->write("(");
const char* separator = "";
for (const auto& arg : c.fArguments) {
for (const std::unique_ptr<Expression>& arg : c.fArguments) {
this->write(separator);
separator = ", ";
this->writeExpression(*arg, kSequence_Precedence);
@ -122,14 +120,14 @@ void PipelineStageCodeGenerator::writeVariableReference(const VariableReference&
auto varIndexByFlag = [this, &ref](uint32_t flag) {
int index = 0;
bool found = false;
for (const auto& e : fProgram) {
for (const ProgramElement& e : fProgram) {
if (found) {
break;
}
if (e.fKind == ProgramElement::Kind::kVar_Kind) {
const VarDeclarations& decls = (const VarDeclarations&) e;
const VarDeclarations& decls = e.as<VarDeclarations>();
for (const auto& decl : decls.fVars) {
const Variable& var = *((VarDeclaration&) *decl).fVar;
const Variable& var = *decl->as<VarDeclaration>().fVar;
if (&var == &ref.fVariable) {
found = true;
break;
@ -179,7 +177,7 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
StringStream buffer;
fOut = &buffer;
if (f.fDeclaration.fName == "main") {
for (const auto& s : ((Block&) *f.fBody).fStatements) {
for (const std::unique_ptr<Statement>& s : f.fBody->as<Block>().fStatements) {
this->writeStatement(*s);
this->writeLine();
}
@ -202,7 +200,7 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
}
result.fParameters.emplace_back(v->fName, paramSLType);
}
for (const auto& s : ((Block&) *f.fBody).fStatements) {
for (const std::unique_ptr<Statement>& s : f.fBody->as<Block>().fStatements) {
this->writeStatement(*s);
this->writeLine();
}
@ -218,11 +216,11 @@ void PipelineStageCodeGenerator::writeProgramElement(const ProgramElement& p) {
return;
}
if (p.fKind == ProgramElement::kVar_Kind) {
const VarDeclarations& decls = (const VarDeclarations&) p;
const VarDeclarations& decls = p.as<VarDeclarations>();
if (!decls.fVars.size()) {
return;
}
const Variable& var = *((VarDeclaration&) *decls.fVars[0]).fVar;
const Variable& var = *decls.fVars[0]->as<VarDeclaration>().fVar;
if (var.fModifiers.fFlags &
(Modifiers::kIn_Flag | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag) ||
-1 != var.fModifiers.fLayout.fBuiltin) {