37class ConstantExpressionVisitor :
public ProgramVisitor {
40 : fLoopIndices(loopIndices) {}
42 bool visitExpression(
const Expression& e)
override {
46 case Expression::Kind::kLiteral:
50 case Expression::Kind::kSetting:
55 case Expression::Kind::kVariableReference: {
56 const Variable* v =
e.as<VariableReference>().variable();
57 if (v->modifierFlags().isConst() && (v->storage() == Variable::Storage::kGlobal ||
58 v->storage() == Variable::Storage::kLocal)) {
61 return !fLoopIndices || !fLoopIndices->contains(v);
65 case Expression::Kind::kBinary:
66 if (
e.as<BinaryExpression>().getOperator().kind() == Operator::Kind::COMMA) {
72 case Expression::Kind::kConstructorArray:
73 case Expression::Kind::kConstructorArrayCast:
74 case Expression::Kind::kConstructorCompound:
75 case Expression::Kind::kConstructorCompoundCast:
76 case Expression::Kind::kConstructorDiagonalMatrix:
77 case Expression::Kind::kConstructorMatrixResize:
78 case Expression::Kind::kConstructorScalarCast:
79 case Expression::Kind::kConstructorSplat:
80 case Expression::Kind::kConstructorStruct:
81 case Expression::Kind::kFieldAccess:
82 case Expression::Kind::kIndex:
83 case Expression::Kind::kPrefix:
84 case Expression::Kind::kPostfix:
85 case Expression::Kind::kSwizzle:
86 case Expression::Kind::kTernary:
87 return INHERITED::visitExpression(e);
93 case Expression::Kind::kFunctionCall:
94 case Expression::Kind::kChildCall:
98 case Expression::Kind::kPoison:
99 case Expression::Kind::kFunctionReference:
100 case Expression::Kind::kMethodReference:
101 case Expression::Kind::kTypeReference:
102 case Expression::Kind::kEmpty:
118class ES2IndexingVisitor :
public ProgramVisitor {
120 ES2IndexingVisitor(ErrorReporter& errors) : fErrors(
errors) {}
122 bool visitStatement(
const Statement&
s)
override {
123 if (
s.is<ForStatement>()) {
124 const ForStatement&
f =
s.as<ForStatement>();
125 SkASSERT(
f.initializer() &&
f.initializer()->is<VarDeclaration>());
126 const Variable* var =
f.initializer()->as<VarDeclaration>().var();
127 SkASSERT(!fLoopIndices.contains(var));
128 fLoopIndices.add(var);
129 bool result = this->visitStatement(*
f.statement());
130 fLoopIndices.remove(var);
133 return INHERITED::visitStatement(
s);
136 bool visitExpression(
const Expression& e)
override {
137 if (
e.is<IndexExpression>()) {
138 const IndexExpression& i =
e.as<IndexExpression>();
139 if (ConstantExpressionVisitor{&fLoopIndices}.visitExpression(*i.index())) {
140 fErrors.error(i.fPosition,
"index expression must be constant");
144 return INHERITED::visitExpression(e);
147 using ProgramVisitor::visitProgramElement;
150 ErrorReporter& fErrors;
158 return !ConstantExpressionVisitor{
nullptr}.visitExpression(expr);
162 ES2IndexingVisitor visitor(errors);
163 visitor.visitProgramElement(pe);
#define SkDEBUGFAIL(message)
#define INHERITED(method,...)
bool IsConstantExpression(const Expression &expr)
void ValidateIndexingForES2(const ProgramElement &pe, ErrorReporter &errors)