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