432 bool visitExpression(
const Expression& expr)
override {
433 switch (expr.
kind()) {
434 case Expression::Kind::kLiteral:
438 case Expression::Kind::kConstructorArray:
439 case Expression::Kind::kConstructorCompound:
440 case Expression::Kind::kConstructorDiagonalMatrix:
441 case Expression::Kind::kConstructorMatrixResize:
442 case Expression::Kind::kConstructorSplat:
443 case Expression::Kind::kConstructorStruct:
448 return INHERITED::visitExpression(expr);
457 bool fIsConstant =
true;
461 IsCompileTimeConstantVisitor visitor;
462 visitor.visitExpression(expr);
463 return visitor.fIsConstant;
544 case Expression::Kind::kEmpty:
545 case Expression::Kind::kFunctionReference:
546 case Expression::Kind::kLiteral:
547 case Expression::Kind::kMethodReference:
548 case Expression::Kind::kPoison:
549 case Expression::Kind::kSetting:
550 case Expression::Kind::kTypeReference:
551 case Expression::Kind::kVariableReference:
555 case Expression::Kind::kBinary: {
556 auto&
b = e.template as<BinaryExpression>();
557 return (
b.left() && this->visitExpressionPtr(
b.left())) ||
558 (
b.right() && this->visitExpressionPtr(
b.right()));
560 case Expression::Kind::kChildCall: {
562 auto& c = e.template as<ChildCall>();
563 for (
auto& arg : c.arguments()) {
564 if (arg && this->visitExpressionPtr(arg)) {
return true; }
568 case Expression::Kind::kConstructorArray:
569 case Expression::Kind::kConstructorArrayCast:
570 case Expression::Kind::kConstructorCompound:
571 case Expression::Kind::kConstructorCompoundCast:
572 case Expression::Kind::kConstructorDiagonalMatrix:
573 case Expression::Kind::kConstructorMatrixResize:
574 case Expression::Kind::kConstructorScalarCast:
575 case Expression::Kind::kConstructorSplat:
576 case Expression::Kind::kConstructorStruct: {
577 auto& c = e.asAnyConstructor();
578 for (
auto& arg : c.argumentSpan()) {
579 if (this->visitExpressionPtr(arg)) {
return true; }
583 case Expression::Kind::kFieldAccess:
584 return this->visitExpressionPtr(e.template as<FieldAccess>().base());
586 case Expression::Kind::kFunctionCall: {
587 auto& c = e.template as<FunctionCall>();
588 for (
auto& arg : c.arguments()) {
589 if (arg && this->visitExpressionPtr(arg)) {
return true; }
593 case Expression::Kind::kIndex: {
594 auto& i = e.template as<IndexExpression>();
595 return this->visitExpressionPtr(i.base()) || this->visitExpressionPtr(i.index());
597 case Expression::Kind::kPostfix:
598 return this->visitExpressionPtr(e.template as<PostfixExpression>().operand());
600 case Expression::Kind::kPrefix:
601 return this->visitExpressionPtr(e.template as<PrefixExpression>().operand());
603 case Expression::Kind::kSwizzle: {
604 auto&
s = e.template as<Swizzle>();
605 return s.base() && this->visitExpressionPtr(
s.base());
608 case Expression::Kind::kTernary: {
609 auto& t = e.template as<TernaryExpression>();
610 return this->visitExpressionPtr(t.test()) ||
611 (t.ifTrue() && this->visitExpressionPtr(t.ifTrue())) ||
612 (t.ifFalse() && this->visitExpressionPtr(t.ifFalse()));
621 case Statement::Kind::kBreak:
622 case Statement::Kind::kContinue:
623 case Statement::Kind::kDiscard:
624 case Statement::Kind::kNop:
628 case Statement::Kind::kBlock:
629 for (
auto& stmt :
s.template as<Block>().children()) {
630 if (stmt && this->visitStatementPtr(stmt)) {
636 case Statement::Kind::kSwitchCase: {
637 auto& sc =
s.template as<SwitchCase>();
638 return this->visitStatementPtr(sc.statement());
640 case Statement::Kind::kDo: {
641 auto&
d =
s.template as<DoStatement>();
642 return this->visitExpressionPtr(
d.test()) || this->visitStatementPtr(
d.statement());
644 case Statement::Kind::kExpression:
645 return this->visitExpressionPtr(
s.template as<ExpressionStatement>().expression());
647 case Statement::Kind::kFor: {
648 auto& f =
s.template as<ForStatement>();
649 return (f.initializer() && this->visitStatementPtr(f.initializer())) ||
650 (f.test() && this->visitExpressionPtr(f.test())) ||
651 (f.next() && this->visitExpressionPtr(f.next())) ||
652 this->visitStatementPtr(f.statement());
654 case Statement::Kind::kIf: {
655 auto& i =
s.template as<IfStatement>();
656 return (i.test() && this->visitExpressionPtr(i.test())) ||
657 (i.ifTrue() && this->visitStatementPtr(i.ifTrue())) ||
658 (i.ifFalse() && this->visitStatementPtr(i.ifFalse()));
660 case Statement::Kind::kReturn: {
661 auto& r =
s.template as<ReturnStatement>();
662 return r.expression() && this->visitExpressionPtr(r.expression());
664 case Statement::Kind::kSwitch: {
665 auto& sw =
s.template as<SwitchStatement>();
666 return this->visitExpressionPtr(sw.value()) || this->visitStatementPtr(sw.caseBlock());
668 case Statement::Kind::kVarDeclaration: {
669 auto& v =
s.template as<VarDeclaration>();
670 return v.value() && this->visitExpressionPtr(v.value());
679 case ProgramElement::Kind::kExtension:
680 case ProgramElement::Kind::kFunctionPrototype:
681 case ProgramElement::Kind::kInterfaceBlock:
682 case ProgramElement::Kind::kModifiers:
683 case ProgramElement::Kind::kStructDefinition:
687 case ProgramElement::Kind::kFunction:
688 return this->visitStatementPtr(pe.template as<FunctionDefinition>().body());
690 case ProgramElement::Kind::kGlobalVar:
691 return this->visitStatementPtr(pe.template as<GlobalVarDeclaration>().declaration());