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_VARIABLE
9#define SKSL_VARIABLE
10
11#include "SkSLModifiers.h"
12#include "SkSLPosition.h"
13#include "SkSLSymbol.h"
14#include "SkSLType.h"
15
16namespace SkSL {
17
18struct Expression;
19
20/**
21 * Represents a variable, whether local, global, or a function parameter. This represents the
22 * variable itself (the storage location), which is shared between all VariableReferences which
23 * read or write that storage location.
24 */
25struct Variable : public Symbol {
26    enum Storage {
27        kGlobal_Storage,
28        kLocal_Storage,
29        kParameter_Storage
30    };
31
32    Variable(int offset, Modifiers modifiers, StringFragment name, const Type& type,
33             Storage storage, Expression* initialValue = nullptr)
34    : INHERITED(offset, kVariable_Kind, name)
35    , fModifiers(modifiers)
36    , fType(type)
37    , fStorage(storage)
38    , fInitialValue(initialValue)
39    , fReadCount(0)
40    , fWriteCount(0) {}
41
42    virtual String description() const override {
43        return fModifiers.description() + fType.fName + " " + fName;
44    }
45
46    bool dead() const {
47        return !fWriteCount || (!fReadCount && !(fModifiers.fFlags & Modifiers::kOut_Flag));
48    }
49
50    mutable Modifiers fModifiers;
51    const Type& fType;
52    const Storage fStorage;
53
54    Expression* fInitialValue = nullptr;
55
56    // Tracks how many sites read from the variable. If this is zero for a non-out variable (or
57    // becomes zero during optimization), the variable is dead and may be eliminated.
58    mutable int fReadCount;
59    // Tracks how many sites write to the variable. If this is zero, the variable is dead and may be
60    // eliminated.
61    mutable int fWriteCount;
62
63    typedef Symbol INHERITED;
64};
65
66} // namespace SkSL
67
68#endif
69