blob: 95c7ce130707cbb0ecd6489fba95807b9137dbcf [file] [log] [blame]
Michael Ludwig8f3a8362020-06-29 17:27:00 -04001/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkSLAnalysis_DEFINED
9#define SkSLAnalysis_DEFINED
10
John Stilesdce4d3e2020-09-25 14:35:13 -040011#include <vector>
12
Brian Osman1298bc42020-06-30 13:39:35 -040013#include "include/private/SkSLSampleUsage.h"
Michael Ludwig8f3a8362020-06-29 17:27:00 -040014#include "src/sksl/SkSLDefines.h"
15
16namespace SkSL {
17
John Stilesdce4d3e2020-09-25 14:35:13 -040018class ErrorReporter;
Michael Ludwig8f3a8362020-06-29 17:27:00 -040019struct Expression;
Ethan Nicholas6e0fa402020-08-20 14:08:23 -040020struct FunctionDefinition;
Michael Ludwig8f3a8362020-06-29 17:27:00 -040021struct Program;
22struct ProgramElement;
23struct Statement;
24struct Variable;
John Stilesdce4d3e2020-09-25 14:35:13 -040025struct VariableReference;
Michael Ludwig8f3a8362020-06-29 17:27:00 -040026
27/**
28 * Provides utilities for analyzing SkSL statically before it's composed into a full program.
29 */
30struct Analysis {
Brian Osman1298bc42020-06-30 13:39:35 -040031 static SampleUsage GetSampleUsage(const Program& program, const Variable& fp);
Michael Ludwig8f3a8362020-06-29 17:27:00 -040032
Brian Osman92aac1e2020-08-05 16:48:58 -040033 static bool ReferencesBuiltin(const Program& program, int builtin);
34
Michael Ludwig8f3a8362020-06-29 17:27:00 -040035 static bool ReferencesSampleCoords(const Program& program);
Brian Osman92aac1e2020-08-05 16:48:58 -040036 static bool ReferencesFragCoords(const Program& program);
Ethan Nicholas6e0fa402020-08-20 14:08:23 -040037
38 static int NodeCount(const FunctionDefinition& function);
Ethan Nicholas765d2fe2020-08-26 08:29:55 -040039
40 static bool StatementWritesToVariable(const Statement& stmt, const Variable& var);
John Stilesa976da72020-09-25 23:06:26 -040041 static bool IsAssignable(Expression& expr, VariableReference** assignableVar,
42 ErrorReporter* errors = nullptr);
Michael Ludwig8f3a8362020-06-29 17:27:00 -040043};
44
45/**
46 * Utility class to visit every element, statement, and expression in an SkSL program IR.
47 * This is intended for simple analysis and accumulation, where custom visitation behavior is only
48 * needed for a limited set of expression kinds.
49 *
50 * Subclasses should override visitExpression/visitStatement/visitProgramElement as needed and
51 * intercept elements of interest. They can then invoke the base class's function to visit all
52 * sub expressions. They can also choose not to call the base function to arrest recursion, or
53 * implement custom recursion.
54 *
55 * The visit functions return a bool that determines how the default implementation recurses. Once
56 * any visit call returns true, the default behavior stops recursing and propagates true up the
57 * stack.
58 */
59
John Stiles70b82422020-09-30 10:55:12 -040060template <typename PROG, typename EXPR, typename STMT, typename ELEM>
61class TProgramVisitor {
Michael Ludwig8f3a8362020-06-29 17:27:00 -040062public:
John Stiles70b82422020-09-30 10:55:12 -040063 virtual ~TProgramVisitor() = default;
Michael Ludwig8f3a8362020-06-29 17:27:00 -040064
John Stiles70b82422020-09-30 10:55:12 -040065 bool visit(PROG program);
Michael Ludwig8f3a8362020-06-29 17:27:00 -040066
67protected:
John Stiles70b82422020-09-30 10:55:12 -040068 virtual bool visitExpression(EXPR expression);
69 virtual bool visitStatement(STMT statement);
70 virtual bool visitProgramElement(ELEM programElement);
Michael Ludwig8f3a8362020-06-29 17:27:00 -040071};
72
John Stiles70b82422020-09-30 10:55:12 -040073// Squelch bogus Clang warning about template vtables: https://bugs.llvm.org/show_bug.cgi?id=18733
74#if defined(__clang__)
75#pragma clang diagnostic push
76#pragma clang diagnostic ignored "-Wweak-template-vtables"
77#endif
78extern template class TProgramVisitor<const Program&, const Expression&,
79 const Statement&, const ProgramElement&>;
80extern template class TProgramVisitor<Program&, Expression&, Statement&, ProgramElement&>;
81#if defined(__clang__)
82#pragma clang diagnostic pop
83#endif
84
85using ProgramVisitor = TProgramVisitor<const Program&, const Expression&,
86 const Statement&, const ProgramElement&>;
87using ProgramWriter = TProgramVisitor<Program&, Expression&, Statement&, ProgramElement&>;
88
John Stilesa6841be2020-08-06 14:11:56 -040089} // namespace SkSL
Michael Ludwig8f3a8362020-06-29 17:27:00 -040090
91#endif