Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 3dc0da6

Browse files
johnstiles-googleSkia Commit-Bot
authored andcommitted
Add as<ProgramElementSubclass> to downcast ProgramElements more safely.
The as<T>() function asserts that the ProgramElement is of the correct kind before performing the downcast, and is also generally easier to read as function calls flow naturally from left-to-right, and C-style casts don't. This CL updates several downcasts throughout SkSL to the as<T> syntax, but is not intended to exhaustively replace them all (although that would be ideal). In places where we SkASSERTed the element's fKind immediately before a cast, the assert has been removed because it would be redundant with the behavior of as<T>(). Change-Id: I89a487aeaf56e56c720479fee0c2633377a202f1 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/312020 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
1 parent f3c8f5d commit 3dc0da6

15 files changed

Lines changed: 122 additions & 92 deletions

src/sksl/SkSLAnalysis.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,14 @@ bool ProgramVisitor::visitProgramElement(const ProgramElement& pe) {
316316
// Leaf program elements just return false by default
317317
return false;
318318
case ProgramElement::kFunction_Kind:
319-
return this->visitStatement(*((const FunctionDefinition&) pe).fBody);
319+
return this->visitStatement(*pe.as<FunctionDefinition>().fBody);
320320
case ProgramElement::kInterfaceBlock_Kind:
321-
for (const auto& e : ((const InterfaceBlock&) pe).fSizes) {
321+
for (const auto& e : pe.as<InterfaceBlock>().fSizes) {
322322
if (this->visitExpression(*e)) { return true; }
323323
}
324324
return false;
325325
case ProgramElement::kVar_Kind:
326-
for (const auto& v : ((const VarDeclarations&) pe).fVars) {
326+
for (const auto& v : pe.as<VarDeclarations>().fVars) {
327327
if (this->visitStatement(*v)) { return true; }
328328
}
329329
return false;

src/sksl/SkSLByteCodeGenerator.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,19 @@ bool ByteCodeGenerator::generateCode() {
142142
for (const auto& e : fProgram) {
143143
switch (e.fKind) {
144144
case ProgramElement::kFunction_Kind: {
145-
std::unique_ptr<ByteCodeFunction> f = this->writeFunction((FunctionDefinition&) e);
145+
std::unique_ptr<ByteCodeFunction> f =
146+
this->writeFunction(e.as<FunctionDefinition>());
146147
if (!f) {
147148
return false;
148149
}
149150
fOutput->fFunctions.push_back(std::move(f));
150-
fFunctions.push_back(&(FunctionDefinition&)e);
151+
fFunctions.push_back(&e.as<FunctionDefinition>());
151152
break;
152153
}
153154
case ProgramElement::kVar_Kind: {
154-
VarDeclarations& decl = (VarDeclarations&) e;
155+
const VarDeclarations& decl = e.as<VarDeclarations>();
155156
for (const auto& v : decl.fVars) {
156-
const Variable* declVar = ((VarDeclaration&) *v).fVar;
157+
const Variable* declVar = v->as<VarDeclaration>().fVar;
157158
if (declVar->fType == *fContext.fFragmentProcessor_Type) {
158159
fOutput->fChildFPCount++;
159160
}

src/sksl/SkSLCPPCodeGenerator.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
113113
void CPPCodeGenerator::writeIndexExpression(const IndexExpression& i) {
114114
const Expression& base = *i.fBase;
115115
if (base.fKind == Expression::kVariableReference_Kind) {
116-
int builtin = ((VariableReference&) base).fVariable.fModifiers.fLayout.fBuiltin;
116+
int builtin = base.as<VariableReference>().fVariable.fModifiers.fLayout.fBuiltin;
117117
if (SK_TEXTURESAMPLERS_BUILTIN == builtin) {
118118
this->write("%s");
119119
if (i.fIndex->fKind != Expression::kIntLiteral_Kind) {
@@ -385,7 +385,7 @@ void CPPCodeGenerator::writeFieldAccess(const FieldAccess& access) {
385385
}
386386

387387
const Type::Field& field = fContext.fFragmentProcessor_Type->fields()[access.fFieldIndex];
388-
const Variable& var = ((const VariableReference&) *access.fBase).fVariable;
388+
const Variable& var = access.fBase->as<VariableReference>().fVariable;
389389
String cppAccess = String::printf("_outer.childProcessor(%d)->%s()",
390390
this->getChildFPIndex(var),
391391
String(field.fName).c_str());
@@ -405,9 +405,9 @@ int CPPCodeGenerator::getChildFPIndex(const Variable& var) const {
405405
bool found = false;
406406
for (const auto& p : fProgram) {
407407
if (ProgramElement::kVar_Kind == p.fKind) {
408-
const VarDeclarations& decls = (const VarDeclarations&) p;
408+
const VarDeclarations& decls = p.as<VarDeclarations>();
409409
for (const auto& raw : decls.fVars) {
410-
const VarDeclaration& decl = (VarDeclaration&) *raw;
410+
const VarDeclaration& decl = raw->as<VarDeclaration>();
411411
if (decl.fVar == &var) {
412412
found = true;
413413
} else if (decl.fVar->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
@@ -439,7 +439,7 @@ void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
439439
"sample()'s fragmentProcessor argument must be a variable reference\n");
440440
return;
441441
}
442-
const Variable& child = ((const VariableReference&) *c.fArguments[0]).fVariable;
442+
const Variable& child = c.fArguments[0]->as<VariableReference>().fVariable;
443443

444444
// Start a new extra emit code section so that the emitted child processor can depend on
445445
// sksl variables defined in earlier sksl code.
@@ -508,7 +508,7 @@ void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
508508
this->write(".%s");
509509
SkASSERT(c.fArguments.size() >= 1);
510510
SkASSERT(c.fArguments[0]->fKind == Expression::kVariableReference_Kind);
511-
String sampler = this->getSamplerHandle(((VariableReference&) *c.fArguments[0]).fVariable);
511+
String sampler = this->getSamplerHandle(c.fArguments[0]->as<VariableReference>().fVariable);
512512
fFormatArgs.push_back("fragBuilder->getProgramBuilder()->samplerSwizzle(" + sampler +
513513
").asString().c_str()");
514514
}
@@ -595,7 +595,7 @@ void CPPCodeGenerator::writeFunction(const FunctionDefinition& f) {
595595
fOut = &buffer;
596596
if (decl.fName == "main") {
597597
fInMain = true;
598-
for (const auto& s : ((Block&) *f.fBody).fStatements) {
598+
for (const auto& s : f.fBody->as<Block>().fStatements) {
599599
this->writeStatement(*s);
600600
this->writeLine();
601601
}
@@ -615,7 +615,7 @@ void CPPCodeGenerator::writeFunction(const FunctionDefinition& f) {
615615
}
616616
args += "};";
617617
this->addExtraEmitCodeLine(args.c_str());
618-
for (const auto& s : ((Block&) *f.fBody).fStatements) {
618+
for (const auto& s : f.fBody->as<Block>().fStatements) {
619619
this->writeStatement(*s);
620620
this->writeLine();
621621
}
@@ -650,11 +650,11 @@ void CPPCodeGenerator::writeProgramElement(const ProgramElement& p) {
650650
return;
651651
}
652652
if (p.fKind == ProgramElement::kVar_Kind) {
653-
const VarDeclarations& decls = (const VarDeclarations&) p;
653+
const VarDeclarations& decls = p.as<VarDeclarations>();
654654
if (!decls.fVars.size()) {
655655
return;
656656
}
657-
const Variable& var = *((VarDeclaration&) *decls.fVars[0]).fVar;
657+
const Variable& var = *decls.fVars[0]->as<VarDeclaration>().fVar;
658658
if (var.fModifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
659659
-1 != var.fModifiers.fLayout.fBuiltin) {
660660
return;
@@ -686,9 +686,9 @@ void CPPCodeGenerator::writeInputVars() {
686686
void CPPCodeGenerator::writePrivateVars() {
687687
for (const auto& p : fProgram) {
688688
if (ProgramElement::kVar_Kind == p.fKind) {
689-
const VarDeclarations& decls = (const VarDeclarations&) p;
689+
const VarDeclarations& decls = p.as<VarDeclarations>();
690690
for (const auto& raw : decls.fVars) {
691-
VarDeclaration& decl = (VarDeclaration&) *raw;
691+
VarDeclaration& decl = raw->as<VarDeclaration>();
692692
if (is_private(*decl.fVar)) {
693693
if (decl.fVar->fType == *fContext.fFragmentProcessor_Type) {
694694
fErrors.error(decl.fOffset,
@@ -726,9 +726,9 @@ void CPPCodeGenerator::writePrivateVars() {
726726
void CPPCodeGenerator::writePrivateVarValues() {
727727
for (const auto& p : fProgram) {
728728
if (ProgramElement::kVar_Kind == p.fKind) {
729-
const VarDeclarations& decls = (const VarDeclarations&) p;
729+
const VarDeclarations& decls = p.as<VarDeclarations>();
730730
for (const auto& raw : decls.fVars) {
731-
VarDeclaration& decl = (VarDeclaration&) *raw;
731+
VarDeclaration& decl = raw->as<VarDeclaration>();
732732
if (is_private(*decl.fVar) && decl.fValue) {
733733
this->writef("%s = ", String(decl.fVar->fName).c_str());
734734
fCPPMode = true;
@@ -943,9 +943,9 @@ bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
943943
fFullName.c_str(), fFullName.c_str());
944944
for (const auto& p : fProgram) {
945945
if (ProgramElement::kVar_Kind == p.fKind) {
946-
const VarDeclarations& decls = (const VarDeclarations&) p;
946+
const VarDeclarations& decls = p.as<VarDeclarations>();
947947
for (const auto& raw : decls.fVars) {
948-
VarDeclaration& decl = (VarDeclaration&) *raw;
948+
VarDeclaration& decl = raw->as<VarDeclaration>();
949949
String nameString(decl.fVar->fName);
950950
const char* name = nameString.c_str();
951951
if (SectionAndParameterHelper::IsParameter(*decl.fVar) &&
@@ -1059,9 +1059,9 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
10591059
int samplerIndex = 0;
10601060
for (const auto& p : fProgram) {
10611061
if (ProgramElement::kVar_Kind == p.fKind) {
1062-
const VarDeclarations& decls = (const VarDeclarations&) p;
1062+
const VarDeclarations& decls = p.as<VarDeclarations>();
10631063
for (const std::unique_ptr<Statement>& raw : decls.fVars) {
1064-
const VarDeclaration& decl = static_cast<VarDeclaration&>(*raw);
1064+
const VarDeclaration& decl = raw->as<VarDeclaration>();
10651065
const Variable& variable = *decl.fVar;
10661066
String nameString(variable.fName);
10671067
const char* name = nameString.c_str();
@@ -1233,9 +1233,9 @@ void CPPCodeGenerator::writeGetKey() {
12331233
fFullName.c_str());
12341234
for (const auto& p : fProgram) {
12351235
if (ProgramElement::kVar_Kind == p.fKind) {
1236-
const VarDeclarations& decls = (const VarDeclarations&) p;
1236+
const VarDeclarations& decls = p.as<VarDeclarations>();
12371237
for (const auto& raw : decls.fVars) {
1238-
const VarDeclaration& decl = (VarDeclaration&) *raw;
1238+
const VarDeclaration& decl = raw->as<VarDeclaration>();
12391239
const Variable& var = *decl.fVar;
12401240
String nameString(var.fName);
12411241
const char* name = nameString.c_str();
@@ -1311,9 +1311,9 @@ bool CPPCodeGenerator::generateCode() {
13111311
std::vector<const Variable*> uniforms;
13121312
for (const auto& p : fProgram) {
13131313
if (ProgramElement::kVar_Kind == p.fKind) {
1314-
const VarDeclarations& decls = (const VarDeclarations&) p;
1314+
const VarDeclarations& decls = p.as<VarDeclarations>();
13151315
for (const auto& raw : decls.fVars) {
1316-
VarDeclaration& decl = (VarDeclaration&) *raw;
1316+
VarDeclaration& decl = raw->as<VarDeclaration>();
13171317
if ((decl.fVar->fModifiers.fFlags & Modifiers::kUniform_Flag) &&
13181318
decl.fVar->fType.kind() != Type::kSampler_Kind) {
13191319
uniforms.push_back(decl.fVar);

src/sksl/SkSLCompiler.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static void grab_intrinsics(std::vector<std::unique_ptr<ProgramElement>>* src,
7575
std::unique_ptr<ProgramElement>& element = *iter;
7676
switch (element->fKind) {
7777
case ProgramElement::kFunction_Kind: {
78-
FunctionDefinition& f = (FunctionDefinition&) *element;
78+
FunctionDefinition& f = element->as<FunctionDefinition>();
7979
SkASSERT(f.fDeclaration.fBuiltin);
8080
String key = f.fDeclaration.description();
8181
SkASSERT(target->find(key) == target->end());
@@ -84,7 +84,7 @@ static void grab_intrinsics(std::vector<std::unique_ptr<ProgramElement>>* src,
8484
break;
8585
}
8686
case ProgramElement::kEnum_Kind: {
87-
Enum& e = (Enum&) *element;
87+
Enum& e = element->as<Enum>();
8888
StringFragment name = e.fTypeName;
8989
SkASSERT(target->find(name) == target->end());
9090
(*target)[name] = std::make_pair(std::move(element), false);
@@ -1637,15 +1637,15 @@ bool Compiler::optimize(Program& program) {
16371637
fIRGenerator->fSettings = &program.fSettings;
16381638
for (auto& element : program) {
16391639
if (element.fKind == ProgramElement::kFunction_Kind) {
1640-
this->scanCFG((FunctionDefinition&) element);
1640+
this->scanCFG(element.as<FunctionDefinition>());
16411641
}
16421642
}
16431643
// we wait until after analysis to remove dead functions so that we still report errors
16441644
// even in unused code
16451645
if (program.fSettings.fRemoveDeadFunctions) {
16461646
for (auto iter = program.fElements.begin(); iter != program.fElements.end(); ) {
16471647
if ((*iter)->fKind == ProgramElement::kFunction_Kind) {
1648-
const FunctionDefinition& f = (const FunctionDefinition&) **iter;
1648+
const FunctionDefinition& f = (*iter)->as<FunctionDefinition>();
16491649
if (!f.fDeclaration.fCallCount && f.fDeclaration.fName != "main") {
16501650
iter = program.fElements.erase(iter);
16511651
continue;
@@ -1657,7 +1657,7 @@ bool Compiler::optimize(Program& program) {
16571657
if (program.fKind != Program::kFragmentProcessor_Kind) {
16581658
for (auto iter = program.fElements.begin(); iter != program.fElements.end();) {
16591659
if ((*iter)->fKind == ProgramElement::kVar_Kind) {
1660-
VarDeclarations& vars = (VarDeclarations&) **iter;
1660+
VarDeclarations& vars = (*iter)->as<VarDeclarations>();
16611661
for (auto varIter = vars.fVars.begin(); varIter != vars.fVars.end();) {
16621662
const Variable& var = *((VarDeclaration&) **varIter).fVar;
16631663
if (var.dead()) {

src/sksl/SkSLDehydrator.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ void Dehydrator::write(const Statement* s) {
496496
void Dehydrator::write(const ProgramElement& e) {
497497
switch (e.fKind) {
498498
case ProgramElement::kEnum_Kind: {
499-
Enum& en = (Enum&) e;
499+
const Enum& en = e.as<Enum>();
500500
this->writeU8(Rehydrator::kEnum_Command);
501501
this->write(en.fTypeName);
502502
AutoDehydratorSymbolTable symbols(this, en.fSymbols);
@@ -513,7 +513,7 @@ void Dehydrator::write(const ProgramElement& e) {
513513
SkASSERT(false);
514514
break;
515515
case ProgramElement::kFunction_Kind: {
516-
FunctionDefinition& f = (FunctionDefinition&) e;
516+
const FunctionDefinition& f = e.as<FunctionDefinition>();
517517
this->writeU8(Rehydrator::kFunctionDefinition_Command);
518518
this->writeU16(this->symbolId(&f.fDeclaration));
519519
this->write(f.fBody.get());
@@ -528,7 +528,7 @@ void Dehydrator::write(const ProgramElement& e) {
528528
break;
529529
}
530530
case ProgramElement::kInterfaceBlock_Kind: {
531-
InterfaceBlock& i = (InterfaceBlock&) e;
531+
const InterfaceBlock& i = e.as<InterfaceBlock>();
532532
this->writeU8(Rehydrator::kInterfaceBlock_Command);
533533
this->write(i.fVariable);
534534
this->write(i.fTypeName);
@@ -546,7 +546,7 @@ void Dehydrator::write(const ProgramElement& e) {
546546
SkASSERT(false);
547547
break;
548548
case ProgramElement::kVar_Kind: {
549-
VarDeclarations& v = (VarDeclarations&) e;
549+
const VarDeclarations& v = e.as<VarDeclarations>();
550550
this->writeU8(Rehydrator::kVarDeclarations_Command);
551551
this->write(v.fBaseType);
552552
this->writeU8(v.fVars.size());

src/sksl/SkSLGLSLCodeGenerator.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,7 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
12451245
OutputStream* oldOut = fOut;
12461246
StringStream buffer;
12471247
fOut = &buffer;
1248-
this->writeStatements(((Block&) *f.fBody).fStatements);
1248+
this->writeStatements(f.fBody->as<Block>().fStatements);
12491249
if (fProgramKind != Program::kPipelineStage_Kind) {
12501250
fIndentation--;
12511251
this->writeLine("}");
@@ -1416,7 +1416,7 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g
14161416
}
14171417
bool wroteType = false;
14181418
for (const auto& stmt : decl.fVars) {
1419-
VarDeclaration& var = (VarDeclaration&) *stmt;
1419+
const VarDeclaration& var = stmt->as<VarDeclaration>();
14201420
if (wroteType) {
14211421
this->write(", ");
14221422
} else {
@@ -1460,7 +1460,7 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g
14601460
void GLSLCodeGenerator::writeStatement(const Statement& s) {
14611461
switch (s.fKind) {
14621462
case Statement::kBlock_Kind:
1463-
this->writeBlock((Block&) s);
1463+
this->writeBlock(s.as<Block>());
14641464
break;
14651465
case Statement::kExpression_Kind:
14661466
this->writeExpression(*s.as<ExpressionStatement>().fExpression, kTopLevel_Precedence);
@@ -1666,19 +1666,19 @@ void GLSLCodeGenerator::writeHeader() {
16661666
void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
16671667
switch (e.fKind) {
16681668
case ProgramElement::kExtension_Kind:
1669-
this->writeExtension(((Extension&) e).fName);
1669+
this->writeExtension(e.as<Extension>().fName);
16701670
break;
16711671
case ProgramElement::kVar_Kind: {
1672-
VarDeclarations& decl = (VarDeclarations&) e;
1672+
const VarDeclarations& decl = e.as<VarDeclarations>();
16731673
if (decl.fVars.size() > 0) {
1674-
int builtin = ((VarDeclaration&) *decl.fVars[0]).fVar->fModifiers.fLayout.fBuiltin;
1674+
int builtin = decl.fVars[0]->as<VarDeclaration>().fVar->fModifiers.fLayout.fBuiltin;
16751675
if (builtin == -1) {
16761676
// normal var
16771677
this->writeVarDeclarations(decl, true);
16781678
this->writeLine();
16791679
} else if (builtin == SK_FRAGCOLOR_BUILTIN &&
16801680
fProgram.fSettings.fCaps->mustDeclareFragmentShaderOutput() &&
1681-
((VarDeclaration&) *decl.fVars[0]).fVar->fWriteCount) {
1681+
decl.fVars[0]->as<VarDeclaration>().fVar->fWriteCount) {
16821682
if (fProgram.fSettings.fFragColorIsInOut) {
16831683
this->write("inout ");
16841684
} else {
@@ -1693,13 +1693,13 @@ void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
16931693
break;
16941694
}
16951695
case ProgramElement::kInterfaceBlock_Kind:
1696-
this->writeInterfaceBlock((InterfaceBlock&) e);
1696+
this->writeInterfaceBlock(e.as<InterfaceBlock>());
16971697
break;
16981698
case ProgramElement::kFunction_Kind:
1699-
this->writeFunction((FunctionDefinition&) e);
1699+
this->writeFunction(e.as<FunctionDefinition>());
17001700
break;
17011701
case ProgramElement::kModifiers_Kind: {
1702-
const Modifiers& modifiers = ((ModifiersDeclaration&) e).fModifiers;
1702+
const Modifiers& modifiers = e.as<ModifiersDeclaration>().fModifiers;
17031703
if (!fFoundGSInvocations && modifiers.fLayout.fInvocations >= 0) {
17041704
if (fProgram.fSettings.fCaps->gsInvocationsExtensionString()) {
17051705
this->writeExtension(fProgram.fSettings.fCaps->gsInvocationsExtensionString());

0 commit comments

Comments
 (0)