1/*
2 * Copyright 2016 Google Inc.
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 SKSL_VARIABLEREFERENCE
9#define SKSL_VARIABLEREFERENCE
10
11#include "src/sksl/ir/SkSLExpression.h"
12#include "src/sksl/ir/SkSLVariable.h"
13
14namespace SkSL {
15
16class IRGenerator;
17
18/**
19 * A reference to a variable, through which it can be read or written. In the statement:
20 *
21 * x = x + 1;
22 *
23 * there is only one Variable 'x', but two VariableReferences to it.
24 */
25struct VariableReference : public Expression {
26 enum RefKind {
27 kRead_RefKind,
28 kWrite_RefKind,
29 kReadWrite_RefKind,
30 // taking the address of a variable - we consider this a read & write but don't complain if
31 // the variable was not previously assigned
32 kPointer_RefKind
33 };
34
35 VariableReference(int offset, const Variable& variable, RefKind refKind = kRead_RefKind);
36
37 ~VariableReference() override;
38
39 VariableReference(const VariableReference&) = delete;
40 VariableReference& operator=(const VariableReference&) = delete;
41
42 RefKind refKind() const {
43 return fRefKind;
44 }
45
46 void setRefKind(RefKind refKind);
47
48 bool hasProperty(Property property) const override {
49 switch (property) {
50 case Property::kSideEffects: return false;
51 case Property::kContainsRTAdjust: return fVariable.fName == "sk_RTAdjust";
52 default:
53 SkASSERT(false);
54 return false;
55 }
56 }
57
58 bool isConstantOrUniform() const override {
59 return (fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag) != 0;
60 }
61
62 int nodeCount() const override {
63 return 1;
64 }
65
66 std::unique_ptr<Expression> clone() const override {
67 return std::unique_ptr<Expression>(new VariableReference(fOffset, fVariable, fRefKind));
68 }
69
70 String description() const override {
71 return fVariable.fName;
72 }
73
74 static std::unique_ptr<Expression> copy_constant(const IRGenerator& irGenerator,
75 const Expression* expr);
76
77 std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
78 const DefinitionMap& definitions) override;
79
80 const Variable& fVariable;
81 RefKind fRefKind;
82
83private:
84 typedef Expression INHERITED;
85};
86
87} // namespace SkSL
88
89#endif
90