• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/private/SkSLModifiers.h"
12 #include "include/private/SkSLSymbol.h"
13 #include "src/sksl/ir/SkSLExpression.h"
14 #include "src/sksl/ir/SkSLType.h"
15 #include "src/sksl/ir/SkSLVariableReference.h"
16 
17 namespace SkSL {
18 
19 class Expression;
20 class VarDeclaration;
21 
22 namespace dsl {
23 class DSLCore;
24 class DSLFunction;
25 } // namespace dsl
26 
27 enum class VariableStorage : int8_t {
28     kGlobal,
29     kInterfaceBlock,
30     kLocal,
31     kParameter
32 };
33 
34 /**
35  * Represents a variable, whether local, global, or a function parameter. This represents the
36  * variable itself (the storage location), which is shared between all VariableReferences which
37  * read or write that storage location.
38  */
39 class Variable final : public Symbol {
40 public:
41     using Storage = VariableStorage;
42 
43     inline static constexpr Kind kSymbolKind = Kind::kVariable;
44 
Variable(int line,const Modifiers * modifiers,skstd::string_view name,const Type * type,bool builtin,Storage storage)45     Variable(int line, const Modifiers* modifiers, skstd::string_view name, const Type* type,
46              bool builtin, Storage storage)
47     : INHERITED(line, kSymbolKind, name, type)
48     , fModifiers(modifiers)
49     , fStorage(storage)
50     , fBuiltin(builtin) {}
51 
52     ~Variable() override;
53 
54     static std::unique_ptr<Variable> Convert(const Context& context, int line,
55             const Modifiers& modifiers, const Type* baseType, skstd::string_view name, bool isArray,
56             std::unique_ptr<Expression> arraySize, Variable::Storage storage);
57 
58     static std::unique_ptr<Variable> Make(const Context& context, int line,
59             const Modifiers& modifiers, const Type* baseType, skstd::string_view name, bool isArray,
60             std::unique_ptr<Expression> arraySize, Variable::Storage storage);
61 
62     /**
63      * Creates a local scratch variable and the associated VarDeclaration statement.
64      * Useful when doing IR rewrites, e.g. inlining a function call.
65      */
66     struct ScratchVariable {
67         const Variable* fVarSymbol;
68         std::unique_ptr<Statement> fVarDecl;
69     };
70     static ScratchVariable MakeScratchVariable(const Context& context,
71                                                skstd::string_view baseName,
72                                                const Type* type,
73                                                const Modifiers& modifiers,
74                                                SymbolTable* symbolTable,
75                                                std::unique_ptr<Expression> initialValue);
modifiers()76     const Modifiers& modifiers() const {
77         return *fModifiers;
78     }
79 
setModifiers(const Modifiers * modifiers)80     void setModifiers(const Modifiers* modifiers) {
81         fModifiers = modifiers;
82     }
83 
isBuiltin()84     bool isBuiltin() const {
85         return fBuiltin;
86     }
87 
storage()88     Storage storage() const {
89         return (Storage) fStorage;
90     }
91 
92     const Expression* initialValue() const;
93 
setDeclaration(VarDeclaration * declaration)94     void setDeclaration(VarDeclaration* declaration) {
95         SkASSERT(!fDeclaration);
96         fDeclaration = declaration;
97     }
98 
detachDeadVarDeclaration()99     void detachDeadVarDeclaration() const {
100         // The VarDeclaration is being deleted, so our reference to it has become stale.
101         // This variable is now dead, so it shouldn't matter that we are modifying its symbol.
102         const_cast<Variable*>(this)->fDeclaration = nullptr;
103     }
104 
description()105     String description() const override {
106         return this->modifiers().description() + this->type().name() + " " + this->name();
107     }
108 
109 private:
110     VarDeclaration* fDeclaration = nullptr;
111     const Modifiers* fModifiers;
112     VariableStorage fStorage;
113     bool fBuiltin;
114 
115     using INHERITED = Symbol;
116 
117     friend class dsl::DSLCore;
118     friend class dsl::DSLFunction;
119     friend class VariableReference;
120 };
121 
122 } // namespace SkSL
123 
124 #endif
125