blob: 7d90511590b4e600e2651364da65a253ac385d5e [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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"
Hal Canary6b20a552017-02-07 14:09:38 -050012#include "SkSLFloatLiteral.h"
13#include "SkSLIRGenerator.h"
14#include "SkSLIntLiteral.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070015
16namespace 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 */
25struct VariableReference : public Expression {
Ethan Nicholas86a43402017-01-19 13:32:00 -050026 enum RefKind {
27 kRead_RefKind,
28 kWrite_RefKind,
29 kReadWrite_RefKind
30 };
31
32 VariableReference(Position position, const Variable& variable, RefKind refKind = kRead_RefKind)
ethannicholasd598f792016-07-25 10:08:54 -070033 : INHERITED(position, kVariableReference_Kind, variable.fType)
Ethan Nicholas86a43402017-01-19 13:32:00 -050034 , fVariable(variable)
35 , fRefKind(refKind) {
36 if (refKind != kRead_RefKind) {
37 fVariable.fWriteCount++;
38 }
39 if (refKind != kWrite_RefKind) {
40 fVariable.fReadCount++;
41 }
42 }
43
Ethan Nicholase1d9cb82017-02-06 18:53:07 +000044 virtual ~VariableReference() override {
Ethan Nicholas86a43402017-01-19 13:32:00 -050045 if (fRefKind != kWrite_RefKind) {
46 fVariable.fReadCount--;
47 }
48 }
49
50 RefKind refKind() {
51 return fRefKind;
52 }
53
54 void setRefKind(RefKind refKind) {
55 if (fRefKind != kRead_RefKind) {
56 fVariable.fWriteCount--;
57 }
58 if (fRefKind != kWrite_RefKind) {
59 fVariable.fReadCount--;
60 }
61 if (refKind != kRead_RefKind) {
62 fVariable.fWriteCount++;
63 }
64 if (refKind != kWrite_RefKind) {
65 fVariable.fReadCount++;
66 }
67 fRefKind = refKind;
68 }
ethannicholasb3058bd2016-07-01 08:22:01 -070069
Ethan Nicholas9e1138d2016-11-21 10:39:35 -050070 SkString description() const override {
ethannicholasd598f792016-07-25 10:08:54 -070071 return fVariable.fName;
ethannicholasb3058bd2016-07-01 08:22:01 -070072 }
73
Ethan Nicholase1d9cb82017-02-06 18:53:07 +000074 virtual std::unique_ptr<Expression> constantPropagate(
75 const IRGenerator& irGenerator,
76 const DefinitionMap& definitions) override {
Ethan Nicholas86a43402017-01-19 13:32:00 -050077 auto exprIter = definitions.find(&fVariable);
78 if (exprIter != definitions.end() && exprIter->second) {
79 const Expression* expr = exprIter->second->get();
80 switch (expr->fKind) {
81 case Expression::kIntLiteral_Kind:
82 return std::unique_ptr<Expression>(new IntLiteral(
83 irGenerator.fContext,
84 Position(),
85 ((IntLiteral*) expr)->fValue));
86 case Expression::kFloatLiteral_Kind:
87 return std::unique_ptr<Expression>(new FloatLiteral(
88 irGenerator.fContext,
89 Position(),
90 ((FloatLiteral*) expr)->fValue));
91 default:
92 break;
93 }
94 }
95 return nullptr;
96 }
97
ethannicholasd598f792016-07-25 10:08:54 -070098 const Variable& fVariable;
Ethan Nicholas86a43402017-01-19 13:32:00 -050099
Ethan Nicholas113628d2017-02-02 16:11:39 -0500100private:
Ethan Nicholase1d9cb82017-02-06 18:53:07 +0000101 RefKind fRefKind;
102
ethannicholasb3058bd2016-07-01 08:22:01 -0700103 typedef Expression INHERITED;
104};
105
106} // namespace
107
108#endif