Flutter Engine
The Flutter Engine
Public Member Functions | Protected Member Functions | List of all members
SkSL::TProgramVisitor< T > Class Template Referenceabstract

#include <SkSLProgramVisitor.h>

Public Member Functions

virtual ~TProgramVisitor ()=default
 

Protected Member Functions

virtual bool visitExpression (typename T::Expression &expression)
 
virtual bool visitStatement (typename T::Statement &statement)
 
virtual bool visitProgramElement (typename T::ProgramElement &programElement)
 
virtual bool visitExpressionPtr (typename T::UniquePtrExpression &expr)=0
 
virtual bool visitStatementPtr (typename T::UniquePtrStatement &stmt)=0
 

Detailed Description

template<typename T>
class SkSL::TProgramVisitor< T >

Utility class to visit every element, statement, and expression in an SkSL program IR. This is intended for simple analysis and accumulation, where custom visitation behavior is only needed for a limited set of expression kinds.

Subclasses should override visitExpression/visitStatement/visitProgramElement as needed and intercept elements of interest. They can then invoke the base class's function to visit all sub expressions. They can also choose not to call the base function to arrest recursion, or implement custom recursion.

The visit functions return a bool that determines how the default implementation recurses. Once any visit call returns true, the default behavior stops recursing and propagates true up the stack.

Definition at line 35 of file SkSLProgramVisitor.h.

Constructor & Destructor Documentation

◆ ~TProgramVisitor()

template<typename T >
virtual SkSL::TProgramVisitor< T >::~TProgramVisitor ( )
virtualdefault

Member Function Documentation

◆ visitExpression()

template<typename T >
bool SkSL::TProgramVisitor< T >::visitExpression ( typename T::Expression &  expression)
protectedvirtual

Definition at line 542 of file SkSLAnalysis.cpp.

542 {
543 switch (e.kind()) {
545 case Expression::Kind::kFunctionReference:
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:
552 // Leaf expressions return false
553 return false;
554
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()));
559 }
560 case Expression::Kind::kChildCall: {
561 // We don't visit the child variable itself, just the arguments
562 auto& c = e.template as<ChildCall>();
563 for (auto& arg : c.arguments()) {
564 if (arg && this->visitExpressionPtr(arg)) { return true; }
565 }
566 return false;
567 }
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; }
580 }
581 return false;
582 }
583 case Expression::Kind::kFieldAccess:
584 return this->visitExpressionPtr(e.template as<FieldAccess>().base());
585
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; }
590 }
591 return false;
592 }
594 auto& i = e.template as<IndexExpression>();
595 return this->visitExpressionPtr(i.base()) || this->visitExpressionPtr(i.index());
596 }
597 case Expression::Kind::kPostfix:
598 return this->visitExpressionPtr(e.template as<PostfixExpression>().operand());
599
600 case Expression::Kind::kPrefix:
601 return this->visitExpressionPtr(e.template as<PrefixExpression>().operand());
602
603 case Expression::Kind::kSwizzle: {
604 auto& s = e.template as<Swizzle>();
605 return s.base() && this->visitExpressionPtr(s.base());
606 }
607
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()));
613 }
614 default:
616 }
617}
#define SkUNREACHABLE
Definition: SkAssert.h:135
virtual bool visitExpressionPtr(typename T::UniquePtrExpression &expr)=0
static bool b
struct MyStruct s

◆ visitExpressionPtr()

template<typename T >
virtual bool SkSL::TProgramVisitor< T >::visitExpressionPtr ( typename T::UniquePtrExpression &  expr)
protectedpure virtual

◆ visitProgramElement()

template<typename T >
bool SkSL::TProgramVisitor< T >::visitProgramElement ( typename T::ProgramElement &  programElement)
protectedvirtual

Definition at line 677 of file SkSLAnalysis.cpp.

677 {
678 switch (pe.kind()) {
680 case ProgramElement::Kind::kFunctionPrototype:
681 case ProgramElement::Kind::kInterfaceBlock:
682 case ProgramElement::Kind::kModifiers:
683 case ProgramElement::Kind::kStructDefinition:
684 // Leaf program elements just return false by default
685 return false;
686
688 return this->visitStatementPtr(pe.template as<FunctionDefinition>().body());
689
690 case ProgramElement::Kind::kGlobalVar:
691 return this->visitStatementPtr(pe.template as<GlobalVarDeclaration>().declaration());
692
693 default:
695 }
696}
virtual bool visitStatementPtr(typename T::UniquePtrStatement &stmt)=0

◆ visitStatement()

template<typename T >
bool SkSL::TProgramVisitor< T >::visitStatement ( typename T::Statement &  statement)
protectedvirtual

Definition at line 619 of file SkSLAnalysis.cpp.

619 {
620 switch (s.kind()) {
621 case Statement::Kind::kBreak:
625 // Leaf statements just return false
626 return false;
627
628 case Statement::Kind::kBlock:
629 for (auto& stmt : s.template as<Block>().children()) {
630 if (stmt && this->visitStatementPtr(stmt)) {
631 return true;
632 }
633 }
634 return false;
635
636 case Statement::Kind::kSwitchCase: {
637 auto& sc = s.template as<SwitchCase>();
638 return this->visitStatementPtr(sc.statement());
639 }
640 case Statement::Kind::kDo: {
641 auto& d = s.template as<DoStatement>();
642 return this->visitExpressionPtr(d.test()) || this->visitStatementPtr(d.statement());
643 }
644 case Statement::Kind::kExpression:
645 return this->visitExpressionPtr(s.template as<ExpressionStatement>().expression());
646
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());
653 }
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()));
659 }
660 case Statement::Kind::kReturn: {
661 auto& r = s.template as<ReturnStatement>();
662 return r.expression() && this->visitExpressionPtr(r.expression());
663 }
664 case Statement::Kind::kSwitch: {
665 auto& sw = s.template as<SwitchStatement>();
666 return this->visitExpressionPtr(sw.value()) || this->visitStatementPtr(sw.caseBlock());
667 }
668 case Statement::Kind::kVarDeclaration: {
669 auto& v = s.template as<VarDeclaration>();
670 return v.value() && this->visitExpressionPtr(v.value());
671 }
672 default:
674 }
675}
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19

◆ visitStatementPtr()

template<typename T >
virtual bool SkSL::TProgramVisitor< T >::visitStatementPtr ( typename T::UniquePtrStatement &  stmt)
protectedpure virtual

The documentation for this class was generated from the following files: