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:
parent
2eabdf5b07
commit
403a363c2e
@ -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); }
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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 + "'");
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user