Line data Source code
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 "SkSLExpression.h"
12 : #include "SkSLFloatLiteral.h"
13 : #include "SkSLIRGenerator.h"
14 : #include "SkSLIntLiteral.h"
15 :
16 : namespace SkSL {
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 : */
25 : struct VariableReference : public Expression {
26 : enum RefKind {
27 : kRead_RefKind,
28 : kWrite_RefKind,
29 : kReadWrite_RefKind
30 : };
31 :
32 0 : VariableReference(Position position, const Variable& variable, RefKind refKind = kRead_RefKind)
33 0 : : INHERITED(position, kVariableReference_Kind, variable.fType)
34 : , fVariable(variable)
35 0 : , fRefKind(refKind) {
36 0 : if (refKind != kRead_RefKind) {
37 0 : fVariable.fWriteCount++;
38 : }
39 0 : if (refKind != kWrite_RefKind) {
40 0 : fVariable.fReadCount++;
41 : }
42 0 : }
43 :
44 0 : virtual ~VariableReference() override {
45 0 : if (fRefKind != kWrite_RefKind) {
46 0 : fVariable.fReadCount--;
47 : }
48 0 : }
49 :
50 : RefKind refKind() {
51 : return fRefKind;
52 : }
53 :
54 0 : void setRefKind(RefKind refKind) {
55 0 : if (fRefKind != kRead_RefKind) {
56 0 : fVariable.fWriteCount--;
57 : }
58 0 : if (fRefKind != kWrite_RefKind) {
59 0 : fVariable.fReadCount--;
60 : }
61 0 : if (refKind != kRead_RefKind) {
62 0 : fVariable.fWriteCount++;
63 : }
64 0 : if (refKind != kWrite_RefKind) {
65 0 : fVariable.fReadCount++;
66 : }
67 0 : fRefKind = refKind;
68 0 : }
69 :
70 0 : String description() const override {
71 0 : return fVariable.fName;
72 : }
73 :
74 0 : virtual std::unique_ptr<Expression> constantPropagate(
75 : const IRGenerator& irGenerator,
76 : const DefinitionMap& definitions) override {
77 0 : auto exprIter = definitions.find(&fVariable);
78 0 : if (exprIter != definitions.end() && exprIter->second) {
79 0 : const Expression* expr = exprIter->second->get();
80 0 : switch (expr->fKind) {
81 : case Expression::kIntLiteral_Kind:
82 : return std::unique_ptr<Expression>(new IntLiteral(
83 : irGenerator.fContext,
84 0 : Position(),
85 0 : ((IntLiteral*) expr)->fValue));
86 : case Expression::kFloatLiteral_Kind:
87 : return std::unique_ptr<Expression>(new FloatLiteral(
88 : irGenerator.fContext,
89 0 : Position(),
90 0 : ((FloatLiteral*) expr)->fValue));
91 : default:
92 0 : break;
93 : }
94 : }
95 0 : return nullptr;
96 : }
97 :
98 : const Variable& fVariable;
99 :
100 : private:
101 : RefKind fRefKind;
102 :
103 : typedef Expression INHERITED;
104 : };
105 :
106 : } // namespace
107 :
108 : #endif
|